Skip to content
This repository was archived by the owner on Jan 21, 2025. It is now read-only.

Commit 495b053

Browse files
committed
reporter: attach thread ID to emitted profiles (#20)
get thread ID from bpf_get_current_uid_gid (based on https://man7.org/linux/man-pages/man7/bpf-helpers.7.html) and pass it down through the trace to the reporter. attach it to the emitted pprof as a label
1 parent e4fe4cd commit 495b053

File tree

13 files changed

+29
-6
lines changed

13 files changed

+29
-6
lines changed

host/host.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ type Trace struct {
5555
Hash TraceHash
5656
KTime util.KTime
5757
PID util.PID
58+
TID util.TID
5859
APMTraceID libpf.APMTraceID
5960
APMTransactionID libpf.APMTransactionID
6061
}

libpf/libpf.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ type TraceAndCounts struct {
8181
ContainerName string
8282
APMServiceName string
8383
PID util.PID
84+
TID util.TID
8485
}
8586

8687
type FrameMetadata struct {

reporter/datadog_reporter.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,8 @@ type DatadogReporter struct {
7575

7676
// ReportTraceEvent enqueues reported trace events for the Datadog reporter.
7777
func (r *DatadogReporter) ReportTraceEvent(trace *libpf.Trace, timestamp libpf.UnixTime64,
78-
comm, podName, containerID, containerName, apmServiceName string, pid util.PID) {
78+
comm, podName, containerID, containerName, apmServiceName string,
79+
pid util.PID, tid util.TID) {
7980
traceEvents := r.traceEvents.WLock()
8081
defer r.traceEvents.WUnlock(&traceEvents)
8182

@@ -95,6 +96,7 @@ func (r *DatadogReporter) ReportTraceEvent(trace *libpf.Trace, timestamp libpf.U
9596
containerName: containerName,
9697
apmServiceName: apmServiceName,
9798
pid: pid,
99+
tid: tid,
98100
timestamps: []uint64{uint64(timestamp)},
99101
}
100102
}
@@ -567,6 +569,13 @@ func addTraceLabels(labels map[string][]string, i traceFramesCounts) {
567569
if i.pid != 0 {
568570
labels["process_id"] = append(labels["process_id"], fmt.Sprintf("%d", i.pid))
569571
}
572+
573+
if i.tid != 0 {
574+
// The naming has an impact on the backend side,
575+
// this is why we use "thread id" instead of "thread_id"
576+
// This is also consistent with ddprof.
577+
labels["thread id"] = append(labels["thread id"], fmt.Sprintf("%d", i.tid))
578+
}
570579
}
571580

572581
// getDummyMappingIndex inserts or looks up a dummy entry for interpreted FileIDs.

reporter/iface.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,8 @@ type TraceReporter interface {
4141
// and caches it for reporting to the backend. It returns true if the event was
4242
// enqueued for reporting, and false if the event was ignored.
4343
ReportTraceEvent(trace *libpf.Trace, timestamp libpf.UnixTime64,
44-
comm, podName, containerID, containerName, apmServiceName string, pid util.PID)
44+
comm, podName, containerID, containerName, apmServiceName string,
45+
pid util.PID, tid util.TID)
4546

4647
// SupportsReportTraceEvent returns true if the reporter supports reporting trace events
4748
// via ReportTraceEvent().

reporter/otlp_reporter.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ type traceFramesCounts struct {
6767
containerName string
6868
apmServiceName string
6969
pid util.PID
70+
tid util.TID
7071
timestamps []uint64 // in nanoseconds
7172
}
7273

@@ -125,7 +126,7 @@ func (r *OTLPReporter) SupportsReportTraceEvent() bool { return true }
125126
// ReportTraceEvent enqueues reported trace events for the OTLP reporter.
126127
func (r *OTLPReporter) ReportTraceEvent(trace *libpf.Trace,
127128
timestamp libpf.UnixTime64, comm, podName, containerID,
128-
containerName, apmServiceName string, pid util.PID) {
129+
containerName, apmServiceName string, pid util.PID, tid util.TID) {
129130
traceEvents := r.traceEvents.WLock()
130131
defer r.traceEvents.WUnlock(&traceEvents)
131132

@@ -145,6 +146,7 @@ func (r *OTLPReporter) ReportTraceEvent(trace *libpf.Trace,
145146
containerName: containerName,
146147
apmServiceName: apmServiceName,
147148
pid: pid,
149+
tid: tid,
148150
timestamps: []uint64{uint64(timestamp)},
149151
}
150152
}
@@ -708,6 +710,7 @@ func getSampleAttributes(profile *profiles.Profile, i traceFramesCounts) []uint6
708710
addAttr(semconv.ThreadNameKey, i.comm)
709711
addAttr(semconv.ServiceNameKey, i.apmServiceName)
710712
addAttr("process_id", strconv.Itoa(int(i.pid)))
713+
addAttr(semconv.ThreadIDKey, strconv.Itoa(int(i.tid)))
711714

712715
return indices
713716
}

support/ebpf/native_stack_trace.ebpf.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -805,6 +805,7 @@ static inline
805805
int collect_trace(struct pt_regs *ctx) {
806806
// Get the PID and TGID register.
807807
u64 id = bpf_get_current_pid_tgid();
808+
u64 tid = id & 0xFFFFFFFF;
808809
u64 pid = id >> 32;
809810

810811
if (pid == 0) {
@@ -824,6 +825,7 @@ int collect_trace(struct pt_regs *ctx) {
824825
}
825826

826827
Trace *trace = &record->trace;
828+
trace->tid = tid;
827829
trace->pid = pid;
828830
trace->ktime = ktime;
829831
if (bpf_get_current_comm(&(trace->comm), sizeof(trace->comm)) < 0) {

support/ebpf/tracer.ebpf.arm64

56 Bytes
Binary file not shown.

support/ebpf/tracer.ebpf.x86

16 Bytes
Binary file not shown.

support/ebpf/types.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -516,6 +516,8 @@ typedef struct __attribute__((packed)) ApmCorrelationBuf {
516516
typedef struct Trace {
517517
// The process ID
518518
u32 pid;
519+
// The thread ID
520+
u32 tid;
519521
// Monotonic kernel time in nanosecond precision.
520522
u64 ktime;
521523
// The current COMM of the thread of this Trace.

tracehandler/tracehandler.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ func (m *traceHandler) HandleTrace(bpfTrace *host.Trace) {
159159
if m.reporter.SupportsReportTraceEvent() {
160160
m.reporter.ReportTraceEvent(umTrace, timestamp,
161161
bpfTrace.Comm, meta.PodName, meta.ContainerID, meta.ContainerName,
162-
svcName, bpfTrace.PID)
162+
svcName, bpfTrace.PID, bpfTrace.TID)
163163
return
164164
}
165165
m.reporter.ReportCountForTrace(umTrace.Hash, timestamp, 1,

tracehandler/tracehandler_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ func (m *mockReporter) ReportCountForTrace(traceHash libpf.TraceHash,
9090
func (m *mockReporter) SupportsReportTraceEvent() bool { return false }
9191

9292
func (m *mockReporter) ReportTraceEvent(_ *libpf.Trace,
93-
_ libpf.UnixTime64, _, _, _, _, _ string, _ util.PID) {
93+
_ libpf.UnixTime64, _, _, _, _, _ string, _ util.PID, _ util.TID) {
9494
}
9595

9696
type mockContainerMetadataHandler struct{}

tracer/tracer.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -853,13 +853,14 @@ func (t *Tracer) loadBpfTrace(raw []byte) *host.Trace {
853853
APMTraceID: *(*libpf.APMTraceID)(unsafe.Pointer(&ptr.apm_trace_id)),
854854
APMTransactionID: *(*libpf.APMTransactionID)(unsafe.Pointer(&ptr.apm_transaction_id)),
855855
PID: util.PID(ptr.pid),
856+
TID: util.TID(ptr.tid),
856857
KTime: util.KTime(ptr.ktime),
857858
}
858859

859860
// Trace fields included in the hash:
860861
// - PID, kernel stack ID, length & frame array
861862
// Intentionally excluded:
862-
// - ktime, COMM, APM trace, APM transaction ID
863+
// - ktime, COMM, TID, APM trace, APM transaction ID
863864
ptr.comm = [16]C.char{}
864865
ptr.apm_trace_id = C.ApmTraceID{}
865866
ptr.apm_transaction_id = C.ApmSpanID{}

util/util.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ func (p PID) Hash32() uint32 {
2525
return uint32(p)
2626
}
2727

28+
// TID represent a thread ID
29+
type TID int32
30+
2831
// HashString turns a string into a 64-bit hash.
2932
func HashString(s string) uint64 {
3033
h := fnv.New64a()

0 commit comments

Comments
 (0)