31

I've been trying to make tail a little more readable for server startups. My current command filters out most of the INFO and DEBUG messages from the startup:

tail -F ../server/durango/log/server.log | grep -e "ERROR" -e "WARN" -e "Shutdown" -e "MicroKernel" | grep --color=auto -E 'MicroKernel|$'

What I would like to do is craft something that would highlight WARN in yellow and ERROR in red, and MicroKernel in green. I tried just piping grep --color=auto multiple times, but the only color that survives is the last command in the pipe.

Is there a one liner to do this? Or even a many-liner?

tpederson
  • 516
  • 1
  • 5
  • 12
  • if you just want the color red, you can [use `grep` which is a little easier because you don't need to know any ANSI escape sequences](https://stackoverflow.com/q/981601/52074). – Trevor Boyd Smith Sep 14 '18 at 18:40
  • [if you're on a server where it's inconvenient to install non-standard tools](https://unix.stackexchange.com/questions/8414/how-to-have-tail-f-show-colored-output#8419), using sed or awk – Nick Dong Dec 04 '22 at 18:05

6 Answers6

33

yes, there is way to do this. That is, as long as your terminal supports ANSI escape sequences. This is most terminals that exist.

I think I don't need explain how to grep, sed etc. point is the color right?

see below, this will make

WARN yellow
ERROR red
foo   green

here is example:

kent$ echo "WARN
ERROR
foo"|sed 's#WARN#\x1b[33m&#; s#ERROR#\x1b[31m&#; s#foo#\x1b[32m&#'

Note: \x1b is hexadecimal for the ESC character (^VEsc).

to see the result:

enter image description here

Kent
  • 189,393
  • 32
  • 233
  • 301
  • 5
    Add "^[[0m" immediately after the ampersands (&) in the `sed` command if you only want to colorize the matching keyword, not the entire line. – chepner Feb 04 '13 at 17:38
  • @sehe ...yes, a bit lazy to type those... sry.. btw, I would upvote your `\x1b` edit ; it's pity the gif cannot be edited. :) – Kent Feb 04 '13 at 17:42
  • 1
    @Kent I realized that, otherwise I'd have dropped any mention of `^[` in the first place :) – sehe Feb 04 '13 at 17:57
  • 1
    I impressed with your style :) nice terminal – Satish Feb 04 '13 at 18:30
  • @sehe I'm on the way right now, I will make a new gif when I am home, to make the answer complete – Kent Feb 04 '13 at 19:02
  • 1
    Not sure if its a terminal issue, but ^[[0m didnt do a thing for me except echo those characters at the end of the match, and the color persisted even when I exited the command. So, I too the match eg #WARN# and turned it into #^.*WARN.*$#, and I used \x1b[0m after the amperstand. Thank you for the assitance though, I've got it working now and its way easier to see if the server is having troubles starting. – tpederson Feb 04 '13 at 23:12
  • @tpederson That's definitely an issue with _you_ :) See the edited post that makes that a lot clearer. Watch closely as the edit might be subtle to spot (see also the [revisions](http://stackoverflow.com/posts/14691971/revisions)) ***EDIT*** Oh wait, you must be referring to a leftover comment. Well, it goes without saying that `^[` denotes the (single) Escape character. Several ways to enter that character have been described in the post. – sehe Feb 04 '13 at 23:43
10

I wrote a script for this years ago. You can easily cover the case of multiple colors by piping successive invocations of highlight to each other.

From the README:

Usage: ./highlight [-i] [--color=COLOR_STRING] [--] <PATTERN0> [PATTERN1...]

This is highlight version 1.0.

This program takes text via standard input and outputs it with the given
perlre(1) pattern(s) highlighted with the given color.  If no color option
is specified, it defaults to 'bold red'.  Colors may be anything
that Perl's Term::ANSIColor understands.  This program is similar to
"grep --color PATTERN" except both matching and non-matching lines are
printed.

The default color can be selected via the $HIGHLIGHT_COLOR environment
variable.  The command-line option takes precedence.

Passing -i or --ignore-case will enable case-insensitive matching.

If your pattern begins with a dash ('-'), you can pass a '--' argument
after any options and before your pattern to distinguish it from an
option.
Dave Goodell
  • 2,143
  • 16
  • 18
8

I have been using a tool called grc for this for years. works like a charm. It comes with some quite good templates for many standard log outputs and formats and it is easy to define your own. A command I use often is

grc tail -f /var/log/syslog

It colorizes the syslog output so it is easy to spot errors (typically marked red.

Find the tool here:

https://github.com/garabik/grc

(it is also available as package for most common linux flavours).

kimusan
  • 495
  • 5
  • 13
  • I love how this tool is generic, from apt : "generic colouriser for everything" so it works on syslog files but also ls output, etc. On top of that it is included in my Debian/Ubuntu releases – Gerben Versluis Sep 26 '22 at 14:09
  • Heck, I love it so much I put a file in /etc/profile.d/grc.sh so it uses grc by default for cat/head/tail if grc is installed: if [ -x /usr/bin/grc ]; then alias cat='grc --colour auto cat'; alias tail='grc --colour auto tail'; alias head='grc --colour auto head'; fi – Gerben Versluis Sep 26 '22 at 14:27
5

I wrote TxtStyle, a small utility for colorising logs. You define regular expressions to highlight in ~/.txts.conf file:

[Style="example"]
!red: regex("error")
green: regex("\d{4}-\d\d-\d\d")
# ...

And then apply the styles:

txts -n example example.log

or you can also pipe the output

tail -f example.log | txts -n example

enter image description here

armandino
  • 17,625
  • 17
  • 69
  • 81
0

You can create a colored log instead of using a complex command.

enter image description here

For php is like this:

echo "^[[30;43m".$ip."^[[0m";

The key point is to use Ctrl-v ctrl-[ to input a green ^[ under insert mode in vim, direct input ^[ does not work.

enter image description here

More info here

Yep_It's_Me
  • 4,494
  • 4
  • 43
  • 66
Markbuild
  • 1
  • 1
  • 2
    When linking to your own site or content (or content that you are affiliated with), you [must disclose your affiliation _in the answer_](/help/promotion) in order for it not to be considered spam. Having the same text in your username as the URL or mentioning it in your profile is not considered sufficient disclosure under Stack Exchange policy. – Sabito stands with Ukraine Dec 18 '20 at 16:55
0

My sample using awk. Match log format like: xxxx [debug] xxxxx xxxx xxxx

black=30m
red=31m
green=32m
yellow=33m
blue=34m
magenta=35m
cyan=36m
white=37m

blacklog="\"\033[$black\" \$0 \"\033[39m\""
redlog="\"\033[$red\" \$0 \"\033[39m\""
greenlog="\"\033[$green\" \$0 \"\033[39m\""
yellowlog="\"\033[$yellow\" \$0 \"\033[39m\""
bluelog="\"\033[$blue\" \$0 \"\033[39m\""
magentalog="\"\033[$magenta\" \$0 \"\033[39m\""
cyanlog="\"\033[$cyan\" \$0 \"\033[39m\""
whitelog="\"\033[$white\" \$0 \"\033[39m\""

trace="/\[trace\]/ {print $redlog}"
debug="/\[debug\]/ {print $magentalog}"
info="/\[info\]/ {print $greenlog}"
warning="/\[warning\]/ {print $bluelog}"
error="/\[error\]/ {print $yellowlog}"

yourcommand | awk "$trace $debug $info $warning $error"

Nick Dong
  • 3,638
  • 8
  • 47
  • 84