Rsyslogd 配置
一般的,Rsyslogd的配置文件在/etc/rsyslog.conf。
配置文件格式
有3种格式的配置文件
- basic 基础配置格式,兼容syslog.conf格式
- advanced 以前叫RainerScript格式,在rsyslog v6开始使用
- obsolete legacy 传统的格式,仅为确保旧有配置不会出错
需要用哪种格式
强烈建议不要使用传统格式,应在基础配置中使用使用basic格式,在其它情况下使用advanced格式。
basic格式一般由简单语句组成,看起来像这样:
mail.info /var/log/mail.log
mail.err @@server.example.net
advanced格式有以下好处:
- 可以通过高级选项参数更容易控制rsyslog的操作
- 块结构化配置
- 容易书写
- 可以使用include
看起来是这样的:
mail.err action(type="omfwd" protocol="tcp" queue.type="linkedList")
sysklogd格式
也就是basic格式,以#开头的行以及空行直接被忽略,注释还可以用类C语言的/* */。
这种配置格式由logging规则(rules)组成。每条规则包括两部分:selector和action。这两部分由多个空格或TAB分隔。selector字段指定特定类型(facility)和优先级(priority)以关联相应的action。
SELECTORS
selector字段由两部分组成,facility和priority,由"."分隔。各部分均为大小写无关,且都可以由对应的10进制数替代,参见(/usr/include/syslog.h)。
facility由下列类型组成:auth, authpriv, cron, daemon, ftp, kern, lpr, mail, mark, news, security (auth), syslog, user, uucp, local0 - local7。其中security 不建议使用,只作内部用途。
priority由下列组成,按重要程序升序排列:debug, info, notice, warning, warn (warning), err, error (err), crit, alert, emerg, panic (emerg)
rsyslog将记录指定priority以及更高的日志到指定action。
同时*表明任意facility和priority,具体含义取决于*出现在"."的前面或后面。关键字none表示指定facility无priority。
在同一行可以用","分隔多个facility并指定同一priority。
在同一行中可以用";"分隔多个selector采用同一action。多个selector将以从左至右的顺序处理,每一selector可以覆盖之前的selector。一般用这种方式来指定pattern中需要排除的一部分。
可以在priority前加上"=",来指定rsyslog仅记录该级别的priority,而更高级别的被忽略。
可以在priority前加上"!",来指定rsyslog忽略该级别及更高级别的priority。
以上的"=“和”!“可以联用,来指定仅忽略该级别的priority,注意必须是”!="这样的顺序。
ACTIONS
action字段是rule中logfile的抽象描述。logfile不必是个真实文件。其可以是以下类型:
-
Regular File 常规文件
文件名必须指定绝对路径。
可以在文件名前加上"-",来避免每条log就同步一次文件。
-
Named Pipes 命名管道
fifo或命名管道可以在文件名前加上管道符号"|"。fifo必须在rsyslogd启动前由mkfifo创建。
-
Terminal and Console 终端
可以用设备名指定tty,如/dev/console。
-
Remote Machine 远程服务器
在主机名前加上"@"。
-
List of Users 指定用户
一般critical消息会同时转发到本机的"root"用户。同样可以将需要的日志发送到指定用户的终端上。可以用","分隔用户名列表。如果这些用户已登录系统,将会收到log消息。
-
Everyone logged on 所有已登录用户
紧急消息用来通知当前在线用户有奇怪的事情发生。这样的消息action以"*"指定即可。
处理流程
- 输入模块将收到的消息提交到ruleset
- 若未绑定ruleset,则使用默认ruleset
- 默认会有一个ruleset(RSYSLOG_DefaultRuleset)
- 额外的ruleset可以用户自定义
- 每个ruleset包括0条或更多rule
- 允许在ruleset内部为0条rule则显然没有任何作用
- 每条rule由一个filter和一个action list组成
- filter提供yes/no决策和流控
- 若filter命中,则对应的action list被执行,否则,不发生任何事
- 在指定ruleset内的rule会按顺序依次检查。无关联的ruleset中的rule将不会被检查。
- 所有rule都将被检查,不管是否已有filter命中(因此不会在首次命中后停止检查)。如果希望停止,则需要明确指定"discard"这个action(由"~"或stop命令表示)。如果丢弃action被执行,则消息不再继续进行下一rule的检查。
- 每个action list包含一条或多条action
- 在action list内部,不能包括更多的filter
- 要在list里包含超过一条action,后续action每条占一行,原来filter的位置要改为"&",并且此行要紧跟上一action。
- action由action调用本身(比如: :omusrmsg:)以及所有action定义配置语句($Actin…指示)组成
- 所有$开头的语句均为legacy配置,具体不深入探究
FILTER
Property-based Filters
除了之前描述的传统selector外rsyslogd还支持基于属性的filter: Property-based Filters。
可以使用任意属性,如HOSTNAME, syslogtag以及msg这些。所有支持的属性列表详见rsyslog properties documentation
这种filter有如下形式:
:property, [!]compare-operation, "value"
以":“开头,紧跟属性名,再跟个”,",比较操作名,再一个",",然后是要比较的值。值必须加双引号""。 在这些",“之间可以有空格和TAB。属性名/比较操作,都是大小写相关,所以"msg"可以用,但"MSG"则是非法属性名。比较操作前的”!"表达结果相反。
比较操作列表如下:
- contains 包含
- isequal 相等
- startswith 以此开头
- regex BRE正则表达式
- ereregex ERE正则表达式
值部分必须是带""的字符串,可以有两种转义符:
- \" - 引号本身
- \\ - 反斜杠
Expression-Based Filters
Filter还可以基于任意复杂的表达式,可以包含布尔值,数学和字符串操作。表达式可以进化为完整的配置脚本语言。不幸的是,这些语法仍在完善中,可能会有后续的修改。因此,如果你现在就用,今后很有可能需要修改配置。
基于表达式的filter由新一行的"if"开头。看起来像这样:
if expr then action-part-of-selector-line
“if” 和 “then” 是固定关键字必须存在。 "expr"是表达式,详见:expression documentation。"action-part-of-selector-line"则是通常的action(如 /var/log/logfile)。
Tempaltes 模板
模板是rsyslog的关键特性。此特性允许用户自定义任意格式。同时也可用于动态文件名的生成。
模板用template()语句指定,也可由传统语法$template语句指定。
template() 语句
template()语句是static静态的语句,意思是所有模板在rsyslog读入config文件时被定义,无法被if语句影响。
基本语法如下:
template(parameters)
此外,列表式模板支持扩展语法:
template(parameters) { list-descriptions }
每个模板有一个参数name,其指定了模板名称,以及参数type,其指定了模板类型。name参数必须唯一,否则结果无法预测。type参数指定了模板的不同类型。不同的类型可以用不同的方式定义模板内容。模板类型并不会影响(output)plugin如果处理该内容。因此,按最适合你需求的方式(从编写配置的视角而言)来使用type类型。以下是可用的类型:
- list
- subtree
- string
- plugin
以下分别描述这些类型。
List
在这种情况下,模板由一组常量(constant)语句和可变语句生成。这组列表在花括号"{}"跟在template定义后。此类型主要用于结构化的输出,如ommongodb。当然也可以完美的工作于基于文本的输出中。一般建议在需要复杂属性替换时使用此类型。这种情况下,基于列表的模板语法会比简单的基于字符串方式更清晰。
列表模板包括模板头(type=“list”),跟着是用花括号包围的表明从属此模板的constant和property语句。从名字可以看出,constant语句描述了固定常量文本字义,而property描述了属性值的访问。后面会讲到property有很多选项。大多数选项用于从属性中抽取一部分内容或改变获取的内容(例如改变大小写等)。
来个实际的例子:
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")
}
这个例子或许主要用于常见的基于文件的输出。
Constant 语句
这是用于指定常量文本的方式。文本按字面使用。一般面向基于文本的输出。例如,复杂模板构建时,经常会在末尾添加换行,这时即可以用constant语句。举个例子:
template(name="outfmt" type="list") {
property(name="$!usr!msgnum")
constant(value="\n")
}
下列是所有在常量文本内可识别的转义字符序列:
- \\ - 单个反斜杠
- \n - 换行
- \ooo - (3个八进制数字) - 表示有此值的字符(如:\101表示’A’)。注意,必须是3个数字。这里虽然支持八进制记号,但建议使用下列更易理解的十六进制方式。
- \xhh - (这里h是十六进制数字) - 表示有此值的字符(如:\x41表示’A’)。注:两个十六进制数必须都给出(一些语言里可能1个或2个数字都支持)。
注:若在反斜杠后跟了未支持的字符,将认为是错误。行为不可预料。
在一些基于文本和基于结构使用同一个模板的情况下,没有"outname"参数的常量文本在创建name/value树结构化输出时会被忽略。因此,若希望向类似mongodb提供常量文本时,必须包括outname,例如:
template(name="outfmt" type="list") {
property(name="$!usr!msgnum")
constant(value="\n" outname="IWantThisInMyDB")
}
要生成常量的json字段,format字段要指定为"jsonf",例如:
template(name="outfmt" type="list" option.jsonf="on") {
property(outname="message" name="msg" format="jsonf")
constant(outname="@version" value="1" format="jsonf")
}
在这个例子中,constant语句会生成"@version":“1”。注意,要达到这个效果,value和format参数都必须给出。
constant语句支持下列参数:
- value - 将使用的常量值
- outname - 输出字段名(结构化输出时)
- format - 可以为空或是jsonf
Property 语句
此语句用于包含property属性文本。可以访问所有可用属性。属性列表详见rsyslog properties documentation
可以用选项指定选取部分或改变属性。支持下列参数:
- name - 要访问的属性名
- outname - 输出字段名(结构化输出时)
- dateformat - Date格式。这里是所有property的选项
要生成自定义格式,可以用多个property选项。例如要生成YYYY-MM-DD:
property(name="timereported" dateformat="date-year")
constant(value="-")
property(name="timereported" dateformat="date-month")
constant(value="-")
property(name="timereported" dateformat="date-day")
其余参数参见官网
Subtree 子树
这种情况下,模板基于完整的(CEE)子树。这种模板最常用于输出模块知道如何处理结构树,如ommongodb。例如template(name=”tpl1” type=”subtree” subtree=” ! ” ) 包 括 了 所 有 C E E 数 据 , 而 t e m p l a t e ( n a m e = ” t p l 2 ” t y p e = ” s u b t r e e ” s u b t r e e = ” !”)包括了所有CEE数据,而template(name=”tpl2” type=”subtree” subtree=” !”)包括了所有CEE数据,而template(name=”tpl2”type=”subtree”subtree=”!usr!tpl2”)仅包括从$!usr!tpl2开始的子树。当使用此类型模板时,所有数据必须用set和unset脚本语句预先构造好。要了解详情,参见官网,这里只举个例子:
set $!usr!tpl2!msg = $msg;
set $!usr!tpl2!dataflow = field($msg, 58, 2);
template(name="tpl2" type="subtree" subtree="$!usr!tpl2")
String 字符串
最接近于传统模板定义的语句。其有必须的参数string,其中包含了将被应用于模板的字符串。模板字符串混合了常量文本和替换变量(见Property替换)。这些变量从消息或其它动态内容中获得。基于字符串的模板可以很容易指定文本内容,特别是没有复杂属性需要处理的情况下。
以下是示例:
template(name="tpl3" type="string"
string="%TIMESTAMP:::date-rfc3339% %HOSTNAME% %syslogtag%%msg:::sp-if-no-1st-sp%%msg:::drop-last-lf%\n"
)
在’%'之间的文本由rsyslog的property替换来处理。简单来说,其包含了属性及其格式化选项。其与list模板中的property对象类似,仅是两种不同的表达方式而已。
在’%'之外的所有内容均为常量文本。
Plugin 插件
这种模板由插件(所以一般叫作"strgen"或"字符串生成器")。由于是编程实现,所以格式是固定的。由于是不可变的,因此性能上会好很多,并且一般都是因此而使用(并不是说常规模板性能就很差-而是在特定的要求超高的情况下,很可能1比特的性能差距也很关键)。具体详情需要查看具体插件的文档。必须指定plugin参数,且必须包含插件名以表明自身。注意该插件必须在使用之前加载。同样举个例子:
template(name="tpl4" type="plugin" plugin="mystrgen")
创建动态文件名示例
模板可用于生成动态文件名。例如,当希望将syslog按不同主机名分别写到不同文件时(每台主机一个文件),你可以如下定义模板:
template (name="DynFile" type="string" string="/var/log/system-%HOSTNAME%.log")
保留模板名
所有"RSYSLOG_"开头的模板名都被保留给rsyslog使用。请不要在配置中使用它们,否则将有可能在未来导致冲突。