Linux下setlogmask()为何只能降低日志优先级,无法提升?
我编写了如下日志输出代码:
// 发送给所有已登录用户:syslog(LOG_EMERG syslog(LOG_ALERT, "1 %s: rcvd NV_update from Sub/Node: %d/%d\n", __func__, rcvd_subnet, rcvd_node); syslog(LOG_CRIT, "2 %s: rcvd NV_update from Sub/Node: %d/%d\n", __func__, rcvd_subnet, rcvd_node); syslog(LOG_ERR, "3 %s: rcvd NV_update from Sub/Node: %d/%d\n", __func__, rcvd_subnet, rcvd_node); syslog(LOG_WARNING, "4 %s: rcvd NV_update from Sub/Node: %d/%d\n", __func__, rcvd_subnet, rcvd_node); syslog(LOG_NOTICE, "5 %s: rcvd NV_update from Sub/Node: %d/%d\n", __func__, rcvd_subnet, rcvd_node); syslog(LOG_INFO, "6 %s: rcvd NV_update from Sub/Node: %d/%d\n", __func__, rcvd_subnet, rcvd_node); syslog(LOG_DEBUG, "7 %s: rcvd NV_update from Sub/Node: %d/%d\n", __func__, rcvd_subnet, rcvd_node); setlogmask(LOG_UPTO(LOG_CRIT)) (得到1和2) setlogmask(LOG_UPTO(LOG_NOTICE)) (得到1-5) setlogmask(LOG_UPTO(LOG_DEBUG)) (得到1-6)
未调用setlogmask()时,仅能获取LOG_EMERG至LOG_INFO级别的日志;即使调用setlogmask(0xff),也无法得到LOG_DEBUG日志。
当前/etc/rsyslog.conf配置如下:
"/etc/rsyslog.conf": *.info;mail.none;authpriv.none;cron.none /var/log/messages
我尝试调用setlogmask(0xff)、setlogmask(LOG_UPTO(LOG_DEBUG)),以及组合所有日志掩码的setlogmask调用,期望在/var/log/messages中看到LOG_DEBUG日志,但均未成功。直到将/etc/rsyslog.conf中的.info改为.debug后,才成功获取到LOG_DEBUG日志。这似乎是设置了日志的最高级别,但我在手册页中并未找到相关说明。想请教:为何Linux下setlogmask()只能降低日志优先级,无法提升?
这是因为setlogmask()和rsyslog服务是两层独立的日志过滤机制,各自负责不同的环节:
setlogmask()是进程级的发送控制
setlogmask()的作用是控制当前进程会不会把对应级别的日志提交给syslog服务。默认情况下,多数Linux发行版的libc库会默认屏蔽LOG_DEBUG级别的日志(即默认掩码不包含LOG_DEBUG的位),所以你调用setlogmask(LOG_UPTO(LOG_DEBUG))的作用是打开进程发送DEBUG日志的开关,让进程把DEBUG日志发出去,但这只是完成了第一步。rsyslog是系统服务级的接收/存储控制
你的rsyslog.conf配置里的*.info是一条过滤规则:它告诉rsyslog服务,只接收并记录**INFO级别及优先级更高(更严重)**的日志。而LOG_DEBUG是优先级最低的日志级别,比LOG_INFO更低,所以即使进程把DEBUG日志发出去了,rsyslog会直接丢弃这条日志,不会写入/var/log/messages。修改rsyslog配置生效的原因
把配置中的.info改成.debug后,rsyslog的过滤规则就变成了接收DEBUG级别及以上的所有日志,这时候进程发送的DEBUG日志才能被rsyslog接收并写入日志文件。关于“提升优先级”的误解
setlogmask()并没有“降低/提升优先级”的功能,它只是控制哪些级别的日志会被进程发送。你觉得它“只能降低”是因为默认掩码已经屏蔽了DEBUG,而即使你打开了发送开关,后面的rsyslog服务不收,自然看不到日志——这不是setlogmask()的限制,而是rsyslog的配置限制。
内容的提问来源于stack exchange,提问作者William Dickerson

