steamsprocket.org.uk

Stop amavisd-new wrapping long lines in syslog

Update: Newer versions of amavisd-new (certainly 2.6.4-3) have a variable called $logline_maxlen which does exactly what it says on the tin. The rest of this post is therefore of only historic interest.

I administer a mail server that uses the popular amavisd-new to perform virus scanning, and spam filtering using SpamAssassin. That server uses Logcheck to send mail notifications if any unusual messages are logged – it works by filtering out any log messages fitting a set of patterns considered unimportant, and reporting any that are left. One small annoyance with amavis is that it splits lines that are longer than a certain magic number, so you get syslog entries like this:

Feb 23 15:15:23 hostname amavis[3139]: (03139-11) Imagine this message is long en....
Feb 23 15:15:23 hostname amavis[3139]: (03139-11) ...ough to be split

The split means that neither line fits the pattern of a message which can be ignored. Since you can’t predict how long the message will be, it’s not possible to write an ignore rule to take this splitting into account.

Extensive Googling revealed no mention of this problem anywhere, and eventually I decided I would have to Use The Source. The business part of amavis is the script /usr/sbin/amavisd-new – at least that’s where the Debian package puts it – which includes the following section ((as of version 1:2.6.1.dfsg-1)):

1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
    my($pre) = $alert_mark;
    my($logline_size) = 980;  # less than  (1023 - prefix)
    while (length($am_id)+length($pre)+length($errmsg) > $logline_size) {
      my($avail) = $logline_size - length($am_id . $pre . "...");
      $log_lines++; $! = 0;
      syslog($prio, "%s", $am_id . $pre . substr($errmsg,0,$avail) . "...");
      if ($! != 0) { $log_warnings++; $log_status_counts{"$!"}++ }
      $pre = $alert_mark . "...";  $errmsg = substr($errmsg, $avail);
    }
    $log_lines++; $! = 0; syslog($prio, "%s", $am_id . $pre . $errmsg);

As we can see, there’s a hardcoded constant which determines how long a line may be. Removing or commenting out the undesired section leaves us with

1876
1877
    my($pre) = $alert_mark;
    $log_lines++; $! = 0; syslog($prio, "%s", $am_id . $pre . $errmsg);

Another option might be to increase the value of $logline_size to something that means you rarely if ever exceed it.

What could possibly go wrong?

Generally it’s a very bad idea to start messing with files that are managed by the distribution’s packaging system – for one thing, it’ll be overwritten the next time there’s an update. Additionally, there must presumably have been a reason for the line splitting in the first place, and hence a reason not to disable it. This is a dirty hack, and I don’t recommend doing it. I’m only even posting it so that in the future there might be some record that the issue exists.

That said, so far it’s working as desired and there have been no side effects.

Leave a Response