How to have tail -f show colored output

I’d like to be able to tail the output of a server log file that has messages like:

INFO
SEVERE

etc, and if it’s SEVERE, show the line in red; if it’s INFO, in green. What kind of alias can I setup for a tail command that would help me do this?

Asked By: Amir Afghani

||

Have you had a look at ccze? You have the possibility to customize the default colors of some keywords using the option -c or directly in your configuration file. If your screen is clearing after colorizing you must use option -A.

Edit:

If you really would like to have the complete line colored in red, you could also have a try at the following:

$ tail -f myfile.log | perl -pe 's/.*SEVERE.*/e[1;31m$&e[0m/g'

e[1;31m will give you the red color. If you would like some yellow, use e[1;33m, and for green use e[1;32m. The e[0m restores the normal text color.

Answered By: uloBasEI

Try out multitail¹. This is an übergeneralization of tail -f. You can watch multiple files in separate windows, highlight lines based on their content, and more.

multitail -c /path/to/log

The colors are configurable. If the default color scheme doesn’t work for you, write your own in the config file. For example, call multitail -cS amir_log /path/to/log with the following ~/.multitailrc:

colorscheme:amir_log
cs_re:green:INFO
cs_re:red:SEVERE

Another solution, if you’re on a server where it’s inconvenient to install non-standard tools, is to combine tail -f with sed or awk to add color selection control sequences. This requires tail -f to flush its standard output without delay even when its standard output is a pipe, I don’t know if all implementations do this.

tail -f /path/to/log | awk '
  /INFO/ {print "33[32m" $0 "33[39m"}
  /SEVERE/ {print "33[31m" $0 "33[39m"}
'

or with sed

tail -f /path/to/log | sed --unbuffered 
    -e 's/(.*INFO.*)/o033[32m1o033[39m/' 
    -e 's/(.*SEVERE.*)/o033[31m1o033[39m/'

If your sed isn’t GNU sed, replace o033 by a literal escape character and remove --unbuffered.

Yet another possibility is to run tail -f in an Emacs shell buffer and use Emacs’s syntax coloring abilities.

¹ The historical website vanished in early 2021. The latest version is still available in many distributions, e.g. Arch, Debian.

You can use rainbow, which colorizes lines based on regular expressions:

rainbow --red='SEVERE.*' --green='INFO.*' tail -f my-file.log

It also comes bundled with predefined configs, for example for Tomcat logs:

rainbow --config=tomcat tail -f my-file.log

(disclaimer: I am the author)

Answered By: nicoulaj
tail -f /var/log/logname | source-highlight -f esc -s log
Answered By: user5771

Also note that if you just want to look for one matching regex, GNU grep with --color will work — just pipe your tail output through that.

Answered By: mattdm

grc, the generic colourizer is pretty cool.

apt-get install grc

Just do

grc tail -f /var/log/apache2/error.log

and enjoy!

You’ll also find it on GitHub.

Answered By: thias

To get colored output from standard commands like grep, you should set this alias in your .bashrc

# User specific aliases and functions
alias grep='grep --color=auto'

when you grep something in your file you see something like this, (but probably in red):

[root@linuxbox mydir]# grep "(INFO|SEVERE)" /var/log/logname
this entry is an INFO 
SEVERE this entry is a warn!
this entry is an INFO
this entry is an INFO
SEVERE this entry is a warn!

if want to use tail or awk and want that the color survive to a pipe, then the alias is not enough and you should use the --color=always parameter, for example:

[root@linubox mydir]# grep --color=always "(INFO|SEVERE)" /var/log/logname | tail -f | awk '{ print $1 }'
this 
SEVERE
this
this
SEVERE

If you want color text with awk the story is a little bit complex but more powerfull, for example:

[root@linubox mydir]# tail -f /var/log/messages | awk '{if ($5 ~ /INFO/) print "33[1;32m"$0"33[0m"; else if ($1 ~ /SEVERE/) print "33[1;31m"$0"33[0m"; else print $0}'
this entry is an INFO 
SEVERE this entry is a warn!
this is another ENTRY
this entry is an INFO
this is another ENTRY
this entry is an INFO
SEVERE this entry is a warn!

with each line in its own color.

There are many other way to get colorized text from shell with other tools and they are well descripted by other members.

Answered By: tombolinux

I quite like colorex. Simple, yet satisfying.

tail -f /var/log/syslog | colorex -G '[0-9]{2}:[0-9]{2}:[0-9]{2}' -b $(hostname)
Answered By: Brian M. Hunt

Shameless plug: I wrote a tool called TxtStyle that does something similar as the options mentioned earlier. You can run it as follows:

tail -f /var/log/syslog | txts --regex 'd+'

You can also define named styles in the config file (~/.txts.conf) and use it like so:

ifconfig | txts --name ifconfig

(ifconfig style is defined out of the box)

Answered By: armandino

I wrote a bash function that accepts up to three parameters and does a grep-like filter on a text file, and outputs text to the screen in color.

I would also like to see a tail function that would do this, but haven’t found one yet.

This function can also be improved – I’d appreciate any help on how to make it better.

function multigrep(){

    #THIS WORKS - Recreate this, using input parameters
    #sed -En '/(App)|(Spe)/p' ./flashlog.txt;

    filename="/Users/stevewarren/Library/Preferences/Macromedia/Flash Player/Logs/flashlog.txt";
    paramString="";

    for element in "$@"
        do
            #echo $element;
            paramString="$paramString($element)|";
        done

    #TRIM FINAL | OFF PARAMSTRING
    paramString=${paramString:0:${#paramString}-1};

    #CREATE SED EXPRESSION - '/($1)|($2)|(...)/p'
    paramString="'/$paramString/p'";

    #CREATE SED FUNCTION, CALL ON FILE
    paramString="sed -En $paramString ./flashlog.txt"

    echo $paramString;
    echo "${txtbld}$(tput setaf 7)" > ./flashlog_output.txt;
    eval $paramString >> ./flashlog_output.txt;
    echo >> ./flashlog_output.txt;
    #cat ./flashlog_output.txt;

    cat ./flashlog_output.txt | while read LINE
    do

        [[  $1 && ${1-x} ]] && 
            if grep -q $1 <<<$LINE; then
                echo "$(tput setaf 3)$LINE"
            fi

        [[  $2 && ${2-x} ]] && 
            if grep -q $2 <<<$LINE; then
                echo "$(tput setaf 7)$LINE"
            fi


        [[  $3 && ${3-x} ]] && 
            if grep -q $3 <<<$LINE; then
                echo "$(tput setaf 6)$LINE"
            fi

    done
}
Answered By: Steve Warren

sure !

I wrote long a go a function called “egrepi”, based on the 8 color variables definitions.
This works ONLY piped like a “tail -f” colored function.

1. setColors

first, the color variables function to be called at first:


setColors ()
{
set -a
which printf >/dev/null 2>&1 && print=printf || print=print # Mandriva doesn't know about printf

hide='eval tput civis'
show='eval tput cnorm'
CLS=$(tput clear)
bel=$(tput bel)

case ${UNAME} in
AIX)
# text / foreground
N=$(${print} '33[1;30m')
n=$(${print} '33[0;30m')
R=$(${print} '33[1;31m')
r=$(${print} '33[0;31m')
G=$(${print} '33[1;32m')
g=$(${print} '33[0;32m')
Y=$(${print} '33[1;33m')
y=$(${print} '33[0;33m')
B=$(${print} '33[1;34m')
b=$(${print} '33[0;34m')
M=$(${print} '33[1;35m')
m=$(${print} '33[0;35m')
C=$(${print} '33[1;36m')
c=$(${print} '33[0;36m')
W=$(${print} '33[1;37m')
w=$(${print} '33[0;37m')
END=$(${print} '33[0m')

# background
RN=$(${print} '33[6;40m')
Rn=$(${print} '33[40m')
RR=$(${print} '33[6;41m')
Rr=$(${print} '33[41m')
RG=$(${print} '33[6;42m')
Rg=$(${print} '33[42m')
RY=$(${print} '33[6;43m')
Ry=$(${print} '33[43m')
RB=$(${print} '33[6;44m')
Rb=$(${print} '33[44m')
RM=$(${print} '33[6;45m')
Rm=$(${print} '33[45m')
RC=$(${print} '33[6;46m')
Rc=$(${print} '33[46m')
RW=$(${print} '33[6;47m')
Rw=$(${print} '33[47m')

HIGH=$(tput bold)
SMUL=$(tput smul)
RMUL=$(tput rmul)
BLINK=$(tput blink)
REVERSE=$(tput smso)
REVERSO=$(tput rmso)
;;
*)
# text / foreground
n=$(tput setaf 0)
r=$(tput setaf 1)
g=$(tput setaf 2)
y=$(tput setaf 3)
b=$(tput setaf 4)
m=$(tput setaf 5)
c=$(tput setaf 6)
w=$(tput setaf 7)
N=$(tput setaf 8)
R=$(tput setaf 9)
G=$(tput setaf 10)
Y=$(tput setaf 11)
B=$(tput setaf 12)
M=$(tput setaf 13)
C=$(tput setaf 14)
W=$(tput setaf 15)
END=$(tput sgr0)

HIGH=$(tput bold)
SMUL=$(tput smul)
RMUL=$(tput rmul)
BLINK=$(tput blink)
REVERSE=$(tput smso)
REVERSO=$(tput rmso)

# background
Rn=$(tput setab 0)
Rr=$(tput setab 1)
Rg=$(tput setab 2)
Ry=$(tput setab 3)
Rb=$(tput setab 4)
Rm=$(tput setab 5)
Rc=$(tput setab 6)
Rw=$(tput setab 7)
RN=$(tput setab 8)
RR=$(tput setab 9)
RG=$(tput setab 10)
RY=$(tput setab 11)
RB=$(tput setab 12)
RM=$(tput setab 13)
RC=$(tput setab 14)
RW=$(tput setab 15)
;;
esac

BLUEf=${B}
BLUE=${b}
REDf=${R}
RED=${r}
GREENf=${G}
GREEN=${g}
YELLOWf=${Y}
YELLOW=${y}
MANGENTAf=${M}
MANGENTA=${m}
WHITEf=${W}
WHITE=${w}
CYANf=${C}
CYAN=${c}

OK="${RG}${n}OK${END}"
KO="${RR}${n}KO${END}"
NA="${N}NA${END}"

COLORIZE='eval sed -e "s/{END}/${END}/g" -e "s/{HIGH}/${HIGH}/g" -e "s/{SMUL}/${SMUL}/g" -e "s/{RMUL}/${RMUL}/g" -e "s/{BLINK}/${BLINK}/g" -e "s/{REVERSE}/${REVERSE}/g" -e "s/{REVERSO}/${REVERSO}/g"'
LOWS=' -e "s/{n}/${n}/g" -e "s/{r}/${r}/g" -e "s/{g}/${g}/g" -e "s/{y}/${y}/g" -e "s/{b}/${b}/g" -e "s/{m}/${m}/g" -e "s/{c}/${c}/g" -e "s/{w}/${w}/g"'
HIGHS=' -e "s/{N}/${N}/g" -e "s/{R}/${R}/g" -e "s/{G}/${G}/g" -e "s/{Y}/${Y}/g" -e "s/{B}/${B}/g" -e "s/{M}/${M}/g" -e "s/{C}/${C}/g" -e "s/{W}/${W}/g"'
REVLOWS=' -e "s/{Rn}/${Rn}/g" -e "s/{Rr}/${Rr}/g" -e "s/{Rg}/${Rg}/g" -e "s/{Ry}/${Ry}/g" -e "s/{Rb}/${Rb}/g" -e "s/{Rm}/${Rm}/g" -e "s/{Rc}/${Rc}/g" -e "s/{Rw}/${Rw}/g"'
REVHIGHS=' -e "s/{RN}/${RN}/g" -e "s/{RR}/${RR}/g" -e "s/{RG}/${RG}/g" -e "s/{RY}/${RY}/g" -e "s/{RB}/${RB}/g" -e "s/{RM}/${RM}/g" -e "s/{RC}/${RC}/g" -e "s/{RW}/${RW}/g"'
# COLORIZE Usage:
# command |${COLORIZE} ${LOWS} ${HIGHS} ${REVLOWS} ${REVHIGHS}

set +a
}

2. egrepi

and the egrepi function, effective and elegant: color cycling between 8 or more colors (your needs) AND tested under 3 different unix OS, with comments :


# egrepi() egrep with 8 REVERSE cyclic colorations on regexps almost like egrep
# egrepi 
# current script will work for KSH88, KSH93, bash 2+, zsh, under AIX / Linux / SunOS
egrepi ()
{
args=$*
# colorList=wBcgymrN                                                # KSH93 or bash 3+, not for AIX
# set -A color                                                  # needed with older sh
color[0]=$Rw; color[1]=$RB; color[2]=$Rc; color[3]=$Rg; color[4]=$Ry; color[5]=$Rm; color[6]=$Rr; color[7]=$RN; # this is the only one AIX solution
i=0
unset argsToGrep argsSedColor argsPerlColor

for arg in ${args}
do
    [ "${arg}" == "." ] && arg=\.                              # if you wanna grep "."
    # color=R${colorList:((${RANDOM: -1:1})):1}                     # bash RANDOMized colors
    # color=R${colorList:$i:1} && let i++ && ((i==8)) && i=0                # KSH93 or bash 3+, not for AIX
    argsToGrep="${argsToGrep}${argsToGrep:+|}${arg}"
    # argsSedColor="${argsSedColor} -e s#${arg}#$n${!color}&${w}#gI"            # AIX KSH88 do not recognise this fucking variable double expansion
    # argsSedColor="${argsSedColor} -e s#${arg}#$n${color[$i]}&${w}#gI"         # AIX neither do include sed with Ignore case
    argsPerlColor="${argsPerlColor}${argsPerlColor:+,}s#${arg}#$n${color[$i]}$&${END}#gi"   # So: gotta use perl
    let i+=1 && ((i==8)) && i=0                             # AIX KSH88 do not recognise "let i++"
done
# egrep -i "${argsToGrep}" | sed ${argsSedColor} | egrep -v "grep|sed"              # AIX sed incompatibility with Ignore case
# (($# > 0)) && (egrep -i "${argsToGrep}" | perl -p -e ${argsPerlColor}) || cat         # this line colors & grep the words, will NOT act as "tail -f"
(($# > 0)) && (perl -p -e ${argsPerlColor}) || cat                      # this line just colors the words
}

3. Usage

command | egrepi word1 .. wordN

Answered By: scavenger

You can use colortail:

colortail -f /var/log/messages
Answered By: Kartik M

Based on @uloBasEI answer, I’ve tried to use ... | perl ... | perl ..., but Linux pipe gets a bit crazy and is too slow. If I put all rules in only one perl command, it works fine.

For example, create a perl file colorTail.pl as below:

#!/usr/bin/perl -w

while(<STDIN>) {
    my $line = $_;
    chomp($line);
    for($line){
        s/==>.*<==/e[1;44m$&e[0m/gi; #tail multiples files name in blue background
        s/.*exception.*|at .*/e[0;31m$&e[0m/gi;  #java errors & stacktraces in red
        s/info.*/e[1;32m$&e[0m/gi; #info replacement in green
        s/warning.*/e[1;33m$&e[0m/gi; #warning replacement in yellow
    }
    print $line, "n";
}

Use it as:

tail -f *.log | perl colorTail.pl
tail -f *.log -f **/*.log | perl colorTail.pl

NOTE: you can use it on MobaXTerm too! Just download perl plug-in from MobaXTerm site.

Answered By: surfealokesea

Have a look at lnav, the advanced log file viewer.

lnav
lnav

It can also pretty print various formats.

Before:

lnav-before-pretty

After:

lnav-pretty

Answered By: bagonyi

You might also want to take a look at lwatch:

tail -f /var/log/syslog | lwatch --input -

Answered By: Michael Krupp

Publishes some time ago Node Js utility – log-color-highlight

tail -f file | lch -red error warn -green success
lch -f file -red.bold error warn -underline.bgGreen success
Answered By: gliviu

One solution that works for coloring all sorts of text, not just logfiles, is a Python tool, ‘colout‘.

pip install colout
myprocess | colout REGEX_WITH_GROUPS color1,color2... [attr1,attr2...]

Where any text in the output of ‘myprocess’ which matches group 1 of the regex will be colored with color1, group 2 with color2, etc.

For example:

tail -f /var/log/mylogfile | colout '^(w+ d+ [d:]+)|(w+.py:d+ .+()): (.+)$' white,black,cyan bold,bold,normal

i.e. the first regex group (parens) matches the initial date in the logfile, the second group matches a python filename, line number and function name, and the third group matches the log message that comes after that. This looks like:

logfile with colored formatting

Note that lines or parts of lines which don’t match any of my regex are still echoed, so this isn’t like ‘grep –color’ – nothing is filtered out of the output.

Obviously this is flexible enough that you can use it with any process, not just tailing logfiles. I usually just whip up a new regex on the fly any time I want to colorize something. For this reason, I prefer colout to any custom logfile-coloring tool, because I only need to learn one tool, regardless of what I’m coloring: logging, test output, syntax highlighting snippets of code in the terminal, etc.

Answered By: Jonathan Hartley

As for the color codes, I would use tput:

red=$( tput -Txterm setaf 1 )
norm=$( tput -Txterm sgr0 )
bold=$( tput -Txterm bold )

See for reference: man tput

Then:

tail -F myfile.log | sed "s/(.ERROR.*)/$red$bold1$norm/g"
Answered By: Fabien Bouleau

grc for sure!

customize your collors with regex in the file: ~.grc/conf.tail (or whatever name you want)

regexp=.*(select .*)$
colours=unchanged,cyan
=====
regexp=.*(update .*)$
colours=unchanged,bold yellow
=====
regexp=.*(insert .*)$
colours=unchanged,bold yellow
=====
regexp=.*(emp=d+).*
colours=unchanged,reverse green
=====
regexp=.*http.*/rest/contahub.cmds.(.*?)/(w*).*$
colours=unchanged,green,magenta
=====
regexp=.*http.*/M/.*.(.*?Facade)/(w*).*$
colours=unchanged,underline green,underline magenta

command line:

grc -c conf.tail tail -f log/tomcat/catalina.out

results:
screenshot

info for configuring grc:
https://github.com/manjuraj/config/blob/master/.grc/sample.conf

Answered By: Flavio

for Centos

yum install -y ccze
tail -f /var/log/file.log | ccze -A
Answered By: lestat_kim

Based on the @this post, I’ve created a solution which shows dynamic tail output from the multiple logs files and returns coloured warning and error messages as below:

tail -f -n 5 application.log debug.log| perl -pe 's#WARNING#x1b[33m$&#; s#ERROR#x1b[31m$&#; s#foo#x1b[32m$&#' 

No installation needed. Hope this helps someone.

Answered By: Invincible

Working solution on Mac

Colored logs on mac

Tried a bunch of things that just didn’t work because of some escaping issue.

Eventually found a working solution:

tail -f example.log | sed 
-e "s/FATAL/"$'e[31m'"&"$'e[m'"/" 
-e "s/ERROR/"$'e[31m'"&"$'e[m'"/" 
-e "s/WARNING/"$'e[33m'"&"$'e[m'"/" 
-e "s/INFO/"$'e[32m'"&"$'e[m'"/" 
-e "s/DEBUG/"$'e[34m'"&"$'e[m'"/"

A quick way to show it working:

echo " [timestamp] production.FATAL Some Messagen" 
"[timestamp] production.ERROR Some Messagen" 
"[timestamp] production.WARNING Some Messagen" 
"[timestamp] production.INFO Some Messagen" 
"[timestamp] production.DEBUG Some Messagen"  | sed 
-e "s/FATAL/"$'e[31m'"&"$'e[m'"/" 
-e "s/ERROR/"$'e[31m'"&"$'e[m'"/" 
-e "s/WARNING/"$'e[33m'"&"$'e[m'"/" 
-e "s/INFO/"$'e[32m'"&"$'e[m'"/" 
-e "s/DEBUG/"$'e[34m'"&"$'e[m'"/"

Note: this won’t hide any logs, just color the parts needed

Answered By: Oli Girling
sudo apt install grc
grc tail /var/log/syslog
alias tail='grc tail'

enter image description here

Answered By: DEV Tiago França

There is a new open source tool (Logdy.dev) that satisfies the need. You can use TypeScript to parse and transform the content of log messages. All of that in a web UI that comes filters/facets.

Update: you can style each individual row or cell by applying a style in a Message or CellHandler handler.

For example, here is a code that makes the background of a column with an error level cell row red. The code is applied for a level column.

(line: Message): CellHandler => {
    return {
        text: line.json_content.level,
        style: {
            background: line.json_content.level === 'error' ? "red" : ""
        },
        facets: [
            { name: "Level", value: line.json_content.level }
        ]
    }
}

enter image description here

Answered By: spinache