blob: e09acf022fa11c27ae0c1ca34034a6abf0e41146 [file] [log] [blame]
Abhay Kumar40252eb2025-10-13 13:25:53 +00001// Copyright The OpenTelemetry Authors
2// SPDX-License-Identifier: Apache-2.0
3
4package sdk
5
6import (
7 "context"
Abhay Kumar062cda52025-12-23 06:49:37 +00008 "math"
Abhay Kumar40252eb2025-10-13 13:25:53 +00009 "time"
10
11 "go.opentelemetry.io/otel/trace"
12 "go.opentelemetry.io/otel/trace/noop"
13
14 "go.opentelemetry.io/auto/sdk/internal/telemetry"
15)
16
17type tracer struct {
18 noop.Tracer
19
20 name, schemaURL, version string
21}
22
23var _ trace.Tracer = tracer{}
24
Abhay Kumar062cda52025-12-23 06:49:37 +000025func (t tracer) Start(
26 ctx context.Context,
27 name string,
28 opts ...trace.SpanStartOption,
29) (context.Context, trace.Span) {
30 var psc, sc trace.SpanContext
Abhay Kumar40252eb2025-10-13 13:25:53 +000031 sampled := true
32 span := new(span)
33
34 // Ask eBPF for sampling decision and span context info.
Abhay Kumar062cda52025-12-23 06:49:37 +000035 t.start(ctx, span, &psc, &sampled, &sc)
Abhay Kumar40252eb2025-10-13 13:25:53 +000036
37 span.sampled.Store(sampled)
Abhay Kumar062cda52025-12-23 06:49:37 +000038 span.spanContext = sc
Abhay Kumar40252eb2025-10-13 13:25:53 +000039
40 ctx = trace.ContextWithSpan(ctx, span)
41
42 if sampled {
43 // Only build traces if sampled.
44 cfg := trace.NewSpanStartConfig(opts...)
45 span.traces, span.span = t.traces(name, cfg, span.spanContext, psc)
46 }
47
48 return ctx, span
49}
50
51// Expected to be implemented in eBPF.
52//
53//go:noinline
54func (t *tracer) start(
55 ctx context.Context,
56 spanPtr *span,
57 psc *trace.SpanContext,
58 sampled *bool,
59 sc *trace.SpanContext,
60) {
61 start(ctx, spanPtr, psc, sampled, sc)
62}
63
64// start is used for testing.
65var start = func(context.Context, *span, *trace.SpanContext, *bool, *trace.SpanContext) {}
66
Abhay Kumar062cda52025-12-23 06:49:37 +000067var intToUint32Bound = min(math.MaxInt, math.MaxUint32)
68
69func (t tracer) traces(
70 name string,
71 cfg trace.SpanConfig,
72 sc, psc trace.SpanContext,
73) (*telemetry.Traces, *telemetry.Span) {
Abhay Kumar40252eb2025-10-13 13:25:53 +000074 span := &telemetry.Span{
75 TraceID: telemetry.TraceID(sc.TraceID()),
76 SpanID: telemetry.SpanID(sc.SpanID()),
77 Flags: uint32(sc.TraceFlags()),
78 TraceState: sc.TraceState().String(),
79 ParentSpanID: telemetry.SpanID(psc.SpanID()),
80 Name: name,
81 Kind: spanKind(cfg.SpanKind()),
82 }
83
84 span.Attrs, span.DroppedAttrs = convCappedAttrs(maxSpan.Attrs, cfg.Attributes())
85
86 links := cfg.Links()
87 if limit := maxSpan.Links; limit == 0 {
Abhay Kumar062cda52025-12-23 06:49:37 +000088 n := len(links)
89 if n > 0 {
90 bounded := max(min(n, intToUint32Bound), 0)
91 span.DroppedLinks = uint32(bounded) //nolint:gosec // Bounds checked.
92 }
Abhay Kumar40252eb2025-10-13 13:25:53 +000093 } else {
94 if limit > 0 {
95 n := max(len(links)-limit, 0)
Abhay Kumar062cda52025-12-23 06:49:37 +000096 bounded := min(n, intToUint32Bound)
97 span.DroppedLinks = uint32(bounded) //nolint:gosec // Bounds checked.
Abhay Kumar40252eb2025-10-13 13:25:53 +000098 links = links[n:]
99 }
100 span.Links = convLinks(links)
101 }
102
103 if t := cfg.Timestamp(); !t.IsZero() {
104 span.StartTime = cfg.Timestamp()
105 } else {
106 span.StartTime = time.Now()
107 }
108
109 return &telemetry.Traces{
110 ResourceSpans: []*telemetry.ResourceSpans{
111 {
112 ScopeSpans: []*telemetry.ScopeSpans{
113 {
114 Scope: &telemetry.Scope{
115 Name: t.name,
116 Version: t.version,
117 },
118 Spans: []*telemetry.Span{span},
119 SchemaURL: t.schemaURL,
120 },
121 },
122 },
123 },
124 }, span
125}
126
127func spanKind(kind trace.SpanKind) telemetry.SpanKind {
128 switch kind {
129 case trace.SpanKindInternal:
130 return telemetry.SpanKindInternal
131 case trace.SpanKindServer:
132 return telemetry.SpanKindServer
133 case trace.SpanKindClient:
134 return telemetry.SpanKindClient
135 case trace.SpanKindProducer:
136 return telemetry.SpanKindProducer
137 case trace.SpanKindConsumer:
138 return telemetry.SpanKindConsumer
139 }
140 return telemetry.SpanKind(0) // undefined.
141}