19

I'm watching different logs by

tail -q -f /var/log/syslog -f /var/log/fail2ban.log -f /var/log/nginx/error.log

How can I have the output of each log colored differently?

Daniel W.
  • 403

2 Answers2

21

Using GNU grep for the colouring:

color() { GREP_COLOR=$1 grep --color '.*'; }

(tail -qf /var/log/syslog | color 31 &
tail -qf /var/log/fail2ban.log | color 32 &
tail -qf /var/log/nginx/error.log | color 33)

Note that the first 2 are started in background. That means they won't be killed if you press Ctrl-C (shell explicitly ignore SIGINT for asynchronous jobs).

To prevent that, you can do instead:

color() { GREP_COLOR=$1 grep --line-buffered --color=always '.*'; }

(tail -qf /var/log/syslog | color 31 &
tail -qf /var/log/fail2ban.log | color 32 &
tail -qf /var/log/nginx/error.log | color 33) | cat

That way, upon Ctrl-C, the last tail+grep and cat die (of the SIGINT) and the other two grep+tails will die of a SIGPIPE the next time they write something.

Or restore the SIGINT handler (won't work with all shells):

color() { GREP_COLOR=$1 grep --color '.*'; }

((trap - INT; tail -qf /var/log/syslog | color 31) &
(trap - INT; tail -qf /var/log/fail2ban.log | color 32) &
tail -qf /var/log/nginx/error.log | color 33)

You can also do it in the color function. That won't apply to tail, but tail will die of a SIGPIPE the next time it writes if grep dies.

color() (trap - INT; GREP_COLOR=$1 exec grep --color '.*')

(tail -qf /var/log/syslog | color 31 &
tail -qf /var/log/fail2ban.log | color 32 &
tail -qf /var/log/nginx/error.log | color 33)

Or make the whole tail+grep a function:

tailc() (trap - INT; export GREP_COLOR="$1"; shift; tail -qf -- "$@" |
   grep --color '.*')
tailc 31 /var/log/syslog &
tailc 32 /var/log/syslog &
tailc 33 /var/log/nginx/error.log

Or the whole thing:

tailc() (
  while [ "$#" -ge 2 ]; do
    (trap - INT; tail -f -- "$2" | GREP_COLOR=$1 grep --color '.*') &
    shift 2
  done
  wait
)

tailc 31 /var/log/syslog 32 /var/log/syslog 33 /var/log/nginx/error.log
4

Someting like this worked for me:

(tail -f /var/log/syslog | awk -W interactive '{printf "\033[1;31m%s\033[0m\n", $0}' & \
tail -f /var/log/auth.log | awk -W interactive '{printf "\033[1;32m%s\033[0m\n", $0}' & \
tail -f /var/log/Xorg.0.log | awk -W interactive '{printf "\033[1;34m%s\033[0m\n", $0}')

Explanation:

  • tail -f file: append data as file grows
  • awk -W interactive: set awk to interactive mode
  • '{printf "\033[1;31m%s\033[0m\n", $0}' print the output colorzized to the terminal.
  • \033[1;31m means red
  • \033[1;32m means green
  • \033[1;34m means blue
chaos
  • 48,171
  • -W interactive seems to be mawk-specific. (the way mawk buffers its input by default is also unique, and -W interactive would not be needed in other awk implementations). – Stéphane Chazelas Aug 19 '14 at 15:17