RSYSLOG 与 Logrotate

2023-09-07, 星期四, 16:45

DevOps培训

RSYSLOG

RSYSLOG is the rocket-fast system for log processing.

It offers high-performance, great security features and a modular design. While it started as a regular syslogd, rsyslog has evolved into a kind of swiss army knife of logging, being able to accept inputs from a wide variety of sources, transform them, and output to the results to diverse destinations.

RSYSLOG can deliver over one million messages per second to local destinations when limited processing is applied. Even with remote destinations and more elaborate processing the performance is usually considered “stunning”.

rsyslog 在 Fedora / RHEL / CentOS / Ubuntu 等主流发行版中都是默认的日志系统。

# rsyslogd -v
rsyslogd  8.2102.0-113.el9_2 (aka 2021.02) compiled with:
	PLATFORM:				x86_64-redhat-linux-gnu
	PLATFORM (lsb_release -d):
	FEATURE_REGEXP:				Yes
	GSSAPI Kerberos 5 support:		Yes
	FEATURE_DEBUG (debug build, slow code):	No
	32bit Atomic operations supported:	Yes
	64bit Atomic operations supported:	Yes
	memory allocator:			system default
	Runtime Instrumentation (slow code):	No
	uuid support:				Yes
	systemd support:			Yes
	Config file:				/etc/rsyslog.conf
	PID file:				/var/run/rsyslogd.pid
	Number of Bits in RainerScript integers: 64

See https://www.rsyslog.com for more information.

在网络上查找配置时,有时会出现 obsolete legacy 格式的配置,特征是 $ 符号作为配置语句的起始字符,这种语法在 v5 之后就已经废弃。

basic 配置格式(sysklogd)简洁明了,但是表达能力可能略有不足:

# 写入文件
mail.info /var/log/mail.log
# 通过 TCP 发送到远端服务器
mail.err @@server.example.net

advanced 配置格式(RainerScript):

if prifilt("mail.info") then {
     action(type="omfile" file="/var/log/maillog")
}

输入的日志先通过一系列规则集(RuleSet)和规则(Rule)过滤,然后执行相应的动作(Action)。

mail.info 这样满足 <facility>.<priority> 结构的称为选择器(Selector)。facility 指示了日志是由哪种应用程序发出的,对于用户应用程序,应当使用 userpriority 表示日志的等级,通常有:debug, info, notice, warning, err, crit, alert, emerg。因此 mail.info 就表示对来自 mailinfo 及以上级别的日志执行后面声明的动作。这两个参数都可以使用通配符 *,多个选择器可使用 ; 连接。

另一种方法是使用属性过滤器(Property-based filters),常用的属性有:programname:msg 等,可以在 RSyslog Documentation - rsyslog Properties 中查询。

:programname, isequal, "go-http-server" /var/log/honeypot-remote.log
Jun 13 17:19:56 Central-Air-Data-Computer go-http-server[38198]: 2023/06/13 17:19:56 Unauthorized access detected

isequal 是一个字符串比较操作符,此外还可以使用 containsstartswithregex 等,也可以使用 ! 取反。

# /etc/rsyslog.d/honeypot.conf
# 含有 honey-pot 字符串的日志写入 /var/log/honeypot.log
:msg, contains, "honey-pot" /var/log/honeypot.log

需要重启 rsyslog 服务。

systemctl restart rsyslog
tail -f /var/log/honeypot.log

可以使用 logger 命令手动产生日志,用来测试配置是否正确。

logger -p user.warn 'honey-pot log message test'

Logrotate

Logrotate 是一种日志轮转、归档、清理自动化工具,在 Fedora / RHEL / CentOS / Ubuntu 等主流发行版中都默认安装。通过包管理器安装软件包后,软件的日志轮转配置会保存到 /etc/logrotate.d/ 目录。

以 NGINX 的 /etc/logrotate.d/nginx 为例:

/var/log/nginx/*.log {
        daily
        missingok
        rotate 52
        compress
        delaycompress
        notifempty
        create 640 nginx adm
        sharedscripts
        postrotate
                if [ -f /var/run/nginx.pid ]; then
                        kill -USR1 `cat /var/run/nginx.pid`
                fi
        endscript
}
  • /var/log/nginx/*.log 处理 /var/log/nginx/ 目录下的所有 *.log 文件
  • daily 表示每日触发,其他选项包括 weeklymonthlyyearly
  • missingok 如果 *.log 文件不存在,不必抛出异常
  • rotate 52 保留至少 52 个归档日志文件(一年有 52 周,所以这个配合 weekly 可以存一整年的日志)
  • compress 表示使用 gzip 压缩,delaycompress 表示到下一次归档时再压缩,这样上一份日志是未压缩的。可以用 compresscmd 指定其他压缩命令
  • notifempty 不处理空日志文件
  • create 640 nginx adm 使用 adm 用户组的 nginx 用户创建文件,权限为 640
  • sharedscripts 时,处理完所有匹配的日志文件后执行 postrotate 命令,否则每处理一个文件就执行一次
  • postrotate 中的命令会在处理完日志文件后执行
    • 本例中 kill -USR1 $PID 表示向指定进程发送 user defined signal 1,参考 Controlling nginx 这会使 NGINX 重新打开日志文件

由于日志的轮转涉及到替换文件,写日志的程序需要识别这一过程并能够正常打开新文件。你可以像 NGINX 一样主动接受相应的信号并重新打开文件,也可以尝试在不影响业务的情况下重启应用。由于应用程序可能是通过 syslog 写日志的,所以 /usr/bin/killall -HUP rsyslogd 一般也不会有什么问题。