Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 92 additions & 0 deletions internal/pkg/inject/offset_results.json
Original file line number Diff line number Diff line change
Expand Up @@ -939,6 +939,98 @@
]
}
]
},
{
"field": "name",
"offsets": [
{
"offset": null,
"versions": [
"0.1.0",
"0.1.1",
"0.1.2",
"0.2.0",
"0.2.1",
"0.2.2",
"0.2.3",
"0.3.0",
"0.4.0",
"0.4.1",
"0.4.2",
"0.4.3",
"0.5.0",
"0.6.0",
"0.7.0",
"0.8.0",
"0.9.0",
"0.10.0",
"0.11.0",
"0.12.0",
"0.13.0"
]
},
{
"offset": 0,
"versions": [
"0.19.0",
"0.20.0",
"1.0.0-RC1",
"1.0.0-RC2",
"1.0.0-RC3",
"1.0.0",
"1.0.1",
"1.1.0",
"1.2.0",
"1.3.0",
"1.4.0",
"1.4.1",
"1.5.0",
"1.6.0",
"1.6.1",
"1.6.2",
"1.6.3",
"1.7.0",
"1.8.0",
"1.9.0",
"1.10.0",
"1.11.0",
"1.11.1",
"1.11.2",
"1.12.0",
"1.13.0",
"1.14.0",
"1.15.0-rc.1",
"1.15.0-rc.2",
"1.15.0",
"1.15.1",
"1.16.0-rc.1",
"1.16.0",
"1.17.0",
"1.18.0",
"1.19.0-rc.1",
"1.19.0"
]
},
{
"offset": 16,
"versions": [
"0.14.0",
"0.15.0",
"0.16.0",
"0.17.0",
"0.18.0",
"1.20.0",
"1.21.0",
"1.22.0",
"1.23.0-rc.1",
"1.23.0",
"1.23.1",
"1.24.0",
"1.25.0",
"1.26.0"
]
}
]
}
]
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ char __license[] SEC("license") = "Dual MIT/GPL";
#define MAX_CONCURRENT 50
#define MAX_SPAN_NAME_LEN 64
#define MAX_STATUS_DESCRIPTION_LEN 64
#define MAX_TRACER_NAME_LEN 128

