-
Notifications
You must be signed in to change notification settings - Fork 91
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Manual instrumentation support - Phase 1 (#523)
* Initial instrumentation of otel sdk trace functions * Add offsets for otel go sdk * Pass the user defined span name through eBPF * Initial attribute parsing * Fix struct for attribute value * Try more efficient attribute encoding, currently only working for numeric values, missing Go decoding * Initial draft * Instrument Otel API functions to integrate manual spans with automatic ones * revert changes to verifier log collection settings * Add tests for otel API instrumentation * update changelog and lint * Check kernel version * Change format of attributes in eBPF to make the verification easier * Small fix * Adding printk if attribute is too long for buffer * Update internal/include/otel_types.h Co-authored-by: Mike Goldsmith <goldsmith.mike@gmail.com> * Code review 1 * Apply suggestions from code review Co-authored-by: Tyler Yahn <MrAlias@users.noreply.github.com> * rename WithOtelApi to globalImpl * Rename probe folder * Inject attribute types consts from Go * add cli flag for otel-global to record telemetry from the OpenTelemetry default global * debug tests * fix debug * modify set_attr_value * print verifier log * larger verifier log * ... * simplify eBPF code * Clean-up and updating changelog * run make precommit * Fix doc * Apply suggestions from code review --------- Co-authored-by: Mike Goldsmith <goldsmith.mike@gmail.com> Co-authored-by: Tyler Yahn <MrAlias@users.noreply.github.com>
- Loading branch information
1 parent
2d37cd2
commit dc3681a
Showing
20 changed files
with
1,337 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,143 @@ | ||
// 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 _OTEL_TYPES_H | ||
#define _OTEL_TYPES_H | ||
|
||
#include "go_types.h" | ||
#include "common.h" | ||
|
||
// Injected in init | ||
volatile const u64 attr_type_invalid; | ||
|
||
volatile const u64 attr_type_bool; | ||
volatile const u64 attr_type_int64; | ||
volatile const u64 attr_type_float64; | ||
volatile const u64 attr_type_string; | ||
|
||
volatile const u64 attr_type_boolslice; | ||
volatile const u64 attr_type_int64slice; | ||
volatile const u64 attr_type_float64slice; | ||
volatile const u64 attr_type_stringslice; | ||
|
||
/* Defintions should mimic structs defined in go.opentelemetry.io/otel/attribute */ | ||
|
||
typedef struct go_otel_attr_value { | ||
u64 vtype; | ||
u64 numeric; | ||
struct go_string string; | ||
struct go_iface slice; | ||
} go_otel_attr_value_t; | ||
|
||
typedef struct go_otel_key_value { | ||
struct go_string key; | ||
go_otel_attr_value_t value; | ||
} go_otel_key_value_t; | ||
|
||
#define OTEL_ATTRIBUTE_KEY_MAX_LEN (32) | ||
#define OTEL_ATTRIBUTE_VALUE_MAX_LEN (128) | ||
#define OTEL_ATTRUBUTE_MAX_COUNT (16) | ||
|
||
typedef struct otel_attirbute { | ||
u16 val_length; | ||
u8 vtype; | ||
u8 reserved; | ||
char key[OTEL_ATTRIBUTE_KEY_MAX_LEN]; | ||
char value[OTEL_ATTRIBUTE_VALUE_MAX_LEN]; | ||
} otel_attirbute_t; | ||
|
||
typedef struct otel_attributes { | ||
otel_attirbute_t attrs[OTEL_ATTRUBUTE_MAX_COUNT]; | ||
u8 valid_attrs; | ||
}__attribute__((packed)) otel_attributes_t; | ||
|
||
static __always_inline bool set_attr_value(otel_attirbute_t *attr, go_otel_attr_value_t *go_attr_value) | ||
{ | ||
u64 vtype = go_attr_value->vtype; | ||
|
||
if (vtype == attr_type_invalid) { | ||
bpf_printk("Invalid attribute value type\n"); | ||
return false; | ||
} | ||
|
||
// Constant size values | ||
if (vtype == attr_type_bool || | ||
vtype == attr_type_int64 || | ||
vtype == attr_type_float64) { | ||
bpf_probe_read(attr->value, sizeof(s64), &go_attr_value->numeric); | ||
return true; | ||
} | ||
|
||
// String values | ||
if (vtype == attr_type_string) { | ||
if (go_attr_value->string.len >= OTEL_ATTRIBUTE_VALUE_MAX_LEN) { | ||
bpf_printk("Aattribute string value is too long\n"); | ||
return false; | ||
} | ||
return get_go_string_from_user_ptr(&go_attr_value->string, attr->value, OTEL_ATTRIBUTE_VALUE_MAX_LEN); | ||
} | ||
|
||
// TODO (#525): handle slices | ||
return false; | ||
} | ||
|
||
static __always_inline void convert_go_otel_attributes(void *attrs_buf, s64 slice_len, otel_attributes_t *enc_attrs) | ||
{ | ||
if (attrs_buf == NULL || enc_attrs == NULL){ | ||
return; | ||
} | ||
|
||
if (slice_len < 1) { | ||
return; | ||
} | ||
|
||
s64 num_attrs = slice_len < OTEL_ATTRUBUTE_MAX_COUNT ? slice_len : OTEL_ATTRUBUTE_MAX_COUNT; | ||
go_otel_key_value_t *go_attr = (go_otel_key_value_t*)attrs_buf; | ||
go_otel_attr_value_t go_attr_value = {0}; | ||
struct go_string go_str = {0}; | ||
u8 valid_attrs = 0; | ||
|
||
for (u32 go_attr_index = 0; go_attr_index < num_attrs; go_attr_index++) { | ||
__builtin_memset(&go_attr_value, 0, sizeof(go_otel_attr_value_t)); | ||
// Read the value struct | ||
bpf_probe_read(&go_attr_value, sizeof(go_otel_attr_value_t), &go_attr[go_attr_index].value); | ||
|
||
if (go_attr_value.vtype == attr_type_invalid) { | ||
continue; | ||
} | ||
|
||
// Read the key string | ||
bpf_probe_read(&go_str, sizeof(struct go_string), &go_attr[go_attr_index].key); | ||
if (go_str.len >= OTEL_ATTRIBUTE_KEY_MAX_LEN) { | ||
// key string is too large | ||
bpf_printk("Attribute key string is too long\n"); | ||
continue; | ||
} | ||
|
||
if (!get_go_string_from_user_ptr(&go_str, enc_attrs->attrs[valid_attrs].key, OTEL_ATTRIBUTE_KEY_MAX_LEN)) { | ||
continue; | ||
} | ||
|
||
if (!set_attr_value(&enc_attrs->attrs[valid_attrs], &go_attr_value)) { | ||
continue; | ||
} | ||
|
||
enc_attrs->attrs[valid_attrs].vtype = go_attr_value.vtype; | ||
valid_attrs++; | ||
} | ||
|
||
enc_attrs->valid_attrs = valid_attrs; | ||
} | ||
|
||
#endif |
Oops, something went wrong.