英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论