Introduce trace verbosity config and produce less spans by default
This commit is contained in:
parent
77ef7fe490
commit
8c23eb6833
93 changed files with 1005 additions and 524 deletions
|
|
@ -48,11 +48,17 @@ func newEntryPoint(ctx context.Context, tracer *tracing.Tracer, entryPointName s
|
|||
}
|
||||
|
||||
func (e *entryPointTracing) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
|
||||
if e.tracer == nil || !TracingEnabled(req.Context()) {
|
||||
e.next.ServeHTTP(rw, req)
|
||||
return
|
||||
}
|
||||
|
||||
tracingCtx := tracing.ExtractCarrierIntoContext(req.Context(), req.Header)
|
||||
start := time.Now()
|
||||
tracingCtx, span := e.tracer.Start(tracingCtx, "EntryPoint", trace.WithSpanKind(trace.SpanKindServer), trace.WithTimestamp(start))
|
||||
|
||||
// Associate the request context with the logger.
|
||||
// This allows the logger to be aware of the tracing context and log accordingly (TraceID, SpanID, etc.).
|
||||
logger := log.Ctx(tracingCtx).With().Ctx(tracingCtx).Logger()
|
||||
loggerCtx := logger.WithContext(tracingCtx)
|
||||
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ import (
|
|||
|
||||
// Traceable embeds tracing information.
|
||||
type Traceable interface {
|
||||
GetTracingInformation() (name string, typeName string, spanKind trace.SpanKind)
|
||||
GetTracingInformation() (name string, typeName string)
|
||||
}
|
||||
|
||||
// WrapMiddleware adds traceability to an alice.Constructor.
|
||||
|
|
@ -29,21 +29,20 @@ func WrapMiddleware(ctx context.Context, constructor alice.Constructor) alice.Co
|
|||
}
|
||||
|
||||
if traceableHandler, ok := handler.(Traceable); ok {
|
||||
name, typeName, spanKind := traceableHandler.GetTracingInformation()
|
||||
name, typeName := traceableHandler.GetTracingInformation()
|
||||
log.Ctx(ctx).Debug().Str(logs.MiddlewareName, name).Msg("Adding tracing to middleware")
|
||||
return NewMiddleware(handler, name, typeName, spanKind), nil
|
||||
return NewMiddleware(handler, name, typeName), nil
|
||||
}
|
||||
return handler, nil
|
||||
}
|
||||
}
|
||||
|
||||
// NewMiddleware returns a http.Handler struct.
|
||||
func NewMiddleware(next http.Handler, name string, typeName string, spanKind trace.SpanKind) http.Handler {
|
||||
func NewMiddleware(next http.Handler, name string, typeName string) http.Handler {
|
||||
return &middlewareTracing{
|
||||
next: next,
|
||||
name: name,
|
||||
typeName: typeName,
|
||||
spanKind: spanKind,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -52,12 +51,11 @@ type middlewareTracing struct {
|
|||
next http.Handler
|
||||
name string
|
||||
typeName string
|
||||
spanKind trace.SpanKind
|
||||
}
|
||||
|
||||
func (w *middlewareTracing) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
|
||||
if tracer := tracing.TracerFromContext(req.Context()); tracer != nil {
|
||||
tracingCtx, span := tracer.Start(req.Context(), w.typeName, trace.WithSpanKind(w.spanKind))
|
||||
if tracer := tracing.TracerFromContext(req.Context()); tracer != nil && DetailedTracingEnabled(req.Context()) {
|
||||
tracingCtx, span := tracer.Start(req.Context(), w.typeName, trace.WithSpanKind(trace.SpanKindInternal))
|
||||
defer span.End()
|
||||
|
||||
req = req.WithContext(tracingCtx)
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package observability
|
|||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"go.opentelemetry.io/otel/codes"
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
|
|
@ -10,8 +11,58 @@ import (
|
|||
|
||||
type contextKey int
|
||||
|
||||
// DisableMetricsKey is a context key used to disable the metrics.
|
||||
const DisableMetricsKey contextKey = iota
|
||||
const observabilityKey contextKey = iota
|
||||
|
||||
type Observability struct {
|
||||
AccessLogsEnabled bool
|
||||
MetricsEnabled bool
|
||||
SemConvMetricsEnabled bool
|
||||
TracingEnabled bool
|
||||
DetailedTracingEnabled bool
|
||||
}
|
||||
|
||||
// WithObservabilityHandler sets the observability state in the context for the next handler.
|
||||
// This is also used for testing purposes to control whether access logs are enabled or not.
|
||||
func WithObservabilityHandler(next http.Handler, obs Observability) http.Handler {
|
||||
return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
|
||||
next.ServeHTTP(rw, req.WithContext(WithObservability(req.Context(), obs)))
|
||||
})
|
||||
}
|
||||
|
||||
// WithObservability injects the observability state into the context.
|
||||
func WithObservability(ctx context.Context, obs Observability) context.Context {
|
||||
return context.WithValue(ctx, observabilityKey, obs)
|
||||
}
|
||||
|
||||
// AccessLogsEnabled returns whether access-logs are enabled.
|
||||
func AccessLogsEnabled(ctx context.Context) bool {
|
||||
obs, ok := ctx.Value(observabilityKey).(Observability)
|
||||
return ok && obs.AccessLogsEnabled
|
||||
}
|
||||
|
||||
// MetricsEnabled returns whether metrics are enabled.
|
||||
func MetricsEnabled(ctx context.Context) bool {
|
||||
obs, ok := ctx.Value(observabilityKey).(Observability)
|
||||
return ok && obs.MetricsEnabled
|
||||
}
|
||||
|
||||
// SemConvMetricsEnabled returns whether metrics are enabled.
|
||||
func SemConvMetricsEnabled(ctx context.Context) bool {
|
||||
obs, ok := ctx.Value(observabilityKey).(Observability)
|
||||
return ok && obs.SemConvMetricsEnabled
|
||||
}
|
||||
|
||||
// TracingEnabled returns whether tracing is enabled.
|
||||
func TracingEnabled(ctx context.Context) bool {
|
||||
obs, ok := ctx.Value(observabilityKey).(Observability)
|
||||
return ok && obs.TracingEnabled
|
||||
}
|
||||
|
||||
// DetailedTracingEnabled returns whether detailed tracing is enabled.
|
||||
func DetailedTracingEnabled(ctx context.Context) bool {
|
||||
obs, ok := ctx.Value(observabilityKey).(Observability)
|
||||
return ok && obs.DetailedTracingEnabled
|
||||
}
|
||||
|
||||
// SetStatusErrorf flags the span as in error and log an event.
|
||||
func SetStatusErrorf(ctx context.Context, format string, args ...interface{}) {
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ func newRouter(ctx context.Context, router, routerRule, service string, next htt
|
|||
}
|
||||
|
||||
func (f *routerTracing) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
|
||||
if tracer := tracing.TracerFromContext(req.Context()); tracer != nil {
|
||||
if tracer := tracing.TracerFromContext(req.Context()); tracer != nil && DetailedTracingEnabled(req.Context()) {
|
||||
tracingCtx, span := tracer.Start(req.Context(), "Router", trace.WithSpanKind(trace.SpanKindInternal))
|
||||
defer span.End()
|
||||
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ func newServerMetricsSemConv(ctx context.Context, semConvMetricRegistry *metrics
|
|||
}
|
||||
|
||||
func (e *semConvServerMetrics) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
|
||||
if e.semConvMetricRegistry == nil || e.semConvMetricRegistry.HTTPServerRequestDuration() == nil {
|
||||
if e.semConvMetricRegistry == nil || e.semConvMetricRegistry.HTTPServerRequestDuration() == nil || !SemConvMetricsEnabled(req.Context()) {
|
||||
e.next.ServeHTTP(rw, req)
|
||||
return
|
||||
}
|
||||
|
|
|
|||
|
|
@ -83,6 +83,11 @@ func TestSemConvServerMetrics(t *testing.T) {
|
|||
handler, err = capture.Wrap(handler)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Injection of the observability variables in the request context.
|
||||
handler = WithObservabilityHandler(handler, Observability{
|
||||
SemConvMetricsEnabled: true,
|
||||
})
|
||||
|
||||
handler.ServeHTTP(rw, req)
|
||||
|
||||
got := metricdata.ResourceMetrics{}
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ func NewService(ctx context.Context, service string, next http.Handler) http.Han
|
|||
}
|
||||
|
||||
func (t *serviceTracing) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
|
||||
if tracer := tracing.TracerFromContext(req.Context()); tracer != nil {
|
||||
if tracer := tracing.TracerFromContext(req.Context()); tracer != nil && DetailedTracingEnabled(req.Context()) {
|
||||
tracingCtx, span := tracer.Start(req.Context(), "Service", trace.WithSpanKind(trace.SpanKindInternal))
|
||||
defer span.End()
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue