“tailcfg”

Since I first became fed up with tunnelling through to the same machine just to tail the same LCFG server log (about the third or fourth time I had to type the tiresome sequence of commands, a good few years ago) I’ve had a small function which does it for me.  However, for some reason I’d never thought to take advantage of the fact that all the logs end up tailed through my script for my manipulation, until last week.

The result of a little ANSI manipulation is a startling improvement in readability!

$ tailcfg
04/06/09 10:23:52:    publishing deferred: foo.inf.ed.ac.uk (XML)
04/06/09 10:23:52:    publishing deferred: quux.inf.ed.ac.uk (XML)
04/06/09 10:34:13:    processing: myhost [1/1, pass 1]
04/06/09 10:34:15:                1 error(s), 0 warning(s) (XML published)
04/06/09 10:34:15:    processing: netsrva [1/8, pass 2]
04/06/09 10:34:15:                (dhcp/all.map changed by myhost)
04/06/09 10:34:23:                0 error(s), 0 warning(s) (XML deferred)
04/06/09 10:34:23:    processing: netsrvb [2/8, pass 2]
04/06/09 10:34:23:                (dhcp/all.map changed by myhost)
[...]

It’s of course straightforward to achieve this. Why it took me so long to think to do it, I’m not sure.

function tailcfg() {
    ssh lcfg1 "tail -n 100 -f /var/lcfg/log/server" | sed \
        -e "s_\([1-9][0-9]* error(s)\)_`c red`\1`c off`_" \
        -e "s_\([1-9][0-9]* warning(s)\)_`c yellow`\1`c off`_" \
        -e "s_\([^1-9]0 \(error\|warning\)(s)\)_`c green`\1`c off`_g" \
        -e "s_\(processing: \)\(\<\w\+\>\)_\1`c bd`\2`c off`_"
}

Note the use of the `c` application; mine is a small binary whose source I’ve lost, but you can just as easily recreate this with a small script (I’ve left out the unused colours to save time / space…):

function c() {
    case $1 in
        red)    code='33[0;31m' ;;
        green)  code='33[0;32m' ;;
        yellow) code='33[0;33m' ;;
        bd)     code='33[1m' ;;
        off)    code='33[00m' ;;
        *)      echo "Invalid colour / state." >&2 ;;
    esac
    [[ -z ${code} ]] && return 1
    echo -e $code >&1 # note forced output to fd1.
}

2 thoughts on ““tailcfg”

  1. gdutton Post author

    Oh OK, it’s not exactly full-console syntax highlighting. And there’s probably a python filter class which does it all for me. But here’s another, to test if it’s possible to have too much of a good thing:

    function tailcli() {
    tail -f /var/lcfg/log/client | sed \
    -e “s_\(last modified\)\(.*\)\$_\1`c bd`\2`c off`_” \
    -e “s_\(profile accepted\)_`c green`\1`c off`_”
    }

  2. cc

    Nice! Thanks.

    Your settings didn’t quite suit my terminal windows – my Tiger terminal app doesn’t work quite as nicely as your Leopard one – so that for instance bold text comes out looking muddy and dirty and less readable than if it wasn’t bold, if anything. My terminal copes with this by making it red instead. Also, I’ve emphasised the errors and warnings more by making them white-on-red and black-on-yellow respectively rather than red-on-white and yellow-on-white. Oh, and I’ve coloured in the hostnames in magenta and I also highlight compilation lockings and unlockings.

    Here’s the expanded c function with more colours:

    function c() {
    case $1 in
    red) code=’33[0;31m’ ;;
    green) code=’33[0;32m’ ;;
    yellow) code=’33[0;33m’ ;;
    blue) code=’33[0;34m’ ;;
    magenta) code=’33[0;35m’ ;;
    cyan) code=’33[0;36m’ ;;
    revblack) code=’33[0;37;40m’ ;;
    revred) code=’33[0;37;41m’ ;;
    revgreen) code=’33[0;37;42m’ ;;
    revyellow) code=’33[0;43m’ ;;
    revblue) code=’33[0;37;44m’ ;;
    revmagenta) code=’33[0;37;45m’ ;;
    revcyan) code=’33[0;46m’ ;;
    bd) code=’33[1;30m’ ;;
    off) code=’33[00m’ ;;
    *) echo “Invalid colour / state.” >&2 ;;
    esac
    [[ -z ${code} ]] && return 1
    echo -e $code >&1 # note forced output to fd1.
    }

    and here’s my uglified tailcfg:

    function tailcfg() {
    tail -n 20 -f /var/lcfg/log/server | sed \
    -e “s_\(compilation locked\)_`c revblue`\1`c off`_” \
    -e “s_\(compilation unlocked\)_`c revcyan`\1`c off`_” \
    -e “s_\([1-9][0-9]* error(s)\)_`c revred`\1`c off`_” \
    -e “s_\([1-9][0-9]* warning(s)\)_`c revyellow`\1`c off`_” \
    -e “s_\([^1-9]0 \(error\|warning\)(s)\)_`c green`\1`c off`_g” \
    -e “s_\(processing: \)\(\\)_\1`c magenta`\2`c off`_”
    }

Leave a Reply

Your email address will not be published. Required fields are marked *