Best way to follow a log and execute a command when some text appears in the log
A simple way would be awk.
tail -f /path/to/serverLog | awk '
/Printer is on fire!/ { system("shutdown -h now") }
/new USB high speed/ { system("echo \"New USB\" | mail admin") }'
And yes, both of those are real messages from a kernel log. Perl might be a little more elegant to use for this and can also replace the need for tail. If using perl, it will look something like this:
open(my $fd, "<", "/path/to/serverLog") or die "Can't open log";
while(1) {
if(eof $fd) {
sleep 1;
$fd->clearerr;
next;
}
my $line = <$fd>;
chomp($line);
if($line =~ /Printer is on fire!/) {
system("shutdown -h now");
} elsif($line =~ /new USB high speed/) {
system("echo \"New USB\" | mail admin");
}
}
If you're only looking for one possibility and want to stay mostly in the shell rather than using awk
or perl
, you could do something like:
tail -F /path/to/serverLog |
grep --line-buffered 'server is up' |
while read ; do my_command ; done
...which will run my_command
every time "server is up" appears in the log file. For multiple possibilities, you could maybe drop the grep
and instead use a case
within the while
.
The capital -F
tells tail
to watch for the log file to be rotated; i.e. if the current file gets renamed and another file with the same name takes its place, tail
will switch over to the new file.
The --line-buffered
option tells grep
to flush its buffer after every line; otherwise, my_command
may not be reached in a timely fashion (assuming the logs have reasonably sized lines).
This question appears to be answered already, but I think there's a better solution.
Rather than tail | whatever
, I think what you really want is swatch
. Swatch is a program designed explicitly for doing what you're asking, watching a log file and executing actions based on log lines. Using tail|foo
will require that you've got a terminal actively running to do this. Swatch on the other hand runs as a daemon and will always be watching your logs. Swatch is available in all Linux distros,
I encourage you to try it out. While you can pound a nail in with the back side of a screwdriver does not mean you should.
The best 30-second tutorial on swatch I could find is here.