tracinghandler.go 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. package handler
  2. import (
  3. "net/http"
  4. "sync"
  5. "github.com/zeromicro/go-zero/core/lang"
  6. "github.com/zeromicro/go-zero/core/trace"
  7. "github.com/zeromicro/go-zero/rest/internal/response"
  8. "go.opentelemetry.io/otel"
  9. "go.opentelemetry.io/otel/propagation"
  10. semconv "go.opentelemetry.io/otel/semconv/v1.4.0"
  11. oteltrace "go.opentelemetry.io/otel/trace"
  12. )
  13. var notTracingSpans sync.Map
  14. // DontTraceSpan disable tracing for the specified span name.
  15. func DontTraceSpan(spanName string) {
  16. notTracingSpans.Store(spanName, lang.Placeholder)
  17. }
  18. // TracingHandler return a middleware that process the opentelemetry.
  19. func TracingHandler(serviceName, path string) func(http.Handler) http.Handler {
  20. return func(next http.Handler) http.Handler {
  21. propagator := otel.GetTextMapPropagator()
  22. tracer := otel.GetTracerProvider().Tracer(trace.TraceName)
  23. return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  24. spanName := path
  25. if len(spanName) == 0 {
  26. spanName = r.URL.Path
  27. }
  28. if _, ok := notTracingSpans.Load(spanName); ok {
  29. next.ServeHTTP(w, r)
  30. return
  31. }
  32. ctx := propagator.Extract(r.Context(), propagation.HeaderCarrier(r.Header))
  33. spanCtx, span := tracer.Start(
  34. ctx,
  35. spanName,
  36. oteltrace.WithSpanKind(oteltrace.SpanKindServer),
  37. oteltrace.WithAttributes(semconv.HTTPServerAttributesFromHTTPRequest(
  38. serviceName, spanName, r)...),
  39. )
  40. defer span.End()
  41. // convenient for tracking error messages
  42. propagator.Inject(spanCtx, propagation.HeaderCarrier(w.Header()))
  43. trw := &response.WithCodeResponseWriter{Writer: w, Code: http.StatusOK}
  44. next.ServeHTTP(trw, r.WithContext(spanCtx))
  45. span.SetAttributes(semconv.HTTPAttributesFromHTTPStatusCode(trw.Code)...)
  46. span.SetStatus(semconv.SpanStatusFromHTTPStatusCodeAndSpanKind(trw.Code, oteltrace.SpanKindServer))
  47. })
  48. }
  49. }