metricsinterceptor.go 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. package internal
  2. import (
  3. "net/http"
  4. "net/url"
  5. "strconv"
  6. "time"
  7. "github.com/zeromicro/go-zero/core/metric"
  8. "github.com/zeromicro/go-zero/core/timex"
  9. )
  10. const clientNamespace = "httpc_client"
  11. var (
  12. MetricClientReqDur = metric.NewHistogramVec(&metric.HistogramVecOpts{
  13. Namespace: clientNamespace,
  14. Subsystem: "requests",
  15. Name: "duration_ms",
  16. Help: "http client requests duration(ms).",
  17. Labels: []string{"name", "method", "url"},
  18. Buckets: []float64{0.25, 0.5, 1, 2, 5, 10, 25, 50, 100, 250, 500, 1000, 2000, 5000, 10000, 15000},
  19. })
  20. MetricClientReqCodeTotal = metric.NewCounterVec(&metric.CounterVecOpts{
  21. Namespace: clientNamespace,
  22. Subsystem: "requests",
  23. Name: "code_total",
  24. Help: "http client requests code count.",
  25. Labels: []string{"name", "method", "url", "code"},
  26. })
  27. )
  28. type (
  29. MetricsURLRewriter func(u url.URL) string
  30. )
  31. func MetricsInterceptor(name string, pr MetricsURLRewriter) Interceptor {
  32. return func(r *http.Request) (*http.Request, ResponseHandler) {
  33. startTime := timex.Now()
  34. return r, func(resp *http.Response, err error) {
  35. u := cleanURL(*r.URL)
  36. method := r.Method
  37. var (
  38. code int
  39. path string
  40. )
  41. // error or resp is nil, set code=500
  42. if err != nil || resp == nil {
  43. code = http.StatusInternalServerError
  44. } else {
  45. code = resp.StatusCode
  46. }
  47. if pr != nil {
  48. path = pr(u)
  49. } else {
  50. path = u.String()
  51. }
  52. MetricClientReqDur.ObserveFloat(float64(timex.Since(startTime))/float64(time.Millisecond), name, method, path)
  53. MetricClientReqCodeTotal.Inc(name, method, path, strconv.Itoa(code))
  54. }
  55. }
  56. }
  57. func cleanURL(r url.URL) url.URL {
  58. r.RawQuery = ""
  59. r.RawFragment = ""
  60. r.User = nil
  61. return r
  62. }