Apache errorlog piping fail

Solution 1:

The first pipe is code for Apache to fork a new command, but it's probably not forking a whole new shell, which would allow you to use a new pipe, but instead exec'ing the command, so everything is treated as a command argument, including the new pipe etc. You can likely go around it by wrapping it into a shell, using two methods, one is explicitly:

ErrorLog "|/bin/sh -c 'tee ... | logger ...'"

And the other is implicitly, using the prefix keyword |$:

ErrorLog "|$tee ... | logger ..."

The root cause is a change in Apache 2.4, cf. http://httpd.apache.org/docs/2.4/upgrading.html:

On Unix platforms, piped logging commands configured using either ErrorLog or CustomLog were invoked using /bin/sh -c in 2.2 and earlier. In 2.4 and later, piped logging commands are executed directly. To restore the old behaviour, see the piped logging documentation.

Solution 2:

Found this post while searching for a solution involving scrubbing log events from ErrorLog in Apache 2.2.31 which does not yet have ErrorLogFormat. Here's the solution I came up with, and thought others would find it useful.

This strips referer from the ErrorLog using unbuffered sed:

ErrorLog "|/bin/sed -u \'s/,\ referer: .*//\' >> /var/log/httpd/error_log"

Strips the querystring from referer using inline unbuffered perl:

ErrorLog "|/usr/local/bin/perl -ne \'$|=1;while (<>){$output = $_; $output =~ s/(referer:\ .*)\?/$1/; print $output}\'>>/var/log/httpd/error_log

Call a perl script:

ErrorLog "|/usr/local/bin/perl /tmp/fuss.pl >> /var/log/httpd/error_log