You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何记录Linux进程退出信息?排查进程自主退出或被杀死问题

没问题!我来给你分享几个实用的方法,帮你搞清楚进程到底是自己退出还是被别的进程干掉的:

方法1:利用systemd自带日志追踪(适合systemd管理的服务)

如果你的进程是通过systemd作为服务运行的,那直接用systemd的日志就够了:

  • 实时追踪服务日志:journalctl -u <你的服务名> -f,比如journalctl -u nginx -f
  • 区分退出原因:
    • 自主退出:日志里会显示类似Main process exited, code=exited, status=0/SUCCESS的内容,status后面的代码就是进程的退出码
    • 被杀死:会出现Main process exited, code=killed, status=9/KILL或者status=15/TERMstatus里的数字就是杀死进程的信号(9是SIGKILL,15是SIGTERM)
方法2:用auditd记录进程终止事件(最精准的系统级追踪)

auditd是Linux的审计系统,能详细记录进程的kill操作,需要先安装:

  1. 安装auditd:sudo apt install auditd(Debian/Ubuntu)或者sudo yum install auditd(RHEL/CentOS)
  2. 添加kill操作的审计规则:sudo auditctl -a exit,always -F arch=b64 -S kill,这条规则会记录所有64位系统上的kill调用
  3. 查看审计日志:
    • 实时查看:sudo ausearch -k kill -f
    • 查看历史记录:sudo ausearch -k kill,日志里会明确显示哪个PID发送了kill信号给目标PID,比如类似type=SYSCALL msg=audit(1699999999.999:999): arch=c000003e syscall=62 success=yes exit=0 a0=1234 a1=9 a2=0 a3=0 items=0 ppid=5678 pid=9012 auid=1000 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts0 ses=1 comm="kill" exe="/usr/bin/kill",这里a0=1234是目标PID,a1=9是发送的信号(SIGKILL),pid=9012是执行kill操作的进程PID
方法3:自定义脚本实时监控(灵活适配各种场景)

如果上面的方法不合适,你可以自己写个简单的bash脚本,专门监控目标进程的退出状态:

#!/bin/bash
# 替换成你要监控的进程名
TARGET_PROC="your-process-name"
# 日志文件路径
LOG_FILE="/var/log/process_exit_monitor.log"

while true; do
    # 获取进程PID(只匹配精确名称)
    PID=$(pgrep -x "$TARGET_PROC")
    if [ -n "$PID" ]; then
        # 等待进程退出,捕获退出状态
        wait "$PID" 2>/dev/null
        EXIT_CODE=$?
        
        if [ $((EXIT_CODE & 127)) -eq 0 ]; then
            # 退出码没有信号位,说明是自主退出
            echo "$(date '+%Y-%m-%d %H:%M:%S'): $TARGET_PROC PID $PID exit by self (exit code: $EXIT_CODE)" >> "$LOG_FILE"
        else
            # 提取杀死进程的信号
            SIGNAL=$((EXIT_CODE & 127))
            # 尝试查找发送信号的进程(需要root权限)
            KILLER_PID=$(grep -r "signal $SIGNAL" /proc/*/status 2>/dev/null | grep -v "$PID" | awk -F/ '{print $3}' | head -n1)
            
            if [ -n "$KILLER_PID" ]; then
                echo "$(date '+%Y-%m-%d %H:%M:%S'): $KILLER_PID killed $TARGET_PROC PID $PID (signal: $SIGNAL)" >> "$LOG_FILE"
            else
                echo "$(date '+%Y-%m-%d %H:%M:%S'): $TARGET_PROC PID $PID killed by unknown process (signal: $SIGNAL)" >> "$LOG_FILE"
            fi
        fi
    else
        # 进程没运行,每隔5秒检查一次
        sleep 5
    fi
done

使用脚本的注意事项:

  • 给脚本加执行权限:chmod +x process_monitor.sh
  • 用root权限运行(否则可能查不到发送信号的进程):sudo ./process_monitor.sh
  • 可以把脚本做成后台服务,比如用systemd配置成开机自启

内容的提问来源于stack exchange,提问作者violetgo

火山引擎 最新活动