/ Mostly Unixish

Quick log for bash scripts, with line limit

Sometimes you need to write a quick shell script; many a time, you need to put it on a server, and launch it every now and then, or run it in a cron job. That script may end up doing something important and/or altering the state of the server machine.

If that script starts being using often enough, you'll want logging as well, and that can be a complex beast to tame, for logs require rotation and deletion, otherwise the beast will eat up
all your disk space. Setting up logrotate for a single shell script looks like an overkill to me most of the times.

So what? Many a times logging will be neglected, and you'll lose the ability to track what happened and why.

This is my quick recipe for a basic bash logging solution with line-based truncation: the logfile will never exceed RETAIN_NUM_LINES lines (actually, it will never exceed such size when the script is launched, so the number of lines when the script has run is RETAIN_NUM_LINES + number of lines logged by the script).

Whenever you use the log function you'll get output on stdout as well, complete with a timestamp.

#!/bin/bash

# set LOGFILE to the full path of your desired logfile; make sure
# you have write permissions there. set RETAIN_NUM_LINES to the
# maximum number of lines that should be retained at the beginning
# of your program execution.
# execute 'logsetup' once at the beginning of your script, then
# use 'log' how many times you like.

LOGFILE=quicklog.sh.log
RETAIN_NUM_LINES=10

function logsetup {
    TMP=$(tail -n $RETAIN_NUM_LINES $LOGFILE 2>/dev/null) && echo "${TMP}" > $LOGFILE
    exec > >(tee -a $LOGFILE)
    exec 2>&1
}

function log {
    echo "[$(date --rfc-3339=seconds)]: $*"
}

logsetup

log hello this is a log

Launch this a lot of times and you'll end up with this in quicklog.sh.log:

[2016-09-26 11:44:09+02:00]: hello this is a log
[2016-09-26 11:44:09+02:00]: hello this is a log
[2016-09-26 11:44:09+02:00]: hello this is a log
[2016-09-26 11:44:09+02:00]: hello this is a log
[2016-09-26 11:44:10+02:00]: hello this is a log
[2016-09-26 11:44:10+02:00]: hello this is a log
[2016-09-26 11:44:10+02:00]: hello this is a log
[2016-09-26 11:44:11+02:00]: hello this is a log
[2016-09-26 11:44:11+02:00]: hello this is a log
[2016-09-26 11:44:11+02:00]: hello this is a log
[2016-09-26 11:44:14+02:00]: hello this is a log

Enjoy!

UPDATED on September 26th, 2016 to employ the rfc-3339 date option, which makes the logline quite more readable and greppable.