logrotate 期间 gunzip 出错

logrotate 期间 gunzip 出错

我正在使用 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

http://pastebin.com/C0uj0419

答案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不存在。程序退出,由于管道的另一端已经消失,所以stdoutofgzip返回。因此 gzip 以 1 退出。SIGPIPE

您需要做的是安装一个mail命令。这可能bsd-mailx在 debianesque 系统上或mailx在基于 Redhat 的系统上。

答案2

使用prerotatepostrotate脚本自行发送日志。这样,您可以灵活地将日志作为压缩附件发送(如果您愿意),也可以解压缩它们。

有一个从 CLI 发送附件的选项数量

相关内容