mirror of
https://github.com/containers/podman.git
synced 2025-07-02 08:47:43 +08:00
hack/podmansnoop
Add a script to measure the execution times of podman, crun, run and conmon. It's a trimmed down version of the exitsnoop tool and intended to guide us in future performance optimizations. The below output was generated when running `podman run --net=host docker.io/library/alpine:latest true` ``` podman (snoop) $ sudo ./hack/podmansnoop PCOMM PID PPID TID AGE(ms) conmon 51580 51569 51580 1.67 conmon 51583 51569 51583 3.53 crun 51591 51590 51591 18.28 crun 51593 51569 51593 2.48 conmon 51606 51594 51606 0.85 crun 51608 51594 51608 2.50 podman 51594 51590 51594 176.27 conmon 51590 1950 51590 214.78 podman 51569 40964 51569 431.36 ``` In the future, it would be helpful to add the arguments of the commands. `execsnoop` can reveal them quite nicely but I did not manage to merge the two scripts due to time constraints. Signed-off-by: Valentin Rothberg <vrothberg@redhat.com>
This commit is contained in:
98
hack/podmansnoop
Executable file
98
hack/podmansnoop
Executable file
@ -0,0 +1,98 @@
|
||||
#!/usr/bin/env python
|
||||
from __future__ import print_function
|
||||
|
||||
# Based on the `exitsnoop` scripts at https://github.com/iovisor/bcc/blob/master/tools/exitsnoop.py
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import platform
|
||||
import re
|
||||
import signal
|
||||
import sys
|
||||
|
||||
from bcc import BPF
|
||||
from datetime import datetime
|
||||
from time import strftime
|
||||
|
||||
bpf_src = """
|
||||
#include <uapi/linux/ptrace.h>
|
||||
#include <linux/sched.h>
|
||||
|
||||
#define ARGSIZE 128
|
||||
|
||||
struct data_t {
|
||||
u64 start_time;
|
||||
u64 exit_time;
|
||||
u32 pid;
|
||||
u32 tid;
|
||||
u32 ppid;
|
||||
u32 sig_info;
|
||||
char task[TASK_COMM_LEN];
|
||||
char argv[ARGSIZE];
|
||||
};
|
||||
|
||||
BPF_PERF_OUTPUT(events);
|
||||
|
||||
TRACEPOINT_PROBE(sched, sched_process_exit)
|
||||
{
|
||||
struct task_struct *task = (typeof(task))bpf_get_current_task();
|
||||
if (task->pid != task->tgid) { return 0; }
|
||||
|
||||
struct data_t data = {};
|
||||
|
||||
data.start_time = task->start_time,
|
||||
data.exit_time = bpf_ktime_get_ns(),
|
||||
data.pid = task->tgid,
|
||||
data.tid = task->pid,
|
||||
data.ppid = task->real_parent->tgid,
|
||||
data.sig_info = task->exit_code & 0xFF,
|
||||
bpf_get_current_comm(&data.task, sizeof(data.task));
|
||||
|
||||
events.perf_submit(args, &data, sizeof(data));
|
||||
return 0;
|
||||
}
|
||||
"""
|
||||
|
||||
def _print_header():
|
||||
print("%-16s %-7s %-7s %-7s %-7s" %
|
||||
("PCOMM", "PID", "PPID", "TID", "AGE(ms)"))
|
||||
|
||||
buffer = None
|
||||
|
||||
def _print_event(cpu, data, size): # callback
|
||||
"""Print the exit event."""
|
||||
global buffer
|
||||
e = buffer["events"].event(data)
|
||||
|
||||
task = e.task.decode()
|
||||
if task == "3":
|
||||
# For absolutely unknown reasons, 'crun' appears as '3'.
|
||||
task = "crun"
|
||||
|
||||
if task not in ["podman", "crun", "runc", "conmon", "netavark", "aardvark-dns"]:
|
||||
return
|
||||
|
||||
age = (e.exit_time - e.start_time) / 1e6
|
||||
print("%-16s %-7d %-7d %-7d %-7.2f " %
|
||||
(task, e.pid, e.ppid, e.tid, age), end="")
|
||||
print()
|
||||
|
||||
def snoop(bpf, event_handler):
|
||||
bpf["events"].open_perf_buffer(event_handler)
|
||||
while True:
|
||||
bpf.perf_buffer_poll()
|
||||
|
||||
def main():
|
||||
global buffer
|
||||
try:
|
||||
buffer = BPF(text=bpf_src)
|
||||
_print_header()
|
||||
snoop(buffer, _print_event)
|
||||
except KeyboardInterrupt:
|
||||
print()
|
||||
sys.exit()
|
||||
|
||||
return 0
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
Reference in New Issue
Block a user