Skip to content

Commit

Permalink
proc_image:增加进程画像控制器程序,实现支持预先按需挂载,使用时激活并输出的功能 (#756)
Browse files Browse the repository at this point in the history
* Supports pre-on-demand mounting, activation and output when in use

* new framework passes proc_test

* md output

* md readme

* md readme

* md readme
  • Loading branch information
zhangzihengya authored Apr 11, 2024
1 parent 602ac98 commit 0a7e912
Show file tree
Hide file tree
Showing 18 changed files with 1,026 additions and 316 deletions.
5 changes: 3 additions & 2 deletions .github/workflows/eBPF_proc_image.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,9 @@ jobs:
- name: Run proc_image
run: |
cd eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image
make proc_image
sudo ./proc_image -a -p 1 -t 1
make
sudo ./proc_image -a &
sudo ./controller -f
- name: Run test_proc
run: |
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ eBPF_Supermarket/kvm_watcher/**/temp*
eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/.output/*
eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/proc_image
eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/test/test_proc
eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/controller

# libbpf_bootstrap
.output
Expand Down
31 changes: 26 additions & 5 deletions eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ CFLAGS := -g -Wall
ALL_LDFLAGS := $(LDFLAGS) $(EXTRA_LDFLAGS)

APPS = resource_image lock_image syscall_image keytime_image schedule_image
TARGETS = proc_image
WORKTOOL := proc_image
CONTROLLER := controller

SRC_DIR = ./include
COMMON_OBJ = \
Expand Down Expand Up @@ -83,12 +84,12 @@ $(call allow-override,CC,$(CROSS_COMPILE)cc)
$(call allow-override,LD,$(CROSS_COMPILE)ld)

.PHONY: all
all: $(TARGETS)
all: $(CONTROLLER) $(WORKTOOL) SUCCESS_MESSAGE

.PHONY: clean
clean:
$(call msg,CLEAN)
$(Q)rm -rf $(OUTPUT) $(TARGETS)
$(Q)rm -rf $(OUTPUT) $(WORKTOOL) $(CONTROLLER)

$(OUTPUT) $(OUTPUT)/libbpf $(BPFTOOL_OUTPUT):
$(call msg,MKDIR,$@)
Expand Down Expand Up @@ -126,17 +127,37 @@ $(OUTPUT)/%.o: $(SRC_DIR)/%.c | $(OUTPUT)
$(call msg,CC,$@)
$(Q)$(CC) $(CFLAGS) $(INCLUDES) -c $< -o $@

$(OUTPUT)/$(TARGETS).o: $(TARGETS).c $(APPS) | $(OUTPUT)
$(OUTPUT)/%.o: $(CONTROLLER).c | $(OUTPUT)
$(call msg,CC,$@)
$(Q)$(CC) $(CFLAGS) $(INCLUDES) -c $< -o $@

$(OUTPUT)/$(WORKTOOL).o: $(WORKTOOL).c $(APPS) | $(OUTPUT)
$(call msg,CC,$@)
$(Q)$(CC) $(CFLAGS) $(INCLUDES) -c $(filter %.c,$^) -o $@

# Build application binary and Create a file for storing data
$(TARGETS): %: $(OUTPUT)/%.o $(COMMON_OBJ) $(LIBBPF_OBJ) | $(OUTPUT)
$(CONTROLLER): %: $(OUTPUT)/%.o $(COMMON_OBJ) $(LIBBPF_OBJ) | $(OUTPUT)
$(call msg,BINARY,$@)
$(Q)$(CC) $^ $(ALL_LDFLAGS) -lstdc++ -lelf -lz -o $@

$(WORKTOOL): %: $(OUTPUT)/%.o $(COMMON_OBJ) $(LIBBPF_OBJ) | $(OUTPUT)
$(call msg,BINARY,$@)
$(Q)$(CC) $^ $(ALL_LDFLAGS) -lstdc++ -lelf -lz -o $@
@mkdir -p $(OUTPUT)/data
@[ -f $(OUTPUT)/data/offcpu_stack.txt ] || touch $(OUTPUT)/data/offcpu_stack.txt

SUCCESS_MESSAGE:
@echo " ____ ____ ______ ____ ____ "
@echo " ___ / __ )/ __ \/ ____/ / __ \_________ _____ / _/___ ___ ____ _____ ____ "
@echo " / _ \/ __ / /_/ / /_ / /_/ / ___/ __ \/ ___/ / // __ \`__ \/ __ \`/ __ \`/ _ \\"
@echo "/ __/ /_/ / ____/ __/ / ____/ / / /_/ / /__ _/ // / / / / / /_/ / /_/ / __/"
@echo "\___/_____/_/ /_/ /_/ /_/ \____/\___/ /___/_/ /_/ /_/\__,_/\__, /\___/ "
@echo " /____/ "
@echo "Successful to compile eBPF_proc_image tools:"
@echo "proc_image ——— Pre-attach to eBPF program, data is collected and output after activation"
@echo "controller ——— Controller for proc_image tool"
@echo "Please start your use ~"

# delete failed targets
.DELETE_ON_ERROR:

Expand Down
74 changes: 42 additions & 32 deletions eBPF_Supermarket/CPU_Subsystem/eBPF_proc_image/README.md
Original file line number Diff line number Diff line change
@@ -1,44 +1,62 @@
# 基于eBPF的Linux系统性能监测工具-进程画像
# 基于eBPF的进程生命周期画像

## 一、介绍

本项目是一个Linux进程生命周期画像工具,通过该工具可以清晰展示出一个进程从创建到终止的完整生命周期,并可以额外展示出进程/线程持有锁的区间画像、进程/线程上下文切换原因的标注、线程之间依赖关系(线程)、进程关联调用栈信息标注等。在这些功能的前提下,加入了更多的可视化元素和交互方式,使得整个画像更加直观、易于理解
本项目是一个Linux进程生命周期画像工具,可以清晰地展示出目标线程、目标线程组甚至系统中所有线程从创建到终止的完整生命周期,所展示出的进程生命周期信息包括关键时间点信息(execve、exit、fork、vfork、pthread_create、上下CPU等)、持有锁信息、资源使用信息、调度信息、系统调用序列信息等,并在特定的信息中加入了系统相关信息以作为参考和对比,考虑到对系统性能的影响和在高负载环境下的使用,该工具支持预先挂载使用激活的操作模式,同时在这些功能的前提下,基于Prometheus和Grafana构建了一个进程可视化平台,以实现进程画像的目的,并且通过清晰的进程画像即可察觉到进程的异常行为

运行环境:Ubuntu 22.04,内核版本 6.2
eBPF_proc_image 工具的框架图:

<div align='center'><img src="./docs/images/eBPF_proc_image.png"></div>

## 二、安装依赖
## 二、安装工具

运行环境:Ubuntu 22.04,内核版本 6.2

```
sudo apt update
sudo apt install libbpf-dev clang llvm libelf-dev libpcap-dev gcc-multilib build-essential
git submodule update --init --recursive
make
```

## 三、proc_image 工具

目前 proc_image 工具具备的功能:

- 记录进程上下CPU的时间信息
- 记录进程的关键时间点信息,即exec和exit
- 记录进程持有锁的区间信息,目前实现了用户态互斥锁、内核态互斥锁、用户态读写锁
- 记录新创建进程或线程的时间信息
proc_image 工具用于挂载 eBPF 的内核态程序,但不进行采集数据,并在用户态循环遍历 map,若有数据则输出

proc_image 工具的参数信息:

| 参数 | 描述 |
| -------------------- | ------------------------------------------------- |
| -p, --pid=PID | 指定跟踪进程的pid,默认为0号进程 |
| -t, --time=TIME-SEC | 设置程序的最大运行时间(0表示无限),默认一直运行 |
| -c, --cpuid=CPUID | 为每CPU进程设置,其他进程不需要设置该参数 |
| -r, --resource | 采集进程的资源使用情况,包括CPU利用率、内存利用率、每秒读写字节数(可持续开发) |
| -s, --syscall | 采集进程的系统调用序列信息 |
| -l, --lock | 采集进程持有的用户态锁信息,包括用户态互斥锁、用户态读写锁(可持续开发) |
| -q, --quote | 在参数周围添加引号(") |
| -k, --keytime | 采集进程关键时间点的相关信息,包括execve、exit、fork、vfork、pthread_create |
| -S, --schedule | 采集进程的调度信息 |
| -a, --all | 启动所有的采集进程数据的功能 |
| -a, --all | 挂载所有的 eBPF 内核态程序,但不进行采集数据 |
| -k, --keytime | 挂载进程关键时间点相关的 eBPF 内核态程序,但不进行采集数据 |
| -l, --lock | 挂载进程用户态持有锁相关的 eBPF 内核态程序,但不进行采集数据 |
| -r, --resource | 挂载进程资源使用情况相关的 eBPF 内核态程序,但不进行采集数据 |
| -s, --syscall | 挂载进程系统调用相关的 eBPF 内核态程序,但不进行采集数据 |
| -S, --schedule | 挂载进程调度相关的 eBPF 内核态程序,但不进行采集数据 |
| -h, --help | 显示帮助信息 |

## 四、controller 工具

controller 工具用于控制eBPF程序的执行,可动态调整数据的采集策略

controller 工具的参数信息:

| 参数 | 描述 |
| ---------------------- | ------------------------------------------------------------ |
| -a, --activate | 设置 proc_image 工具的启动策略 |
| -d, --deactivate | 初始化为原始的失活状态 |
| -f, --finish | 结束 proc_image 工具的运行 |
| -p, --pid=PID | 指定跟踪进程的pid |
| -P, --tgid=TGID | 指定跟踪进程的tgid |
| -c, --cpuid=CPUID | 为每CPU进程设置,其他进程不需要设置该参数 |
| -t, --time=TIME-SEC | 设置程序的最大运行时间(0表示无限),默认一直运行 |
| -r, --resource | 采集进程的资源使用情况,包括CPU利用率、内存利用率、每秒读写字节数(可持续开发) |
| -l, --lock | 采集进程持有用户态锁的时间信息,包括用户态互斥锁、用户态读写锁、用户态自旋锁(可持续开发) |
| -k, --keytime=KEYTIME | 采集进程关键时间点的相关信息,包括fork、vfork、pthread_create、execve、exit、onCPU、offCPU及offCPU的原因(可持续开发) |
| -s, --syscall=SYSCALLS | 采集进程以及系统的系统调用信息,进程的系统调用信息包括系统调用序列、前三个调用最频繁的系统调用、系统调用的平均延迟、最大延迟以及最小延迟,同时也采集了系统的这些延迟信息以作为参考和对比 |
| -S, --schedule | 采集进程及系统的调度信息,其中系统的调度信息具有参考和对比的作用,调度信息包括调度的平均延迟、最大延迟以及最小延迟 |
| -h, --help | 显示帮助信息 |

## 四、tools

tools文件夹中的eBPF程序是按照进程生命周期中数据的类型分别进行实现的:
Expand All @@ -51,18 +69,10 @@ tools文件夹中的eBPF程序是按照进程生命周期中数据的类型分
| syscall_image | 对进程的系统调用序列进行画像 |
| schedule_image | 对进程的调度信息进行画像 |

## 五、test_proc 测试程序

目前 [test_proc](./test/test_proc.c) 测试程序所具备逻辑:
## 五、基于 Prometheus 和 Grafana 的可视化平台

- 逻辑1:加入sleep逻辑使进程睡眠3秒,即offCPU 3秒
- 逻辑2:加入互斥锁逻辑,为了应对复杂场景,模拟进程异常地递归加锁解锁
- 逻辑3:加入fork和vfork逻辑,创建子进程让子进程睡眠3秒,以表示它存在的时间
- 逻辑4:加入pthread_create逻辑,创建线程让线程睡眠3秒,以表示它存在的时间
- 逻辑5:加入读写锁逻辑,在读模式或写模式下上锁后睡眠3s,以表示持有锁时间
- 逻辑6:加入execve逻辑,用于测试采集到数据的准确性
- 逻辑7:加入exit逻辑,可以手动输入程序退出的error_code值
基于 Prometheus 和 Grafana 的可视化平台框架图:

## 六、进程画像可视化
<div align='center'><img src="./docs/images/visualization_platform.png"></div>

可以参考[进程画像可视化指南](docs/proc_image_vis_guide.md)
eBPF_proc_image 工具的可视化操作可以参考[进程画像可视化指南](docs/proc_image_vis_guide.md)
Loading

0 comments on commit 0a7e912

Please sign in to comment.