Golang prometheus:有没有一种方法可以测量出站请求的指标?

huangapple go评论88阅读模式
英文:

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.NewCounterVecprometheus.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

Golang prometheus:有没有一种方法可以测量出站请求的指标?

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.

huangapple
  • 本文由 发表于 2023年5月20日 04:45:03
  • 转载请务必保留本文链接:https://go.coder-hub.com/76292323.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定