文章

rsyslog配置详解

rsyslog配置详解

早期的syslog日志服务对应的是syslogd守护进程,而目前很多linux发行版本已经使用rsyslog服务替换了syslog服务预装在linux系统中了,相应的守护进程就变成了rsyslogd。

对于rsyslog的历史,可参考rsyslog官网:https://www.rsyslog.com/doc/master/index.html

一、rsyslog配置详解

配置文件格式

有3种格式的配置文件

  • basic 基础配置格式,兼容syslog.conf格式
  • advanced 以前叫RainerScript格式,在rsyslog v6开始使用
  • obsolete legacy 传统的格式,仅为确保旧有配置不会出错

需要用哪种格式

强烈建议不要使用传统格式,应在基础配置中使用使用basic格式,在其它情况下使用 advanced格式。

rsyslog.conf 文件

首先来看一下/etc/rsyslog.conf配置文件: (目前官网已经更新到了v8.x了,,低版本(v5)的一大缺点是很多rsyslog的新特性无法使用,其他的都还OK。)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
#rsyslog v3 config file

# if you experience problems, check
# https://www.rsyslog.com/troubleshoot for assistance

#### MODULES ####
#导入模块
$ModLoad imuxsock.so    # provides support for local system logging (e.g. via logger command)
$ModLoad imklog.so      # provides kernel logging support (previously done by rklogd)
#$ModLoad immark.so     # provides --MARK-- message capability

#使用UDP进行接收,端口是514
# Provides UDP syslog reception
$ModLoad imudp.so
$UDPServerRun 514

#使用TCP进行接收,端口是514
# Provides TCP syslog reception
#$ModLoad imtcp.so
#$InputTCPServerRun 514

#### GLOBAL DIRECTIVES ####
#使用默认的RSYSLOG_TraditionalFileFormat模板
# Use default timestamp format
$ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat
 
# File syncing capability is disabled by default. This feature is usually not required,
# not useful and an extreme performance hit
#$ActionFileEnableSync on
 
#### RULES ####
#RULES部分主要是对各种facility和level进行设置
#设置你想要接收的facility的何种level的日志消息
 
# 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                                                 *

# Save news errors of level crit and higher in a special file.
uucp,news.crit                                          /var/log/spooler

# Save boot messages also to boot.log
local7.*                                                /var/log/boot.log

#这一部分可以设置一些转发规则
# ### begin forwarding rule ###
# The statement between the begin ... end define a SINGLE forwarding
# rule. They belong together, do NOT split them. If you create multiple
# forwarding rules, duplicate the whole block!
# Remote Logging (we use TCP for reliable delivery)
#
# An on-disk queue is created for this action. If the remote host is
# down, messages are spooled to disk and sent when it is up again.
#$WorkDirectory /var/spppl/rsyslog # where to place spool files
#$ActionQueueFileName fwdRule1 # unique name prefix for spool files
#$ActionQueueMaxDiskSpace 1g   # 1gb space limit (use as much as possible)
#$ActionQueueSaveOnShutdown on # save messages to disk on shutdown
#$ActionQueueType LinkedList   # run asynchronously
#$ActionResumeRetryCount -1    # infinite retries if host is down
# remote host is: name/ip:port, e.g. 192.168.0.1:514, port optional
#*.* @@remote-host:514
# ### end of the forwarding rule ###

rsyslog.conf 组成

其中,配置文件主要分为以下四块内容:

  • Modules
  • Global Directives
  • Rules
  • Forwarding Rule

Modules

Modules 加载一些模块,语法是$ModLoad 模块名(旧式语法,新旧语法是兼容的,新式语法可以参考下方的官网链接)。 此处还可以设置syslog服务是以UDP还是TCP进行接收,相应的去掉前面的注释即可,例如上面的配置文件中指定了514端口,以UDP进行接收日志消息。

Global Directives

全局指令的设置。

Rules

Rules 规则,该项设置主要是围绕着前面介绍的facility、level来进行配置的,首先,我们知道产生的日志记录信息的源头会有很多,比如有kernel内核、user用户、mail邮件、daemon守护进程、authorization安全/授权、syslog系统日志、line-priter打印子系统、news新闻组件子系统、UUCP子系统、cron计划任务进程、ftp守护进程等。 而每个消息源头产生的消息也都有轻重缓急之分,有的消息很重要必须记录,有的消息可能并不重要不需要记录。因此,对各消息源产生的何种级别的消息进行记录,以及记录到哪里就有了如下的配置格式:

1
2
3
facility.level    destionation    #将facility产生的level级别以及高于level级别的消息记录到指定文件destionation中
facility.=level   destionation    #将facility产生的level级别的消息记录到指定文件destionation中
facility.!Level   destionation     #将facility产生的非level级别的消息记录到指定文件destionation中

