Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Collect user provided tracer name, version and schemaURL #844

Merged
Merged
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 != "" {
RonFed marked this conversation as resolved.
Show resolved Hide resolved
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 != "" {
RonFed marked this conversation as resolved.
Show resolved Hide resolved
// 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),
)
MrAlias marked this conversation as resolved.
Show resolved Hide resolved
}

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
Loading