我正在使用 logrotate 轮换 Web 服务器上的 Symfony2 日志。
一切正常,但我希望旧日志通过电子邮件发送给我。
因此,我在 logrotate conf 文件中增加了几行,如下所示
Logrotate 配置
/var/www/symfony/app/logs/prod.log {
daily
missingok
rotate 5
compress
notifempty
mail [email protected]
su www-data www-data
}
现在我确实收到了电子邮件,但内容并不像我所期望的那样。
已收到电子邮件
/etc/cron.daily/logrotate:
错误:/var/www/symfony/app/logs/prod.log.6.gz 的邮件命令失败
错误:解压缩命令无法发送邮件 /var/www/symfony/app/logs/prod.log.6.gz
run-parts:/etc/cron.daily/logrotate 退出,返回代码 1
我对此错误进行了大量研究,但没有发现任何有用的东西。我启动了 strace,希望对问题有所了解,但结果并不如预期。
Strace 命令
strace -f -o ./strace.txt logrotate -d /etc/logrotate.d/symfony2
生成的文件很大,但我认为相关部分如下
Strace 输出
6842 execve(“ / usr / bin / mail”,[“ / usr / bin / mail”,“ -s”,“ / var / www / symfony / app / logs / prod。” ...,“[电子邮件保护]"], [/* 18 个变量/]
6841 <... setgid resumed> ) = 0
6842 <... execve resumed> ) = -1 ENOENT (没有此文件或目录)
6841 setuid(0) = 0
6841 execve("/bin/gunzip", ["/bin/gunzip"], [/18 个变量 */]
6842 退出组 (1) = ?
6841 <... execve 恢复> ) = 0
6842 +++ 以 1 退出 +++
6841 brk(0
6840 <... wait4 恢复> [{WIFEXITED(s) && WEXITSTATUS(s) == 1}], 0, NULL) = 6842
6841 <... brk 恢复> ) = 0x85f010
6840 --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=6842, si_uid=0, si_status=1, si_utime=0, si_stime=0} ---
6840 写入(2, "错误: ", 7
6841 访问("/etc/ld.so.nohwcap", F_OK
6840 <... 写入恢复> ) = 7
6841 <... 访问恢复> ) = -1 ENOENT (没有此文件或目录)
6840 write(2, “/var/www 的邮件命令失败”..., 65
如您所见,gunzip 命令退出时显示错误代码 1 和一些非常明确的问号 (?),以帮助我更好地了解正在发生的事情。我收到的唯一错误是“没有这样的文件或目录”,我觉得这很奇怪,因为 logrotate 应该在发送电子邮件之前处理文件轮换。
我的问题是,如何使用 gunzip/logrotate 解决此问题,以便在删除轮换的日志文件之前通过电子邮件接收它?
以下是我的服务器上可能与问题相关的一些信息
root@someServer:/home/someUser# cat /etc/debian_version
8.1
root@someServer:/home/someUser# logrotate --version
logrotate 3.8.7
root@someServer:/home/someUser# gzip --version
gzip 1.6
另外,我的日志文件非常小(~300-400 字节),如果我手动使用 gunzip,它就可以正常工作。
编辑-添加 logrotate 输出
处理 1 个日志
轮换模式:/var/www/symfony/app/logs/prod.log 从命令行强制执行(5 次轮换)
空日志文件不会轮换,旧日志会邮寄到[电子邮件保护]
将 euid 切换为 1000 并将 egid 切换为 33
考虑到日志 /var/www/symfony/app/logs/prod.log
日志需要旋转
旋转日志 /var/www/symfony/app/logs/prod.log,log->rotateCount 为 5
dateext 后缀 '-2016011811'
glob 模式 '-[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]'
将 /var/www/symfony/app/logs/prod.log.5.gz 重命名为 /var/www/symfony/app/logs/prod.log.6.gz(rotatecount 5、logstart 1、i 5),
将 /var/www/symfony/app/logs/prod.log.4.gz 重命名为/var/www/symfony/app/logs/prod.log.5.gz(rotatecount 5、logstart 1、i 4),
将 /var/www/symfony/app/logs/prod.log.3.gz 重命名为 /var/www/symfony/app/logs/prod.log.4.gz(rotatecount 5、logstart 1、i 3),将
/var/www/symfony/app/logs/prod.log.2.gz 重命名为 /var/www/symfony/app/logs/prod.log.3.gz(rotatecount 5、logstart 1、i 2),将
/var/www/symfony/app/logs/prod.log.1.gz 重命名为 /var/www/symfony/app/logs/prod.log.2.gz(rotatecount 5、logstart 1、i 1),
重命名/var/www/symfony/app/logs/prod.log.0.gz 到 /var/www/symfony/app/logs/prod.log.1.gz(rotatecount 5、logstart 1、i 0),
旧日志 /var/www/symfony/app/logs/prod.log.0.gz 不存在
将 /var/www/symfony/app/logs/prod.log 重命名为 /var/www/symfony/app/logs/prod.log.1
使用以下工具压缩日志:/bin/gzip
将 uid 切换为 1000 并将 gid 切换为 33
将 uid 切换为 1000 并将 gid 切换为 33
将 euid 切换为 0 并将 egid 切换为 0
错误:/var/www/symfony/app/logs/prod.log.6.gz 的邮件命令失败
错误:解压缩命令发送邮件失败/var/www/symfony/app/logs/prod.log.6.gz
将 euid 切换为 0,将 egid 切换为 0
完整内容如下:
strace -vf -s 128 -e verbose=all -o ./strace.txt logrotate -d /etc/logrotate.d/symfony2
答案1
根据您的 strace,您的问题实际上不是 gzip。
这就是 gzip 失败的原因。
14972 write(1, "<Here is the content of my prod.log file>"..., 32768) = -1 EPIPE (Broken pipe)
该过程正在写入 stdout,但实际输出却是 mail 命令的输入。如果我们检查一下:
14973 execve("/usr/bin/mail", ["/usr/bin/mail", "-s", "/var/www/symfony/app/logs/prod.log", "[email protected]"], ["SHELL=/bin/bash", "TERM=xterm", "USER=root", "LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:su=37;41:sg=30;43:ca=30;41"..., "SUDO_USER=none", "SUDO_UID=1000", "USERNAME=root", "MAIL=/var/mail/root", "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", "PWD=/home/none", "LANG=en_GB.UTF-8", "SHLVL=1", "SUDO_COMMAND=/bin/bash", "HOME=/root", "LANGUAGE=en_GB:en", "LOGNAME=root", "SUDO_GID=1000", "_=/usr/bin/strace"] <unfinished ...>
14973 <... execve resumed> ) = -1 ENOENT (No such file or directory)
当您尝试执行 mail 命令时,它会失败,因为/usr/bin/mail
不存在。程序退出,由于管道的另一端已经消失,所以stdout
ofgzip
返回。因此 gzip 以 1 退出。SIGPIPE
您需要做的是安装一个mail
命令。这可能bsd-mailx
在 debianesque 系统上或mailx
在基于 Redhat 的系统上。
答案2
使用prerotate
或postrotate
脚本自行发送日志。这样,您可以灵活地将日志作为压缩附件发送(如果您愿意),也可以解压缩它们。
有一个从 CLI 发送附件的选项数量。