加载中...
返回

syslog机制简述

断更了将近两个月?

五月下旬开始参加实习,工作颇为忙碌,单程一小时的通勤也磨灭了我回到宿舍之后继续学习和输出的热情;然而实习已近两月,所幸稍有所得,不做记录则恐愧对时光矣。

syslog工作流程简述

不管是什么应用,日志机制永是最重要的机制之一,从日志中,维护人员可以排查错误、发现攻击,从而有效地提高应用的可用性。

操作系统也是如此,本文将对Linux日志机制中的一个重要组成部分——syslog/rsyslog——进行一个简要的叙述。

大部分Linux发行版默认的日志守护进程为syslog(或较新版本的rsyslog),位于 /etc/syslog/etc/syslogd/etc/rsyslog.d ,默认配置文件为 /etc/syslog.confrsyslog.conf ,任何希望生成日志的程序都可以向syslog发送信息。

syslog应该对接收的信息进行某种处理。我们可以从直觉出发,考虑一下syslog收到一条信息后应该做哪些事情:首先,系统中有那么多的信息源,我们会考虑对这些信息源进行分类;之后,每个信息源给出的信息都具有不同的情境,正常运行产生的信息跟报错信息肯定不能一视同仁的,我们会考虑根据信息的严重性对这些信息进行分类;最后,符合筛选条件的信息就触发某种动作,比如把它写进某个日志文件里。

流程图是个好东西。我们假设系统中有若干类信息源,每类信息源产生不同等级的信息,那么syslog应该对这些信息进行分类分级处理,如下图所示:

当然,这一流程图只是为了较为直观地呈现syslog分类分级的机制,以使读者有个初步的印象,接下来,我们将从配置文件出发,介绍syslog(rsyslog)的日志记录细节。

过滤规则

如果你的系统是CentOS,可以打开 /etc/rsyslog.conf ,这是syslog的配置文件,Ubuntu下的配置文件位于 /etc/rsyslog.d/50-default.conf ;在这里,你可以看到不少类似下方的语句:

authpriv.* /var/log/secure

这是syslog日志记录的一条规则,我们将规则拆开来看,实际上只有三个部分:

第一个部分是facility(设备类型),第二个部分是priority(优先级/严重性),第三个部分是action(动作)。

你应该能够想到,这一条规则就描述了上文所说的对消息进行分类分级处理的过程!

仔细看看配置文件吧,每一条规则都是如此的简单而实用:

#### RULES ####

# Log all kernel messages to the console.
# Logging much else clutters up the screen.
#kern.*                                                 /dev/console

# Log anything (except mail) of level info or higher.
# Don't log private authentication messages!
*.info;mail.none;authpriv.none;cron.none                /var/log/messages

# The authpriv file has restricted access.
authpriv.*                                              /var/log/secure

# Log all the mail messages in one place.
mail.*                                                  -/var/log/maillog


# Log cron stuff
cron.*                                                  /var/log/cron

# Everybody gets emergency messages
*.emerg                                                 :omusrmsg:*

facility

规则的第一部分facility指的是消息源设备的类型。syslog体系中已经将Linux中的大部分进程进行了合理的分类,例如与内核消息相关的 kern 类型、与授权信息相关的 auth/authpriv 类型等等,官方为我们总结出了如下的表格:

priority和selector

将消息源设备进行分类之后,就需要看看这条消息对应的是什么级别,priority(或者叫severity)就用来表示消息的严重性。

facility + priority的形式能够唯一确定一条消息的种类,因此被称为 选择器(selector) 。正如我们所看到的规则那样,使用 facility.priority 的形式来指定一个选择器。其中,在不特别指定的情况下,选中的是 facility 设备类型所产生的 priority 级别及以上的消息,也就是说,一个 kern.info 选择器不仅能选中 kern 类型的 info 级别消息,还能选中 info 以上的所有级别。

例如 kernel 进程产生了一条严重性为 warning 的信息,那么这条信息就将被 kern.infokern.notice 等规则选中。

除了基本的选择器用法,rsyslog在syslog的基础上扩展了一些选择器的语法。例如使用符号 = 可以 严格选中 某一优先级的消息,使用符号 ! 可以选中 除了 某一优先级的所有消息,最常用的 * 号表示这一字段的 所有取值 ,字段 none 常常配合 * 号使用,表示不记录某些facility的消息。还有一些使用表达式构造的选择器,在此不加叙述(因为在Linux默认配置中本身就用得不多),读者可以阅读文末给出的参考资料[1]来进行扩展学习。

action

最后,是规则的最后一部分——动作(action)。这一部分的内容可以有较多的玩法,一般来说,我们使用两种操作:

  • action字段写上一个文件名。如默认配置文件中的多数规则,这表示将选择器选中的消息记录到目标文件上。
  • action字段形如 @<IP>:<端口> ,这表示将选择器选中的消息 转发 到目标服务器的目标端口上。一个 @ 号表示使用UDP协议发送(默认),两个 @ 号表示使用TCP协议发送。例如我们配置一条规则 *.* @@192.168.0.1:514 表示将所有类型的、所有级别的消息都转发到服务器 192.168.0.1514 端口。

至此,我们就了解了规则的含义,顺带地,你可以初步读懂Linux日志配置文件里的部分内容了。从这些规则出发,你能够对Linux系统下的一些日志文件有更深入的了解。我们再来看一下这些规则:

*.info;mail.none;authpriv.none;cron.none                /var/log/messages
# 这条规则表示将除了 mail、authpriv、cron 的类型之外的所有设备类型的消息记录到 /var/log/messages 文件中
# 因此,你可以在 /var/log/message 文件中找到大部分日志消息

