这个问题类似于未答复的rsyslog specific question on Server Fault。我不清楚最好的解决方案是通过已有的软件,如rsyslog或logstash,还是我必须自己构建一些东西。这就是我在这里问的原因。
我有几个并行运行的python进程(不由多处理处理)。他们构建需要写入该组的同一日志文件的组。从多个进程记录到同一个文件必须经过某种序列化以避免文件损坏,因此可以想到rsyslog或logstash。
我没有找到的(对于rsyslog和logstash都没有)是如何过滤包含我事先不知道的文件名的字段(或标记或在该系统中可能被调用的任何内容) (包含我无法控制的版本号)并将这些消息写入对应文件。
所以,我知道如何使用动态输出的静态输入滤波器。但我不知道动态输入和动态输出是如何完成的。
在Python应用程序中:
创建一个自定义格式化程序,用于添加包含目标日志文件名称的字段(例如rsyslog的syslogtag)
添加SyslogHandler或与我的记录器类似的东西。
在rsyslog或logstash config中添加类似
的规则<config of some logging system>
[filterfor] <field> -> write messages containing <value of field> to logfile /path/to/logs/<value of field>.log
进行。
是否可以开箱即用或(在logstash中)使用(尚未编写)插件?
编辑:也许一个例子可以澄清我在寻找什么。
示例日志消息,其中目标在括号中为exapmle:
<group_a> Message that will end up only in "group_a.log"
<group_a> Another Message for "group_a.log"
<group_b> Some interesting message for "group_b.log"
<group_c> Message for "group_c.log"
这些基于匹配名称的消息将最终出现在相应的日志文件中。对于上面的示例,包含其内容的日志文件将是:
/var/log/group_logs/group_a.log
<group_a> Message that will end up only in "group_a.log"
<group_a> Another Message for "group_a.log"
/var/log/group_logs/group_b.log
<group_b> Some interesting message for "group_b.log"
/var/log/group_logs/group_c.log
<group_c> Message for "group_c.log"
因此它可以像正则表达式一样将匹配的名称保存在一个组中,并将其用作文件的名称。
答案 0 :(得分:1)
以下解决方案适用于logstash(无需插件)。
我将每个流程输出到一个单独的文件,比如/path/logs/process-<unique-process-specific-id>.log
。该文件将包含如下行:
<group> <rest of line>
然后你可以使用这个配置:
input {
file {
path => "/path/logs/process-*.log"
start_position => beginning
}
}
filter {
grok {
match => { "message" => "\A(?<group>[^ ]++) (?<rest>.*+)\z" }
}
}
output {
file {
path => "/path/logs/group-%{group}.log"
message_format => "%{rest}"
}
}
因此,如果一个进程正在向/path/logs/process-foobar.log
写一行,如下所示:
groupA Hello world!
..然后这会生成一个包含内容
的日志文件/path/logs/group-groupA.log
Hello world!
答案 1 :(得分:1)
rsyslog的工作解决方案如下:
rsyslog配置中的重要部分是:
$template debugFile,"/var/log/%msg:R,ERE,1,DFLT:\[\[(.*)\]\]--end%.log"
通过正则表达式从消息生成日志文件的绝对路径 - rsyslog团队提供的Regular Expression Checker/Generator在这里可能会有所帮助。
$template rawFormat,"%msg%\n"
输出模板仅包含原始日志消息(主要是装饰性的)。
local0.* ?debugFile;rawFormat
将此模板和格式用于发送到local0工具的所有日志。