(latencyMetricsName string, registerer prometheus.Registerer)
| 508 | } |
| 509 | |
| 510 | // Create new logger with fields and pass along |
| 511 | requestLogger := GetLogger(rootCtx).WithFields(logFields) |
| 512 | next.ServeHTTP(rw, r.WithContext(WithLogger(r.Context(), requestLogger))) |
| 513 | }) |
| 514 | } |
| 515 | } |
| 516 | |
| 517 | func metricsMiddleware(latencyMetricsName string, registerer prometheus.Registerer) mux.MiddlewareFunc { |
| 518 | var latency *prometheus.HistogramVec |
| 519 | var count *prometheus.CounterVec |
| 520 | if latencyMetricsName != "" { |
| 521 | latency = prometheus.NewHistogramVec(prometheus.HistogramOpts{ |
| 522 | Name: fmt.Sprintf("%s_http_duration_seconds", latencyMetricsName), |
| 523 | Help: "Duration of HTTP requests.", |
| 524 | }, []string{"path", "method"}) |
| 525 | count = prometheus.NewCounterVec(prometheus.CounterOpts{ |
| 526 | Name: fmt.Sprintf("%s_http_request_counts", latencyMetricsName), |
| 527 | Help: "Counter of HTTP requests.", |
| 528 | }, []string{"path", "method", "status_code"}) |
| 529 | |
| 530 | registerer.MustRegister(latency) |
| 531 | registerer.MustRegister(count) |
| 532 | } |
| 533 | |
| 534 | return func(next http.Handler) http.Handler { |
| 535 | return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { |
| 536 | log := GetLogger(r.Context()) |
| 537 | w := getRRW(rw) |
| 538 | defer func() { |
| 539 | log.WithField("status_code", w.statusCode).Debugf("Handler finished") |
| 540 | if count != nil { |
| 541 | count.WithLabelValues(r.URL.Path, r.Method, fmt.Sprintf("%d", w.statusCode)).Inc() |
| 542 | } |
| 543 | // TODO(mcamp) this is a hack to get lightstep to recognize the span |
| 544 | // as an error. Either lightstep launcher or otelmux (probably the latter) should give us |
| 545 | // a hook to set this attribute. Until then we'll just set it here. |
| 546 | if v, _ := semconv.SpanStatusFromHTTPStatusCode(w.statusCode); v == codes.Error { |
| 547 | trace.SpanFromContext(r.Context()).SetAttributes(attribute.Bool("error", true)) |
| 548 | } |
| 549 | // Return the writer back to the pool |
| 550 | putRRW(w) |
| 551 | }() |
| 552 | log.Debugf("Handler started") |
| 553 | |
| 554 | if latency != nil { |
| 555 | timer := prometheus.NewTimer(latency.WithLabelValues(r.URL.Path, r.Method)) |
| 556 | next.ServeHTTP(w.writer, r) |
| 557 | timer.ObserveDuration() |
| 558 | } else { |
| 559 | next.ServeHTTP(w.writer, r) |
no test coverage detected