在一台生产 Linux 机器上,我使用以下配置捕获 SIP 数据包:
日志旋转.conf:
# Opensips SIP traces
/var/log/sip.log
{
rotate 31
daily
missingok
notifempty
compress
delaycompress
sharedscripts
postrotate
pkill tcpdump
/home/ubuntu/log-sip-messages.sh &
endscript
}
日志-sip-messages.sh:
#!/bin/sh
tcpdump host 159.63.X.X -s0 -v >> /var/log/sip-159.63.X.X.log
这在 Ubuntu 11.04 服务器上效果很好,但在 Ubuntu 12.10 机器上,这只会生成一个带有日志轮转时时间戳的文件。就好像 pkill 在再次运行 tcpdump 开始写入新文件之前尚未完成。
我尝试直接从终端运行它作为实验:
pkill tcpdump && tcpdump -s0 -v udp >> /var/log/sip.log
然后当我运行时ps aux|grep tcpdump
没有进程在运行,确认我已经知道的... pkill 命令在 12.10 上异步运行(但要么在 11.04 上同步运行,要么只是击败第二个命令)
我怎样才能做到这一点,以便我可以在一个漂亮的、可读的日志文件(我不需要 pcaps)中捕获网络流量,而不会冒填满硬盘空间的风险?
答案1
Unix 信号传递是异步的。当kill
系统调用返回时,信号已传递给进程,但进程可能尚未对此做出反应。在 11.04 下你很幸运有调度程序。如果被杀死的进程有该信号的处理程序,它可以在死亡之前花费任意长的时间,或者选择不因该信号而死亡。
您可以使用锁来确保进程的新实例在前一个实例完成之前不会启动。
此外,我不建议随意终止tcpdump
进程:如果还有其他实例在运行怎么办?相反,请终止所有打开锁定文件的进程。
#!/bin/sh
lockfile=/var/run/log-sip-messages.lock
# Kill all processes that have the lock file open
fuser -k -TERM "$lockfile" >/dev/null 2>/dev/null
(
# Wait until the lock is released
flock -s 3
# Don't let this shell be killed by fuser: wait until tcpdump exits
trap : TERM
# Call tcpdump with the lock file open, so that fuser kills it
tcpdump -s0 -v udp >> /var/log/sip.log
) 3>"$lockfile"
并且从 logrotate 中,/home/ubuntu/log-sip-messages.sh
仅运行。
答案2
一种想法是在( )pkill
和启动备份之间引入一些等待时间。这感觉就像是黑客攻击,确实如此,但是是这样的:tcpdump
/home/ubuntu/log-sip-messages.sh &
postrotate
pkill tcpdump
sleep 3
/home/ubuntu/log-sip-messages.sh &
endscript
答案3
所有这些激励我深入研究 logrotate 联机帮助页,看看我可以使用哪些工具。我发现它copytruncate
会复制日志文件,然后截断它,但不会中断写入日志文件的进程。我的测试表明它确实会轮换日志并允许 tcpdump 继续写入已清除的文件。我使用测试配置文件让每小时的 cronjob 运行过夜,这样我就会每小时轮换这些日志。有效:
# Opensips SIP traces
/var/log/sip.log
{
rotate 31
daily
missingok
notifempty
compress
delaycompress
sharedscripts
copytruncate
}
一个可能的缺点是,如果 tcpdump 进程被不知道我在做什么的人杀死,我必须进来并手动重新启动该进程,但目前这已经足够了。
另一个潜在的问题是,如果日志文件非常大,则制作副本可能会短暂需要大量磁盘空间,目前我有足够的磁盘空间,但如果没有足够的空间,则该过程可能会中断。复印一份。