journal和rsyslog的恩怨情仇

  

背景


        在复杂的嵌入式环境中,通常使用systemd管理服务,以及通过syslog向上层application提供日志存储功能。

        这里有如下问题:

        1.systemd自带journal日志管理。

        2.syslog流程是怎么样的。

        3.journal和rsyslog放一起会发生化学反应吗?两者如何分工协作?

环境


        本文案例基于linux开源学习项目:linux-ps / ls · GitCode

        该项目基于yocto搭建了一整套qemuarm64的环境,学习使用参考前期博文。

分析

syslog

syslog是什么

        man 一下:

        即是向系统log存储日志的一个接口。存在于glibc,供大家使用统一管理日志。

        那么他提供什么规则来撑起linux的日志?

        syslog的日志类别

        分别为如下实体定义了特定的日志输出类(misc\sys\syslog.h):

CODE facilitynames[] =
  {
    { "auth", LOG_AUTH },
    { "authpriv", LOG_AUTHPRIV },
    { "cron", LOG_CRON },
    { "daemon", LOG_DAEMON },
    { "ftp", LOG_FTP },
    { "kern", LOG_KERN },
    { "lpr", LOG_LPR },
    { "mail", LOG_MAIL },
    { "mark", INTERNAL_MARK },		/* INTERNAL */
    { "news", LOG_NEWS },
    { "security", LOG_AUTH },		/* DEPRECATED */
    { "syslog", LOG_SYSLOG },
    { "user", LOG_USER },
    { "uucp", LOG_UUCP },
    { "local0", LOG_LOCAL0 },
    { "local1", LOG_LOCAL1 },
    { "local2", LOG_LOCAL2 },
    { "local3", LOG_LOCAL3 },
    { "local4", LOG_LOCAL4 },
    { "local5", LOG_LOCAL5 },
    { "local6", LOG_LOCAL6 },
    { "local7", LOG_LOCAL7 },
    { NULL, -1 }
  };

        举几个例子:

        #define    LOG_CRON    (9<<3)    /* clock daemon */    为定时相关的日志,于是乎,在其他代码中,基本不会混乱使用,而在crond代码中,会使用该日志实体。 (其余类似)

        syslog实体等级

        当然,每个实体均存在不同等级。

CODE prioritynames[] =
  {
    { "alert", LOG_ALERT },
    { "crit", LOG_CRIT },
    { "debug", LOG_DEBUG },
    { "emerg", LOG_EMERG },
    { "err", LOG_ERR },
    { "error", LOG_ERR },		/* DEPRECATED */
    { "info", LOG_INFO },
    { "none", INTERNAL_NOPRI },		/* INTERNAL */
    { "notice", LOG_NOTICE },
    { "panic", LOG_EMERG },		/* DEPRECATED */
    { "warn", LOG_WARNING },		/* DEPRECATED */
    { "warning", LOG_WARNING },
    { NULL, -1 }
  };

        也就是说,syslog已经定义了很多日志实体和等级供开发者选择。

        syslog流程

        (misc\syslog.c), 实际很简单,就是添加日志前缀,向/dev/log 使用udp发送log日志,整理如下:

关键的几个地方:

        1.当openlog的时候,根据参数控制是否直接创建并连接socket。

        2.每次发送log,用户态将申请8k的buf使用,然后释放。

        3.线程之间存在锁。

        4.发送时,使用udp,MSG_NOSIGNAL,并没有使用MSG_DONTWAIT,即可能阻塞。

rsyslog是什么

        syslog仅仅是c库中转发日志的api,并没有做日志管理。而rsyslog才是日志管理模块。见:

        rsyslog的内容较多,这里给出参考资料,然后说明重要的点。

        rsyslog官网:Welcome to Rsyslog — Rsyslog documentation

        rsyslog的配置:

        rsyslog的main配置存在于/etc/rsyslog.conf,部分截图如下:

        配置规则参考:https://www.rsyslog.com/doc/configuration/index.html

        主要支持三种配置:

        1.basic format:基本方式previously known as the sysklogd format,

        举例:

                mail.info /var/log/mail.log

                mail.err @@server.example.net

        2.advanced format:reviously known as the RainerScript format,

        mail.err action(type="omfwd" protocol="tcp" queue.type="linkedList")

        3.obsolete legacy format:previously known simply as the legacy format

废弃,不在使用。

        basic format规则:

        整体规则分为:

       SELECTORS   ACTIONS

        SELECTORS   由两部分组成,a facility and a priority。

        对了,参考上述章节syslog实体和等级,等于[syslog实体].[等级]。

        比如:kern.notice    mail.info 等等。

        支持模糊匹配。

        ACTIONS: 

        就是描述log文件的行为,目前我们主要是定义文件位置。

        #mail.info -/log/mail.info

        就是将mail.info类日志存放到/log/mail.info

        -代表异步。

        好了,这里大家值得注意,/log/mail.info 这个是rsyslog存放实际日志的地方。

        journal

        问题来了,syslog这个跟journal有什么关系?

        先介绍下 journal,journal是systemd的日志管理方案。使用journalctl查看和管理systemd日志(适用于大多数现代Linux发行版)Sytemd日志由journalctl管理,journalctl本身支持落盘。

        参考资料:https://www.freedesktop.org/software/systemd/man/latest/journalctl.html# 

        示例如下:

       

        配置如下,配置说明见连接:

        

