Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 5 additions & 7 deletions bpf/gotracer/go_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,17 @@

#include <gotracer/go_offsets.h>

#include <gotracer/maps/mongo.h>

#include <logger/bpf_dbg.h>

char __license[] SEC("license") = "Dual MIT/GPL";

enum { W3C_KEY_LENGTH = 11, W3C_VAL_LENGTH = 55 };

static unsigned char tp_encoded[] = {
0x4d, 0x83, 0x21, 0x6b, 0x1d, 0x85, 0xa9, 0x3f}; // hpack encoded "traceparent"

// Temporary information about a function invocation. It stores the invocation time of a function
// as well as the value of registers at the invocation time. This way we can retrieve them at the
// return uprobes so we can know the values of the function arguments (which are passed as registers
Expand Down Expand Up @@ -119,13 +124,6 @@ struct {
__uint(max_entries, MAX_CONCURRENT_REQUESTS);
} ongoing_sql_queries SEC(".maps");

struct {
__uint(type, BPF_MAP_TYPE_LRU_HASH);
__type(key, go_addr_key_t); // key: goroutine id
__type(value, mongo_go_client_req_t); // the request
__uint(max_entries, MAX_CONCURRENT_REQUESTS);
} ongoing_mongo_requests SEC(".maps");

typedef struct grpc_header_field {
u8 *key_ptr;
u64 key_len;
Expand Down
5 changes: 2 additions & 3 deletions bpf/gotracer/go_grpc.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
#include <gotracer/go_common.h>
#include <gotracer/go_offsets.h>
#include <gotracer/go_str.h>
#include <gotracer/hpack.h>

#include <gotracer/maps/grpc.h>

Expand Down Expand Up @@ -826,7 +825,7 @@ int obi_uprobe_grpcFramerWriteHeaders_returns(struct pt_regs *ctx) {
if (original_size > 0) {
u8 type_byte = 0;
const u8 key_len =
TP_ENCODED_LEN | 0x80; // high tagged to signify hpack encoded value
sizeof(tp_encoded) | 0x80; // high tagged to signify hpack encoded value
const u8 val_len = TP_MAX_VAL_LENGTH;

// We don't hpack encode the value of the traceparent field, because that will require that
Expand All @@ -842,7 +841,7 @@ int obi_uprobe_grpcFramerWriteHeaders_returns(struct pt_regs *ctx) {
// Write 'traceparent' encoded as hpack
bpf_probe_write_user(buf_arr + (n & 0x0ffff), tp_encoded, sizeof(tp_encoded));
;
n += TP_ENCODED_LEN;
n += sizeof(tp_encoded);
// Write the length of the hpack encoded traceparent field
bpf_probe_write_user(buf_arr + (n & 0x0ffff), &val_len, sizeof(val_len));
n++;
Expand Down
18 changes: 0 additions & 18 deletions bpf/gotracer/go_kafka_def.h

This file was deleted.

61 changes: 12 additions & 49 deletions bpf/gotracer/go_kafka_go.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,58 +17,16 @@

#include <bpfcore/utils.h>

#include <common/common.h>
#include <common/ringbuf.h>

#include <gotracer/go_common.h>
#include <gotracer/go_kafka_def.h>

#include <logger/bpf_dbg.h>
#include <gotracer/maps/kafka.h>

#include <gotracer/types/kafka.h>

typedef struct produce_req {
u64 msg_ptr;
u64 conn_ptr;
u64 start_monotime_ns;
} produce_req_t;

typedef struct topic {
char name[MAX_TOPIC_NAME_LEN];
tp_info_t tp;
} topic_t;

struct {
__uint(type, BPF_MAP_TYPE_LRU_HASH);
__type(key, go_addr_key_t); // w_ptr
__type(value, tp_info_t); // traceparent
__uint(max_entries, MAX_CONCURRENT_REQUESTS);
} produce_traceparents SEC(".maps");

struct {
__uint(type, BPF_MAP_TYPE_LRU_HASH);
__type(key, go_addr_key_t); // goroutine
__type(value, topic_t); // topic info
__uint(max_entries, MAX_CONCURRENT_REQUESTS);
} ongoing_produce_topics SEC(".maps");

struct {
__uint(type, BPF_MAP_TYPE_LRU_HASH);
__type(key, go_addr_key_t); // msg ptr
__type(value, topic_t); // topic info
__uint(max_entries, MAX_CONCURRENT_REQUESTS);
} ongoing_produce_messages SEC(".maps");

struct {
__uint(type, BPF_MAP_TYPE_LRU_HASH);
__type(key, go_addr_key_t); // goroutine
__type(value, produce_req_t); // rw ptr + start time
__uint(max_entries, MAX_CONCURRENT_REQUESTS);
} produce_requests SEC(".maps");

struct {
__uint(type, BPF_MAP_TYPE_LRU_HASH);
__type(key, go_addr_key_t); // goroutine
__type(value, kafka_go_req_t); // rw ptr + start time
__uint(max_entries, MAX_CONCURRENT_REQUESTS);
} fetch_requests SEC(".maps");
#include <logger/bpf_dbg.h>

// Code for the produce messages path
SEC("uprobe/writer_write_messages")
Expand All @@ -84,7 +42,12 @@ int obi_uprobe_writer_write_messages(struct pt_regs *ctx) {
go_addr_key_t p_key = {};
go_addr_key_from_id(&p_key, w_ptr);

go_addr_key_t g_key = {};
go_addr_key_from_id(&g_key, goroutine_addr);

bpf_map_update_elem(&produce_traceparents, &p_key, &tp, BPF_ANY);
bpf_map_update_elem(&produce_traceparents_by_goroutine, &g_key, &tp, BPF_ANY);

return 0;
}

Expand Down Expand Up @@ -223,7 +186,7 @@ int obi_uprobe_protocol_roundtrip_ret(struct pt_regs *ctx) {
kafka_go_req_t *trace = bpf_ringbuf_reserve(&events, sizeof(kafka_go_req_t), 0);
if (trace) {
trace->type = EVENT_GO_KAFKA_SEG;
trace->op = KAFKA_API_PRODUCE;
trace->op = k_kafka_api_produce;
trace->start_monotime_ns = p_ptr->start_monotime_ns;
trace->end_monotime_ns = bpf_ktime_get_ns();

Expand Down Expand Up @@ -269,7 +232,7 @@ int obi_uprobe_reader_read(struct pt_regs *ctx) {
if (r_ptr) {
kafka_go_req_t r = {
.type = EVENT_GO_KAFKA_SEG,
.op = KAFKA_API_FETCH,
.op = k_kafka_api_fetch,
.start_monotime_ns = 0,
};

Expand Down
3 changes: 3 additions & 0 deletions bpf/gotracer/go_mongo.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,14 @@

#include <bpfcore/utils.h>

#include <common/common.h>
#include <common/ringbuf.h>

#include <gotracer/go_common.h>
#include <gotracer/go_str.h>

#include <gotracer/maps/mongo.h>

#include <logger/bpf_dbg.h>

#define MONGO_OP_DEF(name, str) \
Expand Down
6 changes: 5 additions & 1 deletion bpf/gotracer/go_net.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,12 @@
#include <bpfcore/utils.h>
#include <bpfcore/bpf_builtins.h>

#include <common/common.h>

#include <gotracer/go_common.h>

#include <gotracer/maps/mongo.h>

#include <logger/bpf_dbg.h>

SEC("uprobe/netFdRead")
Expand Down Expand Up @@ -85,4 +89,4 @@ int obi_uprobe_netFdRead(struct pt_regs *ctx) {
}

return 0;
}
}
97 changes: 5 additions & 92 deletions bpf/gotracer/go_nethttp.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,10 @@
#include <gotracer/go_common.h>
#include <gotracer/go_offsets.h>
#include <gotracer/go_str.h>
#include <gotracer/hpack.h>

#include <gotracer/maps/nethttp.h>

#include <gotracer/types/nethttp.h>
#include <gotracer/types/stream_key.h>

#include <logger/bpf_dbg.h>
Expand All @@ -39,64 +41,11 @@

#include <pid/pid_helpers.h>

static const char traceparent[] = "traceparent: ";

static __always_inline unsigned char *tp_char_buf() {
int zero = 0;
return bpf_map_lookup_elem(&tp_char_buf_mem, &zero);
}

typedef struct http_client_data {
s64 content_length;
pid_info pid;
unsigned char path[PATH_MAX_LEN];
unsigned char host[HOST_MAX_LEN];
unsigned char scheme[SCHEME_MAX_LEN];
unsigned char method[METHOD_MAX_LEN];
u8 _pad[3];
} http_client_data_t;

struct {
__uint(type, BPF_MAP_TYPE_LRU_HASH);
__type(key, go_addr_key_t); // key: pointer to the request goroutine
__type(value, http_client_data_t);
__uint(max_entries, MAX_CONCURRENT_REQUESTS);
} ongoing_http_client_requests_data SEC(".maps");

struct {
__uint(type, BPF_MAP_TYPE_LRU_HASH);
__type(key, go_addr_key_t); // key: pointer to the request goroutine
__type(value, tp_info_t);
__uint(max_entries, MAX_CONCURRENT_REQUESTS);
} http2_server_requests_tp SEC(".maps");

typedef struct server_http_func_invocation {
u64 start_monotime_ns;
u64 content_length;
u64 response_length;
u64 status;
u64 rpc_request_addr; // pointer to the jsonrpc Request
tp_info_t tp;
u8 method[METHOD_MAX_LEN];
u8 path[PATH_MAX_LEN];
u8 pattern[PATTERN_MAX_LEN];
u8 _pad[5];
} server_http_func_invocation_t;

struct {
__uint(type, BPF_MAP_TYPE_LRU_HASH);
__type(key, go_addr_key_t); // key: pointer to the request goroutine
__type(value, server_http_func_invocation_t);
__uint(max_entries, MAX_CONCURRENT_REQUESTS);
} ongoing_http_server_requests SEC(".maps");

struct {
__uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
__type(key, u32);
__type(value, unsigned char[HTTP_HEADER_MAX_LEN]);
__uint(max_entries, 1);
} temp_header_mem_store SEC(".maps");

static __always_inline unsigned char *temp_header_mem() {
const u32 zero = 0;
return bpf_map_lookup_elem(&temp_header_mem_store, &zero);
Expand Down Expand Up @@ -636,13 +585,6 @@ int obi_uprobe_ServeHTTPReturns(struct pt_regs *ctx) {
return serve_http_returns(ctx);
}

struct {
__uint(type, BPF_MAP_TYPE_LRU_HASH);
__type(key, void *); // key: pointer to the request header map
__type(value, u64); // the goroutine of the transport request
__uint(max_entries, MAX_CONCURRENT_REQUESTS);
} header_req_map SEC(".maps");

/* HTTP Client. We expect to see HTTP client in both HTTP server and gRPC server calls.*/
static __always_inline void roundTripStartHelper(struct pt_regs *ctx) {
void *goroutine_addr = GOROUTINE_PTR(ctx);
Expand Down Expand Up @@ -1032,15 +974,6 @@ int obi_uprobe_http2serverConn_runHandler(struct pt_regs *ctx) {
return 0;
}

// HTTP 2.0 client support
struct {
__uint(type, BPF_MAP_TYPE_LRU_HASH);
__type(key, stream_key_t); // key: stream id + connection info
// the goroutine of the round trip request, which is the key for our traceparent info
__type(value, u64);
__uint(max_entries, MAX_CONCURRENT_REQUESTS);
} http2_req_map SEC(".maps");

static __always_inline void setup_http2_client_conn(void *goroutine_addr,
void *cc_ptr,
u32 stream_id,
Expand Down Expand Up @@ -1145,23 +1078,6 @@ int obi_uprobe_http2WriteHeaders_vendored(struct pt_regs *ctx) {
return 0;
}

#define MAX_W_PTR_N 1024

typedef struct framer_func_invocation {
u64 framer_ptr;
tp_info_t tp;
s64 initial_n;
} framer_func_invocation_t;

struct {
__uint(type, BPF_MAP_TYPE_LRU_HASH);
__type(key, go_addr_key_t); // key: go routine doing framer write headers
__type(
value,
framer_func_invocation_t); // the goroutine of the round trip request, which is the key for our traceparent info
__uint(max_entries, MAX_CONCURRENT_REQUESTS);
} framer_invocation_map SEC(".maps");

static __always_inline void
on_http2FramerWriteHeaders(struct pt_regs *ctx, off_table_t *ot, u64 stream_id) {
if (!g_bpf_header_propagation) {
Expand Down Expand Up @@ -1273,9 +1189,6 @@ int obi_uprobe_net_http2FramerWriteHeaders(struct pt_regs *ctx) {
return 0;
}

#define HTTP2_ENCODED_HEADER_LEN \
66 // 1 + 1 + 8 + 1 + 55 = type byte + hpack_len_as_byte("traceparent") + strlen(hpack("traceparent")) + len_as_byte(55) + generated traceparent id

SEC("uprobe/http2FramerWriteHeaders_returns")
int obi_uprobe_http2FramerWriteHeaders_returns(struct pt_regs *ctx) {
if (!g_bpf_header_propagation) {
Expand Down Expand Up @@ -1348,7 +1261,7 @@ int obi_uprobe_http2FramerWriteHeaders_returns(struct pt_regs *ctx) {
if (original_size > 0) {
u8 type_byte = 0;
const u8 key_len =
TP_ENCODED_LEN | 0x80; // high tagged to signify hpack encoded value
sizeof(tp_encoded) | 0x80; // high tagged to signify hpack encoded value
const u8 val_len = TP_MAX_VAL_LENGTH;

// We don't hpack encode the value of the traceparent field, because that will require that
Expand All @@ -1364,7 +1277,7 @@ int obi_uprobe_http2FramerWriteHeaders_returns(struct pt_regs *ctx) {
// Write 'traceparent' encoded as hpack
bpf_probe_write_user(buf_arr + (n & 0x0ffff), tp_encoded, sizeof(tp_encoded));
;
n += TP_ENCODED_LEN;
n += sizeof(tp_encoded);
// Write the length of the hpack encoded traceparent field
bpf_probe_write_user(buf_arr + (n & 0x0ffff), &val_len, sizeof(val_len));
n++;
Expand Down
16 changes: 2 additions & 14 deletions bpf/gotracer/go_redis.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,21 +21,9 @@

#include <gotracer/go_common.h>

#include <logger/bpf_dbg.h>
#include <gotracer/maps/redis.h>

struct {
__uint(type, BPF_MAP_TYPE_LRU_HASH);
__type(key, go_addr_key_t); // key: goroutine id
__type(value, redis_client_req_t); // the request
__uint(max_entries, MAX_CONCURRENT_REQUESTS);
} ongoing_redis_requests SEC(".maps");

struct {
__uint(type, BPF_MAP_TYPE_LRU_HASH);
__type(key, go_addr_key_t); // key: goroutine id
__type(value, void *); // the *Conn
__uint(max_entries, MAX_CONCURRENT_REQUESTS);
} redis_writes SEC(".maps");
#include <logger/bpf_dbg.h>

static __always_inline void setup_request(void *goroutine_addr) {
redis_client_req_t req = {
Expand Down
Loading