4
4
package global
5
5
6
6
import (
7
+ "bytes"
7
8
"encoding/binary"
8
9
"fmt"
9
10
"log/slog"
10
11
"math"
12
+ "sync"
11
13
12
14
"go.opentelemetry.io/collector/pdata/pcommon"
13
15
"go.opentelemetry.io/collector/pdata/ptrace"
@@ -18,6 +20,7 @@ import (
18
20
"go.opentelemetry.io/auto/internal/pkg/process"
19
21
"go.opentelemetry.io/auto/internal/pkg/structfield"
20
22
23
+ "github.com/cilium/ebpf/perf"
21
24
"github.com/hashicorp/go-version"
22
25
"golang.org/x/sys/unix"
23
26
@@ -41,6 +44,17 @@ func New(logger *slog.Logger) probe.Probe {
41
44
SpanKind : trace .SpanKindClient ,
42
45
InstrumentedPkg : pkg ,
43
46
}
47
+
48
+ uprobeNewStart := & probe.Uprobe {
49
+ Sym : "go.opentelemetry.io/otel/internal/global.(*tracer).newSpan" ,
50
+ EntryProbe : "uprobe_newStart" ,
51
+ FailureMode : probe .FailureModeWarn ,
52
+ }
53
+
54
+ c := & converter {
55
+ logger : logger ,
56
+ uprobeNewStart : uprobeNewStart ,
57
+ }
44
58
return & probe.TraceProducer [bpfObjects , event ]{
45
59
Base : probe.Base [bpfObjects , event ]{
46
60
ID : id ,
@@ -107,12 +121,8 @@ func New(logger *slog.Logger) probe.Probe {
107
121
tracerIDContainsSchemaURL {},
108
122
tracerIDContainsScopeAttributes {},
109
123
},
110
- Uprobes : []probe.Uprobe {
111
- {
112
- Sym : "go.opentelemetry.io/otel/internal/global.(*tracer).newSpan" ,
113
- EntryProbe : "uprobe_newStart" ,
114
- FailureMode : probe .FailureModeWarn ,
115
- },
124
+ Uprobes : []* probe.Uprobe {
125
+ uprobeNewStart ,
116
126
{
117
127
Sym : "go.opentelemetry.io/otel/internal/global.(*tracer).Start" ,
118
128
EntryProbe : "uprobe_Start" ,
@@ -138,12 +148,55 @@ func New(logger *slog.Logger) probe.Probe {
138
148
FailureMode : probe .FailureModeIgnore ,
139
149
},
140
150
},
141
- SpecFn : loadBpf ,
151
+ SpecFn : loadBpf ,
152
+ ProcessRecord : c .decodeEvent ,
142
153
},
143
154
ProcessFn : processFn ,
144
155
}
145
156
}
146
157
158
+ type recordKind uint32
159
+
160
+ const (
161
+ recordKindTelemetry recordKind = iota
162
+ recordKindConrol
163
+ )
164
+
165
+ type converter struct {
166
+ logger * slog.Logger
167
+
168
+ uprobeNewStart * probe.Uprobe
169
+ uprobeNewStartMu sync.Mutex
170
+ }
171
+
172
+ func (c * converter ) decodeEvent (record perf.Record ) (* event , error ) {
173
+ reader := bytes .NewReader (record .RawSample )
174
+
175
+ var kind recordKind
176
+ err := binary .Read (reader , binary .LittleEndian , & kind )
177
+ if err != nil {
178
+ return nil , err
179
+ }
180
+
181
+ var e * event
182
+ switch kind {
183
+ case recordKindTelemetry :
184
+ e := new (event )
185
+ reader .Reset (record .RawSample )
186
+ err = binary .Read (reader , binary .LittleEndian , e )
187
+ case recordKindConrol :
188
+ c .uprobeNewStartMu .Lock ()
189
+ if c .uprobeNewStart != nil {
190
+ err = c .uprobeNewStart .Close ()
191
+ c .uprobeNewStart = nil
192
+ }
193
+ c .uprobeNewStartMu .Unlock ()
194
+ default :
195
+ err = fmt .Errorf ("unknown record kind: %d" , kind )
196
+ }
197
+ return e , err
198
+ }
199
+
147
200
// tracerIDContainsSchemaURL is a Probe Const defining whether the tracer key contains schemaURL.
148
201
type tracerIDContainsSchemaURL struct {}
149
202
0 commit comments