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.
13package noop // import "go.opentelemetry.io/otel/trace/noop"
14
15import (
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
24var (
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.
33type TracerProvider struct{ embedded.TracerProvider }
34
35// NewTracerProvider returns a TracerProvider that does not record any telemetry.
36func NewTracerProvider() TracerProvider {
37 return TracerProvider{}
38}
39
40// Tracer returns an OpenTelemetry Tracer that does not record any telemetry.
41func (TracerProvider) Tracer(string, ...trace.TracerOption) trace.Tracer {
42 return Tracer{}
43}
44
45// Tracer is an OpenTelemetry No-Op Tracer.
46type 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.
54func (t 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
75var noopSpanInstance trace.Span = Span{}
76
77// Span is an OpenTelemetry No-Op Span.
78type Span struct {
79 embedded.Span
80
81 sc trace.SpanContext
82}
83
84// SpanContext returns an empty span context.
85func (s Span) SpanContext() trace.SpanContext { return s.sc }
86
87// IsRecording always returns false.
88func (Span) IsRecording() bool { return false }
89
90// SetStatus does nothing.
91func (Span) SetStatus(codes.Code, string) {}
92
93// SetAttributes does nothing.
94func (Span) SetAttributes(...attribute.KeyValue) {}
95
96// End does nothing.
97func (Span) End(...trace.SpanEndOption) {}
98
99// RecordError does nothing.
100func (Span) RecordError(error, ...trace.EventOption) {}
101
102// AddEvent does nothing.
103func (Span) AddEvent(string, ...trace.EventOption) {}
104
105// AddLink does nothing.
106func (Span) AddLink(trace.Link) {}
107
108// SetName does nothing.
109func (Span) SetName(string) {}
110
111// TracerProvider returns a No-Op TracerProvider.
112func (Span) TracerProvider() trace.TracerProvider { return TracerProvider{} }