|
|
@@ -867,8 +867,8 @@ int trace_exit_read(void *ctx, __u64 id, __u32 pid, __u16 is_tls, long int ret)
|
|
|
// __sync_fetch_and_add(&accept_conn->bytes_received, total_size);
|
|
|
// }
|
|
|
|
|
|
- //bpf_tail_call PROGUP(l7_http_request)
|
|
|
- cw_bpf_debug("======== PROG_DATA_L7_HTTP_TRACE_ID_UP_IDX ========== __KERNEL_FROM < 512 pid:[%d] ",tid);
|
|
|
+ //-- 在http请求入口生成 横向串联的trace_id --
|
|
|
+ //bpf_tail_call PROGTP(l7_http_trace_id)
|
|
|
bpf_tail_call(ctx, &NAME(progs_jmp_tp_map), PROG_DATA_L7_HTTP_TRACE_ID_TP_IDX);
|
|
|
return 0;
|
|
|
}
|
|
|
@@ -1216,6 +1216,340 @@ int trace_exit_read(void *ctx, __u64 id, __u32 pid, __u16 is_tls, long int ret)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+//copy from trace_exit_read
|
|
|
+static inline __attribute__((__always_inline__))
|
|
|
+int jvm_ssl_trace_exit_read(void *ctx, __u64 id, __u32 pid, __u16 is_tls, long int ret) {
|
|
|
+ __u32 tid = (__u32)id;
|
|
|
+
|
|
|
+ if (load_filter_pid() != 0 && pid != load_filter_pid()) {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ struct read_args *args = bpf_map_lookup_elem(&active_reads, &id);
|
|
|
+ if (!args) {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ struct l7_request_key k = {};
|
|
|
+ k.pid = pid;
|
|
|
+ k.fd = args->fd;
|
|
|
+ k.is_tls = is_tls;
|
|
|
+ k.stream_id = -1;
|
|
|
+
|
|
|
+ bpf_map_delete_elem(&active_reads, &id);
|
|
|
+
|
|
|
+ if (ret <= 0) {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ if (args->ret) {
|
|
|
+ if (bpf_probe_read(&ret, sizeof(ret), (void*)args->ret)) {
|
|
|
+ return 0;
|
|
|
+ };
|
|
|
+ if (ret <= 0) {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ __u64 total_size = ret;
|
|
|
+ int zero = 0;
|
|
|
+ char* payload = args->buf;
|
|
|
+// if (args->iovlen) {
|
|
|
+// payload = bpf_map_lookup_elem(&iovec_buf_heap, &zero);
|
|
|
+// if (!payload) {
|
|
|
+// return 0;
|
|
|
+// }
|
|
|
+// total_size = 0;
|
|
|
+// ret = read_iovec(args->buf, args->iovlen, ret, payload, &total_size);
|
|
|
+// if (!ret) {
|
|
|
+// return 0;
|
|
|
+// }
|
|
|
+// }
|
|
|
+
|
|
|
+ struct l7_event *e = bpf_map_lookup_elem(&l7_event_heap, &zero);
|
|
|
+ if (!e) {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ e->fd = k.fd;
|
|
|
+ e->pid = k.pid;
|
|
|
+ e->protocol = PROTOCOL_UNKNOWN;
|
|
|
+ e->status = STATUS_UNKNOWN;
|
|
|
+ e->method = METHOD_UNKNOWN;
|
|
|
+ e->statement_id = 0;
|
|
|
+ e->payload_size = 0;
|
|
|
+ e->trace_id = 0;
|
|
|
+
|
|
|
+
|
|
|
+ struct connection_id cid = {};
|
|
|
+ cid.pid = pid;
|
|
|
+ cid.fd = args->fd;
|
|
|
+ // 被调用方http入口
|
|
|
+ // 作为服务端在走。coroot 原有逻辑是没有的
|
|
|
+ if (is_http_request(payload)) {
|
|
|
+
|
|
|
+ //处理http请求之前,确认进程信息是否存在
|
|
|
+ struct ebpf_proc_info *proc_info = bpf_map_lookup_elem(&proc_info_map, &pid);
|
|
|
+ if (!proc_info) {
|
|
|
+ cw_bpf_debug("[Receive][HTTP]:no proc info. pid:%d",k.pid);
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ struct l7_request *req = bpf_map_lookup_elem(&l7_request_heap, &zero);
|
|
|
+ if (!req)
|
|
|
+ {
|
|
|
+ return 0;
|
|
|
+ } else
|
|
|
+ {
|
|
|
+ req->protocol = PROTOCOL_HTTP;
|
|
|
+ req->payload_size = ret;
|
|
|
+ req->ns = bpf_ktime_get_ns();
|
|
|
+ COPY_PAYLOAD(req->payload, ret, payload);
|
|
|
+ // cw_bpf_debug("[Receive][HTTP]:pid:%d|tid:%d",k.pid,k.fd);
|
|
|
+ // cw_bpf_debug("[Receive][HTTP]:is_tls:%d|tid:%d",k.is_tls,k.stream_id);
|
|
|
+ bpf_map_update_elem(&active_l7_requests, &k, req, BPF_NOEXIST);
|
|
|
+ }
|
|
|
+
|
|
|
+// // trace info
|
|
|
+ struct apm_trace_info_t trace_info = cw_save_trace_info(id,pid, k.fd);
|
|
|
+// __u64 uid_base = bpf_ktime_get_ns();
|
|
|
+// trace_info.trace_id = bpf_get_current_pid_tgid() + uid_base;
|
|
|
+
|
|
|
+ e->trace_start = 1;
|
|
|
+ e->trace_end = 0;
|
|
|
+ e->protocol = PROTOCOL_TRACE;
|
|
|
+ e->trace_id = trace_info.trace_id;
|
|
|
+ cw_bpf_debug("\n");
|
|
|
+ cw_bpf_debug("[Trace Start in l7][HTTP]pid:[%d]--[%lld]--trace_id:%llu\n", tid, bpf_ktime_get_ns(),trace_info.trace_id);
|
|
|
+ cw_bpf_debug("[Trace Start in l7][Receive][HTTP]pid:[%d]|GOID:[%d]|FD:%d|Trace:%llu\n", tid, trace_info.trace_key.goid,k.fd);
|
|
|
+ e->payload_size = ret;
|
|
|
+ COPY_PAYLOAD(e->payload, ret, payload);
|
|
|
+
|
|
|
+ bpf_perf_event_output(ctx, &l7_events, BPF_F_CURRENT_CPU, e, sizeof(*e));
|
|
|
+ cw_bpf_debug("[Receive][HTTP] to user space");
|
|
|
+
|
|
|
+ //-- 在http请求入口生成 横向串联的trace_id --
|
|
|
+ //bpf_tail_call PROGUP(java_ssl_l7_http_trace_id)
|
|
|
+ bpf_tail_call(ctx, &NAME(progs_jmp_up_map), PROG_DATA_JAVA_SSL_L7_HTTP_TRACE_ID_UP_IDX);
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ struct connection *conn = bpf_map_lookup_elem(&active_connections, &cid);
|
|
|
+ if (args && !conn) {
|
|
|
+ bpf_map_delete_elem(&active_reads, &id);
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ /// coroot 是以客户端为主体做统计的,所以这里是客户端逻辑
|
|
|
+ if (!is_tls) {
|
|
|
+ __sync_fetch_and_add(&conn->bytes_received, total_size);
|
|
|
+ if(conn->first_read_time == 0){
|
|
|
+ conn->first_read_time = bpf_ktime_get_ns();
|
|
|
+ }
|
|
|
+ conn->new_read_time = bpf_ktime_get_ns();
|
|
|
+ }
|
|
|
+
|
|
|
+ if (is_rabbitmq_consume(payload, ret)) {
|
|
|
+ e->protocol = PROTOCOL_RABBITMQ;
|
|
|
+ e->method = METHOD_CONSUME;
|
|
|
+ send_event(ctx, e, cid, conn);
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ if (nats_method(payload, ret) == METHOD_CONSUME) {
|
|
|
+ e->protocol = PROTOCOL_NATS;
|
|
|
+ e->method = METHOD_CONSUME;
|
|
|
+ send_event(ctx, e, cid, conn);
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ struct l7_request *req = bpf_map_lookup_elem(&active_l7_requests, &k);
|
|
|
+ int response = 0;
|
|
|
+ if (!req) {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ e->protocol = req->protocol;
|
|
|
+ e->payload_size = req->payload_size;
|
|
|
+ COPY_PAYLOAD(e->payload, req->payload_size, req->payload);
|
|
|
+ bpf_map_delete_elem(&active_l7_requests, &k);
|
|
|
+// cw_bpf_debug("delete req--------:[0x%x] k.pid:%d, k.fd:%d",b[4],k.pid,k.fd);
|
|
|
+
|
|
|
+ if (e->protocol == PROTOCOL_HTTP) {
|
|
|
+// __u64 trace_id = req->trace_id;
|
|
|
+ e->trace_id = req->trace_id;
|
|
|
+ cw_bpf_debug("l7.c addr is --------:%d,%s",conn->sport,conn->saddr);
|
|
|
+ e->component_sport = conn->sport;
|
|
|
+ e->component_dport = conn->dport;
|
|
|
+ __builtin_memcpy(&e->component_saddr, &conn->saddr, sizeof(e->component_saddr));
|
|
|
+ __builtin_memcpy(&e->component_daddr, &conn->daddr, sizeof(e->component_daddr));
|
|
|
+// struct apm_span_context * sc = cw_get_current_tracking_span();
|
|
|
+// if (sc) {
|
|
|
+ cw_copy_byte_arrays(req->assumed_app_id, e->assumed_app_id, APM_ASSUMED_APP_ID_SIZE);
|
|
|
+ cw_copy_byte_arrays(req->span_id, e->span_id, APM_SPAN_ID_SIZE);
|
|
|
+// for (int i = 0; i < APM_ASSUMED_APP_ID_SIZE; i++) {
|
|
|
+// cw_bpf_debug("assumed_app_id-assumed_app_id[%d] = %02x", i, req->assumed_app_id[i]);
|
|
|
+// }
|
|
|
+// for (int i = 0; i < APM_SPAN_ID_SIZE; i++) {
|
|
|
+// cw_bpf_debug("cw_get_current_tracking_span-span_id[%d] = %02x", i, req->span_id[i]);
|
|
|
+// }
|
|
|
+// }
|
|
|
+ // cw_bpf_debug("[Response][HTTP222]:thread_id:%d|type:%s|FD:%d\n",k.pid,"",k.fd);
|
|
|
+// cw_bpf_debug("[Response][HTTP222] trace_id:%llu", trace_id);
|
|
|
+// // 请求报文
|
|
|
+// cw_bpf_debug("[Response][HTTP222] req-payload:%s",e->payload);
|
|
|
+// // 响应报文
|
|
|
+// cw_bpf_debug("[Response][HTTP222] resp-payload:%s",payload);
|
|
|
+
|
|
|
+ response = is_http_response(payload, &e->status);
|
|
|
+// cw_bpf_debug("[Kernel End][HTTP]:pid:[%d]|CURRENT-GOID:[%llu]|trace_id:[%llu]---------\n", tid, get_current_goroutine(),e->trace_id);
|
|
|
+
|
|
|
+ } else if (e->protocol == PROTOCOL_POSTGRES) {
|
|
|
+// __u64 trace_id = get_apm_trace_id(pid, tid);
|
|
|
+// cw_bpf_debug("[postgres sql] trace_id:%llu", trace_id);
|
|
|
+// e->trace_id = req->trace_id;
|
|
|
+ e->component_sport = conn->sport;
|
|
|
+ e->component_dport = conn->dport;
|
|
|
+ __builtin_memcpy(&e->component_saddr, &conn->saddr, sizeof(e->component_saddr));
|
|
|
+ __builtin_memcpy(&e->component_daddr, &conn->daddr, sizeof(e->component_daddr));
|
|
|
+ response = is_postgres_response(payload, ret, &e->status);
|
|
|
+ if (req->request_type == POSTGRES_FRAME_PARSE) {
|
|
|
+ e->method = METHOD_STATEMENT_PREPARE;
|
|
|
+ }
|
|
|
+ } else if (e->protocol == PROTOCOL_REDIS) {
|
|
|
+ cw_bpf_debug("[Response][Redis]:TGID:%d|type:%s|FD:%d\n", k.pid, "", k.fd);
|
|
|
+// __u64 trace_id = get_apm_trace_id(pid, tid);
|
|
|
+// e->trace_id = req->trace_id;
|
|
|
+ cw_bpf_debug("[Redis] trace_id:%llu", req->trace_id);
|
|
|
+ e->component_sport = conn->sport;
|
|
|
+ e->component_dport = conn->dport;
|
|
|
+ __builtin_memcpy(&e->component_saddr, &conn->saddr, sizeof(e->component_saddr));
|
|
|
+ __builtin_memcpy(&e->component_daddr, &conn->daddr, sizeof(e->component_daddr));
|
|
|
+ response = is_redis_response(payload, ret, &e->status);
|
|
|
+ } else if (e->protocol == PROTOCOL_MEMCACHED) {
|
|
|
+ response = is_memcached_response(payload, ret, &e->status);
|
|
|
+ } else if (e->protocol == PROTOCOL_MYSQL) {
|
|
|
+ cw_bpf_debug("[Response][Mysql]:thread_id:%d\n", tid);
|
|
|
+// __u64 trace_id = get_apm_trace_id(pid, tid);
|
|
|
+// cw_bpf_debug("[Mysql] trace_id:%llu", trace_id);
|
|
|
+// e->trace_id = trace_id;
|
|
|
+
|
|
|
+ //response package parsing partial data (such as by header)
|
|
|
+ if(ret == MYSQL_PACKAGE_HEADER_LEN) {
|
|
|
+ //sava header to ctx and return
|
|
|
+ char resp_packet_header[MYSQL_PACKAGE_HEADER_LEN];
|
|
|
+ bpf_probe_read(resp_packet_header,MYSQL_PACKAGE_HEADER_LEN, payload);
|
|
|
+ bpf_map_update_elem(&active_l7_requests_mysql_resp_header_ctx, &k, resp_packet_header, BPF_ANY);
|
|
|
+ bpf_map_update_elem(&active_l7_requests, &k, req, BPF_ANY);
|
|
|
+ return 0 ;
|
|
|
+ }
|
|
|
+
|
|
|
+ e->component_sport = conn->sport;
|
|
|
+ e->component_dport = conn->dport;
|
|
|
+ __builtin_memcpy(&e->component_saddr, &conn->saddr, sizeof(e->component_saddr));
|
|
|
+ __builtin_memcpy(&e->component_daddr, &conn->daddr, sizeof(e->component_daddr));
|
|
|
+
|
|
|
+ char* resp_packet_header = bpf_map_lookup_elem(&active_l7_requests_mysql_resp_header_ctx, &k);
|
|
|
+ if(resp_packet_header) {
|
|
|
+ char resp_combined_packet[5];
|
|
|
+ bpf_probe_read(resp_combined_packet,MYSQL_PACKAGE_HEADER_LEN, resp_packet_header);
|
|
|
+ bpf_probe_read(&resp_combined_packet[4],1, payload);
|
|
|
+ response = is_mysql_response(resp_combined_packet,sizeof(resp_combined_packet), req->request_type, &e->statement_id, &e->status);
|
|
|
+ if(response) {
|
|
|
+ bpf_map_delete_elem(&active_l7_requests_mysql_resp_header_ctx, &k);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ response = is_mysql_response(payload, ret, req->request_type, &e->statement_id, &e->status);
|
|
|
+ }
|
|
|
+ if (req->request_type == MYSQL_COM_STMT_PREPARE) {
|
|
|
+ e->method = METHOD_STATEMENT_PREPARE;
|
|
|
+ }
|
|
|
+ } else if (e->protocol == PROTOCOL_DM) {
|
|
|
+// cw_bpf_debug("[Response][DM] start -------->");
|
|
|
+ struct l7_request_dm_ctx *dm_ctx = bpf_map_lookup_elem(&active_l7_requests_dm_ctx, &k);
|
|
|
+ if (!dm_ctx) {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+// __u64 trace_id = get_apm_trace_id(pid, tid);
|
|
|
+// e->trace_id = req->trace_id;
|
|
|
+// cw_bpf_debug("[Response][DM] trace_id:%llu", trace_id);
|
|
|
+ e->component_sport = conn->sport;
|
|
|
+ e->component_dport = conn->dport;
|
|
|
+ __builtin_memcpy(&e->component_saddr, &conn->saddr, sizeof(e->component_saddr));
|
|
|
+ __builtin_memcpy(&e->component_daddr, &conn->daddr, sizeof(e->component_daddr));
|
|
|
+
|
|
|
+ response = is_dm_response(payload, ret, req->request_type, &dm_ctx->status);
|
|
|
+// cw_bpf_debug("[Response][DM] is_dm_response status ---------- %d",dm_ctx->status);
|
|
|
+
|
|
|
+ if (response) {
|
|
|
+ req->ns = dm_ctx->req_start_at_ns;
|
|
|
+ e->status = dm_ctx->status;
|
|
|
+ e->payload_size = dm_ctx->query_sql_payload_size;
|
|
|
+ COPY_PAYLOAD(e->payload, dm_ctx->query_sql_payload_size, dm_ctx->query_sql_payload);
|
|
|
+ bpf_map_delete_elem(&active_l7_requests_dm_ctx, &k);
|
|
|
+// cw_bpf_debug("[Response][DM] is response ,delete active_l7_requests_dm_ctx -- req->request_type<0x%x> , e->payload_size:[%d]",req->request_type,e->payload_size);
|
|
|
+ }
|
|
|
+// else {
|
|
|
+// cw_bpf_debug("[Response][DM] not response req->request_type <0x%x>",req->request_type);
|
|
|
+// }
|
|
|
+
|
|
|
+// cw_bpf_debug("[Response][DM] end <---------\n");
|
|
|
+ } else if (e->protocol == PROTOCOL_MONGO) {
|
|
|
+ response = is_mongo_response(payload, ret, req->partial);
|
|
|
+ if (response == 2) { // partial
|
|
|
+ struct l7_request *r = bpf_map_lookup_elem(&l7_request_heap, &zero);
|
|
|
+ if (!r) {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ r->partial = 1;
|
|
|
+ r->protocol = e->protocol;
|
|
|
+ r->ns = req->ns;
|
|
|
+ r->payload_size = req->payload_size;
|
|
|
+ COPY_PAYLOAD(r->payload, req->payload_size, req->payload);
|
|
|
+ bpf_map_update_elem(&active_l7_requests, &k, r, BPF_ANY);
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ } else if (e->protocol == PROTOCOL_KAFKA) {
|
|
|
+ response = is_kafka_response(payload, req->request_id);
|
|
|
+ } else if (e->protocol == PROTOCOL_DUBBO2) {
|
|
|
+ response = is_dubbo2_response(payload, &e->status);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!response) {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ if (e->trace_id == 0){
|
|
|
+ e->trace_id = get_apm_trace_id(pid,tid);
|
|
|
+ }
|
|
|
+ e->end_at = bpf_ktime_get_ns();
|
|
|
+ e->start_at = req->ns;
|
|
|
+ e->duration = e->end_at - e->start_at;
|
|
|
+ send_event(ctx, e, cid, conn);
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+static inline __attribute__((__always_inline__))
|
|
|
+int setTraceIdToPscByL7Request(){
|
|
|
+ __u32 key = 0;
|
|
|
+
|
|
|
+ struct l7_request *req = bpf_map_lookup_elem(&l7_request_heap, &key);
|
|
|
+ if (!req) {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ struct apm_span_context *cw_parent_span_context = bpf_map_lookup_elem(&apm_span_context_heap3, &key);
|
|
|
+ if (cw_parent_span_context == NULL) {
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ __builtin_memset(cw_parent_span_context, 0, sizeof(struct apm_span_context));
|
|
|
+
|
|
|
+ __u32 offset = has_cw_header(req->payload);
|
|
|
+ if (offset > 0) {
|
|
|
+ cw_string_to_span_context(&req->payload[offset], cw_parent_span_context);
|
|
|
+ } else {
|
|
|
+ generate_random_bytes(cw_parent_span_context->trace_id, TRACE_ID_SIZE);
|
|
|
+ }
|
|
|
+ // 保存 trace_id 到psc
|
|
|
+ cw_save_parent_tracking_span(cw_parent_span_context);
|
|
|
+ cw_bpf_debug("[Trace Start in l7][HTTP] trace_id:[%llu]\n", cw_parent_span_context->trace_id);
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
SEC("tracepoint/syscalls/sys_enter_write")
|
|
|
int sys_enter_write(struct trace_event_raw_sys_enter_rw__stub* ctx) {
|
|
|
return trace_enter_write(ctx, ctx->fd, 0, ctx->buf, ctx->size, 0);
|
|
|
@@ -1335,30 +1669,11 @@ int sys_exit_recvfrom(struct trace_event_raw_sys_exit_rw__stub* ctx) {
|
|
|
|
|
|
//bpf_prog_tp__l7_http_trace_id
|
|
|
PROGTP(l7_http_trace_id)(void * ctx){
|
|
|
+ return setTraceIdToPscByL7Request();
|
|
|
+}
|
|
|
|
|
|
- int zero1 = 0;
|
|
|
|
|
|
- struct l7_request *req = bpf_map_lookup_elem(&l7_request_heap, &zero1);
|
|
|
- if (!req) {
|
|
|
- return 0;
|
|
|
- }
|
|
|
-// ---------- 在http请求入口生成 横向串联的trace_id start ----------
|
|
|
- __u32 key = 0;
|
|
|
- __u32 offset = has_cw_header(req->payload);
|
|
|
- struct apm_span_context *cw_parent_span_context = bpf_map_lookup_elem(&apm_span_context_heap3, &key);
|
|
|
- if (cw_parent_span_context == NULL) {
|
|
|
- return -1;
|
|
|
- }
|
|
|
- __builtin_memset(cw_parent_span_context, 0, sizeof(struct apm_span_context));
|
|
|
-
|
|
|
- if (offset > 0) {
|
|
|
- cw_string_to_span_context(&req->payload[offset], cw_parent_span_context);
|
|
|
- } else {
|
|
|
- generate_random_bytes(cw_parent_span_context->trace_id, TRACE_ID_SIZE);
|
|
|
- }
|
|
|
- // 保存 trace_id 到psc
|
|
|
- cw_save_parent_tracking_span(cw_parent_span_context);
|
|
|
- cw_bpf_debug("[Trace Start in l7][HTTP] trace_id:[%llu]\n", cw_parent_span_context->trace_id);
|
|
|
- // ---------- 在http请求入口生成 横向串联的trace_id end ----------
|
|
|
- return 0;
|
|
|
+//bpf_prog_up__java_ssl_l7_http_trace_id
|
|
|
+PROGUP(java_ssl_l7_http_trace_id)(void * ctx){
|
|
|
+ return setTraceIdToPscByL7Request();
|
|
|
}
|