<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
<META NAME="Generator" CONTENT="MS Exchange Server version 5.5.2655.35">
<TITLE>RE: SQL Redux</TITLE>
</HEAD>
<BODY>

<P><FONT SIZE=2>I added a counter so it would write to DB after n emails and then remaining when shutdown.</FONT>
</P>

<P><FONT SIZE=2>Seemed like a good compromise.</FONT>
</P>

<P><FONT SIZE=2>-----Original Message-----</FONT>
<BR><FONT SIZE=2>From: Kearney, Rob [<A HREF="mailto:RKearney@AZERTY.COM">mailto:RKearney@AZERTY.COM</A>]</FONT>
<BR><FONT SIZE=2>Sent: Thursday, July 31, 2003 10:57 AM</FONT>
<BR><FONT SIZE=2>To: MAILSCANNER@jiscmail.ac.uk</FONT>
<BR><FONT SIZE=2>Subject: Re: SQL Redux</FONT>
</P>
<BR>

<P><FONT SIZE=2>here is what we did for SQL logging, to bypass temp-file stuff.</FONT>
</P>

<P><FONT SIZE=2>Just took the SQLLogging and made SQLRTLogging, to write directly to DB, We</FONT>
<BR><FONT SIZE=2>have not noticed any degradation in performance</FONT>
<BR><FONT SIZE=2>Basically, we took the functions of SQLLogging and EndSQLLogging and put</FONT>
<BR><FONT SIZE=2>them together.</FONT>
<BR><FONT SIZE=2>(dont forget Init and End scripts also</FONT>
</P>

<P><FONT SIZE=2>---</FONT>
<BR><FONT SIZE=2>sub SQLRTLogging {</FONT>
<BR><FONT SIZE=2>&nbsp; my($message) = @_;</FONT>
<BR><FONT SIZE=2>&nbsp; my($dbh);</FONT>
<BR><FONT SIZE=2>&nbsp; $dbh =</FONT>
<BR><FONT SIZE=2>DBI-&gt;connect(&quot;DBI:mysql:mailscanner:localhost:mysql_socket=/var/database/mys</FONT>
<BR><FONT SIZE=2>ql/mysql.sock&quot;,</FONT>
<BR><FONT SIZE=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &quot;mailscanner&quot;, &quot;mailscanner&quot;,</FONT>
<BR><FONT SIZE=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {'PrintError' =&gt; 0})</FONT>
<BR><FONT SIZE=2>&nbsp;&nbsp; or MailScanner::Log::DieLog(&quot;Cannot connect to the database: %s&quot;,</FONT>
<BR><FONT SIZE=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $DBI::errstr);</FONT>
</P>

<P><FONT SIZE=2>&nbsp; my $id = $message-&gt;{id};</FONT>
<BR><FONT SIZE=2>&nbsp; my $size = $message-&gt;{size};</FONT>
<BR><FONT SIZE=2>&nbsp; my $from = $message-&gt;{from};</FONT>
<BR><FONT SIZE=2>&nbsp; my ($from_user, $from_domain);</FONT>
</P>

<P><FONT SIZE=2>&nbsp; # split the from address into user and domain bits.</FONT>
<BR><FONT SIZE=2>&nbsp; # This may be unnecessary for you; we use it to more easily determine</FONT>
<BR><FONT SIZE=2>&nbsp; # inbound vs outbound email in a multi-domain environment.</FONT>
<BR><FONT SIZE=2>&nbsp; # HINT: refine queries using SQL 'join' with a table containing local</FONT>
<BR><FONT SIZE=2>&nbsp; # domains.</FONT>
</P>

<P><FONT SIZE=2>&nbsp; ($from_user, $from_domain) = split /\@/, $from;</FONT>
</P>

<P><FONT SIZE=2>&nbsp; my @to&nbsp;&nbsp; = @{$message-&gt;{to}};</FONT>
<BR><FONT SIZE=2>&nbsp; my $subject = $message-&gt;{subject};</FONT>
<BR><FONT SIZE=2>&nbsp; my $clientip = $message-&gt;{clientip};</FONT>
<BR><FONT SIZE=2>&nbsp; my $archives = join(',', @{$message-&gt;{archiveplaces}});</FONT>
<BR><FONT SIZE=2>&nbsp; my $isspam = $message-&gt;{isspam};</FONT>
<BR><FONT SIZE=2>&nbsp; my $ishighspam = $message-&gt;{ishigh};</FONT>
<BR><FONT SIZE=2>&nbsp; my $sascore = $message-&gt;{sascore};</FONT>
<BR><FONT SIZE=2>&nbsp; my $spamreport = $message-&gt;{spamreport};</FONT>
</P>

<P><FONT SIZE=2>&nbsp; # Get rid of control chars and tidy-up SpamAssassin report</FONT>
<BR><FONT SIZE=2>&nbsp; $spamreport =~ s/\n/ /g;</FONT>
<BR><FONT SIZE=2>&nbsp; $spamreport =~ s/\t//g;</FONT>
</P>

<P><FONT SIZE=2>&nbsp; # Get timestamp, and format it so it is suitable to use with MySQL</FONT>
<BR><FONT SIZE=2>&nbsp; my($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime();</FONT>
<BR><FONT SIZE=2>&nbsp; my($timestamp) = sprintf(&quot;%d-%02d-%02d %02d:%02d:%02d&quot;,</FONT>
<BR><FONT SIZE=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $year+1900,$mon+1,$mday,$hour,$min,$sec);</FONT>
</P>

<P><FONT SIZE=2># maillog_mail insert</FONT>
<BR><FONT SIZE=2>&nbsp;&nbsp;&nbsp; my @fields=($timestamp, $id, $size, $from_user, $from_domain,</FONT>
<BR><FONT SIZE=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $subject, $clientip, $archives, $isspam, $ishighspam,</FONT>
<BR><FONT SIZE=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $sascore, $spamreport);</FONT>
<BR><FONT SIZE=2>&nbsp;&nbsp;&nbsp; map { s/\'/\\'/g } @fields;</FONT>
</P>

<P><FONT SIZE=2>&nbsp;&nbsp;&nbsp; # Insert @fields into a database table</FONT>
<BR><FONT SIZE=2>&nbsp;&nbsp;&nbsp; my($sth) = $dbh-&gt;prepare(&quot;INSERT INTO maillog_mail (time, msg_id, size,</FONT>
<BR><FONT SIZE=2>from_user, from_domain, subject, clientip, archives, isspam, ishighspam,</FONT>
<BR><FONT SIZE=2>sascore, spamreport) VALUES (?,?,?,?,?,?,?,?,?,?,?,?)&quot;);</FONT>
</P>

<P><FONT SIZE=2>$sth-&gt;execute($fields[0],$fields[1],$fields[2],$fields[3],$fields[4],$fields</FONT>
<BR><FONT SIZE=2>[5],$fields[6],$fields[7],$fields[8],$fields[9],$fields[10],$fields[11]) or</FONT>
<BR><FONT SIZE=2>MailScanner::Log::DieLog(&quot;Cannot insert row: %s&quot;, $DBI::errstr);</FONT>
</P>
<BR>

<P><FONT SIZE=2>&nbsp; my($file, $text);</FONT>
<BR><FONT SIZE=2>&nbsp; while(($file, $text) = each %{$message-&gt;{allreports}}) {</FONT>
<BR><FONT SIZE=2>&nbsp;&nbsp;&nbsp; $file = &quot;the entire message&quot; if $file eq &quot;&quot;;</FONT>
<BR><FONT SIZE=2>&nbsp;&nbsp;&nbsp; # Use the sanitised filename to avoid problems caused by people forcing</FONT>
<BR><FONT SIZE=2>&nbsp;&nbsp;&nbsp; # logging of attachment filenames which contain nasty SQL instructions.</FONT>
<BR><FONT SIZE=2>&nbsp;&nbsp;&nbsp; $file = $message-&gt;{file2safefile}{$file} or $file;</FONT>
<BR><FONT SIZE=2>&nbsp;&nbsp;&nbsp; $text =~ s/\n/ /;&nbsp; # Make sure text report only contains 1 line</FONT>
<BR><FONT SIZE=2>&nbsp;&nbsp;&nbsp; $text =~ s/\t/ /; # and no tab characters</FONT>
</P>

<P><FONT SIZE=2>&nbsp;&nbsp;&nbsp; my @fields = ($id, $file, $text);</FONT>
<BR><FONT SIZE=2>&nbsp;&nbsp;&nbsp; map { s/\'/\\'/g } @fields;</FONT>
</P>

<P><FONT SIZE=2>&nbsp;&nbsp;&nbsp; my($sth) = $dbh-&gt;prepare(&quot;INSERT INTO maillog_report (msg_id, filename,</FONT>
<BR><FONT SIZE=2>filereport) VALUES (?,?,?)&quot;);</FONT>
<BR><FONT SIZE=2>&nbsp;&nbsp;&nbsp; $sth-&gt;execute($fields[0],$fields[1],$fields[2]) or</FONT>
<BR><FONT SIZE=2>MailScanner::Log::DieLog(&quot;Cannot insert row: %s&quot;, $DBI::errstr);</FONT>
</P>

<P><FONT SIZE=2>&nbsp; }</FONT>
</P>

<P><FONT SIZE=2>&nbsp; for (@to) {</FONT>
<BR><FONT SIZE=2>&nbsp;&nbsp;&nbsp; # again, split the recipient's email into user and domain halves first.</FONT>
<BR><FONT SIZE=2>&nbsp;&nbsp;&nbsp; # see comment above about splitting the email like this.</FONT>
</P>

<P><FONT SIZE=2>&nbsp;&nbsp;&nbsp; my ($to_user, $to_domain);</FONT>
<BR><FONT SIZE=2>&nbsp;&nbsp;&nbsp; ($to_user, $to_domain) = split /\@/, $_;</FONT>
<BR><FONT SIZE=2>&nbsp;&nbsp;&nbsp; my @fields = ($id, $to_user, $to_domain);</FONT>
<BR><FONT SIZE=2>&nbsp;&nbsp;&nbsp; map { s/\'/\\'/g } @fields;</FONT>
<BR><FONT SIZE=2>&nbsp;&nbsp;&nbsp; my($sth) = $dbh-&gt;prepare(&quot;INSERT INTO maillog_recipient (msg_id,</FONT>
<BR><FONT SIZE=2>to_user, to_domain) VALUES (?,?,?)&quot;);</FONT>
<BR><FONT SIZE=2>&nbsp;&nbsp;&nbsp; $sth-&gt;execute($fields[0],$fields[1],$fields[2]) or</FONT>
<BR><FONT SIZE=2>MailScanner::Log::DieLog(&quot;Cannot insert row: %s&quot;, $DBI::errstr);</FONT>
<BR><FONT SIZE=2>&nbsp; }</FONT>
</P>

<P><FONT SIZE=2>&nbsp; # Close database connection</FONT>
<BR><FONT SIZE=2>&nbsp; $dbh-&gt;disconnect();</FONT>
</P>

<P><FONT SIZE=2>}</FONT>
</P>

<P><FONT SIZE=2>&nbsp; MailScanner::Log::InfoLog(&quot;Ending SQL Real-Time Logging&quot;);</FONT>
<BR><FONT SIZE=2>}</FONT>
</P>

<P><FONT SIZE=2>1;</FONT>
</P>
<BR>
<BR>

<P><FONT SIZE=2>-rob</FONT>
</P>

</BODY>
</HTML>