c - 如何使用 rsyslogd 登录到/var/log/mail.log?

标签 c linux logging glibc rsyslog

我目前正在研究 Linux 下的日志记录。我制作了以下非常简单的测试应用程序(使用纯 C):

#include <syslog.h>

int main(int argc, char **argv)
{
  openlog("mytest", (LOG_PID | LOG_NDELAY), LOG_MAIL);

  syslog(LOG_MAKEPRI(LOG_MAIL, LOG_ERR), "Test");

  return(0);
}

这个“应用程序”编译,当我执行它时,它在 /var/log/syslog 中生成一个条目,但在 /var 中没有条目/log/mail.logno /var/log/mail.err 中的条目。

谁能解释一下为什么?

我在测试机上使用rsyslogd;这是来自 /etc/rsyslog.conf 的配置(请注意 /etc/rsyslog.d 只是空的,我已经删除了所有注释和行显然与问题无关):

:msg,startswith, " fetching user_deny" ~
:msg,startswith, " seen_db: user " ~
auth,authpriv.*                 /var/log/auth.log
*.*;auth,authpriv.none          -/var/log/syslog
daemon.*                        -/var/log/daemon.log
kern.*                          -/var/log/kern.log
lpr.*                           -/var/log/lpr.log
mail.*                          -/var/log/mail.log
user.*                          -/var/log/user.log

mail.info                       -/var/log/mail.info
mail.warn                       -/var/log/mail.warn
mail.err                        /var/log/mail.err

*.=debug;\
        auth,authpriv.none;\
        news.none;mail.none     -/var/log/debug
*.=info;*.=notice;*.=warn;\
        auth,authpriv.none;\
        cron,daemon.none;\
        mail,news.none          -/var/log/messages

*.emerg                         :omusrmsg:*

daemon.*;mail.*;\
        news.err;\
        *.=debug;*.=info;\
        *.=notice;*.=warn       |/dev/xconsole

据我阅读 man rsyslog.conf 的理解,该配置应该使 rsyslogdLOG_MAIL 写入优先级为 的消息>LOG_ERR/var/log/mail.err。不过,我对文件路径前面有 - 的行有些不信任。我不知道这意味着什么,因为我在手册中找不到任何提示。

那么到底出了什么问题呢?

最佳答案

我讨厌回答我自己的问题,但我想我在文档或 glibc 的源代码中发现了一个错误,我希望将它记录下来以供将来访问此问题的人使用。

来自 https://www.gnu.org/software/libc/manual/html_node/syslog_003b-vsyslog.html#syslog_003b-vsyslog (截至撰写本文时):

syslog submits the message with the facility and priority indicated by facility_priority. The macro LOG_MAKEPRI generates a facility/priority from a facility and a priority, as in the following example:

LOG_MAKEPRI(LOG_USER, LOG_WARNING)

现在看看 syslog.h 中的一些代码,因为它驻留在我的测试机器上(Debian wheezy,最新的,没有自定义补丁,不相关的部分被剥离):

/*
 * priorities/facilities are encoded into a single 32-bit quantity, where the
 * bottom 3 bits are the priority (0-7) and the top 28 bits are the facility
 * (0-big number).  Both the priorities and the facilities map roughly
 * one-to-one to strings in the syslogd(8) source code.  This mapping is
 * included in this file.
 *
 * priorities (these are ordered)
 */
#define LOG_EMERG   0   /* system is unusable */
#define LOG_ALERT   1   /* action must be taken immediately */
#define LOG_CRIT    2   /* critical conditions */
#define LOG_ERR     3   /* error conditions */
#define LOG_WARNING 4   /* warning conditions */
#define LOG_NOTICE  5   /* normal but significant condition */
#define LOG_INFO    6   /* informational */
#define LOG_DEBUG   7   /* debug-level messages */

#define LOG_MAKEPRI(fac, pri)   (((fac) << 3) | (pri))

/* facility codes */
#define LOG_KERN    (0<<3)  /* kernel messages */
#define LOG_USER    (1<<3)  /* random user-level messages */
#define LOG_MAIL    (2<<3)  /* mail system */
#define LOG_DAEMON  (3<<3)  /* system daemons */
#define LOG_AUTH    (4<<3)  /* security/authorization messages */
#define LOG_SYSLOG  (5<<3)  /* messages generated internally by syslogd */
#define LOG_LPR     (6<<3)  /* line printer subsystem */
#define LOG_NEWS    (7<<3)  /* network news subsystem */
#define LOG_UUCP    (8<<3)  /* UUCP subsystem */
#define LOG_CRON    (9<<3)  /* clock daemon */
#define LOG_AUTHPRIV    (10<<3) /* security/authorization messages (private) */
#define LOG_FTP     (11<<3) /* ftp daemon */

    /* other codes through 15 reserved for system use */
#define LOG_LOCAL0  (16<<3) /* reserved for local use */
#define LOG_LOCAL1  (17<<3) /* reserved for local use */
#define LOG_LOCAL2  (18<<3) /* reserved for local use */
#define LOG_LOCAL3  (19<<3) /* reserved for local use */
#define LOG_LOCAL4  (20<<3) /* reserved for local use */
#define LOG_LOCAL5  (21<<3) /* reserved for local use */
#define LOG_LOCAL6  (22<<3) /* reserved for local use */
#define LOG_LOCAL7  (23<<3) /* reserved for local use */

我们显然在这里遇到了多个问题。

  • 顶部的评论:如果我有 3 个底部位,那么我有 29 个顶部位(而不是 28 个)。但这是一个小问题。

  • 设施代码已定义为左移三位。使用宏 LOG_MAKEPRI(如上面链接的手册页所推荐的那样)显然会将它们第二次向左移动三位,这显然是错误的。

解决方案

解决方法很简单:不要使用那个宏;相反,只是 OR 设施代码和优先级代码。我已经试过了,它奏效了。根据 /etc/rsyslog.confrsyslogd 的配置,我的测试程序的错误消息现在已按预期记录。

我对 syslog.h 中那个非常明显的错误感到非常惊讶......

关于c - 如何使用 rsyslogd 登录到/var/log/mail.log?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49306646/

相关文章:

c# - Log4Net:如何获取记录器?

c - SPOJ : The day of the competitors

C将一个char数组拆分成不同的变量

c - dup(file_des) 是否等同于 fcntl(filedes, F_DUPFD, 0)?

linux - Linux 中 USB 设备的文件系统有任何更改时如何获得通知或如何递归使用 inotify

java - Log4j2异步记录器默认缓冲区大小

c - 通过流套接字发送图像

c++ - 如何使用模板正确定义函数

c - 定义自定义时间结构

c++ - 当我每秒调用它 40 次时,QListWidget::addItem() 会闪烁