1 // Copyright The OpenTelemetry Authors
2 // SPDX-License-Identifier: Apache-2.0
3 4 // Package noop provides an implementation of the OpenTelemetry trace API that
5 // produces no telemetry and minimizes used computation resources.
6 //
7 // Using this package to implement the OpenTelemetry trace API will effectively
8 // disable OpenTelemetry.
9 //
10 // This implementation can be embedded in other implementations of the
11 // OpenTelemetry trace API. Doing so will mean the implementation defaults to
12 // no operation for methods it does not implement.
13 package noop // import "go.opentelemetry.io/otel/trace/noop"
14 15 import (
16 "context"
17 18 "go.opentelemetry.io/otel/attribute"
19 "go.opentelemetry.io/otel/codes"
20 "go.opentelemetry.io/otel/trace"
21 "go.opentelemetry.io/otel/trace/embedded"
22 )
23 24 var (
25 // Compile-time check this implements the OpenTelemetry API.
26 27 _ trace.TracerProvider = TracerProvider{}
28 _ trace.Tracer = Tracer{}
29 _ trace.Span = Span{}
30 )
31 32 // TracerProvider is an OpenTelemetry No-Op TracerProvider.
33 type TracerProvider struct{ embedded.TracerProvider }
34 35 // NewTracerProvider returns a TracerProvider that does not record any telemetry.
36 func NewTracerProvider() TracerProvider {
37 return TracerProvider{}
38 }
39 40 // Tracer returns an OpenTelemetry Tracer that does not record any telemetry.
41 func (TracerProvider) Tracer(string, ...trace.TracerOption) trace.Tracer {
42 return Tracer{}
43 }
44 45 // Tracer is an OpenTelemetry No-Op Tracer.
46 type Tracer struct{ embedded.Tracer }
47 48 // Start creates a span. The created span will be set in a child context of ctx
49 // and returned with the span.
50 //
51 // If ctx contains a span context, the returned span will also contain that
52 // span context. If the span context in ctx is for a non-recording span, that
53 // span instance will be returned directly.
54 func (Tracer) Start(ctx context.Context, _ string, _ ...trace.SpanStartOption) (context.Context, trace.Span) {
55 span := trace.SpanFromContext(ctx)
56 57 // If the parent context contains a non-zero span context, that span
58 // context needs to be returned as a non-recording span
59 // (https://github.com/open-telemetry/opentelemetry-specification/blob/3a1dde966a4ce87cce5adf464359fe369741bbea/specification/trace/api.md#behavior-of-the-api-in-the-absence-of-an-installed-sdk).
60 var zeroSC trace.SpanContext
61 if sc := span.SpanContext(); !sc.Equal(zeroSC) {
62 if !span.IsRecording() {
63 // If the span is not recording return it directly.
64 return ctx, span
65 }
66 // Otherwise, return the span context needs in a non-recording span.
67 span = Span{sc: sc}
68 } else {
69 // No parent, return a No-Op span with an empty span context.
70 span = noopSpanInstance
71 }
72 return trace.ContextWithSpan(ctx, span), span
73 }
74 75 var noopSpanInstance trace.Span = Span{}
76 77 // Span is an OpenTelemetry No-Op Span.
78 type Span struct {
79 embedded.Span
80 81 sc trace.SpanContext
82 }
83 84 // SpanContext returns an empty span context.
85 func (s Span) SpanContext() trace.SpanContext { return s.sc }
86 87 // IsRecording always returns false.
88 func (Span) IsRecording() bool { return false }
89 90 // SetStatus does nothing.
91 func (Span) SetStatus(codes.Code, string) {}
92 93 // SetAttributes does nothing.
94 func (Span) SetAttributes(...attribute.KeyValue) {}
95 96 // End does nothing.
97 func (Span) End(...trace.SpanEndOption) {}
98 99 // RecordError does nothing.
100 func (Span) RecordError(error, ...trace.EventOption) {}
101 102 // AddEvent does nothing.
103 func (Span) AddEvent(string, ...trace.EventOption) {}
104 105 // AddLink does nothing.
106 func (Span) AddLink(trace.Link) {}
107 108 // SetName does nothing.
109 func (Span) SetName(string) {}
110 111 // TracerProvider returns a No-Op TracerProvider.
112 func (Span) TracerProvider() trace.TracerProvider { return TracerProvider{} }
113