struct span_description_t {
char buf[MAX_STATUS_DESCRIPTION_LEN];
Expand All @@ -39,11 +40,16 @@ struct span_name_t {
char buf[MAX_SPAN_NAME_LEN];
};

typedef struct tracer_name {
char buf[MAX_TRACER_NAME_LEN];
} tracer_name_t;

struct otel_span_t {
BASE_SPAN_PROPERTIES
struct span_name_t span_name;
otel_status_t status;
otel_attributes_t attributes;
tracer_name_t tracer_name;
};

struct {
Expand All @@ -60,6 +66,13 @@ struct {
__uint(max_entries, MAX_CONCURRENT);
} span_name_by_context SEC(".maps");

struct {
__uint(type, BPF_MAP_TYPE_HASH);
__type(key, void*);
__type(value, tracer_name_t);
__uint(max_entries, MAX_CONCURRENT);
} tracer_name_by_context SEC(".maps");

struct
{
__uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
Expand All @@ -74,6 +87,7 @@ struct {

// Injected in init
volatile const u64 tracer_delegate_pos;
volatile const u64 tracer_name_pos;

// read_span_name reads the span name from the provided span_name_ptr and stores the result in
// span_name.buf.
Expand Down Expand Up @@ -105,6 +119,14 @@ int uprobe_Start(struct pt_regs *ctx) {
void *context_ptr_val = get_Go_context(ctx, 3, 0, true);
void *key = get_consistent_key(ctx, context_ptr_val);
bpf_map_update_elem(&span_name_by_context, &key, &span_name, 0);

// Get the tracer name
tracer_name_t tracer_name = {0};
if (!get_go_string_from_user_ptr((void*)(tracer_ptr + tracer_name_pos), tracer_name.buf, MAX_TRACER_NAME_LEN)) {
bpf_printk("Failed to read tracer name");
} else {
bpf_map_update_elem(&tracer_name_by_context, &key, &tracer_name, 0);
}
return 0;
}

Expand All @@ -121,6 +143,11 @@ int uprobe_Start_Returns(struct pt_regs *ctx) {
return 0;
}

tracer_name_t *tracer_name = bpf_map_lookup_elem(&tracer_name_by_context, &key);
if (tracer_name == NULL) {
goto done_without_tracer_name;
}

u32 zero_span_key = 0;
struct otel_span_t *zero_span = bpf_map_lookup_elem(&otel_span_storage_map, &zero_span_key);
if (zero_span == NULL) {
Expand All @@ -137,7 +164,8 @@ int uprobe_Start_Returns(struct pt_regs *ctx) {
}

otel_span->start_time = bpf_ktime_get_ns();
copy_byte_arrays((unsigned char*)span_name->buf, (unsigned char*)otel_span->span_name.buf, MAX_SPAN_NAME_LEN);
otel_span->span_name = *span_name;
otel_span->tracer_name = *tracer_name;

// Get the ** returned ** context and Span (concrete type of the interfaces)
void *ret_context_ptr_val = get_argument(ctx, 2);
Expand All @@ -157,6 +185,8 @@ int uprobe_Start_Returns(struct pt_regs *ctx) {
start_tracking_span(ret_context_ptr_val, &otel_span->sc);

done:
bpf_map_delete_elem(&tracer_name_by_context, &key);
done_without_tracer_name:
bpf_map_delete_elem(&span_name_by_context, &key);
return 0;
}
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,10 @@ func New(logger logr.Logger) probe.Probe {
Key: "tracer_delegate_pos",
Val: structfield.NewID("go.opentelemetry.io/otel", "go.opentelemetry.io/otel/internal/global", "tracer", "delegate"),
},
probe.StructFieldConst{
Key: "tracer_name_pos",
Val: structfield.NewID("go.opentelemetry.io/otel", "go.opentelemetry.io/otel/internal/global", "tracer", "name"),
},
},
Uprobes: []probe.Uprobe[bpfObjects]{
{
Expand Down Expand Up @@ -252,6 +256,7 @@ type event struct {
SpanName [64]byte
Status status
Attributes attributesBuffer
TracerName [128]byte
}

func convertEvent(e *event) []*probe.SpanEvent {
Expand Down Expand Up @@ -288,6 +293,7 @@ func convertEvent(e *event) []*probe.SpanEvent {
Code: codes.Code(e.Status.Code),
Description: string(unix.ByteSliceToString(e.Status.Description[:])),
},
TracerName: unix.ByteSliceToString(e.TracerName[:]),
},
}
}
Expand Down
1 change: 1 addition & 0 deletions internal/pkg/instrumentation/probe/event.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,5 @@ type SpanEvent struct {
SpanContext *trace.SpanContext
ParentSpanContext *trace.SpanContext
Status Status
TracerName string
}
31 changes: 23 additions & 8 deletions internal/pkg/opentelemetry/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,17 +35,32 @@ type Controller struct {
bootTime int64
}

func (c *Controller) getTracer(pkg string) trace.Tracer {
t, exists := c.tracersMap[pkg]
func (c *Controller) getTracer(pkg, tracerName string) trace.Tracer {
var (
newTracer trace.Tracer
tracerKey = pkg
)

if tracerName != "" {
tracerKey = tracerName
}

t, exists := c.tracersMap[tracerKey]
if exists {
return t
}

newTracer := c.tracerProvider.Tracer(
"go.opentelemetry.io/auto/"+pkg,
trace.WithInstrumentationVersion(c.version),
)
c.tracersMap[pkg] = newTracer
if tracerName != "" {
// If the user has provided a tracer name, use it.
newTracer = c.tracerProvider.Tracer(tracerName)
} else {
newTracer = c.tracerProvider.Tracer(
"go.opentelemetry.io/auto/"+pkg,
trace.WithInstrumentationVersion(c.version),
)
}

c.tracersMap[tracerKey] = newTracer
return newTracer
}

Expand All @@ -66,7 +81,7 @@ func (c *Controller) Trace(event *probe.Event) {
}

ctx = ContextWithEBPFEvent(ctx, *se)
_, span := c.getTracer(event.Package).
_, span := c.getTracer(event.Package, se.TracerName).
Start(ctx, se.SpanName,
trace.WithAttributes(se.Attributes...),
trace.WithSpanKind(event.Kind),
Expand Down
31 changes: 31 additions & 0 deletions internal/pkg/opentelemetry/controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -237,3 +237,34 @@ func TestTrace(t *testing.T) {
})
}
}

func TestGetTracer(t *testing.T) {
logger := stdr.New(log.New(os.Stderr, "", log.LstdFlags))

exporter := tracetest.NewInMemoryExporter()
tp := sdktrace.NewTracerProvider(
sdktrace.WithSampler(sdktrace.AlwaysSample()),
sdktrace.WithBatcher(exporter),
sdktrace.WithResource(instResource()),
)
defer func() {
err := tp.Shutdown(context.Background())
assert.NoError(t, err)
}()

ctrl, err := NewController(logger, tp, "test")
assert.NoError(t, err)

t1 := ctrl.getTracer("foo/bar", "test")
assert.Equal(t, t1, ctrl.tracersMap["test"])
assert.Nil(t, ctrl.tracersMap["foo/bar"])

t2 := ctrl.getTracer("net/http", "")
assert.Equal(t, t2, ctrl.tracersMap["net/http"])

t3 := ctrl.getTracer("foo/bar", "test")
assert.Equal(t, t1, t3)

t4 := ctrl.getTracer("net/http", "")
assert.Equal(t, t2, t4)
}
Loading