Forwarding Rule

设置转发规则,如上述配置文件倒数第二行:

1
2
#将所有facility产生的所有level级别的日志消息以TCP形式传输给远程主机remote-host的514端口上。
.* @@remote-host:514       

注:若用UDP传输,则将 @@ 改为 @ 即可。

等价于

1
.* action(type="omfwd" Target="remote-host" Protocol="tcp" Port=514"

rsyslogd的配置文件提供了很多丰富的配置功能,比如上述配置文件的第50行:

1
-/var/log/maillog

文件路径的前缀 - 表示你可以避免日志的同步写入,某些时候对提升系统的性能有很大的帮助。

配置文件其他相关内容,详情可见:https://www.rsyslog.com/doc/v8-stable/configuration/index.html


二、 rsyslog模板

rsyslog template(模板)是rsyslog的一个重要特性。通过模板,用户可以指定他们自己想要的日志输出格式以及用于创建动态的文件名等。比如前一篇文章中一个示例的输出结果:

1
Feb 8 01:06:10 localhost syslog_test[4877]: The pid of syslog_test=4877

我们在syslog()函数中只是指定了日志消息:The pid of syslog_test=4877,但是输出结果并不如此,它还输出了Feb 8 01:06:10 localhost等信息。为什么呢? 因为,rsyslog它使用了默认的模板。 但是,模板不仅仅只能用来个性化定制输出的内容,接着往下看。

模板的定义有两种语法,一种是新式语法template();一种是旧式语法$template。

1. template() 语句 (新式语法)

不管是新式还是旧式语法,模板的定义都是在配置文件中完成的。而每一次rsyslog服务启动时都会从配置文件里加载内容,也就是说,每次修改配置文件之后都要重启一下rsyslog才能使之生效:

模板的新式语法定义的格式如下所示:template(parameters)

parameters是参数部分,其中name、type分别用来指定模板的名字、类型等。模板的类型主要有四种:list, subtree, string, plugin。

(1)list 类型

list 类型的模板是由一系列constantproperty语句组成,定义在一对花括号中,有点类似于函数定义。这种类型的模板主要用于结构感知(structure-aware)的输出,比如ommongodb。尽管如此,对于基于文本(text-based)结构的信息也可以很好的工作。有如下示例的list类型模板:

1
2
3
4
5
6
7
template(name="tpl1" type="list") {
    constant(value="Syslog MSG is: '")
    property(name="msg")
    constant(value="', ")
    property(name="timereported" dateFormat="rfc3339" caseConversion="lower")
    constant(value="\n")
}

定义了一个名为tpl1、类型为list的模板。花括号中是一系列的constant语句和property语句组成的。

1)constant 语句

常量语句中的value参数指定待输出的常量;除此之外还有一个outname参数,当你想要将value指定的常量内容输出到mongodb数据库中时就需要指定outname参数了:

1
2
3
4
template(name="outfmt" type="list") {
    property(name="$!usr!msgnum")
    constant(value="\n" outname="IWantThisInMyDB")
}

2)property 语句

property语句可以用来访问所有的属性,获取相应的属性值。该语句支持的参数众多,如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
name:             指定访问的属性名;
outname:          指定输出字段名(用于结构化输出);
dateformat:       指定日期格式(用于日期相关的属性);
date.inUTC:       日期以UTC形式显示,8.18.0版本之后支持的功能;
caseconversion:   文本转换,可选值是lower、upper;
controlcharacters:指定如果处理控制符。可选值是escape(跳过)、space(用一个空格代替)、drop(从字符串中删除);
securepath:       用于创建适合在动态文件模板中使用的路径名;
format:           指定字段格式,可选的值有csv, json, jsonf, jsonr, jsonfr;
position.from:    从这个位置获取子字符串(1是第一个position);
position.to:      获取到这个位置的子字符串;
position.relativeToEnd:  开始和结束的position是相对于字符串的尾部的,而正常情况是相对于字符串的首部的(rsyslog v7.3.10开始支持的功能)
fixedwidth:      使用空格填充原字符串到指定位置(v8.13.0支持的功能)
field.number:    获取该字段的匹配
field.delimiter: 字段提取的分隔符个数
regex.expression:使用正则表达式
regex.type:      正则表达式的类型,扩展正则表达式ERE或基础正则表达式BRE
regex.nomatchmode:  正则表达式未匹配到的处理方式
regex.match:     使用匹配
regex.submatch:  使用子匹配
droplastlf:      如果尾部有换行符,则丢弃该换行符。LF—line feed
mandatory:        表示该字段是强制的。如果设置为on,那么,即使该字段为空,它也将传递给结构化输出的数据中;如果是off(默认值)的话,当该字段为空时,将不会传递给结构化输出的数据中。这对于支持动态模式(如ommongodb)的输出尤其有用。

