1
0
mirror of https://github.com/open-telemetry/opentelemetry-go.git synced 2024-12-26 21:05:00 +02:00
opentelemetry-go/trace/noop/noop.go
ttoad 86df763d90
trace: Span in noop.Start is no longer allocated (#5457)
trace/noop/noop.Span should be instance. This will reduce memory waste.

Benchmark results

with changes:
new.txt
```
goos: darwin
goarch: arm64
pkg: go.opentelemetry.io/otel/trace/noop
BenchmarkNoopInstance-10        29894822                39.94 ns/op           48 B/op          1 allocs/op
BenchmarkNoopInstance-10        29675424                39.99 ns/op           48 B/op          1 allocs/op
BenchmarkNoopInstance-10        30064700                39.98 ns/op           48 B/op          1 allocs/op
BenchmarkNoopInstance-10        29962016                40.03 ns/op           48 B/op          1 allocs/op
BenchmarkNoopInstance-10        30060465                40.02 ns/op           48 B/op          1 allocs/op
BenchmarkNoopInstance-10        29916855                40.04 ns/op           48 B/op          1 allocs/op
BenchmarkNoopInstance-10        29829998                40.28 ns/op           48 B/op          1 allocs/op
BenchmarkNoopInstance-10        30084706                39.99 ns/op           48 B/op          1 allocs/op
BenchmarkNoopInstance-10        30087441                40.02 ns/op           48 B/op          1 allocs/op
BenchmarkNoopInstance-10        29864365                40.14 ns/op           48 B/op          1 allocs/op
```
without changes on `main`:
old.txt
```
goos: darwin
goarch: arm64
pkg: go.opentelemetry.io/otel/trace/noop
BenchmarkNoopInstance-10        14813442                67.64 ns/op          128 B/op          2 allocs/op
BenchmarkNoopInstance-10        17714486                68.17 ns/op          128 B/op          2 allocs/op
BenchmarkNoopInstance-10        17701257                67.66 ns/op          128 B/op          2 allocs/op
BenchmarkNoopInstance-10        17805859                67.69 ns/op          128 B/op          2 allocs/op
BenchmarkNoopInstance-10        17912841                67.43 ns/op          128 B/op          2 allocs/op
BenchmarkNoopInstance-10        17864120                67.58 ns/op          128 B/op          2 allocs/op
BenchmarkNoopInstance-10        17663130                68.41 ns/op          128 B/op          2 allocs/op
BenchmarkNoopInstance-10        17740423                67.57 ns/op          128 B/op          2 allocs/op
BenchmarkNoopInstance-10        17751040                67.56 ns/op          128 B/op          2 allocs/op
BenchmarkNoopInstance-10        17738064                67.91 ns/op          128 B/op          2 allocs/op

```

benchstat: 
```
goos: darwin
goarch: arm64
pkg: go.opentelemetry.io/otel/trace/noop
                │   old.txt   │               new.txt               │
                │   sec/op    │   sec/op     vs base                │
NoopInstance-10   67.65n ± 1%   40.02n ± 0%  -40.84% (p=0.000 n=10)

                │   old.txt   │              new.txt               │
                │    B/op     │    B/op     vs base                │
NoopInstance-10   128.00 ± 0%   48.00 ± 0%  -62.50% (p=0.000 n=10)

                │  old.txt   │              new.txt               │
                │ allocs/op  │ allocs/op   vs base                │
NoopInstance-10   2.000 ± 0%   1.000 ± 0%  -50.00% (p=0.000 n=10)
```

Co-authored-by: Tyler Yahn <MrAlias@users.noreply.github.com>
2024-06-04 11:14:10 -07:00

113 lines
3.6 KiB
Go

// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0
// Package noop provides an implementation of the OpenTelemetry trace API that
// produces no telemetry and minimizes used computation resources.
//
// Using this package to implement the OpenTelemetry trace API will effectively
// disable OpenTelemetry.
//
// This implementation can be embedded in other implementations of the
// OpenTelemetry trace API. Doing so will mean the implementation defaults to
// no operation for methods it does not implement.
package noop // import "go.opentelemetry.io/otel/trace/noop"
import (
"context"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/codes"
"go.opentelemetry.io/otel/trace"
"go.opentelemetry.io/otel/trace/embedded"
)
var (
// Compile-time check this implements the OpenTelemetry API.
_ trace.TracerProvider = TracerProvider{}
_ trace.Tracer = Tracer{}
_ trace.Span = Span{}
)
// TracerProvider is an OpenTelemetry No-Op TracerProvider.
type TracerProvider struct{ embedded.TracerProvider }
// NewTracerProvider returns a TracerProvider that does not record any telemetry.
func NewTracerProvider() TracerProvider {
return TracerProvider{}
}
// Tracer returns an OpenTelemetry Tracer that does not record any telemetry.
func (TracerProvider) Tracer(string, ...trace.TracerOption) trace.Tracer {
return Tracer{}
}
// Tracer is an OpenTelemetry No-Op Tracer.
type Tracer struct{ embedded.Tracer }
// Start creates a span. The created span will be set in a child context of ctx
// and returned with the span.
//
// If ctx contains a span context, the returned span will also contain that
// span context. If the span context in ctx is for a non-recording span, that
// span instance will be returned directly.
func (t Tracer) Start(ctx context.Context, _ string, _ ...trace.SpanStartOption) (context.Context, trace.Span) {
span := trace.SpanFromContext(ctx)
// If the parent context contains a non-zero span context, that span
// context needs to be returned as a non-recording span
// (https://github.com/open-telemetry/opentelemetry-specification/blob/3a1dde966a4ce87cce5adf464359fe369741bbea/specification/trace/api.md#behavior-of-the-api-in-the-absence-of-an-installed-sdk).
var zeroSC trace.SpanContext
if sc := span.SpanContext(); !sc.Equal(zeroSC) {
if !span.IsRecording() {
// If the span is not recording return it directly.
return ctx, span
}
// Otherwise, return the span context needs in a non-recording span.
span = Span{sc: sc}
} else {
// No parent, return a No-Op span with an empty span context.
span = noopSpanInstance
}
return trace.ContextWithSpan(ctx, span), span
}
var noopSpanInstance trace.Span = Span{}
// Span is an OpenTelemetry No-Op Span.
type Span struct {
embedded.Span
sc trace.SpanContext
}
// SpanContext returns an empty span context.
func (s Span) SpanContext() trace.SpanContext { return s.sc }
// IsRecording always returns false.
func (Span) IsRecording() bool { return false }
// SetStatus does nothing.
func (Span) SetStatus(codes.Code, string) {}
// SetAttributes does nothing.
func (Span) SetAttributes(...attribute.KeyValue) {}
// End does nothing.
func (Span) End(...trace.SpanEndOption) {}
// RecordError does nothing.
func (Span) RecordError(error, ...trace.EventOption) {}
// AddEvent does nothing.
func (Span) AddEvent(string, ...trace.EventOption) {}
// AddLink does nothing.
func (Span) AddLink(trace.Link) {}
// SetName does nothing.
func (Span) SetName(string) {}
// TracerProvider returns a No-Op TracerProvider.
func (Span) TracerProvider() trace.TracerProvider { return TracerProvider{} }