cmd输出日志如何带时间戳_第15篇:Linux 日志管理--rsyslog模板详解

我们用一个简单的模板示例来展示一下模板的用法吧。

示例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

配置如下图

cmd输出日志如何带时间戳_第15篇:Linux 日志管理--rsyslog模板详解_第1张图片

重启一下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属性的讲解。

cmd输出日志如何带时间戳_第15篇:Linux 日志管理--rsyslog模板详解_第2张图片

rsyslog属性

说白了rsyslog属性是rsyslog守护进程内部保留的一些特殊关键字,在旧式的模板语法内在两个百分号之间的保留关键字,即 %属性名% 这样的形式叫rsyslog属性。允许通过使用属性替换器(Property Replacer)来访问syslog消息的各种内容。

这里仅列出我认为常用的rsyslog属性,其他额外的信息可以使用man rsyslog.conf 命令去查看rsyslog.conf手册。

要在生产环境中定制复杂日志模板,一定要耐心查阅这些可用的属性阐述,当你和Linux打交道就一定要有这种觉悟,网上不可能有你能否直接拿来可用的答案。

cmd输出日志如何带时间戳_第15篇:Linux 日志管理--rsyslog模板详解_第3张图片
  • msg: 即消息源进程调用syslog家族函数,所传递的文本信息
  • rawmsg: 从套接字接收到的消息完全相同。应该对调试有用。
  • HOSTNAME:来自消息的主机名
  • FROMHOST:接收到消息的系统的主机名(在中继链中,这是直接在我们面前的系统,但 不一定原始发件者)。
  • syslogtag:来自消息的标签,通常来说,要么是消息源进程的用户名。
  • programname:标签的“静态”部分,通常%programname%是输出的值和%syslogtag%是相同的。
  • PRI:消息的下划线部分-未解码(单值)
  • syslogseverity-text:消息等级的严重性-文本形式
  • timegenerated:接收消息时的时间戳。
  • timereported:消息中的时间戳。 解析精度取决于消息中提供的内容(在大多数情况下,仅精确到秒)
  • TIMESTAMP:timereported的别名
  • PROTOCOL-VERSION:协议版本

以$符号开头的属性是所谓的系统属性。 这些不是消息产生的,而是Linux系统内部产生的。

  • $NOW当前日期戳,格式为YYYY-MM-DD
  • $YEAR当前年份(4位数字)
  • $MONTH当前月份(2位数字)
  • $DAY月的当前日期(两位数)
  • $HOUR当前的军事时数(24小时)(2位数字)
  • $MINUTE当前分钟(2位数字)

示例2展示

我们不妨用上面提到属性,不妨使用新版语法修改上面例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”,在日期输出是存在冗余的。

cmd输出日志如何带时间戳_第15篇:Linux 日志管理--rsyslog模板详解_第4张图片

因此我们希望对%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,想要的效果

cmd输出日志如何带时间戳_第15篇:Linux 日志管理--rsyslog模板详解_第5张图片

如果示例2使用旧版语法,对属性输出的文本执行截取,可以按照如下语法格式:

%<属性名>:<起始位置>:<结束位置>:<选项>%

那么示例2等效的旧版语法配置的模板如下所示

$template MyTpl,"%$NOW% %timestamp:8:15%  %HOSTNAME% %programname%  %msg%n"

关于%msg%属性的文本截取

在日志模版的定义中,我们可以对%msg%属性的输出文本在任意起始字符(fromChar)位置到任意结束位置(toChar)进行字符串截取。在%msg%的字符串截取中第一个字符的偏移计数为1.

字符串截取遵循这个格式%msg::%

示例3展示

如下图是原来%msg%文本吸入/var/log/iptables.log日志文件的原始文本,我们希望日志文本只保留红框内一些笔者认为有参考价值的信息(见红框),那么%msg%属性中的字符串截取如下图所示

cmd输出日志如何带时间戳_第15篇:Linux 日志管理--rsyslog模板详解_第6张图片

这里需要提醒的是,当从%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%>", <选项>
  • $template是模板指令,指示后面的文本定义一个模板。
  • <>是模板的名称。使用此名称引用模板。
  • 两个引号("…")之间的任何内容都是实际的模板文本。在此文本中,可以使用特殊字符.例如用于换行的n或用于回车的r。如果想按字面意思使用其他字符,例如%或",则必须转义。
  • <%属性名%>在两个百分号之间指定的文本就是一个rsyslog属性,即%属性名%,该属性使您可以访问syslog消息的特定内容。 有关属性的更多信息,请参见“属性”部分
  • <选项>属性指定修改模板功能的任何选项。当前支持的模板选项是sql和stdsql,它们用于将文本格式化为sql查询。

日志模板示例

这里罗列一下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

你可能感兴趣的:(cmd输出日志如何带时间戳)