# Notes: # - the use of substr($1,10,8) (note the starting char pos of 10): This is # to prevent awk getting too big a number where it will start losing # precision when doing calculations; we're only # interested in the difference between the start and end times of # the session so can discard the initial digits. The digits used # mean that this script will not be equipped for a digit 'rollover' # in 2038; before then I think there's no issue. # - Currently sessions that haven't ended ("quitting") aren't # reported by this script # - NOOP, unimplemented command log messages are omitted from the output # (but just comment out the relevant lines below if you'd like these). # - Arrays: # tai: tai timestamp from log of first qmail-smtpd entry for session # beginsec: part of tai timestamp from first qmail-smtpd entry for session # beginms: part of tai timestamp from first qmail-smtpd entry for session # msgs: string containing qmail-smtpd log messages for session BEGIN {FS=":"} $1~/qmail-smtpd/ && $3==" NOOP" { next; } $1~/qmail-smtpd/ && $3==" Unimplemented command" { next; } $1~/qmail-smtpd/ { if (!( $2 in tai )) { tai[$2]=substr($1,0,index($1," ")); beginsec[$2]=strtonum("0x"substr($1,10,8)); beginms[$2]=strtonum("0x"substr($1,18,8))/1000000; }; if ($3==" New session") { if (!( $2 in msgs )) $msgs[$2] = ""; } else msgs[$2]=msgs[$2]$3" |"; # Append log message to msgs } $4~/quitting/ { endsec=strtonum("0x"substr($1,10,8)); endms=strtonum("0x"substr($1,18,8))/1000000; ip=substr($2,index($2,"from")); secs=endsec-beginsec[$2]; ms=endms-beginms[$2]; if (ms<0) { ms+=1000; secs--;} # e.g. 12125.9(end), 12126.1(begin) --> .2 sec printf "%s%s:%s (duration %d.%03ds)\n",tai[$2],ip,msgs[$2],secs,ms; delete tai[$2]; delete beginsec[$2]; delete beginms[$2]; delete msgs[$2]; }