Server Fault is a question and answer site for system and network administrators. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

Whats the recommended solution to comb apache's previous day's /var/log/httpd/error_log looking for lines that contain a certain string and email when such strings are detected?

It could be run hourly via cron and the strings in my case would be "sigkill" or "reached maxclients".

Nagios, Cacti, etc would be an overkill. I need something simple.


share|improve this question
up vote 2 down vote accepted

But if really you prefer perl, it's a little lighter than bash, but...

#!/usr/bin/perl -w

use strict;

my $cachefile="/var/cache/lastpos-apache2-scan4maxclntOrSigKill";
my $logfile="/var/log/apache2/error.log";
my $searchstr="sigkill|reached maxclients";

my $lastpos=0;
if (-f $cachefile) {
    open FH,"<".$cachefile;
    close FH;

my $newpos=(stat $logfile)[7];

open FH,"<".$logfile;
seek FH,$lastpos,0;
while (<FH>) {
    print if /$searchstr/i;
close FH;

open FH,">".$cachefile;
print FH $newpos;
close FH;
share|improve this answer
still, no output. – Gaia Oct 27 '12 at 14:09
with i modifier for case independant? – F. Hauri Oct 27 '12 at 14:14
don't forget to clean cache: rm /var/cache/lastpos-apache2-scan4maxclntOrSigKill – F. Hauri Oct 27 '12 at 14:16
yes, i delete the cache every time before i run it. – Gaia Oct 27 '12 at 14:42
Did you add the i modifier after if /$searchstr/i;, did you need case independant, what's the look of your searched lines exactly? – F. Hauri Oct 27 '12 at 14:53

For running periodicaly via cron, you could Us a cache to store last position in logfile than grep on newest lines:


searchstr='sigkill\|reached maxclients'

[ -f $cachefile ] && lastpos=$(<$cachefile)
[ "$lastpos" ] || lastpos=0

newpos=$(stat -c %s $logfile)

[ $lastpos -gt $newpos ] && lastpos=0

tail -c +$lastpos $logfile | grep "$searchstr"

echo $newpos >$cachefile
share|improve this answer
This way I can run it even hourly and it will only send me the new entries, right? – Gaia Oct 27 '12 at 13:51
(added a line for "touch /var/cache/lastpos-apache2-scan4maxclntOrSigKill" to avoid errors on the first run) – Gaia Oct 27 '12 at 13:54
it stores $lastpos in the cachefile but it outputs nothing (even with the correct value in logfile). manually doing tail -c +40667 /var/log/httpd/error_log | grep "sigkill|reached maxclients" also brings nothing. – Gaia Oct 27 '12 at 13:57
maybe did you need case independant: grep -i "... ? – F. Hauri Oct 27 '12 at 14:07
sorry, I forget the \ before | in the grep command – F. Hauri Oct 27 '12 at 14:09

There's always Perl, e.g.:

perl -ne 'print if m/sigkill|reached maxclients/i' /var/log/apache2/error_log
share|improve this answer
how do I make that case insensitive? mi/ ? – Gaia Oct 27 '12 at 13:27
@Gaia m//i, see updated answer. – Ansgar Wiechers Oct 27 '12 at 13:29
ahhh perl is like magic... one more thing. each line begins with the date in format "[Wed Oct 24 05:15:52 2012]". how do i pick only the prior day's (i will set to run it past midnight) or the last 24 hours, whichever is simpler? Logs are rotated weekly. – Gaia Oct 27 '12 at 13:34
See the answers to this question. – Ansgar Wiechers Oct 27 '12 at 14:14
Thanks, but I think i am better off with caching $lastpos, as suggested below. Unless awk or sed has a one-liner that can do the above and only get the last X hrs... – Gaia Oct 27 '12 at 14:35

Monit is a very lightweight system monitoring tool and will watch log files and send alerts when certain strings appear. See the documentation at for usage.

share|improve this answer
thanks, but a 15 line script and a cron job did it. – Gaia Oct 27 '12 at 18:05

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.