我有机器 A,它是一个 pfsense 安装,它通过 syslog 将日志发送到 Ubuntu 机器。Ubuntu Box 将不得不重写日志,以替换例如主机名并稍微更改格式。
格式一般如下
Mar 7 00:05:32 hostname service: field1 field2 field3 field4 field5 field6 field7
Run Code Online (Sandbox Code Playgroud)
我想要重写主机名,服务和更改字段顺序的可能性,并过滤掉某个字段中具有某个值的消息,因为它们不有趣。
在过滤和处理之后,这些消息应该以日志文件的形式写入磁盘,并通过 syslog 发送到另一台机器。
现在,日志记录部分是微不足道的 - 只需设置 rsyslogd 以接受传入的消息,并转发这些消息。但是,我在重写部分有点卡住了。我没有嫁给 rsyslogd;任何 syslog-esque 守护进程都可以。
这个问题有点含糊,但我会尝试提出一个可能的解决方案。重写消息rsyslog提供了许多模块,其中之一是mmfields. 它将特定字符(仅一个字符)处的传入消息拆分为字段,然后允许访问这些字段。对于像这样的消息
a=1 b=two c=3 d=four
Run Code Online (Sandbox Code Playgroud)
该分离器将是一个空白和领域是那么接近的$!f2,$!f3,$!f4,和$!f5。不幸的是,第一个字段 ( $!f1) 总是空的,因为消息前面有一个空格,这将是第一个字段。因此,对于上述消息,我们得到$!f1=="",
$!f2=="a=1",$!f3=="b=two",$!f4=="c=3",和$!f5=="d=four"。
rsyslog还附带其他消息修改模块,但由于缺乏更多细节,我选择了这个。将以下文件存储为/etc/rsyslog.d/10-so.conf. 根据所需的执行顺序更改名称,但保留.conf扩展名。
# Load the "Message Modification" module "mmfields" to split
# incoming messages into fields at a certain separator:
module(load="mmfields")
# Format used for messages that are forwarded to another host.
# The fields are re-ordered and field #3 is omitted.
template(name="rewrite_forward" type="list") {
constant(value="<")
property(name="pri")
constant(value=">")
property(name="timestamp" dateFormat="rfc3339")
constant(value=" ")
property(name="hostname")
constant(value=" ")
property(name="syslogtag")
constant(value=" ")
property(name="$!f4")
constant(value=" ")
property(name="$!f2")
constant(value=" ")
property(name="$!f5")
}
# Format used for messages that are written to a local logfile.
# The format is almost the same as above, but lacks the priority,
# uses a different timestamp format, and ends with a "\n" as this
# is suitable for messages printed to a logfile.
template(name="rewrite_file" type="list") {
property(name="timestamp")
constant(value=" ")
property(name="hostname")
constant(value=" ")
property(name="syslogtag")
constant(value=" ")
property(name="$!f4")
constant(value=" ")
property(name="$!f2")
constant(value=" ")
property(name="$!f5")
constant(value="\n")
}
if ( $programname == "so" ) then {
# split message into fields at (exactly) one space character.
# The "fields" can then be referred to as "$!f1", "$!f2", ..., "$!fN".
# Note that "$!f1" will always be an empty string because the message
# usually starts with a blank and that is considered to be the first
# field.
action( type="mmfields"
separator=" "
)
# If the second field is the string "b=2", then go ahead and log and
# forward the message. Change the condition to your liking.
if ($!f3 == "b=2") then {
# write rewritten logmessage to local file
action( type = "omfile"
file = "/var/log/so-rewrite-fields.log"
template = "rewrite_file"
)
# just for reference: write the unmodified message to the
# very same logfile. Drop this for actual processing. It
# serves just as a debugging aid.
action( type = "omfile"
file = "/var/log/so-rewrite-fields.log"
)
# forward rewritten message to another host
action( type = "omfwd"
target = "127.0.0.1" # change to actual destination
port = "514" # change to actual destination
protocol = "udp" # change to actual destination
template = "rewrite_forward"
)
}
# no further processing:
stop
}
Run Code Online (Sandbox Code Playgroud)
重新启动rsyslog(通过sudo systemctl restart rsyslog.service)并尝试一下:
# A message that won't be logged because `$!f3 != "b=2"`:
logger -t so --id=$$ "a=1 b=3 txt=Hello number=$RANDOM"
# A message that will be logged because `$!f3 == "b=2"`:
logger -t so --id=$$ "a=1 b=2 txt=Hello number=$RANDOM"
Run Code Online (Sandbox Code Playgroud)
第二个logger语句的输出将是:
Mar 14 21:40:34 stratum9 so[3533]: txt=Hello a=1 number=6484 # rewritten msg
Mar 14 21:40:34 stratum9 so[3533]: a=1 b=2 txt=Hello number=6484 # original msg
Run Code Online (Sandbox Code Playgroud)
要更改主机名,只需替换
constant(value=" ")
property(name="hostname")
constant(value=" ")
Run Code Online (Sandbox Code Playgroud)
在模板中
constant(value=" fromElsewhere ")
Run Code Online (Sandbox Code Playgroud)
要更改 syslogtag(您称之为service),请替换
constant(value=" ")
property(name="syslogtag")
constant(value=" ")
Run Code Online (Sandbox Code Playgroud)
和
constant(value=" otherService: ")
Run Code Online (Sandbox Code Playgroud)
然后输出将是:
Mar 14 22:05:51 fromElsewhere otherService: txt=Hello a=1 number=11763 # rewritten
Mar 14 22:05:51 stratum9 so[3533]: a=1 b=2 txt=Hello number=11763 # original
Run Code Online (Sandbox Code Playgroud)
看这里更多消息属性,。
请注意,我的方法(用mmfields)依赖于域总是有相同的顺序,并不会轻易允许改写的消息一样a=1 b=2向b=1 a=2(重排和改变键-值对)。为此,另一个模块可能更合适。