rsyslog template(模板)是rsyslog的一个重要特性。通过模板,用户可以指定他们自己想要的日志输出格式以及用于创建动态的文件名等。比如前一篇文章中一个示例的输出结果:
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才能使之生效:
1 2 3 |
[root@localhost learn-syslog]# service rsyslog restart Shutting down system logger: [ OK ] Starting system logger: [ OK ] |
模板的新式语法定义的格式如下所示:
template(parameters)
parameters是参数部分,其中name、type分别用来指定模板的名字、类型等。模板的类型主要有四种:list, subtree, string, plugin。
(1)list
list类型的模板是由一系列constant和property语句组成,定义在一对花括号中,有点类似于函数定义。这种类型的模板主要用于结构感知(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 22 |
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)的输出尤其有用。 spifno1stsp: RFC3164模板处理的专用选项。 |
property语句支持的参数众多,其中大部分参数很少会用到,了解即可。详情可见参考资料。
参考资料:
http://www.rsyslog.com/doc/v8-stable/configuration/templates.html
(2)subtree
subtree类型的模板是从rsyslog 7.1.4才加进去的特性。由于我的版本还停留在v4.6.2故没有研究,感兴趣的同学可以参考如下链接:
http://www.rsyslog.com/doc/v8-stable/configuration/templates.html
(3)string
string类型的模板非常类似于旧式语法中的模板定义语句,该模板中有一个参数string指定待输出的内容,其中包含了常量文本和变量(替换成相应的文本)。string类型的模板是指定文本内容的一种很好的方法,特别是在没有必要对变量进行复杂操作的情况下。如下所示,一个简单的stirng类型模板:
1 2 3 |
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参数指定了待输出的字符串内容。百分号%之间的变量由rsyslog属性替换器(rsyslog property replacer)进行解释替换为相应文本。
并且,百分号%之外的一切都是常量;%百分号内的变量后面有三个冒号:::,其作用将在下一篇文章中介绍。
(4)plugin
plugin类型的模板是由插件(称作strgen或string generator)产生的,它的格式是固定的。虽然固定的格式带来了不灵活性,但是它能提供更好的性能。不同的插件提供不同的格式,可以参考具体插件的文档。
plugin类型的模板必须指定参数plugin,并且插件必须在使用之前加载,有如下示例:
1 |
template(name="tpl4" type="plugin" plugin="mystrgen") |
(5)模板选项options
前面介绍了模板的四种类型,对每一种类型的模板,还有一个可选的部分——options。
options也是模板的一部分,但是这一部分是可选的。需要注意的是:模板选项不同于属性选项,属性选项是由属性替换器使用的,并且只能应用于单个属性上,而此处介绍的是模板的选项。模板选项目前定义的有:
option.sql:格式化适合于MySQL格式的sql语句的字符串
option.stdsql:格式化适合于发送到符合标准的SQL服务器的SQL语句的字符串
option.json:格式化适用于json语句的字符串
option.casesensitive:将属性名引用视为区分大小写
更多详细内容请见http://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 |
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 |
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 |
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 |
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 |
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: 用于解决性能问题的一种特殊格式。这种格式应该写入日志文件,不要用于生产或远程转发。 |
6.其他
本文主要介绍了rsyslog的模板特性,更多详细的内容可以参考rsyslog官方文档:http://www.rsyslog.com/。下一篇文章将介绍rsyslog的另一特性——属性替换器(property replacer)。