Tail is a very useful tool for monitoring an error stream. Sometimes the output from tail can have too much information, and its black-and-white monotone output can be hard to follow with the eyes.
The basic: a Linux terminal has the capability to colorize text. For example:
1 | echo -e "Sample text nicely highlighted" |
will produce a simple text saying, well:
Sample text nicely highlighted
But with some terminal color tagging such as:
1 | echo -e "Sample \e[36mtext\e[0m nicely highlighted" |
The \e above is identical to \033. I’d suggest using \033 because it’s safer in a programming language such as PHP. PHP will not recognize \e, but it will recognize \033, as you’ll see below.
1 | echo -e "Sample \033[36mtext\033[0m nicely highlighted" |
Sample text nicely highlighted
Some basic coloring tables can be seen at bashguru.com:
1 2 3 4 5 6 7 8 9 | Color Foreground Background Black 30 40 Red 31 41 Green 32 42 Yellow 33 43 Blue 34 44 Magenta 35 45 Cyan 36 46 White 37 47 |
With the help of perl, which most likely comes with all Linux distros, here’s a way to colorize your tail output. Let’s assume that every time you log something you will have a date-time prefixing your log. For example:
1 2 3 4 5 6 7 | [22-Dec-2011 20:28:45] E_DATASOMETHING ...... Too much information ....... Too much information ....... [22-Dec-2011 20:28:46] E_FATAL Something Too much information ....... Too much information ....... Too much information ....... |
Let’s create a script that can colorize the date portion. Create an executable Linux bash file:
1 2 3 | touch logwatch.sh chmod 755 logwatch.sh vim logwatch.sh |
Then copy and paste the following into your empty logwatch.sh:
1 2 3 | #!/bin/bash vNow=$(date +"%d-%b-%Y") tail -f ~username/errorlogfile.txt | perl -pe "s/$vNow/\e[1;30;32m$&\e[0m/g" |
Voilà!
[22-Dec-2011 20:28:45] E_DATASOMETHING ……
Too much information …….
Too much information …….
[22-Dec-2011 20:28:46] E_FATAL Something
Too much information …….
Too much information …….
Too much information …….
If you need something more complex — say you want to highlight several words in the file — you can use the scripting power of PHP. (I’m rusty with my perl.) Save the script below as colorize.php, and you can have the words blah, na, wa, and — highlighted on the fly:
1 | tail -f test.txt | php colorize.php blah na wa -- |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | <?php //stream_set_blocking(STDIN, FALSE); $fp = fopen("php://stdin", "r"); // Failed to connect to STDIN? (shouldn't really happen) if (!$fp) { echo "Cannot connect with standard input"; exit(); } array_shift($argv); $replacements = array(); foreach ($argv as $arg) { $replacements[] = "\033[36m$arg\033[0m"; } // Read each line as it arrives on STDIN while ($line = fgets($fp)) { echo str_ireplace($argv, $replacements, $line); } // Close connection to STDIN fclose($fp); echo "done!"; ?> |
A few useful additions.
The simpler path: grep –color. If you only need to highlight a single pattern, you don’t need perl or PHP at all — grep can do it, and the –color=always flag forces color even through a pipe (where grep otherwise drops it because stdout isn’t a terminal):
1 | tail -f errorlog.txt | grep --color=always -E "E_FATAL|E_ERROR|.*" |
The trailing .* is the trick that makes this work as a highlighter rather than a filter — it matches every line, so nothing gets dropped, but the alternation patterns still get colored where they appear. The -E flag enables extended regex.
The line-buffering gotcha. When you chain tail -f through several filters, each program in the pipeline buffers its output by default. The result: nothing appears on screen for several seconds, then a wall of lines all at once — useless for live monitoring. Force line-buffering on each stage:
1 | tail -f errorlog.txt | grep --line-buffered "ERROR" | sed -u 's/old/new/' |
–line-buffered is the GNU grep flag; -u is the equivalent for sed; for awk, use fflush() after each print. If you don’t see live output through your pipeline, this is almost always why.
Purpose-built tools. If colorizing logs is something you do often, two tools save you from rolling your own:
- ccze — pipe a log into it (tail -f /var/log/syslog | ccze -A) and it auto-colorizes by recognizing common log formats (syslog, Apache, Squid, etc.). The -A flag emits ANSI for piping; without it, ccze prefers its own curses-based UI.
- multitail — like tail -f but with split panes for watching multiple files at once, plus per-pattern highlighting via a config file. Heavier but powerful when you’re staring at three log files at the same time.
Both are in the standard repos for Debian/Ubuntu/Fedora — apt install ccze multitail or equivalent.
Two reset bookkeeping notes. If your colored output starts “leaking” — i.e. text after a match keeps showing up colored — your reset escape (\e[0m) didn’t fire. Common causes: a trailing newline got stripped before the reset, or you forgot the reset entirely. Always pair \e[Xm with \e[0m. And if you ever end up in a terminal stuck in some weird color state, the command reset (or tput reset) puts everything back to defaults.