138 lines
3.9 KiB
Bash
138 lines
3.9 KiB
Bash
#!/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
|