英文:
Golang prometheus: is there a way to measure metrics for outbound requests?
问题
我有一个服务A,我正在使用Prometheus抓取指标,A会向另一个服务B发出一些出站请求。有没有办法获取从A到B的请求指标?我想要统计A到B请求的数量和持续时间。
英文:
I have a service A where I am scrapping metrics using prometheus, A makes some outbound requests to another service B. Is there a way to get metrics for requets from A to B?
Like, I want a measure count and duration of requets from A -> B
答案1
得分: 3
指标可以使用prometheus.NewCounterVec和prometheus.NewHistogramVec(或proemetheus.NewSummaryVec,具体取决于用例)进行记录。
我们可以使用自定义标签来标识客户端和服务器。通过这种方式,可以将客户端的“请求计数”和“持续时间”指标过滤到特定的服务器。
以下是示例代码片段:
client.go
package main
import (
"net/http"
"time"
"github.com/labstack/echo/v4"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
)
var (
requestCounter = prometheus.NewCounterVec(
prometheus.CounterOpts{
Name: "client_request_count",
Help: "Total number of requests from client",
},
[]string{"client", "server", "method", "route", "status"},
)
durationHistogram = prometheus.NewHistogramVec(
prometheus.HistogramOpts{
Name: "client_request_duration_secs",
Help: "Duration of requests from Client",
Buckets: []float64{0.1, 0.5, 1, 2, 5},
},
[]string{"client", "server", "method", "route", "status"},
)
)
func init() {
prometheus.MustRegister(requestCounter)
prometheus.MustRegister(durationHistogram)
}
func main() {
e := echo.New()
e.GET("/", func(c echo.Context) error {
// 请求开始时间
start := time.Now()
req, err := http.NewRequest("GET", "http://localhost:8002", nil)
if err != nil {
return c.JSON(http.StatusInternalServerError, err.Error())
}
resp, err := http.DefaultClient.Do(req)
if err != nil {
return c.JSON(http.StatusInternalServerError, err.Error())
}
defer resp.Body.Close()
labels := prometheus.Labels{
"client": "Server A", // 定义客户端服务器
"server": "Server B", // 定义出站请求服务器
"method": "GET", // HTTP方法
"route": "/", // 请求路由
"status": resp.Status, // 响应状态
}
duration := time.Since(start).Seconds()
// 持续时间
durationHistogram.With(labels).Observe(duration)
// 请求API计数
requestCounter.With(labels).Inc()
return c.String(http.StatusOK, "[Client -> Server] Request send and received")
})
e.GET("/metrics", echo.WrapHandler(promhttp.Handler()))
if err := e.Start(":8001"); err != nil {
panic(err)
}
}
server.go
package main
import (
"net/http"
"github.com/labstack/echo/v4"
)
func main() {
e := echo.New()
e.GET("/", func(c echo.Context) error {
return c.JSON(http.StatusOK, map[string]interface{}{
"message": "response sending from server",
})
})
if err := e.Start(":8002"); err != nil {
panic(err)
}
}
正如您在代码中所看到的,这些是我们的自定义标签。
[]string{"client", "server", "method", "route", "status"},
这些是标签值
labels := prometheus.Labels{
"client": "Server A", // 定义客户端服务器
"server": "Server B", // 定义出站请求服务器
"method": "GET", // HTTP方法
"route": "/", // 请求路由
"status": resp.Status, // 响应状态
}
最后,我们可以查询
client_request_count{client="Server A", server="Server B"}
请求由Server A发送到Server B
参考资料
英文:
The metrics can be record by using prometheus.NewCounterVec and prometheus.NewHistogramVec (or proemetheus.NewSummaryVec, depends on the use case).
We could use custom labels to identify who is the client and who is the server. By this way, can filter out a client's request count and duration metrics to a particular server.
Here is the sample snippet
client.go
package main
import (
"net/http"
"time"
"github.com/labstack/echo/v4"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
)
var (
requestCounter = prometheus.NewCounterVec(
prometheus.CounterOpts{
Name: "client_request_count",
Help: "Total number of requests from client",
},
[]string{"client", "server", "method", "route", "status"},
)
durationHistorgram = prometheus.NewHistogramVec(
prometheus.HistogramOpts{
Name: "client_request_duration_secs",
Help: "Duration of requests from Client",
Buckets: []float64{0.1, 0.5, 1, 2, 5},
},
[]string{"client", "server", "method", "route", "status"},
)
)
func init() {
prometheus.MustRegister(requestCounter)
prometheus.MustRegister(durationHistorgram)
}
func main() {
e := echo.New()
e.GET("/", func(c echo.Context) error {
// the request start time
start := time.Now()
req, err := http.NewRequest("GET", "http://localhost:8002", nil)
if err != nil {
return c.JSON(http.StatusInternalServerError, err.Error())
}
resp, err := http.DefaultClient.Do(req)
if err != nil {
return c.JSON(http.StatusInternalServerError, err.Error())
}
defer resp.Body.Close()
labels := prometheus.Labels{
"client": "Server A", // defines the client server
"server": "Server B", // defines the outbound request server
"method": "GET",// HTTP method
"route": "/", // Request route
"status": resp.Status,// Response status
}
duration := time.Since(start).Seconds()
// the duration
durationHistorgram.With(labels).Observe(duration)
// request api count
requestCounter.With(labels).Inc()
return c.String(http.StatusOK, "[Client -> Server] Request send and received")
})
e.GET("/metrics", echo.WrapHandler(promhttp.Handler()))
if err := e.Start(":8001"); err != nil {
panic(err)
}
}
server.go
package main
import (
"net/http"
"github.com/labstack/echo/v4"
)
func main() {
e := echo.New()
e.GET("/", func(c echo.Context) error {
return c.JSON(http.StatusOK, map[string]interface{}{
"message": "response sending from server",
})
})
if err := e.Start(":8002"); err != nil {
panic(err)
}
}
As you can see in the code, these are our custom labels.
[]string{"client", "server", "method", "route", "status"},
and these are the label values
labels := prometheus.Labels{
"client": "Server A", // defines the client server
"server": "Server B", // defines the outbound request server
"method": "GET", // HTTP method
"route": "/", // Request route
"status": resp.Status,// Response status
}
and finally we can query
client_request_count {client="Server A", server="Server B"}
The request Server A send to the Server B
References
答案2
得分: 0
你可以为HTTP请求实现拦截器-https://morioh.com/p/c67b06c88598
捕获请求的开始和结束时间以计算持续时间。还可以增加计数器来获取从服务A到服务B的请求数量。
英文:
You can implement interceptor for http requests - https://morioh.com/p/c67b06c88598
Capture start and end time for the requests to calculate the duration. Also increment the gauge counter to get the number of requests made from service A to Service B.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。



评论