我们用一个简单的模板示例来展示一下模板的用法吧。
示例1
首先下面展示一下rsyslog v8推荐的语法。有点想构造一个类的风格。
template(name="MyTpl" type="list"){
property(name="timestamp" dateFormat="rfc3339")
constant(value=" ")
property(name="hostname")
constant(value=" ")
property(name="syslogtag")
constant(value=" ")
property(name="msg" spifno1stsp="on")
property(name="msg" droplastlf="on")
constant(value="n")
}
绑定上面定义的模板,有两种绑定方式 :1)设定默认模板 2)规则中绑定模板
设定默认模板
Step1:使用rsyslog的配置选项$ActionFileDefaultTemplate <模板名称>,例如绑定上面MyTpl模板,最好先将/etc/rsyslog.conf配置文件中的默认模板RSYSLOG_TraditionalFileFormat先注释一下,即
#$ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat
Step2:然后,指定拷贝默认模板的配置语句,并改成我们自己的模板名称,即
#$ActionFileDefaultTemplate MyTpl
Step3:这里我们定义一条日志规则,可以利用local设备,这是预留给Linux管理员使用的,定义如下一条规则用作测试上面的模板
local1.* /var/log/test.log
配置如下图
重启一下rsyslog守护进程
sudo systemctl rsyslog restart
我们可以使用logger命令向rsyslog守护进程发送一条消息。如下短视频所示
知乎视频www.zhihu.com规则中绑定模板
只需修改Step3中的步骤即可,在日志规则的动作字段,按照如下所示,添加一个:<模板名称>,其他步骤跟上面一个示例一致。
local1.* /var/log/test.log:MyTpl
当然下面还有一条等效的规则,如下所示
local1.* action(type="omfile" file="/varlog/test.log" template="MyTpl")
这里补充说一下上面例子定义MyTpl模板的等效语法,这是旧版的rsyslog所支持的,值得目前流行的rsyslog v8仍然兼容这样语法。但笔者喜欢旧式的语法风格。
$template MyTpl,"%timestamp::date-rfc3389% %HOSTNAME% %syslogtag% %msg%n"
那么该旧式语法的模板格式所定义日志,如下所示,和之前新版的配置语法在时间戳输出方面是有些区别的,要了解这些细节上的差别,就要深入下面rsyslog属性的讲解。
说白了rsyslog属性是rsyslog守护进程内部保留的一些特殊关键字,在旧式的模板语法内在两个百分号之间的保留关键字,即 %属性名% 这样的形式叫rsyslog属性。允许通过使用属性替换器(Property Replacer)来访问syslog消息的各种内容。
这里仅列出我认为常用的rsyslog属性,其他额外的信息可以使用man rsyslog.conf 命令去查看rsyslog.conf手册。
要在生产环境中定制复杂日志模板,一定要耐心查阅这些可用的属性阐述,当你和Linux打交道就一定要有这种觉悟,网上不可能有你能否直接拿来可用的答案。
以$符号开头的属性是所谓的系统属性。 这些不是消息产生的,而是Linux系统内部产生的。
我们不妨用上面提到属性,不妨使用新版语法修改上面例1的例子
#自定义模板
template(name="MyTpl" type="list"){
property(name="$now")
constant(value=" ")
property(name="timegenerated")
constant(value=" ")
property(name="hostname")
constant(value=" ")
property(name="programname")
constant(value=" ")
property(name="msg" spifno1stsp="on")
property(name="msg" droplastlf="on")
constant(value="n")
}
#日志规则
local1.* action(type="omfile" file="/var/log/test.log" template="MyTpl")
输出如下图所示,这个例子输出是有一些冗余的,因为%timegenerated%输出的一个精确到秒的时间戳,例如“Nov 27 10:29:40”,它和$now属性输出的“2020-11-27”,在日期输出是存在冗余的。
因此我们希望对%timegenerated%输出的文本进行裁切。那么这里对%timegenerated%添加一个position.from属性,那么模板的配置文件例子如下
template(name="MyTpl" type="list"){
property(name="$now")
constant(value=" ")
property(name="timegenerated" position.from="8")
constant(value=" ")
property(name="hostname")
constant(value=" ")
property(name="programname")
constant(value=" ")
property(name="msg" spifno1stsp="on")
property(name="msg" droplastlf="on")
constant(value="n")
}
这个示例,展示了在新版语法的模板配置中,如何使用系统属性,以及如何使用postion.from属性截取属性字段输出的字符串。如下图红框所示,是我们本示例2,想要的效果
如果示例2使用旧版语法,对属性输出的文本执行截取,可以按照如下语法格式:
%<属性名>:<起始位置>:<结束位置>:<选项>%
那么示例2等效的旧版语法配置的模板如下所示
$template MyTpl,"%$NOW% %timestamp:8:15% %HOSTNAME% %programname% %msg%n"
在日志模版的定义中,我们可以对%msg%属性的输出文本在任意起始字符(fromChar)位置到任意结束位置(toChar)进行字符串截取。在%msg%的字符串截取中第一个字符的偏移计数为1.
字符串截取遵循这个格式%msg:
示例3展示
如下图是原来%msg%文本吸入/var/log/iptables.log日志文件的原始文本,我们希望日志文本只保留红框内一些笔者认为有参考价值的信息(见红框),那么%msg%属性中的字符串截取如下图所示
这里需要提醒的是,当从%msg%输出的文本中某个位置提取到字符串末尾,您可以可以在toChar标记的位置用一个(“ $”)例如%msg:80:$%,将从第80个字符开始一直截取到末尾的剩下的文本。
那么,笔者这里有一个较为实用的日志模版配置,该配置中,我们用到基于script过滤日志消息的技术
$template FIREWALL_LOG_TPL,"%$NOW% %timestamp:8:15% %msg%n"
$template UDP_TRAFFIC_DENY_LOG,"%$NOW% %timestamp:8:15% %msg:1:17%
%msg:19:27% %msg:80:$%n"
$template TCP_TRAFFIC_DENY_LOG,"%$NOW% %timestamp:8:15% %msg:1:17%
%msg:19:27% %msg:80:$%n"
$template IP_SPOOF_DENY_LOG,"%$NOW% %timestamp:8:15% %msg:1:12%
%msg:13:21% %msg:74:$%n"
$template RDP_DESKTOP_LOG,"%$NOW% %timestamp:8:15% %msg:1:12%
%msg:14:22% %msg:81:$%n"
kern.* action(type="omfile" file="/var/log/iptables.log"
template="FIREWALL_LOG_TPL")
if $msg contains 'udp_traffic_deny' then /var/log/iptables.log;UDP_TRAFFIC_DENY_LOG
if $msg contains 'tcp_traffic_deny' then /var/log/iptables.log;TCP_TRAFFIC_DENY_LOG
if $msg contains 'ip_spoofing' then /var/log/iptables.log;IP_SPOOF_DENY_LOG
if $msg contains 'rdp_desktop' then /var/log/iptables.log;RDP_DESKTOP_LOG
基于正则表达式过滤
另外在rsyslog属性还可以基于正则表达式来过滤,我们仍然以%msg%属性为例,要实用正则表达式可以实用如下格式%mg:R:<正则表达式>%,如下示例所示
"%msg:R:.*Sev:. (.*) [.*--end%"
详细的配置说明,请参考官网的连接:RSyslog Documentation - rsyslog
顺带一提的是,日志模板的旧式语法配置方式如下图所示
$template <模板名称>,"<描述性文本>..<%rsyslog属性1%>..<<描述性文本>..<%rsyslog属性N%>", <选项>
这里罗列一下rsyslog默认的模板示例,这些日志模板是系统内置的。我们只需在配置/etc/rsyslog.conf中修改对应的下列内置的模板名称的其中一个即可。
$ActionFileDefaultTemplate <模板名称>
日志系统默认是RSYSLOG_TraditionalFileFormat模板
日志系统的内置模板如下所示:
$template verbose, "%syslogseverity%, %syslogfacility%, %timegenerated%, %HOSTNAME%, %syslogtag%,
%msg%n"
显示格式化syslog消息的模板,以便输出消息的严重性、功能、接收消息的时间戳、主机名、消息标记、消息文本,并以新行结束。
以下是一个用于故障诊断属性问题的特殊格式。
$template debug_info,"Debug line with all properties:nFROMHOST: '%FROMHOST%', fromhost-ip:
'%fromhost-ip%', HOSTNAME: '%HOSTNAME%', PRI: %PRI%,nsyslogtag '%syslogtag%', programname:
'%programname%', APP-NAME: '%APP-NAME%', PROCID: '%PROCID%',
MSGID: '%MSGID%',n TIMESTAMP: '%TIMESTAMP%', STRUCTURED-DATA:
'%STRUCTURED-DATA%',nmsg: '%msg%'nescaped msg: '%msg:::drop-cc%'nrawmsg: '%rawmsg%'nn"
RSYSLOG_SyslogProtocol23Format
这个模板是IETF的互联网草案ietf-syslog-protocol-23中指定的格式,该格式被假定为新的syslog标准RFC。
$template RSYSLOG_SyslogProtocol23Format,"%PRI%1 %TIMESTAMP:::date-rfc3339% %HOSTNAME%
%APP-NAME% %PROCID% %MSGID% %STRUCTURED-DATA% %msg%n"
RSYSLOG_FileFormat 该模板一种现代风格的日志文件格式,类似于TraditionalFileFormat,但具有高精度的时间戳和时区信息。
$template RSYSLOG_FileFormat,"%TIMESTAMP:::date-rfc3339% %HOSTNAME%
%syslogtag%%msg:::sp-if-no-1st-sp%%msg:::drop-last-lf%n"
RSYSLOG_TraditionalFileFormat
该模板具有低精度时间戳的较早的默认日志文件格式。
$temlate RSYSLOG_TraditionalFileFormat,
"%TIMESTAMP% %HOSTNAME% %syslogtag%%msg:::sp-if-no-1st-sp%%msg:::drop-last-lf%n"
RSYSLOG_ForwardFormat 该模板具有高精度时间戳和时区信息的转发格式
$temlate RSYSLOG_ForwardFormat,
"%PRI%%TIMESTAMP:::date-rfc3339% %HOSTNAME% %syslogtag:1:32%%msg:::sp-if-no-1st-sp%%msg%"
RSYSLOG_TraditionalForwardFormat
该模板具有低精度时间戳的传统转发格式。
$temlate RSYSLOG_TraditionalForwardFormat,
"%PRI%%TIMESTAMP% %HOSTNAME% %syslogtag:1:32%%msg:::sp-if-no-1st-sp%%msg%"
笔者因为最近需要搭建一个内部的日志系统,所以这里粗略整理一些rsyslog系统的日志模板使用示例,我没有太多精力再细说下去。对于日志模板的配置讲解用例到此为止。因为这里的上面列举的两个用例,再配合官方文档深入研究。读者应该可以做到举一反三。
参考官方文档:RSyslog Documentation - rsyslog