property语句支持的参数众多,其中大部分参数很少会用到,了解即可。详情可见参考资料。

参考资料: https://www.rsyslog.com/doc/v8-stable/configuration/templates.html

(2)subtree 类型

subtree类型的模板是从rsyslog 7.1.4才加进去的特性。 https://www.rsyslog.com/doc/v8-stable/configuration/templates.html

例如template(name=”tpl1” type=”subtree” subtree=” ! ” )包括了所有CEE数据,而 template(name=”tpl2”type=”subtree”subtree= ” !”)包括了所有CEE数据,而template(name=”tpl2” type=”subtree” subtree=” !”)包括了所有CEE数据,而template(name=”tpl2”type=”subtree”subtree=”!usr!tpl2”)仅包括从$!usr!tpl2开始的子树。当使用此类型模板时,所有数据必须用set和unset脚本语句预先构造好。要了解详情,参见官网,这里只举个例子:

1
2
3
set $!usr!tpl2!msg = $msg;
set $!usr!tpl2!dataflow = field($msg, 58, 2);
template(name="tpl2" type="subtree" subtree="$!usr!tpl2")

(3)string 类型

string 类型的模板非常类似于旧式语法中的模板定义语句,该模板中有一个参数``string`指定待输出的内容,其中包含了常量文本和变量(替换成相应的文本)。string类型的模板是指定文本内容的一种很好的方法,特别是在没有必要对变量进行复杂操作的情况下。如下所示,一个简单的stirng类型模板:

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

定义了一个名为tpl3,类型为string的模板,其中string参数指定了待输出的字符串内容。2个百分号%之间的变量由rsyslog 属性替换器(rsyslog property replacer)进行解释替换为相应文本。 并且,百分号 % 之外的一切都是常量;% 百分号内的变量后面有三个冒号:::,其作用将在下一篇文章中介绍。

1
2
3
4
5
template(
    name="DynaFileTemplate" 
    type="string"
    string="/var/log/network/%HOSTNAME%-%FROMHOST-IP%.log"
)

定义了名为DynaFileTemplate,类型为string的模板,string参数指定了要保存的文件路径和文件名(动态文件)。

(4)plugin 类型

plugin类型的模板是由插件(称作strgen或string generator)产生的,它的格式是固定的。虽然固定的格式带来了不灵活性,但是它能提供更好的性能。不同的插件提供不同的格式,可以参考具体插件的文档。

plugin类型的模板必须指定参数plugin,并且插件必须在使用之前加载,有如下示例:

1
template(name="tpl4" type="plugin" plugin="mystrgen")

(5)options 模板选项

前面介绍了模板的四种类型,对每一种类型的模板,还有一个可选的部分 —— options

options也是模板的一部分,但是这一部分是可选的。需要注意的是:模板选项不同于属性选项,属性选项是由属性替换器使用的,并且只能应用于单个属性上,而此处介绍的是模板的选项。模板选项目前定义的有:

1
2
3
4
option.sql:         格式化适合于MySQL格式的sql语句的字符串
option.stdsql:      格式化适合于发送到符合标准的SQL服务器的SQL语句的字符串
option.json:        格式化适用于json语句的字符串
option.casesensitive:   将属性名引用视为区分大小写

更多详细内容请见https://www.rsyslog.com/doc/v8-stable/configuration/templates.html

2. 示例

(1)用于写入文件的list类型模板,可以用来指定输出格式:

1
2
3
4
5
6
7
8
9
10
template(name="FileFormat" type="list") {
    property(name="timestamp" dateFormat="rfc3339")
    constant(value=" ")
    property(name="hostname")
    constant(value=" ")
    property(name="syslogtag")
    property(name="msg" spifno1stsp="on" )
    property(name="msg" droplastlf="on" )
    constant(value="\n")
}

等价于如下string类型的模板:

1
2
3
4
5
template(
    name="FileFormat" 
    type="string"
	string="%TIMESTAMP% %HOSTNAME% %syslogtag%%msg:::sp-if-no-1st-sp%%msg:::drop-last-lf%\n"
)

==注意:模板字符串本身必须在一行上。==

(2)转发到远程主机的list类型模板(RFC3164模式):

1
2
3
4
5
6
7
8
9
10
11
12
template(name="ForwardFormat" type="list") {
    constant(value="<")
    property(name="pri")
    constant(value=">")
    property(name="timestamp" dateFormat="rfc3339")
    constant(value=" ")
    property(name="hostname")
    constant(value=" ")
    property(name="syslogtag" position.from="1" position.to="32")
    property(name="msg" spifno1stsp="on" )
    property(name="msg")
}

等价于如下的string类型模板:

1
2
3
4
5
template(
    name="forwardFormat" 
    type="string"
  	string="<%PRI%>%TIMESTAMP:::date-rfc3339% %HOSTNAME% %syslogtag:1:32%%msg:::sp-if-no-1st-sp%%msg%"
)

(3)用于写入MySQL数据库的标准模板:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
template(name="StdSQLformat" type="list" option.sql="on") {
    constant(value="insert into SystemEvents (Message, Facility, FromHost, Priority, DeviceReportedTime, ReceivedAt, InfoUnitID, SysLogTag)")
    constant(value=" values ('")
    property(name="msg")
    constant(value="', ")
    property(name="syslogfacility")
    constant(value=", '")
    property(name="hostname")
    constant(value="', ")
    property(name="syslogpriority")
    constant(value=", '")
    property(name="timereported" dateFormat="mysql")
    constant(value="', '")
    property(name="timegenerated" dateFormat="mysql")
    constant(value="', ")
    property(name="iut")
    constant(value=", '")
    property(name="syslogtag")
    constant(value="')")
}

其中,模板的 parameter 除了name、type外,还指定了options部分。

等价于如下string类型模板:

1
2
3
4
5
template(
    name="stdSQLformat" 
    type="string" option.sql="on"
    string="insert into SystemEvents (Message, Facility, FromHost, Priority, DeviceReportedTime, ReceivedAt, InfoUnitID, SysLogTag) values ('%msg%', %syslogfacility%, '%HOSTNAME%', %syslogpriority%, '%timereported:::date-mysql%', '%timegenerated:::date-mysql%', %iut%, '%syslogtag%'"
)

注意:模板字符串本身必须在一行上。

还想提及的一点是,对于options.sql选项,老式语法的模板选项部分不同于这种写法,后面会介绍,记得留意一下。

(4)动态创建文件名

模板可用于生成动态文件名。比如,将syslog消息按照不同的主机进行分别记录,可以这样定义模板:

1
2
3
4
5
template(
    name="DynFile" 
    type="string" 
    string="/var/log/system-%HOSTNAME%.log"
)

等价于旧式语法写法(旧式语法稍后就介绍):

1
$template DynFile,"/var/log/system-%HOSTNAME%.log"

3. $template 语句(旧式语法)

对于rsyslog v6之前的版本,那么你的新式语法是不会得到rsyslog配置文件支持的。所以,如果你是v6之前的版本,应该使用老式的语法来定义模板。(其实,不管新式写法还是老式写法,二者都是神似的)

旧式的模板提供了字符串和插件类型的模板,虽然v6之前的版本必须使用旧式写法,但是旧式写法在v6之后的版本仍然是可以很好的兼容的。旧式模板定义的语法格式如下: $template name,param[,options]

其中,name指定模板名;param指定模板内容;,options指定模板选项,是可选的。

(1)string

旧式string类型模板的参数与新式语法中string类型模板中指定的参数一样,例如:

1
$template strtpl,"PRI: %pri%, MSG: %msg%\n"

==注意:list类型的模板在旧版本中不支持,因此你需要使用复杂的属性替换结构来做复杂的事情。==

(2)plugin

相当于前面介绍的插件类型模板,参数是插件名称,前面有一个等号,例如:

1
$template plugintpl,=myplugin

4. 示例(旧式string类型模板)

1
2
3
4
5
$template FileFormat,"%TIMESTAMP:::date-rfc3339% %HOSTNAME% %syslogtag%%msg:::sp-if-no-1st-sp%%msg:::drop-last-lf%\n"
$template TraditionalFileFormat,"%TIMESTAMP% %HOSTNAME% %syslogtag%%msg:::sp-if-no-1st-sp%%msg:::drop-last-lf%\n"
$template ForwardFormat,"<%PRI%>%TIMESTAMP:::date-rfc3339% %HOSTNAME% %syslogtag:1:32%%msg:::sp-if-no-1st-sp%%msg%"
$template TraditionalForwardFormat,"<%PRI%>%TIMESTAMP% %HOSTNAME% %syslogtag:1:32%%msg:::sp-if-no-1st-sp%%msg%"
$template StdSQLFormat,"insert into SystemEvents (Message, Facility, FromHost, Priority, DeviceReportedTime, ReceivedAt, InfoUnitID, SysLogTag) values ('%msg%', %syslogfacility%, '%HOSTNAME%', %syslogpriority%, '%timereported:::date-mysql%', '%timegenerated:::date-mysql%', %iut%, '%syslogtag%')",SQL

其中,最后一个模板也是向数据库中输出消息,“SQL”是模板选项,不同于新式语法。

5. 默认模板 (内建)

rsyslog保留了一些自用的默认模板名称,它们都是以“RSYSLOG_”开头的,有如下默认模板:

1
2
3
4
5
6
7
8
9
10
11
RSYSLOG_TraditionalFileFormat:    “旧式”默认日志文件格式,具有低精度的时间戳;
RSYSLOG_FileFormat:               类似于RSYSLOG_TraditionalFileFormat的现代日志文件格式,具有高精度的时间戳和时区信息;
RSYSLOG_TraditionalForwardFormat: 低精度时间戳的传统转发格式。如果您将消息发送给其他syslogd或者版本低于v3.12.5的rsyslogd,那么久使用这个吧。
RSYSLOG_SysklogdFileFormat:       sysklogd兼容的日志文件格式。
RSYSLOG_ForwardFormat:            一种新的具有高精度的转发格式。非常类似于传统的那个,但具有高精度的时间戳和时区信息,如果您将消息发送给rsyslog v3.12.5或更高版本时,推荐使用这个。
RSYSLOG_SyslogProtocol23Format:   IETF指定的格式。
RSYSLOG_DebugFormat:              用于解决性能问题的一种特殊格式。这种格式应该写入日志文件,不要用于生产或远程转发。
RSYSLOG_WallFmt:                   包含有关主机的信息和消息生成的时间,最后包含 syslogtag 和消息本身。
RSYSLOG_StdDBFmt:                  生成带有消息属性的插入命令到 mysql 数据库的 SystemEvents 表中。
RSYSLOG_StdPgSQLFmt:               生成带有消息属性的插入命令到 pgsql 数据库的 SystemEvents 表中。
RSYSLOG_StdJSONFmt:                生成包含消息属性的 JSON 结构

(1) RSYSLOG_TraditionalFileFormat

具有低精度时间戳的“旧式”默认日志文件格式。(RFC 3164 )

1
2
3
4
5
template(
    name="RSYSLOG_TraditionalFileFormat" 
    type="string"
    string="%TIMESTAMP% %HOSTNAME% %syslogtag%%msg:::sp-if-no-1st-sp%%msg:::drop-last-lf%\n"
)

(2) RSYSLOG_FileFormat

类似于 TraditionalFileFormat 的现代风格日志文件格式,都具有高精度时间戳和时区信息。

1
2
3
4
5
6
7
8
9
10
template(name="RSYSLOG_FileFormat" type="list") {
     property(name="timereported" dateFormat="rfc3339")
     constant(value=" ")
     property(name="hostname")
     constant(value=" ")
     property(name="syslogtag")
     property(name="msg" spifno1stsp="on")
     property(name="msg" droplastlf="on")
     constant(value="\n")
}

(3) SYSLOG_TraditionalForwardFormat

具有低精度时间戳的传统转发格式 (RFC 3164 )。如果您将消息发送到版本 3.12.5 以下的其他 syslogd 或 rsyslogd,则最有用。

1
2
3
4
5
template(
    name="RSYSLOG_TraditionalForwardFormat" 
    type="string"
    string="<%PRI%>%TIMESTAMP% %HOSTNAME% %syslogtag:1:32%%msg:::sp-if-no-1st-sp%%msg%"
)

(4) RSYSLOG_ForwardFormat

一种新的高精度转发格式,与传统格式非常相似,但具有高精度时间戳和时区信息。建议在向 rsyslog 3.12.5 或更高版本发送消息时使用。

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

(5) RSYSLOG_SyslogProtocol23Format

IETF 的互联网草案 ietf-syslog-protocol-23 中指定的格式,非常接近实际的系统日志标准 RFC5424(我们无法更新此模板,因为当 RFC5424 最终获得批准时,事情已经在生产中相当长一段时间了)。此格式包括多项改进。您可以将此格式与所有相对较新版本的 rsyslog 或 syslogd 一起使用。

1
2
3
4
5
template(
    name="RSYSLOG_SyslogProtocol23Format" 
    type="string"
    string="<%PRI%>1 %TIMESTAMP:::date-rfc3339% %HOSTNAME% %APP-NAME% %PROCID% %MSGID% %STRUCTURED-DATA% %msg%\n"
)

三、property replacer 属性替换器

Rsyslog 中的数据项被称为property(属性),有消息属性、系统属性等。每当你要访问数据项时,都需要访问相应的属性。属性主要应用在模板和条件语句中,并且是大小写不敏感的(在3.17.0版本之前是大小写敏感的)。

1. Message Properties(消息属性)

消息属性是由rsyslog解释器从原始的消息中提取出来的,所有的消息属性都以字母开头,主要有如下消息属性:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
msg                  syslog协议的message部分
rawmsg               原始message,不转义的日志内容。转义是默认开启的(EscapecontrolCharactersOnReceive)     
rawmsg-after-pri     与rawmsg几乎相同,但删除了syslog PRI。如果不存在 PRI,则 rawmsg-after-pri 与 rawmsg 相同
hostname             message的主机名
source               hostname的别名
fromhost
fromhost-ip
syslogtag            message的TAG, 大致形如 programed[14321] 。
programname          产生message的进程名,tag的一部分,就是上面的programed那个位置
pri                  pri的值, 以前导"<"开头,后跟一个数字,然后是">", 尖括号内包含的数字称为优先级值Priority value (PRIVAL),代表设施和严重性
pri-text             pri值的文字表示,例如 <133> --> “local0.err”
iut
syslogfacility       facility的值
syslogfacility-text  facility值的文字表示
syslogseverity       severity的值
syslogseverity-text  severity值的文字表示
syslogpriority       syslogseverity别名       
syslogpriority-text  syslogseverity-test别名
timegenerated        消息被接收时的时间戳。始终保持高精度时间戳
timereported         发送设备报告的时间。值来自日志标头字段,精度取决于发送设备。当且仅当收到的日志time标头无法正确解析时,“timereported”才会填充与“timegenerate”相同的值。
timestamp            timereporterd的别名
protocol-version
structured-data      IETF 草案 Draft-ietf-syslog-protocol 中 STRUCTURED-DATA 字段的内容
app-name
procid
msgid                MSGID 应标识消息的类型。例如,防火墙可能对传入 TCP 流量使用 MSGID“TCPIN”,对传出 TCP 流量使用 MSGID“TCPOUT”。具有相同MSGID的消息应该反映相同语义的事件。
inputname

详见:https://www.rsyslog.com/doc/v8-stable/configuration/properties.html

PRI 部分必须具有三个、四个或五个字符,并且将用尖括号作为第一个和最后一个字符进行绑定。 PRI 部分以前导“<”(“小于”字符,%d60)开头,后跟一个数字,然后是“”>”(“大于”)字符,%d62)。这些尖括号内包含的数字称为优先级值 (PRIVAL),代表设施和严重性。 优先级值由 1、2 或 3 个十进制整数 (ABNF DIGITS) 组成,使用 %d48(代表“0”)到 %d57(代表“9”)的值。

设施和严重性值并不规范,但经常使用。下表中对它们的描述仅供参考。

Facility(设施)值必须在 0 到 23 内:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
   Code值          Facility(设施)
-------------------------------------
     0             kernel messages          内核消息
     1             user-level messages      用户级消息
     2             mail system              邮件系统
     3             system daemons           系统守护进程
     4             security/authorization messages  安全/授权消息
     5             messages generated internally by syslogd     由 syslogd 内部生成的消息
     6             line printer subsystem
     7             network news subsystem
     8             UUCP subsystem
     9             clock daemon
    10             security/authorization messages  安全/授权消息
    11             FTP daemon
    12             NTP subsystem
    13             log audit                        日志审计
    14             log alert                        日志警报
    15             clock daemon (note 2)
    16             local use 0  (local0)
    17             local use 1  (local1)
    18             local use 2  (local2)
    19             local use 3  (local3)
    20             local use 4  (local4)
    21             local use 5  (local5)
    22             local use 6  (local6)
    23             local use 7  (local7)

每条消息的优先级还有一个十进制 Severity 指示符。下表描述了这些及其数值。 Severity(严重性)在 0 到 7 的范围内(包括 0 和 7)

“<”后面唯一出现“0”值的情况是“优先级”值“0”。否则,不得使用前导“0”。

1
2
3
4
5
6
7
8
9
10
    Code值         Severity(严重性)
-----------------------------------------------
       0       Emergency: system is unusable              紧急:系统无法使用
       1       Alert: action must be taken immediately    警报:必须立即采取行动
       2       Critical: critical conditions              严重:严重情况
       3       Error: error conditions                    错误:错误情况
       4       Warning: warning conditions                警告:警告情况
       5       Notice: normal but significant condition   注意:正常但重要的情况
       6       Informational: informational messages      信息:信息性消息
       7       Debug: debug-level messages                调试:调试级别消息

2. System Properties(系统属性)

系统属性是由rsyslog核心引擎提供的,不同于消息属性,系统属性都是以$开头的。系统属性主要有:

1
2
3
4
5
6
7
8
9
10
$now                  当前系统时间,YYYY-MM-DD (2020-07-08)
$year                 当前年份, YYYY (2020)
$month                当前月份, MM (07)
$day                  当前月份的day , DD (08)
$hour                 当前小时(24小时机制),两位数(16)
$hhour                半小时机值,就是0-29分钟显示0,30-59分钟显示1。
$qhour                一刻钟机值,通过0-3显示,每15分钟一截。
$minute               当前分钟数,两位数(57)
$bom
$myhostname

详见:https://www.rsyslog.com/doc/v8-stable/configuration/properties.html

3. Property Replacer(属性替换器)

属性替换器是字符串类型模板的核心组件,一条syslog消息包含了许多已经定义了的属性。通过属性替换器,每个属性都可以被访问及修改,使用属性替换器,你可以轻松的使用属性值的一部分数据或修改后的数据。比如,你可以将属性值对应的所有字符改变为小写字母。

(1)访问属性

rsyslog的消息属性是在模板中使用的,你可以通过两个%来访问它们,或者使用属性替换器来修改它们。语法如下:

1
%property:fromChar:toChar:options%

1)字符位置

fromChartoChar 是用来创建子串的。偏移是从1开始计算的,所以如果你想要获取msg属性值中的前两个字符,你可以这样使用:

1
%msg:1:2%

又如果你不想指定开始和结束位置,但是想要指定选项,比如将 msg 转换为小写,那么你应该连续使用三个冒号:::

1
%msg:::lowercase%

又如果你想要从字符串中的某个位置开始提取到字符串尾部的子串,你可以使用$符号,那么你应该这样使用:

1
%msg:10:$%

2)正则表达式

此外,属性替换器还支持正则表达式。一般方法是:使用R取代fromChar,告诉替换器使用正则表达式而不是基于位置的方法来提取子串;正则表达式部分放在toChar的位置,并且以--end结束。有如下示例:

1
%msg:R:.*Sev:.\(.*\)\[.*--end%

并且,在R的后面还可以指定一些参数,用逗号分隔,如下所示:

其中,regexp-type 指定正则表达式的类型:BRE(默认值)或ERE;

详见:https://www.rsyslog.com/doc/v8-stable/configuration/property_replacer.html

3)分隔符

不仅如此,提取子串还可以基于“字段”来进行。若这样做的话,你需要使用F取代fromChar,用来指定分隔符,默认的分隔符是TAB(us-asscii对应的值是9)。你也可以自己指定分隔符,比如使用逗号,(asscii码是44)作为分隔符,在fromChar中相应的修改为F,44。如果你的syslog数据是由分隔符分隔的,那么这种方法要比正则表达式提取子串快的多。

字段号是从1开始的,即第一块被分隔下来的子串代号为1。字段号要被放在toChar中。比如,提取3号字段的内容(默认以TAB分隔):

1
%msg:F:3%

如果以分号:分隔的话:

1
%msg:F,59:3%

遗憾的是,对于获取到的分隔字段,不能再进一步的提取子串。为了解决这个问题,rsyslog v6.3.9版本之后,可以为分隔字段指定开始fromPos和结束toPos位置了。然而,语法相当难看,但是它是为了将这个功能集成到已经存在的语法系统中的唯一方法了。比如,我们想要从第3个字段中提取位置5到9的子串,你应该这样写:

1
%msg:F,59,5:3,9%

其他未介绍到的内容详见:https://www.rsyslog.com/doc/v8-stable/configuration/property_replacer.html

(2)Property Options(属性选项)

属性选项是大小写敏感的,目前有如下选项:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
uppercase        将属性值转换为大写
lowercase        转换为小写
fixed-width      改变toChar的行为,以便它在原字符串更短的情况下,将原字符串填充到toChar的值,rsyslog v8.13.0才提供的功能
json             对值进行编码,以便它可以在JSON字段中使用。这意味着有几个字符要被转义,例如LF将被\n取代。
Jsonf[:outname]  这意味着该属性应该被表示为一个JSON字段。(rsyslog v6.3.9版本之后)
csv              按照4180中指定的CSV格式格式化结果字段。比如:$template csvline,"%syslogtag:::csv%,%msg:::csv%" 该特性是在rsyslog v4.1.6版本引入的。
drop-last-lf     消息中的最后一个LF(换行,如果有的话)被删除。
date-utc         在输出之前将数据转换为UTC日期格式(rsyslog v8.18.0开始支持)
date-mysql       格式化为mysql日期格式 , YYYY-MM-DD HH:MM:SS
date-rfc3164     格式化为RFC 3164的日期格式
date-rfc3339
date-unixtimestamp  格式化为 unix 时间戳(自纪元以来的秒数)
date-year        仅时间戳的`年份`部分(4 位数字)
date-month       仅时间戳的`月份`部分(2 位数字)
date-day         仅时间戳的`day`部分(2 位数字)
date-hour        仅时间戳的`小时`部分(2 位数字,24 小时制)
date-minute      仅时间戳的`分钟`部分(2 位数字)
date-second      仅时间戳的`秒`部分 (2 位数字)
date-subseconds  仅时间戳的subseconds(对于低精度,始终为 0 timestamp)
……
sp-if-no-1st-sp  这个选项看起来很可怕,用户不应该使用。这个选项是解决RFC3164中某个问题的一种方法。了解一下即可。
secpath-drop     在字段内放置斜杠(例如,“a/b”变为“ab”)。适用于 安全路径名生成(使用 Dynafile)
secpath-replace  将字段内的斜杠替换为下划线。(例如,“a/b” 变为 “a_b”)。对于安全路径名生成(使用 dynafiles)很有用。

详情可见:https://www.rsyslog.com/doc/v8-stable/configuration/property_replacer.html

4. 示例

创建一个名为cky_format的模板,其中 TIMESTAMP:8:15 表示timestamp属性值切片第八位到第十五位。

1
2
3
# 旧样式语法
$template cky_format, "%$NOW% %TIMESTAMP:8:15% %hostname% %syslogseverity-text% %syslogtag% %msg%\n"
$ActionFileDefaultTemplate cky_format

等价于

1
2
3
4
5
6
7
8
9
10
11
12
# 新样式语法
template(
    name="cky_format" 
    type="string" 
    string=""%$NOW% %TIMESTAMP:8:15% %hostname% %syslogseverity-text% %syslogtag% %msg%\n""
)
ruleset(name="rule1") {
    action(
        type=="omfile" 
        Template="cky_format"
    )
}

日志格式效果样例:

1
2
3
# NOW | timestamp:8:15| hostname| syslogseverity-text | syslogtag | msg
2020-07-09 09:59:54 mycomputer    info    systemd:  Started System Logging Service.
#    时间戳         | 	 主机名   | 日志等级 | 服务进程 |   日志内容

至此,rsyslog的主要特性已经介绍完了。对于其他为涉及的特性,可参见rsyslog的官方文档。后面有空的话,将会记录一些rsyslog消息日志入库的实践内容。


五、rsyslog日志入库实例分析

Rsyslog日志服务用来记录各种日志信息,默认情况下,rsyslog服务记录本地的日志信息至指定的文件内。此外,通过修改配置文件,rsyslog还可以将本地或远程的日志信息存储到指定的数据库中。

示例 1- omfile

使用 omfile 模块可以将收集的日志数据写入到本地文件中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# 定义一个“动态创建文件名”的模板
template(
    name="DynaFileTemplate" 
    type="string"
    string="/var/log/network/%HOSTNAME%-%FROMHOST-IP%.log"
)

# 定义消息格式模板
template(
     name="tpl1" 
    type="string"
    string="<%pri%> %TIMESTAMP% %HOSTNAME% %syslogtag%%msg:::sp-if-no-1st-sp%%msg:::drop-last-lf%\n"
)

# 设置一个规则集 ruleset ,引用上面定义的模板
ruleset(name="remote-5141"){
    action(
        type="omfile" 
        dynafile="DynaFileTemplate" 
        Template="tpl1"
     )
}

# 加载输入模块imtcp imdup
input(type="imtcp" port="5141" ruleset="remote-5141")
input(type="imudp" port="5141" ruleset="remote-5141")

示例 2 - omfwd

使用 omfwd 模块可以将收集的日志数据写入到本地文件中:

1
2
3
4
5
6
7
8
9
10
11
ruleset(name="remote-5141"){
    action(
        type="omfwd" 
        Target="localhost" 
        Protocol="tcp" 
        Port="1514" 
        Template="RSYSLOG_SyslogProtocol23Format" 
        TCP_Framing="octet-counted" 
        KeepAlive="on"
    )
}

示例 3 - omhttp

使用 omhttp 模块可以将收集的日志数据以 HTTP 请求的方式输出:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 定义消息格式模板
template(
    name="tpl1" 
    type="string"
    string="<%pri%> %TIMESTAMP% %HOSTNAME% %syslogtag%%msg:::sp-if-no-1st-sp%%msg:::drop-last-lf%\n"
)
action(
    type="omhttp"
    server="127.0.0.1"
    serverport="8080"
    restpath="events"
    template="tpl1"
    action.resumeRetryCount="3"
)
本文由作者按照 CC BY 4.0 进行授权