authpriv.*                                              /var/log/secure
# 这条规则表示将 authpriv 类型的所有级别消息记录到 /var/log/secure 文件中
# 因此,你应该在 /var/log/secure 文件中查看与授权信息相关的日志(如sshd登录记录,sudo认证记录等)

mail.*                                                  -/var/log/maillog
cron.*                                                  /var/log/cron

可以看到,上面三条规则的facility是互补的,把这几个文件综合起来看,相当于使用了 *.* 的选择器(info 级别已经和 * 差不多了),也就是说,你基本可以在上面的四个文件中查看到Linux系统产生的所有消息。

模板Template

阅读至此,我们能够把任何需要的消息用我们希望的办法进行记录或转发,但仅仅采用默认的格式可能还远远不够。

正常情况下,一条Linux日志长成这样:

Jul  2 23:30:03 localhost su: pam_unix(su:session): session opened for user root by xr_g(uid=0)

这一条日志分为几个部分: [时间戳] [主机名] [进程名和进程ID] [消息体]

这可不是我瞎说的,因为rsyslog在记录日志的时候使用了默认的 模板

如果你使用过Django或者什么其他的后端编程框架,很可能已经了解了模板的概念;如果你没接触过模板,不妨简单地将其看作一种 格式 ,就像你写论文时候的格式要求那样,所有的消息都要按照这种格式进行记录。而与你写论文时相同,论文模板里总是会指定一些较为宽泛的 属性 ,比如开头要写上摘要和关键字,所有人的论文都是相同的结构,但摘要和关键字的具体内容就因人而异了。

日志的模板也正是如此,一条模板指定了日志的大致结构,就像上面提到的那样;而这一结构由一个一个的属性组成,日志守护进程需要根据这些属性往模板里填充数据,从而产生一条具体的日志。

模板的定义

模板的定义办法有新旧两种,我个人比较习惯旧式的模板定义办法:

# $template [模板名] [模板格式]
$template MyTmp,"%timestamp% %hostname% %syslogfacility-text% %syslogseverity-text% %msg%\n"

而新版的模板定义办法有若干个,例如:

template(name="tpl3" type="string"
         string="%TIMESTAMP:::date-rfc3339% %HOSTNAME% %syslogtag%%msg:::sp-if-no-1st-sp%%msg:::drop-last-lf%\n"
        )

模板的使用

定义好了自己的模板之后,可以直接将模板应用在action字段上,具体办法就是在action原本的内容后加一个分号 ; ,然后写上自己的模板名。

例如修改 /var/log/message 内容为我们自定义的格式:

# Step1 设置模板,使用模板
[root@localhost log]# cat /etc/rsyslog.conf 
···
$template MyTmp,"%timestamp% %hostname% %syslogfacility-text% %syslogseverity-text% %msg%\n"
···
*.info;mail.none;authpriv.none;cron.none                /var/log/messages;MyTmp  # 注意这里!!!!

# Step2 重启rsyslog服务
[root@localhost log]# systemctl restart rsyslog

# Step3 观察日志内容的变化
[root@localhost log]# tail /var/log/messages 
···
Jul  2 23:57:55 localhost daemon info Stopped System Logging Service.
Jul  2 23:57:55 localhost daemon info Starting System Logging Service...
···

rsyslog给出了一些模板中可用的属性,此处列出几个常用的属性,详细信息可以查看参考资料[2]。

属性 含义
%timestamp% 时间戳,格式为默认为 MMM dd HH:mm:ss
%syslogtag% 消息的标签,一般为 进程名[进程ID] 的形式,如 sshd[1234]
%msg% 原程序发送的消息内容,这一字段由原始进程自行定义,一般各不相同
%fromhost-ip% 一般用于远程接收日志的服务器上,获取日志发送方的IP
%syslogfacility-text% 以文字形式打印出facility
%syslogseverity-text% 以文字形式打印出severity
%hostname% 主机名

我们需要为自定义的模板命名,当然,不能与系统默认保留的一些模板重名,比如下面几个系统自带的模板:

template(name="RSYSLOG_TraditionalForwardFormat" type="string"
     string="<%PRI%>%TIMESTAMP% %HOSTNAME% %syslogtag:1:32%%msg:::sp-if-no-1st-sp%%msg%")
     
template(name="RSYSLOG_ForwardFormat" type="string"
     string="<%PRI%>%TIMESTAMP:::date-rfc3339% %HOSTNAME% %syslogtag:1:32%%msg:::sp-if-no-1st-sp%%msg%")

更多的内容可以阅读参考资料[3]。

注意上面给出的第一个系统模板 RSYSLOG_TraditionalForwardFormat ,这正是Linux系统中默认的日志格式,现在你明白前面我们对系统日志的格式解释是从何而来的了。

小结

在实际工作中,syslog还有一些其他的玩法(如配置远程转发,日志模板的进阶使用等),在此就不予介绍了,之后有时间再开一篇。

本文介绍了Linux日志机制的一个重要依赖——syslog/rsyslog,通过对日志配置文件、规则含义等的简要叙述,相信读者能够对Linux日志的机制有一个初步的理解,通过这些日志,你将能够揭开系统运行状态的面纱,更高效地排除错误,更快乐地生活。

参考资料

[1] Filter Conditions — rsyslog 8.18.0.master documentation

[2] RSyslog Documentation - properties - rsyslog

[3] RSyslog Documentation - templates - rsyslog

有朋自远方来,不亦说乎?
Built with Hugo
Theme Stack designed by Jimmy