動機
上一篇 【logstash】解析 postfix 的 log
既然 postfix 好了,打鐵趁熱
sendmail 也來一發
想法
最基掰的地方是, sendmail 會把收件人擠成一條
你得用些技巧去拆開他
動手做
先看一下log長怎樣
Nov 27 01:19:14 server server sendmail[16234]: tAQHJCEb016230: to=直接曬修改過後的 pattern, ctladdr= (0/0), delay=00:00:02, xdelay=00:00:02, mailer=esmtp, pri=114312, relay=a.b.c. [255.255.255.255], dsn=2.0.0, stat=Sent (OK 1448558354 z6si4967775igz.21 - gsmtp)
sendmailPattern/sendmail.grok
COMPID \[%{POSINT:pid}\]:
QUEUEID [A-za-z0-9]{14}
LOGIN [.a-zA-Z0-9_-]+
EMAIL %{LOGIN:local}@%{IPORHOST:remote}
DSN [0-9][.][0-9][.][0-9]
STAT_1 \(%{GREEDYDATA:result_message}\)
STAT_2 %{GREEDYDATA:result_message}
STAT (%{STAT_1}|%{STAT_2})
SENDMAILSMTP %{SYSLOGTIMESTAMP:timestamp} %{SYSLOGHOST:hostname} %{SYSLOGHOST:hostname2} sendmail%{COMPID:pid} %{QUEUEID:qid}: to=<%{EMAIL}>, (%{WORD}=%{DATA},)+ dsn=%{DSN:dsn}, stat=(%{DATA:result}:*|User unknown) %{STAT}
SENDMAILSMTPNODOMAIN %{SYSLOGTIMESTAMP:timestamp} %{SYSLOGHOST:hostname} %{SYSLOGHOST:hostname2} sendmail%{COMPID:pid} %{QUEUEID:qid}: to=(%{LOGIN:local},)+ (%{WORD}=%{DATA},)+ dsn=%{DSN:dsn}, stat=%{STAT:result}
SENDMAILSMTPOMS %{SYSLOGTIMESTAMP:timestamp} %{SYSLOGHOST:hostname} %{SYSLOGHOST:hostname2} sendmail%{COMPID:pid} %{QUEUEID:qid}: to=<%{EMAIL:to}>, (%{WORD}=%{DATA},)+ dsn=%{DSN:dsn}, stat=%{STAT:result}
SENDMAILSMTPMULTI %{SYSLOGTIMESTAMP:timestamp} %{SYSLOGHOST:hostname} %{SYSLOGHOST:hostname2} sendmail%{COMPID:pid} %{QUEUEID:qid}: to=(%{DATA:multiemail},) (%{WORD}=%{DATA},)+ dsn=%{DSN:dsn}, stat=(%{DATA:result}:*|User unknown) %{STAT}
然後 config 檔的部分input {
file {
type => "maillog"
path => ["/path/to/mail"]
# debug => "true"
}
}
filter {
#沒有dsn的都不處理
if ([message] !~ /dsn/){
drop{}
}
#處理sendmail的
if ([message] =~ /sendmail/){
grok {
patterns_dir => "/path/to/sendmailPattern"
match => {"message"=>"%{SENDMAILSMTP}|%{SENDMAILSMTPNODOMAIN}|%{SENDMAILSMTPOMS}|%{SENDMAILSMTPMULTI}"}
}
}
#處理sendmail多個收件人
if ([multiemail] =~ /^<\S+|\S+@\S+,\S+/){
#先換 在切
mutate {
gsub => ["multiemail", "<", "", "multiemail", ">", ""]
}
split {
field => "multiemail"
terminator => ","
}
#再分割 local與remote
if ([multiemail]=~ /\S+@\S+/){
grok {
patterns_dir => "/path/to/sendmailPattern"
match => {"multiemail"=>"%{EMAIL}"}
}
}
}
output {
# stdout {}
elasticsearch {
hosts => ["255.255.255.255:99999"]
flush_size => 1000
index => "maillog-%{+YYYY.MM.dd}"
codec => "plain"
workers => 1
manage_template => true
template_name => "logstash"
template_overwrite => false
idle_flush_time => 1
}
}
這邊比較虐的地方是 split 會把他一分為二然後你得再想辦法切他進 field
光想這個就破頭了
看來人笨是無極限的
驗證
# ./logstash agent --config /path/to/config然後趁現在欣賞自己的正則一下
因為你明天就會忘掉
留言
張貼留言