Skip to content

Commit

Permalink
otelglobal: add support for v1.32.0 of otel-go (#1302)
Browse files Browse the repository at this point in the history
* otelglobal: add support for v1.32.0 of otel-go

* Add changelog entry

* add comment

---------

Co-authored-by: Tyler Yahn <[email protected]>
  • Loading branch information
RonFed and MrAlias authored Nov 20, 2024
1 parent 99192a9 commit 989bb43
Show file tree
Hide file tree
Showing 5 changed files with 121 additions and 20 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ OpenTelemetry Go Automatic Instrumentation adheres to [Semantic Versioning](http
- Support Go standard libraries for 1.22.9 and 1.23.3. ([#1250](https://github.com/open-telemetry/opentelemetry-go-instrumentation/pull/1250))
- Support `google.golang.org/grpc` `1.68.0`. ([#1251](https://github.com/open-telemetry/opentelemetry-go-instrumentation/pull/1251))
- Support `golang.org/x/net` `0.31.0`. ([#1254](https://github.com/open-telemetry/opentelemetry-go-instrumentation/pull/1254))
- Support `go.opentelemetry.io/[email protected]`. ([#1302](https://github.com/open-telemetry/opentelemetry-go-instrumentation/pull/1302))

### Fixed

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,17 +55,26 @@ typedef struct go_tracer_id_partial {
struct go_string version;
} go_tracer_id_partial_t;

typedef struct go_tracer_id_full {
typedef struct go_tracer_with_schema {
struct go_string name;
struct go_string version;
struct go_string schema_url;
} go_tracer_id_full_t;
} go_tracer_with_schema_t;

typedef struct go_tracer_with_scope_attributes {
struct go_string name;
struct go_string version;
struct go_string schema_url;
go_iface_t scope_attributes;
} go_tracer_with_scope_attributes_t;


typedef void* go_tracer_ptr;

// tracerProvider contains a map of tracers
MAP_BUCKET_DEFINITION(go_tracer_id_partial_t, go_tracer_ptr)
MAP_BUCKET_DEFINITION(go_tracer_id_full_t, go_tracer_ptr)
MAP_BUCKET_DEFINITION(go_tracer_with_schema_t, go_tracer_ptr)
MAP_BUCKET_DEFINITION(go_tracer_with_scope_attributes_t, go_tracer_ptr)

struct {
__uint(type, BPF_MAP_TYPE_HASH);
Expand Down Expand Up @@ -100,7 +109,7 @@ struct
{
__uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
__uint(key_size, sizeof(u32));
__uint(value_size, sizeof(MAP_BUCKET_TYPE(go_tracer_id_full_t, go_tracer_ptr)));
__uint(value_size, sizeof(MAP_BUCKET_TYPE(go_tracer_with_scope_attributes_t, go_tracer_ptr)));
__uint(max_entries, 1);
} golang_mapbucket_storage_map SEC(".maps");

Expand Down Expand Up @@ -130,6 +139,7 @@ volatile const u64 tracer_provider_tracers_pos;
volatile const u64 buckets_ptr_pos;

volatile const bool tracer_id_contains_schemaURL;
volatile const bool tracer_id_contains_scope_attributes;

// 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 @@ -202,7 +212,72 @@ static __always_inline long fill_partial_tracer_id_from_tracers_map(void *tracer
return 0;
}

static __always_inline long fill_full_tracer_id_from_tracers_map(void *tracers_map, go_tracer_ptr tracer, tracer_id_t *tracer_id) {
static __always_inline long fill_tracer_id_with_schema_from_tracers_map(void *tracers_map, go_tracer_ptr tracer, tracer_id_t *tracer_id) {
u64 tracers_count = 0;
long res = 0;
res = bpf_probe_read(&tracers_count, sizeof(tracers_count), tracers_map);
if (res < 0)
{
return -1;
}
if (tracers_count == 0)
{
return -1;
}
unsigned char log_2_bucket_count;
res = bpf_probe_read(&log_2_bucket_count, sizeof(log_2_bucket_count), tracers_map + 9);
if (res < 0)
{
return -1;
}
u64 bucket_count = 1 << log_2_bucket_count;
void *buckets_array;
res = bpf_probe_read(&buckets_array, sizeof(buckets_array), (void*)(tracers_map + buckets_ptr_pos));
if (res < 0)
{
return -1;
}
u32 map_id = 0;
MAP_BUCKET_TYPE(go_tracer_with_schema_t, go_tracer_ptr) *map_bucket = bpf_map_lookup_elem(&golang_mapbucket_storage_map, &map_id);
if (!map_bucket)
{
return -1;
}

for (u64 j = 0; j < MAX_BUCKETS; j++)
{
if (j >= bucket_count)
{
break;
}
res = bpf_probe_read(map_bucket, sizeof(MAP_BUCKET_TYPE(go_tracer_with_schema_t, go_tracer_ptr)), buckets_array + (j * sizeof(MAP_BUCKET_TYPE(go_tracer_with_schema_t, go_tracer_ptr))));
if (res < 0)
{
continue;
}
for (u64 i = 0; i < 8; i++)
{
if (map_bucket->tophash[i] == 0)
{
continue;
}
if (map_bucket->values[i] == NULL)
{
continue;
}
if (map_bucket->values[i] != tracer)
{
continue;
}
get_go_string_from_user_ptr(&map_bucket->keys[i].version, tracer_id->version, MAX_TRACER_VERSION_LEN);
get_go_string_from_user_ptr(&map_bucket->keys[i].schema_url, tracer_id->schema_url, MAX_TRACER_SCHEMA_URL_LEN);
return 0;
}
}
return 0;
}

static __always_inline long fill_tracer_id_with_scope_attributes_from_tracers_map(void *tracers_map, go_tracer_ptr tracer, tracer_id_t *tracer_id) {
u64 tracers_count = 0;
long res = 0;
res = bpf_probe_read(&tracers_count, sizeof(tracers_count), tracers_map);
Expand All @@ -228,7 +303,7 @@ static __always_inline long fill_full_tracer_id_from_tracers_map(void *tracers_m
return -1;
}
u32 map_id = 0;
MAP_BUCKET_TYPE(go_tracer_id_full_t, go_tracer_ptr) *map_bucket = bpf_map_lookup_elem(&golang_mapbucket_storage_map, &map_id);
MAP_BUCKET_TYPE(go_tracer_with_scope_attributes_t, go_tracer_ptr) *map_bucket = bpf_map_lookup_elem(&golang_mapbucket_storage_map, &map_id);
if (!map_bucket)
{
return -1;
Expand All @@ -240,7 +315,7 @@ static __always_inline long fill_full_tracer_id_from_tracers_map(void *tracers_m
{
break;
}
res = bpf_probe_read(map_bucket, sizeof(MAP_BUCKET_TYPE(go_tracer_id_full_t, go_tracer_ptr)), buckets_array + (j * sizeof(MAP_BUCKET_TYPE(go_tracer_id_full_t, go_tracer_ptr))));
res = bpf_probe_read(map_bucket, sizeof(MAP_BUCKET_TYPE(go_tracer_with_scope_attributes_t, go_tracer_ptr)), buckets_array + (j * sizeof(MAP_BUCKET_TYPE(go_tracer_with_schema_t, go_tracer_ptr))));
if (res < 0)
{
continue;
Expand Down Expand Up @@ -293,7 +368,15 @@ static __always_inline long fill_tracer_id(tracer_id_t *tracer_id, go_tracer_ptr
}

if (tracer_id_contains_schemaURL) {
res = fill_full_tracer_id_from_tracers_map(tracers_map, tracer, tracer_id);
// version of otel-go is 1.28.0 or higher
if (tracer_id_contains_scope_attributes) {
// version of otel-go is 1.32.0 or higher
// we don't collect the scope attributes, but we need to take their presence into account,
// when parsing the map bucket
res = fill_tracer_id_with_scope_attributes_from_tracers_map(tracers_map, tracer, tracer_id);
} else {
res = fill_tracer_id_with_schema_from_tracers_map(tracers_map, tracer, tracer_id);
}
} else {
res = fill_partial_tracer_id_from_tracers_map(tracers_map, tracer, tracer_id);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ func New(logger *slog.Logger) probe.Probe {
Val: structfield.NewID("std", "runtime", "hmap", "buckets"),
},
tracerIDContainsSchemaURL{},
tracerIDContainsScopeAttributes{},
},
Uprobes: []probe.Uprobe{
{
Expand Down Expand Up @@ -138,21 +139,37 @@ func New(logger *slog.Logger) probe.Probe {
}
}

// framePosConst is a Probe Const defining whether the tracer key contains schemaURL.
// tracerIDContainsSchemaURL is a Probe Const defining whether the tracer key contains schemaURL.
type tracerIDContainsSchemaURL struct{}

// Prior to v1.28 the tracer key did not contain schemaURL. However, in that version a
// change was made to include it.
// https://github.com/open-telemetry/opentelemetry-go/pull/5426/files
var paramChangeVer = version.Must(version.NewVersion("1.28.0"))
var schemaAddedToTracerKeyVer = version.Must(version.NewVersion("1.28.0"))

func (c tracerIDContainsSchemaURL) InjectOption(td *process.TargetDetails) (inject.Option, error) {
ver, ok := td.Libraries["go.opentelemetry.io/otel"]
if !ok {
return nil, fmt.Errorf("unknown module version: %s", pkg)
}

return inject.WithKeyValue("tracer_id_contains_schemaURL", ver.GreaterThanOrEqual(paramChangeVer)), nil
return inject.WithKeyValue("tracer_id_contains_schemaURL", ver.GreaterThanOrEqual(schemaAddedToTracerKeyVer)), nil
}

// In v1.32.0 the tracer key was updated to include the scope attributes.
// https://github.com/open-telemetry/opentelemetry-go/pull/5924/files
var scopeAttributesAddedToTracerKeyVer = version.Must(version.NewVersion("1.32.0"))

// tracerIDContainsScopeAttributes is a Probe Const defining whether the tracer key contains scope attributes.
type tracerIDContainsScopeAttributes struct{}

func (c tracerIDContainsScopeAttributes) InjectOption(td *process.TargetDetails) (inject.Option, error) {
ver, ok := td.Libraries["go.opentelemetry.io/otel"]
if !ok {
return nil, fmt.Errorf("unknown module version: %s", pkg)
}

return inject.WithKeyValue("tracer_id_contains_scope_attributes", ver.GreaterThanOrEqual(scopeAttributesAddedToTracerKeyVer)), nil
}

type attributeKeyVal struct {
Expand Down
6 changes: 3 additions & 3 deletions internal/test/e2e/otelglobal/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@ module go.opentelemetry.io/auto/internal/test/e2e/otelglobal
go 1.22.0

require (
go.opentelemetry.io/otel v1.31.0
go.opentelemetry.io/otel/trace v1.31.0
go.opentelemetry.io/otel v1.32.0
go.opentelemetry.io/otel/trace v1.32.0
)

require (
github.com/go-logr/logr v1.4.2 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
go.opentelemetry.io/otel/metric v1.31.0 // indirect
go.opentelemetry.io/otel/metric v1.32.0 // indirect
)
12 changes: 6 additions & 6 deletions internal/test/e2e/otelglobal/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
go.opentelemetry.io/otel v1.31.0 h1:NsJcKPIW0D0H3NgzPDHmo0WW6SptzPdqg/L1zsIm2hY=
go.opentelemetry.io/otel v1.31.0/go.mod h1:O0C14Yl9FgkjqcCZAsE053C13OaddMYr/hz6clDkEJE=
go.opentelemetry.io/otel/metric v1.31.0 h1:FSErL0ATQAmYHUIzSezZibnyVlft1ybhy4ozRPcF2fE=
go.opentelemetry.io/otel/metric v1.31.0/go.mod h1:C3dEloVbLuYoX41KpmAhOqNriGbA+qqH6PQ5E5mUfnY=
go.opentelemetry.io/otel/trace v1.31.0 h1:ffjsj1aRouKewfr85U2aGagJ46+MvodynlQ1HYdmJys=
go.opentelemetry.io/otel/trace v1.31.0/go.mod h1:TXZkRk7SM2ZQLtR6eoAWQFIHPvzQ06FJAsO1tJg480A=
go.opentelemetry.io/otel v1.32.0 h1:WnBN+Xjcteh0zdk01SVqV55d/m62NJLJdIyb4y/WO5U=
go.opentelemetry.io/otel v1.32.0/go.mod h1:00DCVSB0RQcnzlwyTfqtxSm+DRr9hpYrHjNGiBHVQIg=
go.opentelemetry.io/otel/metric v1.32.0 h1:xV2umtmNcThh2/a/aCP+h64Xx5wsj8qqnkYZktzNa0M=
go.opentelemetry.io/otel/metric v1.32.0/go.mod h1:jH7CIbbK6SH2V2wE16W05BHCtIDzauciCRLoc/SyMv8=
go.opentelemetry.io/otel/trace v1.32.0 h1:WIC9mYrXf8TmY/EXuULKc8hR17vE+Hjv2cssQDe03fM=
go.opentelemetry.io/otel/trace v1.32.0/go.mod h1:+i4rkvCraA+tG6AzwloGaCtkx53Fa+L+V8e9a7YvhT8=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

0 comments on commit 989bb43

Please sign in to comment.