6

Trying to log to a central syslog server, either direct using Apache's ErrorLog to pipe to logger, or getting syslog to forward, but nothing is working and the errors are not making sense to me. I can get the Custom log to work, but not ErrorLog. Using Apache/2.4.7 on Ubuntu 14.04 with rsyslogd 7.4.4.

Config in my vhost (with and without space after logger options makes no difference):

LogLevel warn
ErrorLog  "|/usr/bin/tee -a /var/log/apache2/error.log | /usr/bin/logger -tapache_err -plocal1.error"
CustomLog "|/usr/bin/logger -p local4.warning -t apache" combined

and then getting this error:

/usr/bin/tee: invalid option -- 't'

Also tried (with and without double quotes):

ErrorLog "|syslog:local1"

But then got:

(2)No such file or directory: AH00089: Couldn't start ErrorLog process 'syslog:local1'.
AH00015: Unable to open logs

Even tried:

ErrorLog "| /usr/bin/tee -a /var/log/apache2/error.log | nc -u -j xxx.xxx.xxx.xxx 514"

But then tee is still complaining:

/usr/bin/tee: invalid option -- 'u'

Why on earth is tee picking up options after the second pipe and what can I do to stop that? I am a but stuck, Google isn't my friend, and any other advice is appreciated.

sebix
  • 4,313
  • 2
  • 29
  • 47
SysadminB
  • 71
  • 1
  • 6
  • Regarding ErrorLog to syslog, with your attempt above in quotes and with "|" pipe, apache is wanting to write a file by that name. Instead, the directive should be just: ErrorLog syslog:local1 (no quotes, no pipes) – texas-bronius Oct 19 '17 at 15:43

2 Answers2

7

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.

Josip Rodin
  • 1,695
  • 13
  • 18
  • Perfect, that worked like a charm! This has been doing my head in for a while because according to Apache's docs it should work direct. Thanks – SysadminB Jun 17 '15 at 06:45
  • The strange part here is that http://httpd.apache.org/docs/2.2/logs.html#piped says it should be forking a shell by default. – Josip Rodin Jun 17 '15 at 07:27
  • I know - thats the part that did my head in, but for some reason it wasn't, and this is a default install of Ubuntu 14.04. – SysadminB Jun 23 '15 at 10:01
  • This answer also solved [a similar problem](http://serverfault.com/questions/700708/how-to-set-the-correct-file-permissions-for-custom-logging-with-apache-2) for me. It should be accepted. – Luís de Sousa Jul 02 '15 at 12:14
  • The right documentation for this Apache version is http://httpd.apache.org/docs/2.4/logs.html#piped – Josip Rodin Jul 07 '15 at 14:07
1

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
dawud
  • 15,096
  • 3
  • 42
  • 61
Chad K
  • 11
  • 3