systemd默认是将输出的日志放入/var/log/message,需要输出到指定的文件需要使用systemd参数与rsyslog过滤器。并指示syslog过滤器按程序名称拆分其输出。

systemd配置的参数

涉及到的参数位于[Service]下:

  • SyslogIdentifier:设置日志标识符,用于rsyslog进行过滤。
  • StandardOutput:进程的标准日志输出,填null的时候为不处理,填syslog将其交给rsyslog处理,注意这不影响systemctl自带的journalctl获取日志。
  • StandardError:设置进程的错误日志,配置和StandardOutput含义相同。

rsyslog过滤器设置

  1. 新建一个配置文件,取名任意: vim /etc/rsyslog.d/xx.conf

  2. 填入如下内容: 单个条件处理:

if $programname == 'SyslogIdentifier配置的名称' then /var/log/applog/file.log
& stop

多条件处理:

if ($programname == 'SyslogIdentifier配置的名称') then {
   action(type="omfile" file="/var/log/applog/file1.log")
   stop
} else if ($programname == 'SyslogIdentifier配置的名称') then {
   action(type="omfile" file="/var/log/applog/file2.log")
   stop
}
  1. 检查配置文件是否有错误: rsyslogd -N1 -f xx.conf

  2. 重启rsyslog: systemctl restart rsyslog

  3. 查看rsyslog状状态: systemctl status rsyslog

rsyslog无法输出日志到自定义文件的问题

出现这个问题的原因是rsyslogd访问的文件或目录的context都拥有var_log_t类型。系统根据规则自动对创建的文件或目录赋予指定的context。如果规则中没有我们自定义的路径,自然也就没办法给予var_log_t类型,rsyslogd就没有权限访问。

  1. 查看rsyslog有权限访问的路径: semanage fcontext -l | grep :var_log_t

  2. 自定义路径增加rsyslog访问权限或者配置成有权限的路径都可以

# 根据需要添加自定义的文件或目录
semanage fcontext -a -t var_log_t "/data/log(/.*)?"
semanage fcontext -a -t var_log_t "/data/log/.*"
semanage fcontext -a -t var_log_t -f -d "/data/log"

# 修复目录及其子文件目录的context
restorecon -Rv /data/log

# 重启rsyslogd,此时selinux可以运行rsyslog访问自定义的路径了
service rsyslogd restart

参考

  1. systemd服务的输出重定向到指定文件
  2. selinux开启导致rsyslog无法输出日志到自定义文件的问题