Files
qiming/qiming-rcoder/docker/rcoder-agent-runner/ebpf-tools/syscall-monitor.sh
2026-06-01 13:54:52 +08:00

138 lines
3.9 KiB
Bash
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/bin/bash
# 系统调用监控脚本
# 使用 bpfcc-tools 追踪进程的系统调用活动
set -e
DIAG_OUTPUT_DIR="${DIAG_OUTPUT_DIR:-/app/container-logs/diag}"
SYSLOG="$DIAG_OUTPUT_DIR/syscall-monitor.log"
SAMPLE_DURATION=${SAMPLE_DURATION:-30} # 每次采样时长(秒)
GENERATE_INTERVAL=${GENERATE_INTERVAL:-60} # 生成间隔(秒,默认 1 分钟)
mkdir -p "$DIAG_OUTPUT_DIR"
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" | tee -a "$SYSLOG"
}
# 静默日志(只写入文件,不输出到控制台)
log_silent() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" >> "$SYSLOG"
}
# 获取进程树 PID
get_process_tree_pids() {
local parent_pid=$1
if [ -z "$parent_pid" ]; then
return
fi
echo "$parent_pid"
local child_pids=$(pgrep -P "$parent_pid" 2>/dev/null || true)
for child_pid in $child_pids; do
get_process_tree_pids "$child_pid"
done
}
# 系统调用计数统计(静默模式)
collect_syscall_counts() {
local pids="$1"
local timestamp=$(date '+%Y%m%d_%H%M%S')
local success_count=0
local total_count=0
for pid in $pids; do
((total_count++))
local comm=$(ps -p "$pid" -o comm= 2>/dev/null || echo "unknown")
local output_file="$DIAG_OUTPUT_DIR/syscall-count-${comm}-${pid}-${timestamp}.txt"
# 使用 syscount-bpfcc 统计系统调用(完全静默)
timeout ${SAMPLE_DURATION}s syscount-bpfcc -p "$pid" -s 2>/dev/null > "$output_file" || true
if [ -s "$output_file" ]; then
((success_count++))
# 只记录到文件,不输出到控制台
log_silent "$comm ($pid): 已保存统计"
else
rm -f "$output_file"
fi
done
# 只在汇总时输出一行日志
log "🔍 系统调用统计完成: ${success_count}/${total_count} 个进程"
}
# 进程创建追踪(静默启动)
trace_process_creation() {
local output_file="$DIAG_OUTPUT_DIR/execsnoop-$(date '+%Y%m%d_%H%M%S').log"
# 后台运行 execsnoop-bpfcc完全静默
execsnoop-bpfcc -t -n 1 > "$output_file" 2>/dev/null &
local execsnoop_pid=$!
log_silent "✅ execsnoop-bpfcc 已启动 (PID: $execsnoop_pid)"
echo "$execsnoop_pid"
}
# 文件访问追踪(静默启动)
trace_file_access() {
local output_file="$DIAG_OUTPUT_DIR/opensnoop-$(date '+%Y%m%d_%H%M%S').log"
# 后台运行 opensnoop-bpfcc完全静默
opensnoop-bpfcc -t -n 1 > "$output_file" 2>/dev/null &
local opensnoop_pid=$!
log_silent "✅ opensnoop-bpfcc 已启动 (PID: $opensnoop_pid)"
echo "$opensnoop_pid"
}
# 主监控循环
monitor_loop() {
log "🚀 系统调用监控已启动 (每 ${GENERATE_INTERVAL} 秒采样一次)"
log "📝 详细日志: $SYSLOG"
# 启动持续追踪(静默)
local execsnoop_pid=$(trace_process_creation)
local opensnoop_pid=$(trace_file_access)
# 清理函数
cleanup() {
log "🛑 停止系统调用监控..."
kill "$execsnoop_pid" "$opensnoop_pid" 2>/dev/null || true
log "✅ 系统调用监控已停止"
}
trap cleanup EXIT TERM INT
# 定期生成系统调用统计
local iteration=0
while true; do
((iteration++))
local agent_pid=$(pgrep -f "agent_runner" | head -1)
if [ -n "$agent_pid" ]; then
local pids=$(get_process_tree_pids "$agent_pid" | tr '\n' ' ')
# 每次只输出一行汇总日志
collect_syscall_counts "$pids"
else
log_silent "⚠️ 未检测到 agent_runner 进程"
fi
# 只记录到文件,不输出到控制台
log_silent "⏰ 第 ${iteration} 次采样完成,${GENERATE_INTERVAL} 秒后进行下一次..."
sleep "$GENERATE_INTERVAL"
done
}
# 启动监控
case "$1" in
start)
monitor_loop
;;
*)
echo "用法: $0 start"
exit 1
;;
esac