maillogを解析して一行に集約して出力する方法について
環境: CentOS 6.9
お世話になります。
以前こちらでawkを使用して指定期間内のメールログを抽出する方法をご教授いただき、大変参考なりました。
ここから更に改良できれば思っており色々と考えておりましたが自分だけでは上手くいかず、再度こちらから皆様のご意見をいただければと質問させていただきました。
メールログのサンプルはこちらとなります。
正常送信された場合のものとバウンスになった場合のものとなります。
送信先によって若干異なりますが、基本的にはこのような形式です。
例としてSoftBank(i.softbank.jp)に送信した際のものです。
ちなみにご覧の通りAWSにて送信しております。
May 10 00:00:00 ip-172-31-21-151 mail/smtpd[1439]: B670861CA0: client=ip-172-31-38-47.ap-northeast-1.compute.internal[172.31.38.47]
May 10 00:00:00 ip-172-31-21-151 mail/cleanup[1477]: B670861CA0: message-id=<hogehoge@example.com>
May 10 00:00:00 ip-172-31-21-151 mail/qmgr[1431]: B670861CA0: from=<hogehoge@example.com>, size=494, nrcpt=1 (queue active)
May 10 00:00:00 ip-172-31-21-151 mail/smtp[1459]: B670861CA0: to=<hogehoge@i.softbank.jp>, relay=msv.softbank.jp[117.46.9.104]:25, delay=0.8, delays=0.06/0/3.1/0.6, dsn=2.0.0, status=sent (250 Message received: 20180510111628949.MPQS.14641.ebmky105sc.i.softbank.jp@ebmky105sb.mailsv.softbank.jp)
May 10 00:00:00 ip-172-31-21-151 mail/qmgr[1431]: B670861CA0: removed
May 10 00:00:00 ip-172-31-21-151 mail/smtpd[8874]: 5564561CB8: client=ip-172-31-38-47.ap-northeast-1.compute.internal[172.31.38.47]
May 10 00:00:00 ip-172-31-21-151 mail/cleanup[8877]: 5564561CB8: message-id=<QUdsjiAFHF@OzemvwHngZ>
May 10 00:00:00 ip-172-31-21-151 mail/qmgr[8873]: 5564561CB8: from=<hogehoge@example.com>, size=442, nrcpt=1 (queue active)
May 10 00:00:00 ip-172-31-21-151 mail/smtp[8896]: 5564561CB8: to=<hogehoge@i.softbank.jp>, relay=msv.softbank.jp[117.46.7.40]:25, delay=1.1, delays=0.01/0/1/0.06, dsn=5.0.0, status=bounced (host msv.softbank.jp[117.46.7.40] said: 550 Invalid recipient: <hogehoge@i.softbank.jp> (in reply to RCPT TO command))
May 10 00:00:00 ip-172-31-21-151 mail/bounce[8906]: 5564561CB8: sender non-delivery notification: 6B19061CB3
May 10 00:00:00 ip-172-31-21-151 mail/qmgr[8873]: 5564561CB8: removed
以前ご教示いただいた内容を参考に現在は以下のように出力しております。
(例としてSoftbank系のtoを抽出した場合)
#!/bin/bash
filename='filename.csv'
nowtime=`date +%s`
updatetime=`date +%s -r $filename`
thisyear=`date +%Y`
thismonth=`date +%m`
localstr=`date "+%D %T"`
gmstr=`date "+%D %T" -u`
localtime=`date -d "$localstr" +%s`
gmtime=`date -d "$gmstr" +%s`
timediff=$(($localtime - $gmtime))
cat /var/log/maillog | awk -F - -v nowtime="$nowtime" -v updatetime="$updatetime" \
-v thisyear="$thisyear" -v thismonth="$thismonth" \
-v timediff="$timediff" '{
m = substr($1, 1, 3)
mon = (index("JanFebMarAprMayJunJulAugSepOctNovDec", m) + 2) / 3
year = mon <= thismonth ? thisyear : thisyear - 1
day = substr($1, 5, 2)
hh = substr($1, 8, 2)
mm = substr($1, 11, 2)
ss = substr($1, 14, 2)
if (mon < 3) {mon += 12; year--}
epochtime = (365 * year + int(year / 4) - int(year / 100) + int(year / 400) \
+ int(306 * (mon + 1) / 10) - 428 + day - 719163) * 86400 \
+ (hh * 3600) + (mm * 60) + ss - timediff;
} updatetime < epochtime && epochtime <= nowtime'
|grep -e 'to=<.*@i.softbank.jp>\|to=<.*@softbank.ne.jp>\|to=<.*vodafone.ne.jp>'
|grep -v 'discard' |sed -e 's/(250.*)//'
|awk '{if ($12 == "status=deferred") print $1,$2,$3,$7,$12; else if ($16 == 550) print $1,$2,$3,$7,$12,$16,$23; else print $1,$2,$3,$7,$12,$16}'
|sed -e 's/to=<//' |sed -e 's/>,//'
|sed -e 's/status=//'
|awk '{print($1,$2,$3 "," $4 "," $5 "," $6 "," $7)}' > $filename
日時,送信先メールアドレス(to),status,エラーコード,エラー種別
カンマで区切りCSVファイルとして出力しています。
May 8 00:00:00,to@hogehoge.com,sent,,
May 8 00:01:00,to@hogehoge.com,bounced,550,DATA
May 8 00:02:00,to@hogehoge.com,bounced,550,RCPT
こちらに加えて送信元メールアドレス(from)を追加したいと思っております。
同様の条件でtoのキューIDを抽出し、それを元にfromを抽出、
最終的には上記にfromが追加された状態で出力できればと考えております。
出力したい具体例は以下の通りです。
May 8 00:00:00,to@hogehoge.com,sent,,,from@example.com
May 8 00:01:00,to@hogehoge.com,bounced,550,DATA,from@example.com
May 8 00:02:00,to@hogehoge.com,bounced,550,RCPT,from@example.com
以上、何卒よろしくお願いいたします。