From 9098fc905480f7fa2a56f43a73262196e245da5c Mon Sep 17 00:00:00 2001 From: Ron Federman Date: Wed, 10 Jul 2024 14:37:42 +0300 Subject: [PATCH] Refactor span creation by introducing a common function called start_span --- internal/include/go_context.h | 62 +++++++-------- internal/include/go_types.h | 2 +- internal/include/trace/sampling.h | 32 ++++++++ internal/include/{ => trace}/span_context.h | 12 --- internal/include/{ => trace}/span_output.h | 4 +- internal/include/trace/start_span.h | 75 +++++++++++++++++++ internal/include/uprobe.h | 9 ++- .../bpf/database/sql/bpf/probe.bpf.c | 53 ++++++------- .../bpf/database/sql/bpf_arm64_bpfel.go | 6 +- .../bpf/database/sql/bpf_x86_bpfel.go | 6 +- .../kafka-go/consumer/bpf/probe.bpf.c | 51 ++++++------- .../kafka-go/consumer/bpf_arm64_bpfel.go | 41 +++++----- .../kafka-go/consumer/bpf_x86_bpfel.go | 41 +++++----- .../kafka-go/producer/bpf/probe.bpf.c | 33 ++++---- .../kafka-go/producer/bpf_arm64_bpfel.go | 6 +- .../kafka-go/producer/bpf_x86_bpfel.go | 6 +- .../otel/traceglobal/bpf/probe.bpf.c | 38 +++++----- .../otel/traceglobal/bpf_arm64_bpfel.go | 6 +- .../otel/traceglobal/bpf_x86_bpfel.go | 6 +- .../grpc/client/bpf/probe.bpf.c | 40 +++++----- .../grpc/client/bpf_arm64_bpfel.go | 6 +- .../grpc/client/bpf_x86_bpfel.go | 6 +- .../grpc/server/bpf/probe.bpf.c | 38 ++++++---- .../grpc/server/bpf_arm64_bpfel.go | 6 +- .../grpc/server/bpf_x86_bpfel.go | 6 +- .../bpf/net/http/client/bpf/probe.bpf.c | 40 +++++----- .../bpf/net/http/client/bpf_arm64_bpfel.go | 6 +- .../net/http/client/bpf_no_tp_arm64_bpfel.go | 6 +- .../net/http/client/bpf_no_tp_x86_bpfel.go | 6 +- .../bpf/net/http/client/bpf_x86_bpfel.go | 6 +- .../bpf/net/http/server/bpf/probe.bpf.c | 38 +++++----- .../bpf/net/http/server/bpf_arm64_bpfel.go | 6 +- .../bpf/net/http/server/bpf_x86_bpfel.go | 6 +- 33 files changed, 402 insertions(+), 303 deletions(-) create mode 100644 internal/include/trace/sampling.h rename internal/include/{ => trace}/span_context.h (87%) rename internal/include/{ => trace}/span_output.h (94%) create mode 100644 internal/include/trace/start_span.h diff --git a/internal/include/go_context.h b/internal/include/go_context.h index ac011a8ed..952c4240a 100644 --- a/internal/include/go_context.h +++ b/internal/include/go_context.h @@ -29,7 +29,7 @@ struct __type(value, struct span_context); __uint(max_entries, MAX_CONCURRENT_SPANS); __uint(pinning, LIBBPF_PIN_BY_NAME); -} tracked_spans SEC(".maps"); +} go_context_to_sc SEC(".maps"); struct { @@ -40,8 +40,8 @@ struct __uint(pinning, LIBBPF_PIN_BY_NAME); } tracked_spans_by_sc SEC(".maps"); -static __always_inline void *get_parent_go_context(void *ctx, void *map) { - void *data = ctx; +static __always_inline void *get_parent_go_context(struct go_iface *go_context, void *map) { + void *data = go_context->data; for (int i = 0; i < MAX_DISTANCE; i++) { if (data == NULL) @@ -60,18 +60,17 @@ static __always_inline void *get_parent_go_context(void *ctx, void *map) { bpf_probe_read(&data, sizeof(data), data + 8); } - bpf_printk("context %lx not found in context map", ctx); return NULL; } -static __always_inline struct span_context *get_parent_span_context(void *ctx) { - void *parent_ctx = get_parent_go_context(ctx, &tracked_spans); - if (parent_ctx == NULL) +static __always_inline struct span_context *get_parent_span_context(struct go_iface *go_context) { + void *parent_go_ctx = get_parent_go_context(go_context, &go_context_to_sc); + if (parent_go_ctx == NULL) { return NULL; } - struct span_context *parent_sc = bpf_map_lookup_elem(&tracked_spans, &parent_ctx); + struct span_context *parent_sc = bpf_map_lookup_elem(&go_context_to_sc, &parent_go_ctx); if (parent_sc == NULL) { return NULL; @@ -82,7 +81,7 @@ static __always_inline struct span_context *get_parent_span_context(void *ctx) { static __always_inline void start_tracking_span(void *contextContext, struct span_context *sc) { long err = 0; - err = bpf_map_update_elem(&tracked_spans, &contextContext, sc, BPF_ANY); + err = bpf_map_update_elem(&go_context_to_sc, &contextContext, sc, BPF_ANY); if (err != 0) { bpf_printk("Failed to update tracked_spans map: %ld", err); @@ -114,7 +113,7 @@ static __always_inline void stop_tracking_span(struct span_context *sc, struct s if (parent_ctx == NULL) { // No parent span, delete the context - bpf_map_delete_elem(&tracked_spans, ctx); + bpf_map_delete_elem(&go_context_to_sc, ctx); } else { void *ctx_val = 0; @@ -125,37 +124,38 @@ static __always_inline void stop_tracking_span(struct span_context *sc, struct s if (ctx_val != parent_ctx_val) { // Parent with different context, delete the context - bpf_map_delete_elem(&tracked_spans, ctx); + bpf_map_delete_elem(&go_context_to_sc, ctx); } else { // Parent with the same context, update the entry to point to the parent span - bpf_map_update_elem(&tracked_spans, ctx, psc, BPF_ANY); + bpf_map_update_elem(&go_context_to_sc, ctx, psc, BPF_ANY); } } bpf_map_delete_elem(&tracked_spans_by_sc, sc); } -// Extract the go context.Context data pointer from the function arguments -// context_pos: - // The argument position of the context.Context data pointer - // In case the context.Context is passed as an argument, - // this is the argument index of the pointer (starting from 1). - // In case the context.Context is a member of a struct, - // this is the argument index of the struct pointer (starting from 1). -// context_offset: - // In case the context.Context is a member of a struct, - // this is the offset of the context.Context member in the struct. -// passed_as_arg: - // Indicates whether context.Context is passed as an argument or is a member of a struct -static __always_inline void *get_Go_context(void *ctx, int context_pos, const volatile u64 context_offset, bool passed_as_arg) { - void *arg = get_argument(ctx, context_pos); +// context_pos: +// The argument position of the context.Context type pointer +// In case the context.Context is passed as an argument, +// this is the argument index of the pointer (starting from 1). +// In case the context.Context is a member of a struct, +// this is the argument index of the struct pointer (starting from 1). +// context_offset: +// In case the context.Context is a member of a struct, +// this is the offset of the context.Context member in the struct. +// passed_as_arg: +// Indicates whether context.Context is passed as an argument or is a member of a struct +static __always_inline void get_Go_context(void *ctx, int context_pos, const volatile u64 context_offset, bool passed_as_arg, struct go_iface *contextContext) { + // Read the argument which is either the context.Context type pointer or pointer to a struct containing the context.Context + void *ctx_type_or_struct = get_argument(ctx, context_pos); if (passed_as_arg) { - return arg; + contextContext->type = ctx_type_or_struct; + contextContext->data = get_argument(ctx, context_pos + 1); + } else { + void *context_struct_ptr = (void*)(ctx_type_or_struct + context_offset); + bpf_probe_read(&contextContext->type, sizeof(contextContext->type),context_struct_ptr ); + bpf_probe_read(&contextContext->data, sizeof(contextContext->data), get_go_interface_instance(context_struct_ptr)); } - void *ctx_addr = get_go_interface_instance((void*)(arg + context_offset)); - void *ctx_val = 0; - bpf_probe_read_user(&ctx_val, sizeof(ctx_val), ctx_addr); - return ctx_val; } #endif \ No newline at end of file diff --git a/internal/include/go_types.h b/internal/include/go_types.h index 45861a245..6aed13050 100644 --- a/internal/include/go_types.h +++ b/internal/include/go_types.h @@ -38,7 +38,7 @@ struct go_slice struct go_iface { - void *tab; + void *type; void *data; }; diff --git a/internal/include/trace/sampling.h b/internal/include/trace/sampling.h new file mode 100644 index 000000000..06d495b73 --- /dev/null +++ b/internal/include/trace/sampling.h @@ -0,0 +1,32 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef _SAMPLING_H_ +#define _SAMPLING_H_ + +#include "common.h" +#include "span_context.h" + +typedef struct sampling_parameters { + struct span_context *psc; + u8 *trace_id; + // TODO: add more fields +} sampling_parameters_t; + +static __always_inline bool should_sample(sampling_parameters_t *params) { + // TODO + return true; +} + +#endif \ No newline at end of file diff --git a/internal/include/span_context.h b/internal/include/trace/span_context.h similarity index 87% rename from internal/include/span_context.h rename to internal/include/trace/span_context.h index 9bc32a6d2..1ca75e33d 100644 --- a/internal/include/span_context.h +++ b/internal/include/trace/span_context.h @@ -42,24 +42,12 @@ struct span_context static __always_inline void get_span_context_from_parent(struct span_context *parent, struct span_context *child) { copy_byte_arrays(parent->TraceID, child->TraceID, TRACE_ID_SIZE); generate_random_bytes(child->SpanID, SPAN_ID_SIZE); - child->TraceFlags = parent->TraceFlags; } // Fill the passed span context as root span context static __always_inline void get_root_span_context(struct span_context *sc) { generate_random_bytes(sc->TraceID, TRACE_ID_SIZE); generate_random_bytes(sc->SpanID, SPAN_ID_SIZE); - // currently we always sample - sc->TraceFlags = FLAG_SAMPLED; -} - -// TODO: remove this function once all the probes move to the above functions -static __always_inline struct span_context generate_span_context() -{ - struct span_context context = {}; - generate_random_bytes(context.TraceID, TRACE_ID_SIZE); - generate_random_bytes(context.SpanID, SPAN_ID_SIZE); - return context; } static __always_inline void span_context_to_w3c_string(struct span_context *ctx, char *buff) diff --git a/internal/include/span_output.h b/internal/include/trace/span_output.h similarity index 94% rename from internal/include/span_output.h rename to internal/include/trace/span_output.h index 54404f411..6311f7dc5 100644 --- a/internal/include/span_output.h +++ b/internal/include/trace/span_output.h @@ -12,9 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "span_context.h" +#include "trace/span_context.h" #include "common.h" -#include "span_context.h" +#include "trace/span_context.h" #ifndef _SPAN_OUTPUT_H_ #define _SPAN_OUTPUT_H_ diff --git a/internal/include/trace/start_span.h b/internal/include/trace/start_span.h new file mode 100644 index 000000000..83d043286 --- /dev/null +++ b/internal/include/trace/start_span.h @@ -0,0 +1,75 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef _START_SPAN_H_ +#define _START_SPAN_H_ + +#include "common.h" +#include "span_context.h" +#include "sampling.h" + +// function for getting the parent span context, the result is stored in the passed span context. +// the function should return 0 if the parent span context is found, negative value otherwise. +// Each probe can potentially have a different way of getting the parent span context, +// this is useful for incoming requests (http, kafka, etc.) where the parent span context needs to be extracted from the +// incoming request. +// The handle param can be used to pass any data needed to get the parent span context. +typedef long (*get_parent_sc_fn)(void *handle, struct span_context *psc); + +typedef struct start_span_params { + struct pt_regs *ctx; + struct go_iface *go_context; + struct span_context *psc; + struct span_context *sc; + // function for getting the parent span context, the result is stored in the passed span context. + get_parent_sc_fn get_parent_span_context_fn; + // argument to be passed to the get_parent_span_context_fn + void *get_parent_span_context_arg; +} start_span_params_t; + +// Start a new span, setting the parent span context if found. +// Generate a new span context for the new span. Perform sampling decision and set the TraceFlags accordingly. +static __always_inline void start_span(start_span_params_t *params) { + long found_parent = -1; + if (params->get_parent_span_context_fn != NULL) { + found_parent = params->get_parent_span_context_fn(params->get_parent_span_context_arg, params->psc); + } else { + struct span_context *local_psc = get_parent_span_context(params->go_context); + if (local_psc != NULL) { + found_parent = 0; + *(params->psc) = *local_psc; + } + } + + u8 parent_trace_flags = 0; + if (found_parent == 0) { + get_span_context_from_parent(params->psc, params->sc); + parent_trace_flags = params->psc->TraceFlags; + } else { + get_root_span_context(params->sc); + } + + sampling_parameters_t sampling_params = { + .trace_id = params->sc->TraceID, + .psc = (found_parent == 0) ? params->psc : NULL, + }; + bool sample = should_sample(&sampling_params); + if (sample) { + params->sc->TraceFlags = (parent_trace_flags) | (FLAG_SAMPLED); + } else { + params->sc->TraceFlags = (parent_trace_flags) & (~FLAG_SAMPLED); + } +} + +#endif \ No newline at end of file diff --git a/internal/include/uprobe.h b/internal/include/uprobe.h index ce19c028c..ebc6431f7 100644 --- a/internal/include/uprobe.h +++ b/internal/include/uprobe.h @@ -16,10 +16,10 @@ #define _UPROBE_H_ #include "common.h" -#include "span_context.h" +#include "trace/span_context.h" #include "go_context.h" #include "go_types.h" -#include "span_output.h" +#include "trace/span_output.h" #define BASE_SPAN_PROPERTIES \ u64 start_time; \ @@ -37,8 +37,9 @@ #define UPROBE_RETURN(name, event_type, uprobe_context_map, events_map, context_pos, context_offset, passed_as_arg) \ SEC("uprobe/##name##") \ int uprobe_##name##_Returns(struct pt_regs *ctx) { \ - void *ctx_address = get_Go_context(ctx, context_pos, context_offset, passed_as_arg); \ - void *key = get_consistent_key(ctx, ctx_address); \ + struct go_iface go_context = {0}; \ + get_Go_context(ctx, context_pos, context_offset, passed_as_arg, &go_context); \ + void *key = get_consistent_key(ctx, go_context.data); \ event_type *event = bpf_map_lookup_elem(&uprobe_context_map, &key); \ if (event == NULL) { \ bpf_printk("event is NULL in ret probe"); \ diff --git a/internal/pkg/instrumentation/bpf/database/sql/bpf/probe.bpf.c b/internal/pkg/instrumentation/bpf/database/sql/bpf/probe.bpf.c index d48585e42..29e3ec8ac 100644 --- a/internal/pkg/instrumentation/bpf/database/sql/bpf/probe.bpf.c +++ b/internal/pkg/instrumentation/bpf/database/sql/bpf/probe.bpf.c @@ -13,10 +13,11 @@ // limitations under the License. #include "arguments.h" -#include "span_context.h" +#include "trace/span_context.h" #include "go_context.h" #include "go_types.h" #include "uprobe.h" +#include "trace/start_span.h" char __license[] SEC("license") = "Dual MIT/GPL"; @@ -58,22 +59,23 @@ int uprobe_queryDC(struct pt_regs *ctx) { bpf_probe_read(sql_request.query, query_size, query_str_ptr); } - // Get parent if exists - void *context_ptr_val = get_Go_context(ctx, 3, 0, true); - struct span_context *span_ctx = get_parent_span_context(context_ptr_val); - if (span_ctx != NULL) { - // Set the parent context - bpf_probe_read(&sql_request.psc, sizeof(sql_request.psc), span_ctx); - get_span_context_from_parent(&sql_request.psc, &sql_request.sc); - } else { - get_root_span_context(&sql_request.sc); - } + struct go_iface go_context = {0}; + get_Go_context(ctx, 2, 0, true, &go_context); + start_span_params_t start_span_params = { + .ctx = ctx, + .go_context = &go_context, + .psc = &sql_request.psc, + .sc = &sql_request.sc, + .get_parent_span_context_fn = NULL, + .get_parent_span_context_arg = NULL, + }; + start_span(&start_span_params); // Get key - void *key = get_consistent_key(ctx, context_ptr_val); + void *key = get_consistent_key(ctx, go_context.data); bpf_map_update_elem(&sql_events, &key, &sql_request, 0); - start_tracking_span(context_ptr_val, &sql_request.sc); + start_tracking_span(go_context.data, &sql_request.sc); return 0; } @@ -101,22 +103,23 @@ int uprobe_execDC(struct pt_regs *ctx) { bpf_probe_read(sql_request.query, query_size, query_str_ptr); } - // Get parent if exists - void *context_ptr_val = get_Go_context(ctx, 3, 0, true); - struct span_context *span_ctx = get_parent_span_context(context_ptr_val); - if (span_ctx != NULL) { - // Set the parent context - bpf_probe_read(&sql_request.psc, sizeof(sql_request.psc), span_ctx); - get_span_context_from_parent(&sql_request.psc, &sql_request.sc); - } else { - get_root_span_context(&sql_request.sc); - } + struct go_iface go_context = {0}; + get_Go_context(ctx, 2, 0, true, &go_context); + start_span_params_t start_span_params = { + .ctx = ctx, + .go_context = &go_context, + .psc = &sql_request.psc, + .sc = &sql_request.sc, + .get_parent_span_context_fn = NULL, + .get_parent_span_context_arg = NULL, + }; + start_span(&start_span_params); // Get key - void *key = get_consistent_key(ctx, context_ptr_val); + void *key = get_consistent_key(ctx, go_context.data); bpf_map_update_elem(&sql_events, &key, &sql_request, 0); - start_tracking_span(context_ptr_val, &sql_request.sc); + start_tracking_span(go_context.data, &sql_request.sc); return 0; } diff --git a/internal/pkg/instrumentation/bpf/database/sql/bpf_arm64_bpfel.go b/internal/pkg/instrumentation/bpf/database/sql/bpf_arm64_bpfel.go index c658f5c9b..da2cd723a 100644 --- a/internal/pkg/instrumentation/bpf/database/sql/bpf_arm64_bpfel.go +++ b/internal/pkg/instrumentation/bpf/database/sql/bpf_arm64_bpfel.go @@ -82,9 +82,9 @@ type bpfProgramSpecs struct { type bpfMapSpecs struct { AllocMap *ebpf.MapSpec `ebpf:"alloc_map"` Events *ebpf.MapSpec `ebpf:"events"` + GoContextToSc *ebpf.MapSpec `ebpf:"go_context_to_sc"` SliceArrayBuffMap *ebpf.MapSpec `ebpf:"slice_array_buff_map"` SqlEvents *ebpf.MapSpec `ebpf:"sql_events"` - TrackedSpans *ebpf.MapSpec `ebpf:"tracked_spans"` TrackedSpansBySc *ebpf.MapSpec `ebpf:"tracked_spans_by_sc"` } @@ -109,9 +109,9 @@ func (o *bpfObjects) Close() error { type bpfMaps struct { AllocMap *ebpf.Map `ebpf:"alloc_map"` Events *ebpf.Map `ebpf:"events"` + GoContextToSc *ebpf.Map `ebpf:"go_context_to_sc"` SliceArrayBuffMap *ebpf.Map `ebpf:"slice_array_buff_map"` SqlEvents *ebpf.Map `ebpf:"sql_events"` - TrackedSpans *ebpf.Map `ebpf:"tracked_spans"` TrackedSpansBySc *ebpf.Map `ebpf:"tracked_spans_by_sc"` } @@ -119,9 +119,9 @@ func (m *bpfMaps) Close() error { return _BpfClose( m.AllocMap, m.Events, + m.GoContextToSc, m.SliceArrayBuffMap, m.SqlEvents, - m.TrackedSpans, m.TrackedSpansBySc, ) } diff --git a/internal/pkg/instrumentation/bpf/database/sql/bpf_x86_bpfel.go b/internal/pkg/instrumentation/bpf/database/sql/bpf_x86_bpfel.go index f6367d501..e824ec016 100644 --- a/internal/pkg/instrumentation/bpf/database/sql/bpf_x86_bpfel.go +++ b/internal/pkg/instrumentation/bpf/database/sql/bpf_x86_bpfel.go @@ -82,9 +82,9 @@ type bpfProgramSpecs struct { type bpfMapSpecs struct { AllocMap *ebpf.MapSpec `ebpf:"alloc_map"` Events *ebpf.MapSpec `ebpf:"events"` + GoContextToSc *ebpf.MapSpec `ebpf:"go_context_to_sc"` SliceArrayBuffMap *ebpf.MapSpec `ebpf:"slice_array_buff_map"` SqlEvents *ebpf.MapSpec `ebpf:"sql_events"` - TrackedSpans *ebpf.MapSpec `ebpf:"tracked_spans"` TrackedSpansBySc *ebpf.MapSpec `ebpf:"tracked_spans_by_sc"` } @@ -109,9 +109,9 @@ func (o *bpfObjects) Close() error { type bpfMaps struct { AllocMap *ebpf.Map `ebpf:"alloc_map"` Events *ebpf.Map `ebpf:"events"` + GoContextToSc *ebpf.Map `ebpf:"go_context_to_sc"` SliceArrayBuffMap *ebpf.Map `ebpf:"slice_array_buff_map"` SqlEvents *ebpf.Map `ebpf:"sql_events"` - TrackedSpans *ebpf.Map `ebpf:"tracked_spans"` TrackedSpansBySc *ebpf.Map `ebpf:"tracked_spans_by_sc"` } @@ -119,9 +119,9 @@ func (m *bpfMaps) Close() error { return _BpfClose( m.AllocMap, m.Events, + m.GoContextToSc, m.SliceArrayBuffMap, m.SqlEvents, - m.TrackedSpans, m.TrackedSpansBySc, ) } diff --git a/internal/pkg/instrumentation/bpf/github.com/segmentio/kafka-go/consumer/bpf/probe.bpf.c b/internal/pkg/instrumentation/bpf/github.com/segmentio/kafka-go/consumer/bpf/probe.bpf.c index 85d3a89c5..a906db2e6 100644 --- a/internal/pkg/instrumentation/bpf/github.com/segmentio/kafka-go/consumer/bpf/probe.bpf.c +++ b/internal/pkg/instrumentation/bpf/github.com/segmentio/kafka-go/consumer/bpf/probe.bpf.c @@ -13,11 +13,12 @@ // limitations under the License. #include "arguments.h" -#include "span_context.h" +#include "trace/span_context.h" #include "go_context.h" #include "go_types.h" #include "uprobe.h" -#include "span_output.h" +#include "trace/span_output.h" +#include "trace/start_span.h" char __license[] SEC("license") = "Dual MIT/GPL"; @@ -66,14 +67,6 @@ struct __uint(max_entries, 1); } kafka_request_storage_map SEC(".maps"); -struct -{ - __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY); - __uint(key_size, sizeof(u32)); - __uint(value_size, sizeof(struct span_context)); - __uint(max_entries, 1); -} parent_span_context_storage_map SEC(".maps"); - // https://github.com/segmentio/kafka-go/blob/main/protocol/record.go#L48 struct kafka_header_t { struct go_string key; @@ -92,7 +85,7 @@ volatile const u64 reader_config_group_id_pos; #define MAX_HEADERS 20 -static __always_inline struct span_context *extract_span_context_from_headers(void *message) { +static __always_inline long extract_span_context_from_headers(void *message, struct span_context *parent_span_context) { // Read the headers slice descriptor void *headers = (void *)(message + message_headers_pos); struct go_slice headers_slice = {0}; @@ -101,13 +94,6 @@ static __always_inline struct span_context *extract_span_context_from_headers(vo char key[W3C_KEY_LENGTH] = "traceparent"; char current_key[W3C_KEY_LENGTH]; - u32 map_id = 0; - struct span_context *parent_span_context = bpf_map_lookup_elem(&parent_span_context_storage_map, &map_id); - if (!parent_span_context) - { - return NULL; - } - for (u64 i = 0; i < headers_slice.len; i++) { if (i >= MAX_HEADERS) { break; @@ -123,12 +109,12 @@ static __always_inline struct span_context *extract_span_context_from_headers(vo char val[W3C_VAL_LENGTH]; bpf_probe_read(val, W3C_VAL_LENGTH, header.value.array); w3c_string_to_span_context(val, parent_span_context); - return parent_span_context; + return 0; } } } - return NULL; + return -1; } // This instrumentation attaches uprobe to the following function: @@ -146,7 +132,8 @@ int uprobe_FetchMessage(struct pt_regs *ctx) { Steps 2-4 are executed in a separate goroutine from the one the user of the library. */ void *reader = get_argument(ctx, 1); - void *context_data_ptr = get_Go_context(ctx, 3, 0, true); + struct go_iface go_context = {0}; + get_Go_context(ctx, 2, 0, true, &go_context); void *goroutine = (void *)GOROUTINE(ctx); struct kafka_request_t *kafka_request = bpf_map_lookup_elem(&kafka_events, &goroutine); if (kafka_request == NULL) @@ -166,7 +153,7 @@ int uprobe_FetchMessage(struct pt_regs *ctx) { save_context: // Save the context for the return probe - bpf_map_update_elem(&goroutine_to_go_context, &goroutine, &context_data_ptr, 0); + bpf_map_update_elem(&goroutine_to_go_context, &goroutine, &go_context.data, 0); return 0; } @@ -190,15 +177,19 @@ int uprobe_FetchMessage_Returns(struct pt_regs *ctx) { // The message returned on the stack since it returned as a struct and not a pointer void *message = (void *)(PT_REGS_SP(ctx) + 8); + struct go_iface go_context = {0}; + get_Go_context(ctx, 2, 0, true, &go_context); + // Get the parent span context from the message headers - struct span_context *parent_span_ctx = extract_span_context_from_headers(message); - if (parent_span_ctx != NULL) { - // Set the parent context - bpf_probe_read(&kafka_request->psc, sizeof(kafka_request->psc), parent_span_ctx); - get_span_context_from_parent(parent_span_ctx, &kafka_request->sc); - } else { - get_root_span_context(&kafka_request->sc); - } + start_span_params_t start_span_params = { + .ctx = ctx, + .sc = &kafka_request->sc, + .psc = &kafka_request->psc, + .go_context = &go_context, + .get_parent_span_context_fn = extract_span_context_from_headers, + .get_parent_span_context_arg = message, + }; + start_span(&start_span_params); // Collecting message attributes // topic diff --git a/internal/pkg/instrumentation/bpf/github.com/segmentio/kafka-go/consumer/bpf_arm64_bpfel.go b/internal/pkg/instrumentation/bpf/github.com/segmentio/kafka-go/consumer/bpf_arm64_bpfel.go index 74ed30cc5..6adad9151 100644 --- a/internal/pkg/instrumentation/bpf/github.com/segmentio/kafka-go/consumer/bpf_arm64_bpfel.go +++ b/internal/pkg/instrumentation/bpf/github.com/segmentio/kafka-go/consumer/bpf_arm64_bpfel.go @@ -82,16 +82,15 @@ type bpfProgramSpecs struct { // // It can be passed ebpf.CollectionSpec.Assign. type bpfMapSpecs struct { - AllocMap *ebpf.MapSpec `ebpf:"alloc_map"` - Events *ebpf.MapSpec `ebpf:"events"` - GoroutineToGoContext *ebpf.MapSpec `ebpf:"goroutine_to_go_context"` - KafkaEvents *ebpf.MapSpec `ebpf:"kafka_events"` - KafkaReaderToConn *ebpf.MapSpec `ebpf:"kafka_reader_to_conn"` - KafkaRequestStorageMap *ebpf.MapSpec `ebpf:"kafka_request_storage_map"` - ParentSpanContextStorageMap *ebpf.MapSpec `ebpf:"parent_span_context_storage_map"` - SliceArrayBuffMap *ebpf.MapSpec `ebpf:"slice_array_buff_map"` - TrackedSpans *ebpf.MapSpec `ebpf:"tracked_spans"` - TrackedSpansBySc *ebpf.MapSpec `ebpf:"tracked_spans_by_sc"` + AllocMap *ebpf.MapSpec `ebpf:"alloc_map"` + Events *ebpf.MapSpec `ebpf:"events"` + GoContextToSc *ebpf.MapSpec `ebpf:"go_context_to_sc"` + GoroutineToGoContext *ebpf.MapSpec `ebpf:"goroutine_to_go_context"` + KafkaEvents *ebpf.MapSpec `ebpf:"kafka_events"` + KafkaReaderToConn *ebpf.MapSpec `ebpf:"kafka_reader_to_conn"` + KafkaRequestStorageMap *ebpf.MapSpec `ebpf:"kafka_request_storage_map"` + SliceArrayBuffMap *ebpf.MapSpec `ebpf:"slice_array_buff_map"` + TrackedSpansBySc *ebpf.MapSpec `ebpf:"tracked_spans_by_sc"` } // bpfObjects contains all objects after they have been loaded into the kernel. @@ -113,29 +112,27 @@ func (o *bpfObjects) Close() error { // // It can be passed to loadBpfObjects or ebpf.CollectionSpec.LoadAndAssign. type bpfMaps struct { - AllocMap *ebpf.Map `ebpf:"alloc_map"` - Events *ebpf.Map `ebpf:"events"` - GoroutineToGoContext *ebpf.Map `ebpf:"goroutine_to_go_context"` - KafkaEvents *ebpf.Map `ebpf:"kafka_events"` - KafkaReaderToConn *ebpf.Map `ebpf:"kafka_reader_to_conn"` - KafkaRequestStorageMap *ebpf.Map `ebpf:"kafka_request_storage_map"` - ParentSpanContextStorageMap *ebpf.Map `ebpf:"parent_span_context_storage_map"` - SliceArrayBuffMap *ebpf.Map `ebpf:"slice_array_buff_map"` - TrackedSpans *ebpf.Map `ebpf:"tracked_spans"` - TrackedSpansBySc *ebpf.Map `ebpf:"tracked_spans_by_sc"` + AllocMap *ebpf.Map `ebpf:"alloc_map"` + Events *ebpf.Map `ebpf:"events"` + GoContextToSc *ebpf.Map `ebpf:"go_context_to_sc"` + GoroutineToGoContext *ebpf.Map `ebpf:"goroutine_to_go_context"` + KafkaEvents *ebpf.Map `ebpf:"kafka_events"` + KafkaReaderToConn *ebpf.Map `ebpf:"kafka_reader_to_conn"` + KafkaRequestStorageMap *ebpf.Map `ebpf:"kafka_request_storage_map"` + SliceArrayBuffMap *ebpf.Map `ebpf:"slice_array_buff_map"` + TrackedSpansBySc *ebpf.Map `ebpf:"tracked_spans_by_sc"` } func (m *bpfMaps) Close() error { return _BpfClose( m.AllocMap, m.Events, + m.GoContextToSc, m.GoroutineToGoContext, m.KafkaEvents, m.KafkaReaderToConn, m.KafkaRequestStorageMap, - m.ParentSpanContextStorageMap, m.SliceArrayBuffMap, - m.TrackedSpans, m.TrackedSpansBySc, ) } diff --git a/internal/pkg/instrumentation/bpf/github.com/segmentio/kafka-go/consumer/bpf_x86_bpfel.go b/internal/pkg/instrumentation/bpf/github.com/segmentio/kafka-go/consumer/bpf_x86_bpfel.go index 401c19594..137c7b1a4 100644 --- a/internal/pkg/instrumentation/bpf/github.com/segmentio/kafka-go/consumer/bpf_x86_bpfel.go +++ b/internal/pkg/instrumentation/bpf/github.com/segmentio/kafka-go/consumer/bpf_x86_bpfel.go @@ -82,16 +82,15 @@ type bpfProgramSpecs struct { // // It can be passed ebpf.CollectionSpec.Assign. type bpfMapSpecs struct { - AllocMap *ebpf.MapSpec `ebpf:"alloc_map"` - Events *ebpf.MapSpec `ebpf:"events"` - GoroutineToGoContext *ebpf.MapSpec `ebpf:"goroutine_to_go_context"` - KafkaEvents *ebpf.MapSpec `ebpf:"kafka_events"` - KafkaReaderToConn *ebpf.MapSpec `ebpf:"kafka_reader_to_conn"` - KafkaRequestStorageMap *ebpf.MapSpec `ebpf:"kafka_request_storage_map"` - ParentSpanContextStorageMap *ebpf.MapSpec `ebpf:"parent_span_context_storage_map"` - SliceArrayBuffMap *ebpf.MapSpec `ebpf:"slice_array_buff_map"` - TrackedSpans *ebpf.MapSpec `ebpf:"tracked_spans"` - TrackedSpansBySc *ebpf.MapSpec `ebpf:"tracked_spans_by_sc"` + AllocMap *ebpf.MapSpec `ebpf:"alloc_map"` + Events *ebpf.MapSpec `ebpf:"events"` + GoContextToSc *ebpf.MapSpec `ebpf:"go_context_to_sc"` + GoroutineToGoContext *ebpf.MapSpec `ebpf:"goroutine_to_go_context"` + KafkaEvents *ebpf.MapSpec `ebpf:"kafka_events"` + KafkaReaderToConn *ebpf.MapSpec `ebpf:"kafka_reader_to_conn"` + KafkaRequestStorageMap *ebpf.MapSpec `ebpf:"kafka_request_storage_map"` + SliceArrayBuffMap *ebpf.MapSpec `ebpf:"slice_array_buff_map"` + TrackedSpansBySc *ebpf.MapSpec `ebpf:"tracked_spans_by_sc"` } // bpfObjects contains all objects after they have been loaded into the kernel. @@ -113,29 +112,27 @@ func (o *bpfObjects) Close() error { // // It can be passed to loadBpfObjects or ebpf.CollectionSpec.LoadAndAssign. type bpfMaps struct { - AllocMap *ebpf.Map `ebpf:"alloc_map"` - Events *ebpf.Map `ebpf:"events"` - GoroutineToGoContext *ebpf.Map `ebpf:"goroutine_to_go_context"` - KafkaEvents *ebpf.Map `ebpf:"kafka_events"` - KafkaReaderToConn *ebpf.Map `ebpf:"kafka_reader_to_conn"` - KafkaRequestStorageMap *ebpf.Map `ebpf:"kafka_request_storage_map"` - ParentSpanContextStorageMap *ebpf.Map `ebpf:"parent_span_context_storage_map"` - SliceArrayBuffMap *ebpf.Map `ebpf:"slice_array_buff_map"` - TrackedSpans *ebpf.Map `ebpf:"tracked_spans"` - TrackedSpansBySc *ebpf.Map `ebpf:"tracked_spans_by_sc"` + AllocMap *ebpf.Map `ebpf:"alloc_map"` + Events *ebpf.Map `ebpf:"events"` + GoContextToSc *ebpf.Map `ebpf:"go_context_to_sc"` + GoroutineToGoContext *ebpf.Map `ebpf:"goroutine_to_go_context"` + KafkaEvents *ebpf.Map `ebpf:"kafka_events"` + KafkaReaderToConn *ebpf.Map `ebpf:"kafka_reader_to_conn"` + KafkaRequestStorageMap *ebpf.Map `ebpf:"kafka_request_storage_map"` + SliceArrayBuffMap *ebpf.Map `ebpf:"slice_array_buff_map"` + TrackedSpansBySc *ebpf.Map `ebpf:"tracked_spans_by_sc"` } func (m *bpfMaps) Close() error { return _BpfClose( m.AllocMap, m.Events, + m.GoContextToSc, m.GoroutineToGoContext, m.KafkaEvents, m.KafkaReaderToConn, m.KafkaRequestStorageMap, - m.ParentSpanContextStorageMap, m.SliceArrayBuffMap, - m.TrackedSpans, m.TrackedSpansBySc, ) } diff --git a/internal/pkg/instrumentation/bpf/github.com/segmentio/kafka-go/producer/bpf/probe.bpf.c b/internal/pkg/instrumentation/bpf/github.com/segmentio/kafka-go/producer/bpf/probe.bpf.c index d62c50e55..3e46495ce 100644 --- a/internal/pkg/instrumentation/bpf/github.com/segmentio/kafka-go/producer/bpf/probe.bpf.c +++ b/internal/pkg/instrumentation/bpf/github.com/segmentio/kafka-go/producer/bpf/probe.bpf.c @@ -13,11 +13,12 @@ // limitations under the License. #include "arguments.h" -#include "span_context.h" +#include "trace/span_context.h" #include "go_context.h" #include "go_types.h" #include "uprobe.h" -#include "span_output.h" +#include "trace/span_output.h" +#include "trace/start_span.h" char __license[] SEC("license") = "Dual MIT/GPL"; @@ -143,9 +144,9 @@ int uprobe_WriteMessages(struct pt_regs *ctx) { void *msgs_array = get_argument(ctx, 4); u64 msgs_array_len = (u64)get_argument(ctx, 5); - // Get key - void *context_data_ptr = get_Go_context(ctx, 3, 0, true); - void *key = get_consistent_key(ctx, context_data_ptr); + struct go_iface go_context = {0}; + get_Go_context(ctx, 2, 0, true, &go_context); + void *key = get_consistent_key(ctx, go_context.data); void *kafka_request_ptr = bpf_map_lookup_elem(&kafka_events, &key); if (kafka_request_ptr != NULL) @@ -163,14 +164,15 @@ int uprobe_WriteMessages(struct pt_regs *ctx) { } kafka_request->start_time = bpf_ktime_get_ns(); - // Get parent if exists - struct span_context *parent_span_ctx = get_parent_span_context(context_data_ptr); - if (parent_span_ctx != NULL) { - kafka_request->psc = *parent_span_ctx; - get_span_context_from_parent(&kafka_request->psc, &kafka_request->msgs[0].sc); - } else { - get_root_span_context(&kafka_request->msgs[0].sc); - } + start_span_params_t start_span_params = { + .ctx = ctx, + .go_context = &go_context, + .psc = &kafka_request->psc, + .sc = &kafka_request->msgs[0].sc, + .get_parent_span_context_fn = NULL, + .get_parent_span_context_arg = NULL, + }; + start_span(&start_span_params); // Try to get a global topic from Writer bool global_topic = get_go_string_from_user_ptr((void *)(writer + writer_topic_pos), kafka_request->global_topic, sizeof(kafka_request->global_topic)); @@ -224,8 +226,9 @@ int uprobe_WriteMessages(struct pt_regs *ctx) { SEC("uprobe/WriteMessages") int uprobe_WriteMessages_Returns(struct pt_regs *ctx) { u64 end_time = bpf_ktime_get_ns(); - void *context_data_ptr = get_Go_context(ctx, 3, 0, true); - void *key = get_consistent_key(ctx, context_data_ptr); + struct go_iface go_context = {0}; + get_Go_context(ctx, 2, 0, true, &go_context); + void *key = get_consistent_key(ctx, go_context.data); struct kafka_request_t *kafka_request = bpf_map_lookup_elem(&kafka_events, &key); if (kafka_request == NULL) { diff --git a/internal/pkg/instrumentation/bpf/github.com/segmentio/kafka-go/producer/bpf_arm64_bpfel.go b/internal/pkg/instrumentation/bpf/github.com/segmentio/kafka-go/producer/bpf_arm64_bpfel.go index d20c7c88a..bae0fedd5 100644 --- a/internal/pkg/instrumentation/bpf/github.com/segmentio/kafka-go/producer/bpf_arm64_bpfel.go +++ b/internal/pkg/instrumentation/bpf/github.com/segmentio/kafka-go/producer/bpf_arm64_bpfel.go @@ -85,10 +85,10 @@ type bpfProgramSpecs struct { type bpfMapSpecs struct { AllocMap *ebpf.MapSpec `ebpf:"alloc_map"` Events *ebpf.MapSpec `ebpf:"events"` + GoContextToSc *ebpf.MapSpec `ebpf:"go_context_to_sc"` KafkaEvents *ebpf.MapSpec `ebpf:"kafka_events"` KafkaRequestStorageMap *ebpf.MapSpec `ebpf:"kafka_request_storage_map"` SliceArrayBuffMap *ebpf.MapSpec `ebpf:"slice_array_buff_map"` - TrackedSpans *ebpf.MapSpec `ebpf:"tracked_spans"` TrackedSpansBySc *ebpf.MapSpec `ebpf:"tracked_spans_by_sc"` } @@ -113,10 +113,10 @@ func (o *bpfObjects) Close() error { type bpfMaps struct { AllocMap *ebpf.Map `ebpf:"alloc_map"` Events *ebpf.Map `ebpf:"events"` + GoContextToSc *ebpf.Map `ebpf:"go_context_to_sc"` KafkaEvents *ebpf.Map `ebpf:"kafka_events"` KafkaRequestStorageMap *ebpf.Map `ebpf:"kafka_request_storage_map"` SliceArrayBuffMap *ebpf.Map `ebpf:"slice_array_buff_map"` - TrackedSpans *ebpf.Map `ebpf:"tracked_spans"` TrackedSpansBySc *ebpf.Map `ebpf:"tracked_spans_by_sc"` } @@ -124,10 +124,10 @@ func (m *bpfMaps) Close() error { return _BpfClose( m.AllocMap, m.Events, + m.GoContextToSc, m.KafkaEvents, m.KafkaRequestStorageMap, m.SliceArrayBuffMap, - m.TrackedSpans, m.TrackedSpansBySc, ) } diff --git a/internal/pkg/instrumentation/bpf/github.com/segmentio/kafka-go/producer/bpf_x86_bpfel.go b/internal/pkg/instrumentation/bpf/github.com/segmentio/kafka-go/producer/bpf_x86_bpfel.go index bf5a45abf..7a60c4ab2 100644 --- a/internal/pkg/instrumentation/bpf/github.com/segmentio/kafka-go/producer/bpf_x86_bpfel.go +++ b/internal/pkg/instrumentation/bpf/github.com/segmentio/kafka-go/producer/bpf_x86_bpfel.go @@ -85,10 +85,10 @@ type bpfProgramSpecs struct { type bpfMapSpecs struct { AllocMap *ebpf.MapSpec `ebpf:"alloc_map"` Events *ebpf.MapSpec `ebpf:"events"` + GoContextToSc *ebpf.MapSpec `ebpf:"go_context_to_sc"` KafkaEvents *ebpf.MapSpec `ebpf:"kafka_events"` KafkaRequestStorageMap *ebpf.MapSpec `ebpf:"kafka_request_storage_map"` SliceArrayBuffMap *ebpf.MapSpec `ebpf:"slice_array_buff_map"` - TrackedSpans *ebpf.MapSpec `ebpf:"tracked_spans"` TrackedSpansBySc *ebpf.MapSpec `ebpf:"tracked_spans_by_sc"` } @@ -113,10 +113,10 @@ func (o *bpfObjects) Close() error { type bpfMaps struct { AllocMap *ebpf.Map `ebpf:"alloc_map"` Events *ebpf.Map `ebpf:"events"` + GoContextToSc *ebpf.Map `ebpf:"go_context_to_sc"` KafkaEvents *ebpf.Map `ebpf:"kafka_events"` KafkaRequestStorageMap *ebpf.Map `ebpf:"kafka_request_storage_map"` SliceArrayBuffMap *ebpf.Map `ebpf:"slice_array_buff_map"` - TrackedSpans *ebpf.Map `ebpf:"tracked_spans"` TrackedSpansBySc *ebpf.Map `ebpf:"tracked_spans_by_sc"` } @@ -124,10 +124,10 @@ func (m *bpfMaps) Close() error { return _BpfClose( m.AllocMap, m.Events, + m.GoContextToSc, m.KafkaEvents, m.KafkaRequestStorageMap, m.SliceArrayBuffMap, - m.TrackedSpans, m.TrackedSpansBySc, ) } diff --git a/internal/pkg/instrumentation/bpf/go.opentelemetry.io/otel/traceglobal/bpf/probe.bpf.c b/internal/pkg/instrumentation/bpf/go.opentelemetry.io/otel/traceglobal/bpf/probe.bpf.c index d60af651f..bd2624489 100644 --- a/internal/pkg/instrumentation/bpf/go.opentelemetry.io/otel/traceglobal/bpf/probe.bpf.c +++ b/internal/pkg/instrumentation/bpf/go.opentelemetry.io/otel/traceglobal/bpf/probe.bpf.c @@ -13,12 +13,13 @@ // limitations under the License. #include "arguments.h" -#include "span_context.h" +#include "trace/span_context.h" #include "go_context.h" #include "go_types.h" #include "uprobe.h" #include "otel_types.h" -#include "span_output.h" +#include "trace/span_output.h" +#include "trace/start_span.h" char __license[] SEC("license") = "Dual MIT/GPL"; @@ -99,8 +100,9 @@ int uprobe_Start(struct pt_regs *ctx) { read_span_name(&span_name, span_name_len, span_name_ptr); // Save the span name in map to be read once the Start function returns - void *context_ptr_val = get_Go_context(ctx, 3, 0, true); - void *key = get_consistent_key(ctx, context_ptr_val); + struct go_iface go_context = {0}; + get_Go_context(ctx, 2, 0, true, &go_context); + void *key = get_consistent_key(ctx, go_context.data); bpf_map_update_elem(&span_name_by_context, &key, &span_name, 0); return 0; } @@ -111,8 +113,10 @@ int uprobe_Start(struct pt_regs *ctx) { SEC("uprobe/Start") int uprobe_Start_Returns(struct pt_regs *ctx) { // Get the span name passed to the Start function - void *context_ptr_val = get_Go_context(ctx, 3, 0, true); - void *key = get_consistent_key(ctx, context_ptr_val); + struct go_iface go_context = {0}; + // In return probe, the context is the first return value + get_Go_context(ctx, 1, 0, true, &go_context); + void *key = get_consistent_key(ctx, go_context.data); struct span_name_t *span_name = bpf_map_lookup_elem(&span_name_by_context, &key); if (span_name == NULL) { return 0; @@ -136,21 +140,21 @@ 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); - // Get the ** returned ** context and Span (concrete type of the interfaces) - void *ret_context_ptr_val = get_argument(ctx, 2); + // Get the ** returned ** Span (concrete type of the interfaces) void *span_ptr_val = get_argument(ctx, 4); - struct span_context *span_ctx = get_parent_span_context(ret_context_ptr_val); - if (span_ctx != NULL) { - // Set the parent context - bpf_probe_read(&otel_span->psc, sizeof(otel_span->psc), span_ctx); - get_span_context_from_parent(&otel_span->psc, &otel_span->sc); - } else { - get_root_span_context(&otel_span->sc); - } + start_span_params_t start_span_params = { + .ctx = ctx, + .go_context = &go_context, + .psc = &otel_span->psc, + .sc = &otel_span->sc, + .get_parent_span_context_fn = NULL, + .get_parent_span_context_arg = NULL, + }; + start_span(&start_span_params); bpf_map_update_elem(&active_spans_by_span_ptr, &span_ptr_val, otel_span, 0); - start_tracking_span(ret_context_ptr_val, &otel_span->sc); + start_tracking_span(go_context.data, &otel_span->sc); done: bpf_map_delete_elem(&span_name_by_context, &key); diff --git a/internal/pkg/instrumentation/bpf/go.opentelemetry.io/otel/traceglobal/bpf_arm64_bpfel.go b/internal/pkg/instrumentation/bpf/go.opentelemetry.io/otel/traceglobal/bpf_arm64_bpfel.go index f36e9c00a..034e5e7b7 100644 --- a/internal/pkg/instrumentation/bpf/go.opentelemetry.io/otel/traceglobal/bpf_arm64_bpfel.go +++ b/internal/pkg/instrumentation/bpf/go.opentelemetry.io/otel/traceglobal/bpf_arm64_bpfel.go @@ -102,10 +102,10 @@ type bpfMapSpecs struct { ActiveSpansBySpanPtr *ebpf.MapSpec `ebpf:"active_spans_by_span_ptr"` AllocMap *ebpf.MapSpec `ebpf:"alloc_map"` Events *ebpf.MapSpec `ebpf:"events"` + GoContextToSc *ebpf.MapSpec `ebpf:"go_context_to_sc"` OtelSpanStorageMap *ebpf.MapSpec `ebpf:"otel_span_storage_map"` SliceArrayBuffMap *ebpf.MapSpec `ebpf:"slice_array_buff_map"` SpanNameByContext *ebpf.MapSpec `ebpf:"span_name_by_context"` - TrackedSpans *ebpf.MapSpec `ebpf:"tracked_spans"` TrackedSpansBySc *ebpf.MapSpec `ebpf:"tracked_spans_by_sc"` } @@ -131,10 +131,10 @@ type bpfMaps struct { ActiveSpansBySpanPtr *ebpf.Map `ebpf:"active_spans_by_span_ptr"` AllocMap *ebpf.Map `ebpf:"alloc_map"` Events *ebpf.Map `ebpf:"events"` + GoContextToSc *ebpf.Map `ebpf:"go_context_to_sc"` OtelSpanStorageMap *ebpf.Map `ebpf:"otel_span_storage_map"` SliceArrayBuffMap *ebpf.Map `ebpf:"slice_array_buff_map"` SpanNameByContext *ebpf.Map `ebpf:"span_name_by_context"` - TrackedSpans *ebpf.Map `ebpf:"tracked_spans"` TrackedSpansBySc *ebpf.Map `ebpf:"tracked_spans_by_sc"` } @@ -143,10 +143,10 @@ func (m *bpfMaps) Close() error { m.ActiveSpansBySpanPtr, m.AllocMap, m.Events, + m.GoContextToSc, m.OtelSpanStorageMap, m.SliceArrayBuffMap, m.SpanNameByContext, - m.TrackedSpans, m.TrackedSpansBySc, ) } diff --git a/internal/pkg/instrumentation/bpf/go.opentelemetry.io/otel/traceglobal/bpf_x86_bpfel.go b/internal/pkg/instrumentation/bpf/go.opentelemetry.io/otel/traceglobal/bpf_x86_bpfel.go index 34026c226..1cfb9d7b9 100644 --- a/internal/pkg/instrumentation/bpf/go.opentelemetry.io/otel/traceglobal/bpf_x86_bpfel.go +++ b/internal/pkg/instrumentation/bpf/go.opentelemetry.io/otel/traceglobal/bpf_x86_bpfel.go @@ -102,10 +102,10 @@ type bpfMapSpecs struct { ActiveSpansBySpanPtr *ebpf.MapSpec `ebpf:"active_spans_by_span_ptr"` AllocMap *ebpf.MapSpec `ebpf:"alloc_map"` Events *ebpf.MapSpec `ebpf:"events"` + GoContextToSc *ebpf.MapSpec `ebpf:"go_context_to_sc"` OtelSpanStorageMap *ebpf.MapSpec `ebpf:"otel_span_storage_map"` SliceArrayBuffMap *ebpf.MapSpec `ebpf:"slice_array_buff_map"` SpanNameByContext *ebpf.MapSpec `ebpf:"span_name_by_context"` - TrackedSpans *ebpf.MapSpec `ebpf:"tracked_spans"` TrackedSpansBySc *ebpf.MapSpec `ebpf:"tracked_spans_by_sc"` } @@ -131,10 +131,10 @@ type bpfMaps struct { ActiveSpansBySpanPtr *ebpf.Map `ebpf:"active_spans_by_span_ptr"` AllocMap *ebpf.Map `ebpf:"alloc_map"` Events *ebpf.Map `ebpf:"events"` + GoContextToSc *ebpf.Map `ebpf:"go_context_to_sc"` OtelSpanStorageMap *ebpf.Map `ebpf:"otel_span_storage_map"` SliceArrayBuffMap *ebpf.Map `ebpf:"slice_array_buff_map"` SpanNameByContext *ebpf.Map `ebpf:"span_name_by_context"` - TrackedSpans *ebpf.Map `ebpf:"tracked_spans"` TrackedSpansBySc *ebpf.Map `ebpf:"tracked_spans_by_sc"` } @@ -143,10 +143,10 @@ func (m *bpfMaps) Close() error { m.ActiveSpansBySpanPtr, m.AllocMap, m.Events, + m.GoContextToSc, m.OtelSpanStorageMap, m.SliceArrayBuffMap, m.SpanNameByContext, - m.TrackedSpans, m.TrackedSpansBySc, ) } diff --git a/internal/pkg/instrumentation/bpf/google.golang.org/grpc/client/bpf/probe.bpf.c b/internal/pkg/instrumentation/bpf/google.golang.org/grpc/client/bpf/probe.bpf.c index 5617133ce..36a8ef920 100644 --- a/internal/pkg/instrumentation/bpf/google.golang.org/grpc/client/bpf/probe.bpf.c +++ b/internal/pkg/instrumentation/bpf/google.golang.org/grpc/client/bpf/probe.bpf.c @@ -14,9 +14,10 @@ #include "arguments.h" #include "go_types.h" -#include "span_context.h" +#include "trace/span_context.h" #include "go_context.h" #include "uprobe.h" +#include "trace/start_span.h" char __license[] SEC("license") = "Dual MIT/GPL"; @@ -69,13 +70,11 @@ int uprobe_ClientConn_Invoke(struct pt_regs *ctx) u64 method_ptr_pos = 4; u64 method_len_pos = 5; - void *context_ptr = get_Go_context(ctx, 3, 0, true); - if (context_ptr == NULL) - { - return 0; - } + struct go_iface go_context = {0}; + get_Go_context(ctx, 2, 0, true, &go_context); + // Get key - void *key = get_consistent_key(ctx, context_ptr); + void *key = get_consistent_key(ctx, go_context.data); void *grpcReq_ptr = bpf_map_lookup_elem(&grpc_events, &key); if (grpcReq_ptr != NULL) { @@ -101,21 +100,19 @@ int uprobe_ClientConn_Invoke(struct pt_regs *ctx) return 0; } - // Get parent if exists - struct span_context *parent_span_ctx = get_parent_span_context(context_ptr); - if (parent_span_ctx != NULL) - { - bpf_probe_read(&grpcReq.psc, sizeof(grpcReq.psc), parent_span_ctx); - get_span_context_from_parent(parent_span_ctx, &grpcReq.sc); - } - else - { - get_root_span_context(&grpcReq.sc); - } + start_span_params_t start_span_params = { + .ctx = ctx, + .go_context = &go_context, + .psc = &grpcReq.psc, + .sc = &grpcReq.sc, + .get_parent_span_context_fn = NULL, + .get_parent_span_context_arg = NULL, + }; + start_span(&start_span_params); // Write event bpf_map_update_elem(&grpc_events, &key, &grpcReq, 0); - start_tracking_span(context_ptr, &grpcReq.sc); + start_tracking_span(go_context.data, &grpcReq.sc); return 0; } @@ -166,11 +163,12 @@ SEC("uprobe/http2Client_NewStream") // func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (*Stream, error) int uprobe_http2Client_NewStream(struct pt_regs *ctx) { - void *context_ptr = get_argument(ctx, 3); + struct go_iface go_context = {0}; + get_Go_context(ctx, 2, 0, true, &go_context); void *httpclient_ptr = get_argument(ctx, 1); u32 nextid = 0; bpf_probe_read(&nextid, sizeof(nextid), (void *)(httpclient_ptr + (httpclient_nextid_pos))); - struct span_context *current_span_context = get_parent_span_context(context_ptr); + struct span_context *current_span_context = get_parent_span_context(&go_context); if (current_span_context != NULL) { bpf_map_update_elem(&streamid_to_span_contexts, &nextid, current_span_context, 0); } diff --git a/internal/pkg/instrumentation/bpf/google.golang.org/grpc/client/bpf_arm64_bpfel.go b/internal/pkg/instrumentation/bpf/google.golang.org/grpc/client/bpf_arm64_bpfel.go index fc7189230..397671c99 100644 --- a/internal/pkg/instrumentation/bpf/google.golang.org/grpc/client/bpf_arm64_bpfel.go +++ b/internal/pkg/instrumentation/bpf/google.golang.org/grpc/client/bpf_arm64_bpfel.go @@ -84,10 +84,10 @@ type bpfProgramSpecs struct { type bpfMapSpecs struct { AllocMap *ebpf.MapSpec `ebpf:"alloc_map"` Events *ebpf.MapSpec `ebpf:"events"` + GoContextToSc *ebpf.MapSpec `ebpf:"go_context_to_sc"` GrpcEvents *ebpf.MapSpec `ebpf:"grpc_events"` SliceArrayBuffMap *ebpf.MapSpec `ebpf:"slice_array_buff_map"` StreamidToSpanContexts *ebpf.MapSpec `ebpf:"streamid_to_span_contexts"` - TrackedSpans *ebpf.MapSpec `ebpf:"tracked_spans"` TrackedSpansBySc *ebpf.MapSpec `ebpf:"tracked_spans_by_sc"` } @@ -112,10 +112,10 @@ func (o *bpfObjects) Close() error { type bpfMaps struct { AllocMap *ebpf.Map `ebpf:"alloc_map"` Events *ebpf.Map `ebpf:"events"` + GoContextToSc *ebpf.Map `ebpf:"go_context_to_sc"` GrpcEvents *ebpf.Map `ebpf:"grpc_events"` SliceArrayBuffMap *ebpf.Map `ebpf:"slice_array_buff_map"` StreamidToSpanContexts *ebpf.Map `ebpf:"streamid_to_span_contexts"` - TrackedSpans *ebpf.Map `ebpf:"tracked_spans"` TrackedSpansBySc *ebpf.Map `ebpf:"tracked_spans_by_sc"` } @@ -123,10 +123,10 @@ func (m *bpfMaps) Close() error { return _BpfClose( m.AllocMap, m.Events, + m.GoContextToSc, m.GrpcEvents, m.SliceArrayBuffMap, m.StreamidToSpanContexts, - m.TrackedSpans, m.TrackedSpansBySc, ) } diff --git a/internal/pkg/instrumentation/bpf/google.golang.org/grpc/client/bpf_x86_bpfel.go b/internal/pkg/instrumentation/bpf/google.golang.org/grpc/client/bpf_x86_bpfel.go index 38f8d74ba..10329e809 100644 --- a/internal/pkg/instrumentation/bpf/google.golang.org/grpc/client/bpf_x86_bpfel.go +++ b/internal/pkg/instrumentation/bpf/google.golang.org/grpc/client/bpf_x86_bpfel.go @@ -84,10 +84,10 @@ type bpfProgramSpecs struct { type bpfMapSpecs struct { AllocMap *ebpf.MapSpec `ebpf:"alloc_map"` Events *ebpf.MapSpec `ebpf:"events"` + GoContextToSc *ebpf.MapSpec `ebpf:"go_context_to_sc"` GrpcEvents *ebpf.MapSpec `ebpf:"grpc_events"` SliceArrayBuffMap *ebpf.MapSpec `ebpf:"slice_array_buff_map"` StreamidToSpanContexts *ebpf.MapSpec `ebpf:"streamid_to_span_contexts"` - TrackedSpans *ebpf.MapSpec `ebpf:"tracked_spans"` TrackedSpansBySc *ebpf.MapSpec `ebpf:"tracked_spans_by_sc"` } @@ -112,10 +112,10 @@ func (o *bpfObjects) Close() error { type bpfMaps struct { AllocMap *ebpf.Map `ebpf:"alloc_map"` Events *ebpf.Map `ebpf:"events"` + GoContextToSc *ebpf.Map `ebpf:"go_context_to_sc"` GrpcEvents *ebpf.Map `ebpf:"grpc_events"` SliceArrayBuffMap *ebpf.Map `ebpf:"slice_array_buff_map"` StreamidToSpanContexts *ebpf.Map `ebpf:"streamid_to_span_contexts"` - TrackedSpans *ebpf.Map `ebpf:"tracked_spans"` TrackedSpansBySc *ebpf.Map `ebpf:"tracked_spans_by_sc"` } @@ -123,10 +123,10 @@ func (m *bpfMaps) Close() error { return _BpfClose( m.AllocMap, m.Events, + m.GoContextToSc, m.GrpcEvents, m.SliceArrayBuffMap, m.StreamidToSpanContexts, - m.TrackedSpans, m.TrackedSpansBySc, ) } diff --git a/internal/pkg/instrumentation/bpf/google.golang.org/grpc/server/bpf/probe.bpf.c b/internal/pkg/instrumentation/bpf/google.golang.org/grpc/server/bpf/probe.bpf.c index 84104fd29..8e5a165d5 100644 --- a/internal/pkg/instrumentation/bpf/google.golang.org/grpc/server/bpf/probe.bpf.c +++ b/internal/pkg/instrumentation/bpf/google.golang.org/grpc/server/bpf/probe.bpf.c @@ -14,9 +14,10 @@ #include "arguments.h" #include "go_types.h" -#include "span_context.h" +#include "trace/span_context.h" #include "go_context.h" #include "uprobe.h" +#include "trace/start_span.h" char __license[] SEC("license") = "Dual MIT/GPL"; @@ -70,6 +71,10 @@ volatile const u64 stream_id_pos; volatile const u64 stream_ctx_pos; volatile const bool is_new_frame_pos; +static __always_inline long dummy_extract_span_context_from_headers(void *stream_id, struct span_context *parent_span_context) { + return 0; +} + // This instrumentation attaches uprobe to the following function: // func (s *Server) handleStream(t transport.ServerTransport, stream *transport.Stream, trInfo *traceInfo) SEC("uprobe/server_handleStream") @@ -78,12 +83,9 @@ int uprobe_server_handleStream(struct pt_regs *ctx) u64 stream_pos = 4; void *stream_ptr = get_argument(ctx, stream_pos); // Get key - void *ctx_iface = get_Go_context(ctx, 4, stream_ctx_pos, false); - if (ctx_iface == NULL) - { - return 0; - } - void *key = get_consistent_key(ctx, ctx_iface); + struct go_iface go_context = {0}; + get_Go_context(ctx, 4, stream_ctx_pos, false, &go_context); + void *key = get_consistent_key(ctx, go_context.data); void *grpcReq_event_ptr = bpf_map_lookup_elem(&grpc_events, &key); if (grpcReq_event_ptr != NULL) { @@ -97,19 +99,27 @@ int uprobe_server_handleStream(struct pt_regs *ctx) struct grpc_request_t *grpcReq = bpf_map_lookup_elem(&streamid_to_grpc_events, &stream_id); if (grpcReq == NULL) { // No parent span context, generate new span context - u32 map_id = 0; - grpcReq = bpf_map_lookup_elem(&grpc_storage_map, &map_id); + u32 zero = 0; + grpcReq = bpf_map_lookup_elem(&grpc_storage_map, &zero); if (grpcReq == NULL) { bpf_printk("failed to get grpcReq from storage map"); return 0; } - get_root_span_context(&grpcReq->sc); - } else { - // found parent span context - get_span_context_from_parent(&grpcReq->psc, &grpcReq->sc); } grpcReq->start_time = bpf_ktime_get_ns(); + + start_span_params_t start_span_params = { + .ctx = ctx, + .sc = &grpcReq->sc, + .psc = &grpcReq->psc, + .go_context = &go_context, + // The parent span context is set by operateHeader probe + .get_parent_span_context_fn = dummy_extract_span_context_from_headers, + .get_parent_span_context_arg = NULL, + }; + start_span(&start_span_params); + // Set attributes if (!get_go_string_from_user_ptr((void *)(stream_ptr + stream_method_ptr_pos), grpcReq->method, sizeof(grpcReq->method))) { @@ -119,7 +129,7 @@ int uprobe_server_handleStream(struct pt_regs *ctx) // Write event bpf_map_update_elem(&grpc_events, &key, grpcReq, 0); - start_tracking_span(ctx_iface, &grpcReq->sc); + start_tracking_span(go_context.data, &grpcReq->sc); done: bpf_map_delete_elem(&streamid_to_grpc_events, &stream_id); return 0; diff --git a/internal/pkg/instrumentation/bpf/google.golang.org/grpc/server/bpf_arm64_bpfel.go b/internal/pkg/instrumentation/bpf/google.golang.org/grpc/server/bpf_arm64_bpfel.go index d2e6ff7b9..9317e8cb7 100644 --- a/internal/pkg/instrumentation/bpf/google.golang.org/grpc/server/bpf_arm64_bpfel.go +++ b/internal/pkg/instrumentation/bpf/google.golang.org/grpc/server/bpf_arm64_bpfel.go @@ -82,11 +82,11 @@ type bpfProgramSpecs struct { type bpfMapSpecs struct { AllocMap *ebpf.MapSpec `ebpf:"alloc_map"` Events *ebpf.MapSpec `ebpf:"events"` + GoContextToSc *ebpf.MapSpec `ebpf:"go_context_to_sc"` GrpcEvents *ebpf.MapSpec `ebpf:"grpc_events"` GrpcStorageMap *ebpf.MapSpec `ebpf:"grpc_storage_map"` SliceArrayBuffMap *ebpf.MapSpec `ebpf:"slice_array_buff_map"` StreamidToGrpcEvents *ebpf.MapSpec `ebpf:"streamid_to_grpc_events"` - TrackedSpans *ebpf.MapSpec `ebpf:"tracked_spans"` TrackedSpansBySc *ebpf.MapSpec `ebpf:"tracked_spans_by_sc"` } @@ -111,11 +111,11 @@ func (o *bpfObjects) Close() error { type bpfMaps struct { AllocMap *ebpf.Map `ebpf:"alloc_map"` Events *ebpf.Map `ebpf:"events"` + GoContextToSc *ebpf.Map `ebpf:"go_context_to_sc"` GrpcEvents *ebpf.Map `ebpf:"grpc_events"` GrpcStorageMap *ebpf.Map `ebpf:"grpc_storage_map"` SliceArrayBuffMap *ebpf.Map `ebpf:"slice_array_buff_map"` StreamidToGrpcEvents *ebpf.Map `ebpf:"streamid_to_grpc_events"` - TrackedSpans *ebpf.Map `ebpf:"tracked_spans"` TrackedSpansBySc *ebpf.Map `ebpf:"tracked_spans_by_sc"` } @@ -123,11 +123,11 @@ func (m *bpfMaps) Close() error { return _BpfClose( m.AllocMap, m.Events, + m.GoContextToSc, m.GrpcEvents, m.GrpcStorageMap, m.SliceArrayBuffMap, m.StreamidToGrpcEvents, - m.TrackedSpans, m.TrackedSpansBySc, ) } diff --git a/internal/pkg/instrumentation/bpf/google.golang.org/grpc/server/bpf_x86_bpfel.go b/internal/pkg/instrumentation/bpf/google.golang.org/grpc/server/bpf_x86_bpfel.go index 508904aee..88c219259 100644 --- a/internal/pkg/instrumentation/bpf/google.golang.org/grpc/server/bpf_x86_bpfel.go +++ b/internal/pkg/instrumentation/bpf/google.golang.org/grpc/server/bpf_x86_bpfel.go @@ -82,11 +82,11 @@ type bpfProgramSpecs struct { type bpfMapSpecs struct { AllocMap *ebpf.MapSpec `ebpf:"alloc_map"` Events *ebpf.MapSpec `ebpf:"events"` + GoContextToSc *ebpf.MapSpec `ebpf:"go_context_to_sc"` GrpcEvents *ebpf.MapSpec `ebpf:"grpc_events"` GrpcStorageMap *ebpf.MapSpec `ebpf:"grpc_storage_map"` SliceArrayBuffMap *ebpf.MapSpec `ebpf:"slice_array_buff_map"` StreamidToGrpcEvents *ebpf.MapSpec `ebpf:"streamid_to_grpc_events"` - TrackedSpans *ebpf.MapSpec `ebpf:"tracked_spans"` TrackedSpansBySc *ebpf.MapSpec `ebpf:"tracked_spans_by_sc"` } @@ -111,11 +111,11 @@ func (o *bpfObjects) Close() error { type bpfMaps struct { AllocMap *ebpf.Map `ebpf:"alloc_map"` Events *ebpf.Map `ebpf:"events"` + GoContextToSc *ebpf.Map `ebpf:"go_context_to_sc"` GrpcEvents *ebpf.Map `ebpf:"grpc_events"` GrpcStorageMap *ebpf.Map `ebpf:"grpc_storage_map"` SliceArrayBuffMap *ebpf.Map `ebpf:"slice_array_buff_map"` StreamidToGrpcEvents *ebpf.Map `ebpf:"streamid_to_grpc_events"` - TrackedSpans *ebpf.Map `ebpf:"tracked_spans"` TrackedSpansBySc *ebpf.Map `ebpf:"tracked_spans_by_sc"` } @@ -123,11 +123,11 @@ func (m *bpfMaps) Close() error { return _BpfClose( m.AllocMap, m.Events, + m.GoContextToSc, m.GrpcEvents, m.GrpcStorageMap, m.SliceArrayBuffMap, m.StreamidToGrpcEvents, - m.TrackedSpans, m.TrackedSpansBySc, ) } diff --git a/internal/pkg/instrumentation/bpf/net/http/client/bpf/probe.bpf.c b/internal/pkg/instrumentation/bpf/net/http/client/bpf/probe.bpf.c index 6ce061fc2..88a6103c3 100644 --- a/internal/pkg/instrumentation/bpf/net/http/client/bpf/probe.bpf.c +++ b/internal/pkg/instrumentation/bpf/net/http/client/bpf/probe.bpf.c @@ -1,9 +1,10 @@ #include "arguments.h" -#include "span_context.h" +#include "trace/span_context.h" #include "go_context.h" #include "go_types.h" #include "uprobe.h" -#include "span_output.h" +#include "trace/span_output.h" +#include "trace/start_span.h" char __license[] SEC("license") = "Dual MIT/GPL"; @@ -98,13 +99,10 @@ int uprobe_Transport_roundTrip(struct pt_regs *ctx) { u64 request_pos = 2; void *req_ptr = get_argument(ctx, request_pos); - // Get parent if exists - void *context_ptr_val = get_Go_context(ctx, 2, ctx_ptr_pos, false); - if (context_ptr_val == NULL) - { - return 0; - } - void *key = get_consistent_key(ctx, context_ptr_val); + struct go_iface go_context = {0}; + get_Go_context(ctx, 2, ctx_ptr_pos, false, &go_context); + + void *key = get_consistent_key(ctx, go_context.data); void *httpReq_ptr = bpf_map_lookup_elem(&http_events, &key); if (httpReq_ptr != NULL) { @@ -123,14 +121,15 @@ int uprobe_Transport_roundTrip(struct pt_regs *ctx) { __builtin_memset(httpReq, 0, sizeof(struct http_request_t)); httpReq->start_time = bpf_ktime_get_ns(); - struct span_context *parent_span_ctx = get_parent_span_context(context_ptr_val); - if (parent_span_ctx != NULL) { - bpf_probe_read(&httpReq->psc, sizeof(httpReq->psc), parent_span_ctx); - copy_byte_arrays(httpReq->psc.TraceID, httpReq->sc.TraceID, TRACE_ID_SIZE); - generate_random_bytes(httpReq->sc.SpanID, SPAN_ID_SIZE); - } else { - get_root_span_context(&httpReq->sc); - } + start_span_params_t start_span_params = { + .ctx = ctx, + .go_context = &go_context, + .psc = &httpReq->psc, + .sc = &httpReq->sc, + .get_parent_span_context_fn = NULL, + .get_parent_span_context_arg = NULL, + }; + start_span(&start_span_params); if (!get_go_string_from_user_ptr((void *)(req_ptr+method_ptr_pos), httpReq->method, sizeof(httpReq->method))) { bpf_printk("uprobe_Transport_roundTrip: Failed to get method from request"); @@ -209,7 +208,7 @@ int uprobe_Transport_roundTrip(struct pt_regs *ctx) { // Write event bpf_map_update_elem(&http_events, &key, httpReq, 0); - start_tracking_span(context_ptr_val, &httpReq->sc); + start_tracking_span(go_context.data, &httpReq->sc); return 0; } @@ -218,8 +217,9 @@ int uprobe_Transport_roundTrip(struct pt_regs *ctx) { SEC("uprobe/Transport_roundTrip") int uprobe_Transport_roundTrip_Returns(struct pt_regs *ctx) { u64 end_time = bpf_ktime_get_ns(); - void *req_ctx_ptr = get_Go_context(ctx, 2, ctx_ptr_pos, false); - void *key = get_consistent_key(ctx, req_ctx_ptr); + struct go_iface go_context = {0}; + get_Go_context(ctx, 2, ctx_ptr_pos, false, &go_context); + void *key = get_consistent_key(ctx, go_context.data); struct http_request_t *http_req_span = bpf_map_lookup_elem(&http_events, &key); if (http_req_span == NULL) { diff --git a/internal/pkg/instrumentation/bpf/net/http/client/bpf_arm64_bpfel.go b/internal/pkg/instrumentation/bpf/net/http/client/bpf_arm64_bpfel.go index 62d6e7c2b..cc9eb2ab2 100644 --- a/internal/pkg/instrumentation/bpf/net/http/client/bpf_arm64_bpfel.go +++ b/internal/pkg/instrumentation/bpf/net/http/client/bpf_arm64_bpfel.go @@ -95,12 +95,12 @@ type bpfProgramSpecs struct { type bpfMapSpecs struct { AllocMap *ebpf.MapSpec `ebpf:"alloc_map"` Events *ebpf.MapSpec `ebpf:"events"` + GoContextToSc *ebpf.MapSpec `ebpf:"go_context_to_sc"` GolangMapbucketStorageMap *ebpf.MapSpec `ebpf:"golang_mapbucket_storage_map"` HttpClientUprobeStorageMap *ebpf.MapSpec `ebpf:"http_client_uprobe_storage_map"` HttpEvents *ebpf.MapSpec `ebpf:"http_events"` HttpHeaders *ebpf.MapSpec `ebpf:"http_headers"` SliceArrayBuffMap *ebpf.MapSpec `ebpf:"slice_array_buff_map"` - TrackedSpans *ebpf.MapSpec `ebpf:"tracked_spans"` TrackedSpansBySc *ebpf.MapSpec `ebpf:"tracked_spans_by_sc"` } @@ -125,12 +125,12 @@ func (o *bpfObjects) Close() error { type bpfMaps struct { AllocMap *ebpf.Map `ebpf:"alloc_map"` Events *ebpf.Map `ebpf:"events"` + GoContextToSc *ebpf.Map `ebpf:"go_context_to_sc"` GolangMapbucketStorageMap *ebpf.Map `ebpf:"golang_mapbucket_storage_map"` HttpClientUprobeStorageMap *ebpf.Map `ebpf:"http_client_uprobe_storage_map"` HttpEvents *ebpf.Map `ebpf:"http_events"` HttpHeaders *ebpf.Map `ebpf:"http_headers"` SliceArrayBuffMap *ebpf.Map `ebpf:"slice_array_buff_map"` - TrackedSpans *ebpf.Map `ebpf:"tracked_spans"` TrackedSpansBySc *ebpf.Map `ebpf:"tracked_spans_by_sc"` } @@ -138,12 +138,12 @@ func (m *bpfMaps) Close() error { return _BpfClose( m.AllocMap, m.Events, + m.GoContextToSc, m.GolangMapbucketStorageMap, m.HttpClientUprobeStorageMap, m.HttpEvents, m.HttpHeaders, m.SliceArrayBuffMap, - m.TrackedSpans, m.TrackedSpansBySc, ) } diff --git a/internal/pkg/instrumentation/bpf/net/http/client/bpf_no_tp_arm64_bpfel.go b/internal/pkg/instrumentation/bpf/net/http/client/bpf_no_tp_arm64_bpfel.go index 06294fada..e717dbf26 100644 --- a/internal/pkg/instrumentation/bpf/net/http/client/bpf_no_tp_arm64_bpfel.go +++ b/internal/pkg/instrumentation/bpf/net/http/client/bpf_no_tp_arm64_bpfel.go @@ -95,12 +95,12 @@ type bpf_no_tpProgramSpecs struct { type bpf_no_tpMapSpecs struct { AllocMap *ebpf.MapSpec `ebpf:"alloc_map"` Events *ebpf.MapSpec `ebpf:"events"` + GoContextToSc *ebpf.MapSpec `ebpf:"go_context_to_sc"` GolangMapbucketStorageMap *ebpf.MapSpec `ebpf:"golang_mapbucket_storage_map"` HttpClientUprobeStorageMap *ebpf.MapSpec `ebpf:"http_client_uprobe_storage_map"` HttpEvents *ebpf.MapSpec `ebpf:"http_events"` HttpHeaders *ebpf.MapSpec `ebpf:"http_headers"` SliceArrayBuffMap *ebpf.MapSpec `ebpf:"slice_array_buff_map"` - TrackedSpans *ebpf.MapSpec `ebpf:"tracked_spans"` TrackedSpansBySc *ebpf.MapSpec `ebpf:"tracked_spans_by_sc"` } @@ -125,12 +125,12 @@ func (o *bpf_no_tpObjects) Close() error { type bpf_no_tpMaps struct { AllocMap *ebpf.Map `ebpf:"alloc_map"` Events *ebpf.Map `ebpf:"events"` + GoContextToSc *ebpf.Map `ebpf:"go_context_to_sc"` GolangMapbucketStorageMap *ebpf.Map `ebpf:"golang_mapbucket_storage_map"` HttpClientUprobeStorageMap *ebpf.Map `ebpf:"http_client_uprobe_storage_map"` HttpEvents *ebpf.Map `ebpf:"http_events"` HttpHeaders *ebpf.Map `ebpf:"http_headers"` SliceArrayBuffMap *ebpf.Map `ebpf:"slice_array_buff_map"` - TrackedSpans *ebpf.Map `ebpf:"tracked_spans"` TrackedSpansBySc *ebpf.Map `ebpf:"tracked_spans_by_sc"` } @@ -138,12 +138,12 @@ func (m *bpf_no_tpMaps) Close() error { return _Bpf_no_tpClose( m.AllocMap, m.Events, + m.GoContextToSc, m.GolangMapbucketStorageMap, m.HttpClientUprobeStorageMap, m.HttpEvents, m.HttpHeaders, m.SliceArrayBuffMap, - m.TrackedSpans, m.TrackedSpansBySc, ) } diff --git a/internal/pkg/instrumentation/bpf/net/http/client/bpf_no_tp_x86_bpfel.go b/internal/pkg/instrumentation/bpf/net/http/client/bpf_no_tp_x86_bpfel.go index 9157b67fd..405307e63 100644 --- a/internal/pkg/instrumentation/bpf/net/http/client/bpf_no_tp_x86_bpfel.go +++ b/internal/pkg/instrumentation/bpf/net/http/client/bpf_no_tp_x86_bpfel.go @@ -95,12 +95,12 @@ type bpf_no_tpProgramSpecs struct { type bpf_no_tpMapSpecs struct { AllocMap *ebpf.MapSpec `ebpf:"alloc_map"` Events *ebpf.MapSpec `ebpf:"events"` + GoContextToSc *ebpf.MapSpec `ebpf:"go_context_to_sc"` GolangMapbucketStorageMap *ebpf.MapSpec `ebpf:"golang_mapbucket_storage_map"` HttpClientUprobeStorageMap *ebpf.MapSpec `ebpf:"http_client_uprobe_storage_map"` HttpEvents *ebpf.MapSpec `ebpf:"http_events"` HttpHeaders *ebpf.MapSpec `ebpf:"http_headers"` SliceArrayBuffMap *ebpf.MapSpec `ebpf:"slice_array_buff_map"` - TrackedSpans *ebpf.MapSpec `ebpf:"tracked_spans"` TrackedSpansBySc *ebpf.MapSpec `ebpf:"tracked_spans_by_sc"` } @@ -125,12 +125,12 @@ func (o *bpf_no_tpObjects) Close() error { type bpf_no_tpMaps struct { AllocMap *ebpf.Map `ebpf:"alloc_map"` Events *ebpf.Map `ebpf:"events"` + GoContextToSc *ebpf.Map `ebpf:"go_context_to_sc"` GolangMapbucketStorageMap *ebpf.Map `ebpf:"golang_mapbucket_storage_map"` HttpClientUprobeStorageMap *ebpf.Map `ebpf:"http_client_uprobe_storage_map"` HttpEvents *ebpf.Map `ebpf:"http_events"` HttpHeaders *ebpf.Map `ebpf:"http_headers"` SliceArrayBuffMap *ebpf.Map `ebpf:"slice_array_buff_map"` - TrackedSpans *ebpf.Map `ebpf:"tracked_spans"` TrackedSpansBySc *ebpf.Map `ebpf:"tracked_spans_by_sc"` } @@ -138,12 +138,12 @@ func (m *bpf_no_tpMaps) Close() error { return _Bpf_no_tpClose( m.AllocMap, m.Events, + m.GoContextToSc, m.GolangMapbucketStorageMap, m.HttpClientUprobeStorageMap, m.HttpEvents, m.HttpHeaders, m.SliceArrayBuffMap, - m.TrackedSpans, m.TrackedSpansBySc, ) } diff --git a/internal/pkg/instrumentation/bpf/net/http/client/bpf_x86_bpfel.go b/internal/pkg/instrumentation/bpf/net/http/client/bpf_x86_bpfel.go index 206215330..24fcac62e 100644 --- a/internal/pkg/instrumentation/bpf/net/http/client/bpf_x86_bpfel.go +++ b/internal/pkg/instrumentation/bpf/net/http/client/bpf_x86_bpfel.go @@ -95,12 +95,12 @@ type bpfProgramSpecs struct { type bpfMapSpecs struct { AllocMap *ebpf.MapSpec `ebpf:"alloc_map"` Events *ebpf.MapSpec `ebpf:"events"` + GoContextToSc *ebpf.MapSpec `ebpf:"go_context_to_sc"` GolangMapbucketStorageMap *ebpf.MapSpec `ebpf:"golang_mapbucket_storage_map"` HttpClientUprobeStorageMap *ebpf.MapSpec `ebpf:"http_client_uprobe_storage_map"` HttpEvents *ebpf.MapSpec `ebpf:"http_events"` HttpHeaders *ebpf.MapSpec `ebpf:"http_headers"` SliceArrayBuffMap *ebpf.MapSpec `ebpf:"slice_array_buff_map"` - TrackedSpans *ebpf.MapSpec `ebpf:"tracked_spans"` TrackedSpansBySc *ebpf.MapSpec `ebpf:"tracked_spans_by_sc"` } @@ -125,12 +125,12 @@ func (o *bpfObjects) Close() error { type bpfMaps struct { AllocMap *ebpf.Map `ebpf:"alloc_map"` Events *ebpf.Map `ebpf:"events"` + GoContextToSc *ebpf.Map `ebpf:"go_context_to_sc"` GolangMapbucketStorageMap *ebpf.Map `ebpf:"golang_mapbucket_storage_map"` HttpClientUprobeStorageMap *ebpf.Map `ebpf:"http_client_uprobe_storage_map"` HttpEvents *ebpf.Map `ebpf:"http_events"` HttpHeaders *ebpf.Map `ebpf:"http_headers"` SliceArrayBuffMap *ebpf.Map `ebpf:"slice_array_buff_map"` - TrackedSpans *ebpf.Map `ebpf:"tracked_spans"` TrackedSpansBySc *ebpf.Map `ebpf:"tracked_spans_by_sc"` } @@ -138,12 +138,12 @@ func (m *bpfMaps) Close() error { return _BpfClose( m.AllocMap, m.Events, + m.GoContextToSc, m.GolangMapbucketStorageMap, m.HttpClientUprobeStorageMap, m.HttpEvents, m.HttpHeaders, m.SliceArrayBuffMap, - m.TrackedSpans, m.TrackedSpansBySc, ) } diff --git a/internal/pkg/instrumentation/bpf/net/http/server/bpf/probe.bpf.c b/internal/pkg/instrumentation/bpf/net/http/server/bpf/probe.bpf.c index 00cc93649..0c1fb2b73 100644 --- a/internal/pkg/instrumentation/bpf/net/http/server/bpf/probe.bpf.c +++ b/internal/pkg/instrumentation/bpf/net/http/server/bpf/probe.bpf.c @@ -13,11 +13,12 @@ // limitations under the License. #include "arguments.h" -#include "span_context.h" +#include "trace/span_context.h" #include "go_context.h" #include "go_types.h" #include "uprobe.h" -#include "span_output.h" +#include "trace/span_output.h" +#include "trace/start_span.h" char __license[] SEC("license") = "Dual MIT/GPL"; @@ -198,8 +199,9 @@ static __always_inline void read_go_string(void *base, int offset, char *output, SEC("uprobe/serverHandler_ServeHTTP") int uprobe_serverHandler_ServeHTTP(struct pt_regs *ctx) { - void *req_ctx_ptr = get_Go_context(ctx, 4, ctx_ptr_pos, false); - void *key = get_consistent_key(ctx, req_ctx_ptr); + struct go_iface go_context = {0}; + get_Go_context(ctx, 4, ctx_ptr_pos, false, &go_context); + void *key = get_consistent_key(ctx, go_context.data); void *httpReq_ptr = bpf_map_lookup_elem(&http_server_uprobes, &key); if (httpReq_ptr != NULL) { @@ -226,21 +228,18 @@ int uprobe_serverHandler_ServeHTTP(struct pt_regs *ctx) // Propagate context void *req_ptr = get_argument(ctx, 4); - long res = extract_context_from_req_headers((void*)(req_ptr + headers_ptr_pos), &http_server_span->psc); - if (res < 0) { - get_root_span_context(&http_server_span->sc); - } else { - get_span_context_from_parent(&http_server_span->psc, &http_server_span->sc); - } - - if (req_ctx_ptr == NULL) - { - bpf_printk("uprobe/HandlerFunc_ServeHTTP: req_ctx_ptr is NULL"); - return 0; - } + start_span_params_t start_span_params = { + .ctx = ctx, + .go_context = &go_context, + .psc = &http_server_span->psc, + .sc = &http_server_span->sc, + .get_parent_span_context_fn = extract_context_from_req_headers, + .get_parent_span_context_arg = (void*)(req_ptr + headers_ptr_pos), + }; + start_span(&start_span_params); bpf_map_update_elem(&http_server_uprobes, &key, uprobe_data, 0); - start_tracking_span(req_ctx_ptr, &http_server_span->sc); + start_tracking_span(go_context.data, &http_server_span->sc); return 0; } @@ -249,8 +248,9 @@ int uprobe_serverHandler_ServeHTTP(struct pt_regs *ctx) SEC("uprobe/serverHandler_ServeHTTP") int uprobe_serverHandler_ServeHTTP_Returns(struct pt_regs *ctx) { u64 end_time = bpf_ktime_get_ns(); - void *req_ctx_ptr = get_Go_context(ctx, 4, ctx_ptr_pos, false); - void *key = get_consistent_key(ctx, req_ctx_ptr); + struct go_iface go_context = {0}; + get_Go_context(ctx, 4, ctx_ptr_pos, false, &go_context); + void *key = get_consistent_key(ctx, go_context.data); struct uprobe_data_t *uprobe_data = bpf_map_lookup_elem(&http_server_uprobes, &key); if (uprobe_data == NULL) { diff --git a/internal/pkg/instrumentation/bpf/net/http/server/bpf_arm64_bpfel.go b/internal/pkg/instrumentation/bpf/net/http/server/bpf_arm64_bpfel.go index 1a9d0b7c4..720dcf11c 100644 --- a/internal/pkg/instrumentation/bpf/net/http/server/bpf_arm64_bpfel.go +++ b/internal/pkg/instrumentation/bpf/net/http/server/bpf_arm64_bpfel.go @@ -89,11 +89,11 @@ type bpfProgramSpecs struct { type bpfMapSpecs struct { AllocMap *ebpf.MapSpec `ebpf:"alloc_map"` Events *ebpf.MapSpec `ebpf:"events"` + GoContextToSc *ebpf.MapSpec `ebpf:"go_context_to_sc"` GolangMapbucketStorageMap *ebpf.MapSpec `ebpf:"golang_mapbucket_storage_map"` HttpServerUprobeStorageMap *ebpf.MapSpec `ebpf:"http_server_uprobe_storage_map"` HttpServerUprobes *ebpf.MapSpec `ebpf:"http_server_uprobes"` SliceArrayBuffMap *ebpf.MapSpec `ebpf:"slice_array_buff_map"` - TrackedSpans *ebpf.MapSpec `ebpf:"tracked_spans"` TrackedSpansBySc *ebpf.MapSpec `ebpf:"tracked_spans_by_sc"` } @@ -118,11 +118,11 @@ func (o *bpfObjects) Close() error { type bpfMaps struct { AllocMap *ebpf.Map `ebpf:"alloc_map"` Events *ebpf.Map `ebpf:"events"` + GoContextToSc *ebpf.Map `ebpf:"go_context_to_sc"` GolangMapbucketStorageMap *ebpf.Map `ebpf:"golang_mapbucket_storage_map"` HttpServerUprobeStorageMap *ebpf.Map `ebpf:"http_server_uprobe_storage_map"` HttpServerUprobes *ebpf.Map `ebpf:"http_server_uprobes"` SliceArrayBuffMap *ebpf.Map `ebpf:"slice_array_buff_map"` - TrackedSpans *ebpf.Map `ebpf:"tracked_spans"` TrackedSpansBySc *ebpf.Map `ebpf:"tracked_spans_by_sc"` } @@ -130,11 +130,11 @@ func (m *bpfMaps) Close() error { return _BpfClose( m.AllocMap, m.Events, + m.GoContextToSc, m.GolangMapbucketStorageMap, m.HttpServerUprobeStorageMap, m.HttpServerUprobes, m.SliceArrayBuffMap, - m.TrackedSpans, m.TrackedSpansBySc, ) } diff --git a/internal/pkg/instrumentation/bpf/net/http/server/bpf_x86_bpfel.go b/internal/pkg/instrumentation/bpf/net/http/server/bpf_x86_bpfel.go index 0b5937d2c..c4b3373aa 100644 --- a/internal/pkg/instrumentation/bpf/net/http/server/bpf_x86_bpfel.go +++ b/internal/pkg/instrumentation/bpf/net/http/server/bpf_x86_bpfel.go @@ -89,11 +89,11 @@ type bpfProgramSpecs struct { type bpfMapSpecs struct { AllocMap *ebpf.MapSpec `ebpf:"alloc_map"` Events *ebpf.MapSpec `ebpf:"events"` + GoContextToSc *ebpf.MapSpec `ebpf:"go_context_to_sc"` GolangMapbucketStorageMap *ebpf.MapSpec `ebpf:"golang_mapbucket_storage_map"` HttpServerUprobeStorageMap *ebpf.MapSpec `ebpf:"http_server_uprobe_storage_map"` HttpServerUprobes *ebpf.MapSpec `ebpf:"http_server_uprobes"` SliceArrayBuffMap *ebpf.MapSpec `ebpf:"slice_array_buff_map"` - TrackedSpans *ebpf.MapSpec `ebpf:"tracked_spans"` TrackedSpansBySc *ebpf.MapSpec `ebpf:"tracked_spans_by_sc"` } @@ -118,11 +118,11 @@ func (o *bpfObjects) Close() error { type bpfMaps struct { AllocMap *ebpf.Map `ebpf:"alloc_map"` Events *ebpf.Map `ebpf:"events"` + GoContextToSc *ebpf.Map `ebpf:"go_context_to_sc"` GolangMapbucketStorageMap *ebpf.Map `ebpf:"golang_mapbucket_storage_map"` HttpServerUprobeStorageMap *ebpf.Map `ebpf:"http_server_uprobe_storage_map"` HttpServerUprobes *ebpf.Map `ebpf:"http_server_uprobes"` SliceArrayBuffMap *ebpf.Map `ebpf:"slice_array_buff_map"` - TrackedSpans *ebpf.Map `ebpf:"tracked_spans"` TrackedSpansBySc *ebpf.Map `ebpf:"tracked_spans_by_sc"` } @@ -130,11 +130,11 @@ func (m *bpfMaps) Close() error { return _BpfClose( m.AllocMap, m.Events, + m.GoContextToSc, m.GolangMapbucketStorageMap, m.HttpServerUprobeStorageMap, m.HttpServerUprobes, m.SliceArrayBuffMap, - m.TrackedSpans, m.TrackedSpansBySc, ) }