为何未在规则集中引用的rsyslog模板仍能生效?
我搭了一套可用的rsyslog配置,用来监控JSON格式的日志文件,通过模板缩短并标准化日志条目。因为要用omfwd通过UDP转发消息(没法用TCP),每条日志得塞进单个数据报里,所以必须缩短日志内容。
我现在搞不懂的是:明明没在规则集的动作里引用那个模板,它却照样生效。之前我都会引用模板生成标准化日志给imfile读取,但现在不用这步也能正常运行。
我担心其他日志条目会用到这个模板,想知道是什么阻止rsyslog处理的其他消息使用它?是不是mmjsonparse只解析带CEE标签的消息这个特性在起作用?目前这台机器上没有其他服务用JSON格式记日志。
我的环境是Ubuntu系统,配置文件路径是/etc/rsyslog.d/70-json-normalization.conf,rsyslog版本是8.16.0。
具体配置代码如下:
# Load "Text file input module" module(load="imfile" mode="inotify") # Load module to parse JSON module(load="mmjsonparse") # Template to normalize format of log messages from git-mirroring-service # All log entries will have the same fields after having passed through this # Fields may have value "" template(name="shorten-json" type="list" option.jsonf="on") { # Need to truncate these fields, since they can be very long, and we are # limited to 1400 bytes because we use UDP. Let's grab the first 400 chars. property(outname="error" name="$.json!error" format="jsonf" position.from="1" position.to="400") property(outname="stderr" name="$.json!stderr" format="jsonf" position.from="1" position.to="400") # All other fields (potentially) in the json are added with no change property(outname="level" name="$.json!level" format="jsonf") property(outname="configDir" name="$.json!configDir" format="jsonf") property(outname="msg" name="$.json!msg" format="jsonf") property(outname="name" name="$.json!name" format="jsonf") property(outname="msg" name="$.json!msg" format="jsonf") property(outname="ts" name="$.json!ts" format="jsonf") property(outname="json_file" name="$.json!json_file" format="jsonf") property(outname="repo" name="$.json!repo" format="jsonf") property(outname="id" name="$.json!id" format="jsonf") # These fields are formated as numbers property(outname="workers" name="$.json!workers" format="jsonf" datatype="number") property(outname="pid" name="$.json!pid" format="jsonf" datatype="number") } # Use template to write out normalized log ruleset(name="git-mirror-log") { # Pass the log line as JSON. Put it in variable $.json action(type="mmjsonparse" container="$.json") } # Normalize the raw git-mirroring-service logfile. input( type="imfile" reopenOnTruncate="on" # Prefix lines with "@cee:" so mmjsonparse will parse it addCeeTag="on" file="/var/log/git-mirroring-service/git-mirroring-service.log" tag="git-mirroring-service-service" ruleset="git-mirror-log" )
为什么模板没被引用却看似生效?
你当前的配置里,模板其实并没有真正生效——你看到的“标准化效果”,是mmjsonparse模块把原始JSON日志解析成了rsyslog内部的结构化字段($.json容器里的内容),而非模板在起作用。
rsyslog的模板只有被显式引用时才会触发,比如在action指令里指定template="shorten-json",或者设为全局默认模板。你现在的规则集只做了JSON解析,没有调用模板生成输出,所以模板只是被定义了,但从未被实际使用。你之前引用模板是为了生成标准化输出给imfile,现在没这一步,模板自然不会参与处理流程。
为什么其他日志不会用到这个模板?
核心有两个原因:
- 规则集的隔离性:你的
git-mirror-log规则集只绑定了/var/log/git-mirroring-service/git-mirroring-service.log这一个输入源,其他日志条目不会进入这个规则集,根本碰不到和这个模板相关的逻辑。 - mmjsonparse的CEE标签限制:你给imfile配置了
addCeeTag="on",会给每条日志加上@cee:前缀,而mmjsonparse默认只解析带这个前缀的消息。其他服务的日志没有这个前缀,mmjsonparse不会解析它们,也就不会生成$.json容器——而你的模板所有字段都依赖$.json,没有这个容器的话,就算模板被引用也生成不出有效内容,更不会影响其他日志。
另外,你当前的配置甚至没有把模板和任何输出动作绑定,所以不管其他日志是什么样,都不可能用到这个模板。
内容的提问来源于stack exchange,提问作者Tobias Balle-Petersen

