diff --git a/eBPF_Supermarket/Network_Subsystem/net_watcher/common.bpf.h b/eBPF_Supermarket/Network_Subsystem/net_watcher/common.bpf.h index 9fa88f752..89a5b9d91 100644 --- a/eBPF_Supermarket/Network_Subsystem/net_watcher/common.bpf.h +++ b/eBPF_Supermarket/Network_Subsystem/net_watcher/common.bpf.h @@ -158,6 +158,11 @@ struct { __uint(max_entries, 256 * 1024); } mysql_rb SEC(".maps"); +struct { + __uint(type, BPF_MAP_TYPE_RINGBUF); + __uint(max_entries, 256 * 1024); +} redis_rb SEC(".maps"); + struct { __uint(type, BPF_MAP_TYPE_RINGBUF); __uint(max_entries, 256 * 1024); @@ -242,6 +247,14 @@ struct { __type(value, __u64); } mysql_time SEC(".maps"); +//redis 耗时 +struct { + __uint(type, BPF_MAP_TYPE_HASH); + __uint(max_entries, 256*1024); + __type(key, __u32); + __type(value, struct redis_query); +} redis_time SEC(".maps"); + //sql请求数 struct { __uint(type, BPF_MAP_TYPE_HASH); @@ -270,7 +283,7 @@ const volatile int filter_sport = 0; const volatile int all_conn = 0, err_packet = 0, extra_conn_info = 0, layer_time = 0, http_info = 0, retrans_info = 0, udp_info =0,net_filter = 0, drop_reason = 0,icmp_info = 0 ,tcp_info = 0 ,dns_info = 0 ,stack_info = 0, - mysql_info = 0, redis_info; + mysql_info = 0, redis_info = 0; /* help macro */ diff --git a/eBPF_Supermarket/Network_Subsystem/net_watcher/netwatcher.bpf.c b/eBPF_Supermarket/Network_Subsystem/net_watcher/netwatcher.bpf.c index 3a76a9a39..4ae7d22f6 100644 --- a/eBPF_Supermarket/Network_Subsystem/net_watcher/netwatcher.bpf.c +++ b/eBPF_Supermarket/Network_Subsystem/net_watcher/netwatcher.bpf.c @@ -334,7 +334,11 @@ int BPF_KPROBE(query__end){ return __handle_mysql_end(ctx); } -SEC("uprobe/processCommand") +SEC("uprobe/call") int BPF_KPROBE(query__start_redis) { return __handle_redis_start(ctx); +} +SEC("uretprobe/call") +int BPF_KPROBE(query__end_redis){ + return __handle_redis_end(ctx); } \ No newline at end of file diff --git a/eBPF_Supermarket/Network_Subsystem/net_watcher/netwatcher.c b/eBPF_Supermarket/Network_Subsystem/net_watcher/netwatcher.c index cbe4a5765..190c2689e 100644 --- a/eBPF_Supermarket/Network_Subsystem/net_watcher/netwatcher.c +++ b/eBPF_Supermarket/Network_Subsystem/net_watcher/netwatcher.c @@ -566,6 +566,8 @@ static void set_disable_load(struct netwatcher_bpf *skel) { mysql_info ? true : false); bpf_program__set_autoload(skel->progs.query__start_redis, redis_info ? true : false); + bpf_program__set_autoload(skel->progs.query__end_redis, + redis_info ? true : false); } static void print_header(enum MonitorMode mode) { @@ -629,10 +631,10 @@ static void print_header(enum MonitorMode mode) { break; case MODE_REDIS: printf("===============================================================" - "====================MYSQL " + "====================REDIS " "INFORMATION====================================================" "============================\n"); - printf("%-20s %-20s %-20s %-40s %-20s \n", "Pid", "Comm", "Size", "Sql", + printf("%-20s %-20s %-20s %-20s %-20s \n", "Pid", "Comm", "Size", "Redis", "duration/μs"); break; case MODE_DEFAULT: @@ -1135,6 +1137,20 @@ static int print_mysql(void *ctx, void *packet_info, size_t size) { } return 0; } +static int print_redis(void *ctx, void *packet_info, size_t size) { + const struct redis_query *pack_info = packet_info; + int i=0; + char redis[64]; + for(i=0;iargc;i++) + { + strcat(redis, pack_info->redis[i]); + strcat(redis, " "); + } + printf("%-20d %-20s %-20d %-20s %-21llu\n", pack_info->pid, + pack_info->comm,pack_info->argc, redis,pack_info->duratime); + strcpy(redis,""); + return 0; +} static int libbpf_print_fn(enum libbpf_print_level level, const char *format, va_list args) { return vfprintf(stderr, format, args); @@ -1185,8 +1201,11 @@ int attach_uprobe_mysql(struct netwatcher_bpf *skel) { } int attach_uprobe_redis(struct netwatcher_bpf *skel) { ATTACH_UPROBE_CHECKED( - skel, processCommand, + skel, call, query__start_redis); + ATTACH_UPROBE_CHECKED( + skel, call, + query__end_redis); return 0; } int main(int argc, char **argv) { @@ -1211,6 +1230,7 @@ int main(int argc, char **argv) { struct ring_buffer *dns_rb = NULL; struct ring_buffer *trace_rb = NULL; struct ring_buffer *mysql_rb = NULL; + struct ring_buffer *redis_rb = NULL; struct netwatcher_bpf *skel; int err; /* Parse command line arguments */ @@ -1333,6 +1353,13 @@ int main(int argc, char **argv) { fprintf(stderr, "Failed to create ring buffer(trace)\n"); goto cleanup; } + redis_rb = ring_buffer__new(bpf_map__fd(skel->maps.redis_rb), print_redis, + NULL, NULL); + if (!redis_rb) { + err = -1; + fprintf(stderr, "Failed to create ring buffer(trace)\n"); + goto cleanup; + } /* Set up ring buffer polling */ rb = ring_buffer__new(bpf_map__fd(skel->maps.rb), print_packet, NULL, NULL); if (!rb) { @@ -1354,6 +1381,7 @@ int main(int argc, char **argv) { err = ring_buffer__poll(dns_rb, 100 /* timeout, ms */); err = ring_buffer__poll(trace_rb, 100 /* timeout, ms */); err = ring_buffer__poll(mysql_rb, 100 /* timeout, ms */); + err = ring_buffer__poll(redis_rb, 100 /* timeout, ms */); print_conns(skel); sleep(1); /* Ctrl-C will cause -EINTR */ diff --git a/eBPF_Supermarket/Network_Subsystem/net_watcher/netwatcher.h b/eBPF_Supermarket/Network_Subsystem/net_watcher/netwatcher.h index de8aa5e7a..8687f3e13 100644 --- a/eBPF_Supermarket/Network_Subsystem/net_watcher/netwatcher.h +++ b/eBPF_Supermarket/Network_Subsystem/net_watcher/netwatcher.h @@ -180,4 +180,15 @@ typedef struct mysql_query { int count; } mysql_query; +struct redis_query { + int pid; + int tid; + char comm[20]; + u32 size; + char redis[4][8]; + u64 duratime; + int count; + u64 begin_time; + int argc; +}; #endif /* __NETWATCHER_H */ \ No newline at end of file diff --git a/eBPF_Supermarket/Network_Subsystem/net_watcher/redis.bpf.h b/eBPF_Supermarket/Network_Subsystem/net_watcher/redis.bpf.h index 66ef4364b..ae4cf559a 100644 --- a/eBPF_Supermarket/Network_Subsystem/net_watcher/redis.bpf.h +++ b/eBPF_Supermarket/Network_Subsystem/net_watcher/redis.bpf.h @@ -13,48 +13,58 @@ // limitations under the License. // // author: blown.away@qq.com -// mysql +// redis #include "common.bpf.h" #include "redis_helper.bpf.h" -#define MAXEPOLL 10 +#define MAXEPOLL 4 static __always_inline int __handle_redis_start(struct pt_regs *ctx) { struct client *cli = (struct client *)PT_REGS_PARM1(ctx); - int argc; + struct redis_query start={}; void *ptr; char name[100]=""; int argv_len; - bpf_probe_read(&argc, sizeof(argc), &cli->argc); - bpf_printk("%d",argc); + bpf_probe_read(&start.argc, sizeof(start.argc), &cli->argc); robj **arg0; robj *arg1; - //unsigned type; - unsigned encoding; - unsigned lru; - int refcount; bpf_probe_read(&arg0, sizeof(arg0), &cli->argv); - - // 读取 argv[0],即第一个命令参数 bpf_probe_read(&arg1, sizeof(arg1), &arg0[0]); - - for(int i=0;iptr 中的字符串 bpf_probe_read(&ptr, sizeof(ptr),&arg1->ptr); - bpf_probe_read_str(name, sizeof(name),ptr); - bpf_printk("%s",name); + bpf_probe_read_str(&start.redis[i], sizeof(start.redis[i]), ptr); + //bpf_printk("%s",start.redis[i]); } - // 读取 argv[0]->ptr 中的字符串 - bpf_probe_read(&ptr, sizeof(ptr),&arg1->ptr); - bpf_probe_read_str(name, sizeof(name),ptr); - - - bpf_probe_read(&argv_len, sizeof(argv_len), &cli->argv_len_sum); - - bpf_printk("%d",argv_len); - pid_t pid = bpf_get_current_pid_tgid() >> 32; + u64 start_time = bpf_ktime_get_ns() / 1000; + start.begin_time=start_time; + bpf_map_update_elem(&redis_time, &pid, &start, BPF_ANY); return 0; } +static __always_inline int __handle_redis_end(struct pt_regs *ctx) { + pid_t pid = bpf_get_current_pid_tgid() >> 32; + struct redis_query *start; + u64 end_time = bpf_ktime_get_ns() / 1000; + start = bpf_map_lookup_elem(&redis_time, &pid); + if (!start) { + return 0; + } + struct redis_query *message = bpf_ringbuf_reserve(&redis_rb, sizeof(*message), 0); + if (!message) { + return 0; + } + message->pid = pid; + message->argc = start->argc; + bpf_get_current_comm(&message->comm, sizeof(message->comm)); + for(int i=0;iargc&&iredis[i], sizeof(message->redis[i]), start->redis[i]); + } + bpf_probe_read_str(&message->redis, sizeof(start->redis), start->redis); + message->duratime = end_time - start->begin_time; + bpf_printk("%llu - %llu = %llu",end_time,start->begin_time,message->duratime); + bpf_ringbuf_submit(message, 0); + return 0; +} \ No newline at end of file