恩怨情仇

        那么问题来了,rsyslog管理日志,journal也管理日志,是独立的吗?

        在syslog和journal同时存在时,日志到底发生了什么?

        核心图:

                实际案例:


rsyslogd的线程。
:/userdata# ll /proc/1531/fd/3
lrwx------ 1 root root 64 Jan  1 13:46 /proc/1531/fd/3 -> socket:[20553]

unix  2      [ ]         DGRAM                    20553    /run/systemd/journal/syslog
unix  8      [ ]         DGRAM                    20539    /run/systemd/journal/dev-log


:/userdata# ll /proc/1535/fd/6
l-wx------ 1 root root 64 Jan  1 14:19 /proc/1535/fd/6 -> /userdata/LOG_LOCAL_LOG_DEBUG.log

strace -p 1533
recvmsg(3, {msg_name=NULL, msg_namelen=0, msg_iov=[{iov_base="<135>Jan  1 14:20:59 LOG_NDELAY:"..., iov_len=8096}], msg_iovlen=1, msg_control=[{cmsg_len=32, cmsg_level=SOL_SOCKET, cmsg_type=SO_TIMESTAMP_OLD, cmsg_data={tv_sec=946707659, tv_usec=833484}}, {cmsg_len=28, cmsg_level=SOL_SOCKET, cmsg_type=SCM_CREDENTIALS, cmsg_data={pid=1585, uid=0, gid=0}}], msg_controllen=64, msg_flags=0}, MSG_DONTWAIT) = 69


/userdata# ps -elfT | grep rsys
4 S root        1531    1531       1  0  80   0 - 73219 do_sel 13:46 ?        00:00:00 /usr/sbin/rsyslogd -n -iNONE
1 S root        1531    1532       1  0  80   0 - 73219 do_sel 13:46 ?        00:00:00 /usr/sbin/rsyslogd -n -iNONE
5 S root        1531    1533       1  0  80   0 - 73219 do_sys 13:46 ?        00:00:17 /usr/sbin/rsyslogd -n -iNONE  1533
1 S root        1531    1534       1  0  80   0 - 73219 do_sys 13:46 ?        00:00:00 /usr/sbin/rsyslogd -n -iNONE
5 S root        1531    1535       1  0  80   0 - 73219 futex_ 13:46 ?        00:00:11 /usr/sbin/rsyslogd -n -iNONE  写盘
0 S root        1691    1691    1233  0  80   0 -   752 pipe_r 14:20 pts/1    00:00:00 grep rsys

unix  8      [ ]         DGRAM                    20539    /run/systemd/journal/dev-log
journald
recvmsg(5, {msg_name=0xffffef35d170, msg_namelen=128 => 0, msg_iov=[{iov_base="<135>Jan  1 14:34:47 LOG_NDELAY:"..., iov_len=24575}], msg_iovlen=1, msg_control=[{cmsg_len=32, cmsg_level=SOL_SOCKET, cmsg_type=SO_TIMESTAMP_OLD, cmsg_data={tv_sec=946708487, tv_usec=242530}}, {cmsg_len=28, cmsg_level=SOL_SOCKET, cmsg_type=SCM_CREDENTIALS, cmsg_data={pid=1585, uid=0, gid=0}}], msg_controllen=64, msg_flags=MSG_CMSG_CLOEXEC}, MSG_DONTWAIT|MSG_CMSG_CLOEXEC) = 69
sendmsg(5, {msg_name={sa_family=AF_UNIX, sun_path="/run/systemd/journal/syslog"}, msg_namelen=29, msg_iov=[{iov_base="<135>Jan  1 14:34:47 LOG_NDELAY:"..., iov_len=69}], msg_iovlen=1, msg_control=[{cmsg_len=28, cmsg_level=SOL_SOCKET, cmsg_type=SCM_CREDENTIALS, cmsg_data={pid=1585, uid=0, gid=0}}], msg_controllen=28, msg_flags=0}, MSG_NOSIGNAL) = 69
faccessat(AT_FDCWD, "/run/systemd/journal/flushed", F_OK) = 0
mkdirat(AT_FDCWD, "/var/log/journal/e62c7874699a4022a151c537eb5f3613", 0755) = -1 ENOENT (No such file or directory)
/userdata# ls -l /proc/341/fd/5
lrwx------ 1 root root 64 Jan  1 08:00 /proc/341/fd/5 -> socket:[20539]

        从上图看,当journal和rsyslog同时存在的时候:

        1、/dev/log -> /run/systemd/journal/dev-log   /dev/log的实体为journal创建的socket:

        

        2.即使如此,syslog依旧无脑向/dev/log发送、

        

        3.rsyslog不会从/dev/log接收,然而从/run/systemd/journal/syslog接收消息。

        

unix  2      [ ]         DGRAM                    12376    /run/systemd/journal/syslog

        4./run/systemd/journal/syslog由jounal写入。

        5.rsyslog从/run/systemd/journal/syslog接收消息,然后罗盘。

       

        6.journal本身支持落盘。

总结:

        在同时存在journal和rsyslog的时候,syslog将先转给journal,然后由journal转给rsyslog,rsyslog分线程存储日志。

        因此是比较波折的过程。在配置rsyslog的时候,一定将不需要的调试日志剥离。

        为啥不直接用journal?

        因为他的日志不直接可读,需要使用journalctl解析、

有问题欢迎一起讨论。

        

  • 27
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值