I’m frequently monitoring webservers, cache servers, database servers, etc by tailing their log files, e.g.
tail -f /etc/httpd/logs/access_log
I like the –color option provided by grep, but found it to be too limited (only one allowed, no wildcard support). After a bit of searching to see if a tool existed for doing arbitrary colorizing, I found
acoc, the Arbitrary Command Output Colourer.
…which almost did what I needed, but couldn’t read from a pipe. So I wrote pcoc, the Piped Command Output Colorizer. I’m only publishing this because I’ve been using it for about 1 1/2 years, and still find it useful.
Source code at the end of this post. Here’s an example that highlights iPhone/iPod user agents and requests with a 500/400/404 HTTP response:
tail -f ./logs/access_log | pcoc -f '(iPod)=bold cyan' -f '(iPhone)=bold magenta' -f '\b(500|404|400)\b=red on_black'
Sorry, no screenshots :(.
pcoc source:
#!/usr/bin/perl use strict; use Getopt::Long; use Term::ANSIColor qw(colored); $|++; my %format = (); GetOptions( "format|f=s" => \%format); if ( ! keys %format ) { print <<"EOF"; Synopsis: pcoc - Piped Command Output Colorizer. Inspired by acoc. Usage: $0 -f '<regex1>=<color1>' -f '<regex2>=<color2>' $0 reads from a pipe and colorizes each line based on format (-f) parameters. Arguments: -f '<regex>=<color>' Required, multiple values okay. <regex>: A regular expression from which \$1 will be colorized <color>: One or more colorization keywords, see perldoc Term::ANSIColor, but briefly they are: boldness: bold foreground: red yellow green blue magenta cyan black white background: on_red on_yellow on_green on_blue on_magenta on_cyan on_black on_white Examples: #highlight the account's shell in bold green cat /etc/passwd | $0 -f '.+:([^:]+)\$=bold green' #... and the username in red with black background cat /etc/passwd | $0 -f '([^:]+)=red on_black' -f '.+:([^:]+)\$=bold green' Copyright/License: Allen Day <allenday\@ucla.edu>, licensed under GPL 2006-2008 EOF exit(1); } while ( my $line = <> ) { chomp( $line ); foreach my $f ( keys %format ) { my @c = split ',', $format{ $f }; if ( $line =~ qr/$f/ ) { while ( my ( $s, $t ) = $f =~ m/^(.*?)\(+(.+?)\)+/ ) { my $c = pop @c || last; $line =~ s/($s)($t)/$1.colored($2,$c)/e; $f =~ s/^(.*?)\((.+?)\)/$1$2/; } } } print "$line\n"; }
Post a Comment