发现问题

昨天完成了Logrotate管理MongoDB日志的配置工作,手动执行验证通过,但是今天查看日志切换情况,却没有如期待的一般——在日志目录下仅有一个mongodb.log文件——日志没有切换?!

分析

确定执行情况

为了确定配置的每天执行的MongoDB日至切换是否执行过,我们首先查看/var/log/cron,下面是截取了部分内容:

...
Jul 1 03:01:02 localhost anacron[19152]: Will run job 'cron.daily' in 49 min.
Jul 1 03:01:02 localhost anacron[19152]: Jobs will be executed sequentially
...
Jul 1 03:50:02 localhost anacron[19152]: Job 'cron.daily' started
...
Jul 1 03:50:02 localhost run-parts(/etc/cron.daily)[19251]: starting logrotate
Jul 1 03:50:02 localhost run-parts(/etc/cron.daily)[19267]: finished logrotate
...
Jul 1 03:53:49 localhost anacron[19152]: Job 'cron.daily' terminated
Jul 1 03:53:49 localhost anacron[19152]: Normal exit (1 job run)

可以看到,在7月1日凌晨3点50左右确实执行了每日的计划任务,并且cron.daily正常退出。但是Logrotate有没有出错还要继续分析。

查看/var/log/message,在同样的时间段,发现了这样一条错误信息:

Jul  1 03:50:02 localhost logrotate: ALERT exited abnormally with [1]

而这段错误信息,正是Logrotate每日执行的计划任务脚本中执行异常退出的提示信息:

[root@localhost ~]# cat /etc/cron.daily/logrotate 
#!/bin/sh

/usr/sbin/logrotate /etc/logrotate.conf >/dev/null 2>&1
EXITVALUE=$?
if [ $EXITVALUE != 0 ]; then
/usr/bin/logger -t logrotate "ALERT exited abnormally with [$EXITVALUE]"
fi
exit 0

原因探究

原因探究的过程非常简单——Google,所以略。

噗……友谊的小船说翻就翻!(╯-_-)╯╧╧

回到正题。

引起该问题的原因与SELinux有关。使用getenforce查询SELinux状态:

[root@localhost ~]# getenforce
Enforcing

可以看到,我们当前的SELinux处于Enforcing模式下,此时,因为我们在之前MongoDB轮换配置文件中,使用了除了/var/log/之外的路径,那么:

SELinux was restricting the access to logrotate on log files in directories which does not have the required SELinux file context type. “/var/log” directory has “var_log_t” file context, and logrotate was able to do the needful.

即,/var/log目录具有var_log_t文件上下文,如果要使用Logrotate,我们的日志目录也应该具备这个向下问。所以解决方案就是为配置文件中使用的日志目录设置文件上下文,可以通过下面两个命令做到:

semanage fcontext -a -t var_log_t <directory/logfile>
restorecon -v <directory/logfile>

第一个命令,用于设置上下文,第二个命令用于对于需要设置上下文的目录活文件,递归的设置。

解决过程

检查安装情况

执行man semanagesemanage -h检查是否安装semanage:

[root@localhost ~]# man semanage
No manual entry for semanage

[root@localhost ~]# semanage -h
-bash: semanage: command not found

这里我们并没有找到这个命令,所以需要安装相关软件,如果已安装,则跳过这一步。

安装

找到是什么软件提供了semanage命令:

[root@localhost ~]#  yum provides */semanage
Loaded plugins: fastestmirror, refresh-packagekit, security
Loading mirror speeds from cached hostfile
* base: mirrors.yun-idc.com
* extras: mirrors.yun-idc.com
* updates: mirrors.yun-idc.com
libsemanage-devel-2.0.43-5.1.el6.x86_64 : Header files and libraries used to build policy manipulation tools
Repo : base
Matched from:
Filename : /usr/include/semanage



libsemanage-devel-2.0.43-5.1.el6.i686 : Header files and libraries used to build policy manipulation tools
Repo : base
Matched from:
Filename : /usr/include/semanage



policycoreutils-python-2.0.83-29.el6.x86_64 : SELinux policy core python utilities
Repo : base
Matched from:
Filename : /usr/sbin/semanage



policycoreutils-python-2.0.83-29.el6.x86_64 : SELinux policy core python utilities
Repo : installed
Matched from:
Filename : /usr/sbin/semanage

这里,我们手动安装一下policycoreutils-python即可:

[root@localhost ~]# yum -y install policycoreutils-python

执行命令

安装完毕,执行命令:

[root@localhost ~]# semanage fcontext -a -t var_log_t '/mongoData/mongodb_log/mongodb.log'
[root@localhost ~]# restorecon -Frvv /mongoData/mongodb_log/mongodb.log

设置完file context之后,记录会被持久化到/etc/selinux/targeted/contexts/files/file_contexts.local中,我们可以检查一下:

[root@localhost ~]# cat /etc/selinux/targeted/contexts/files/file_contexts.local
# This file is auto-generated by libsemanage
# Do not edit directly.

/mongoData/mongodb_log/mongodb.log system_u:object_r:var_log_t:s0

此时,补锅工作结束。

更多详细内容,点击这里查看参考文章