TL;DR - Yesterday I wrote a set of tools for logging program runs and sessions.
Currently available at https://github.com/wwalker/quick-log
As an admin, I'm always wanting to log the output of some command, often not a script. To solve that problem, I've written a few things. The easiest is to use the program "script" as xX0v0Xx mentioned. I found that calling script (without any arguments) would often result in me overwriting the output of a previous script. So I created this alias. All it does is prevent overwriting. You need a ~/tmp directory.
$ alias scr='script ~/tmp/typescript-$(date +%FT%T)'
$ scr
Script started, file is /home/wwalker/tmp/typescript-2019-12-05T18:56:31
$
That is great when I want to catch an interactive session.
When I want to log the output of a command (script or binary), I either want the exact output, or I want the output with timestamps in front of each line. So I wrote these two bash functions:
alias iso8601="date +%Y-%m-%dT%H:%M:%S"
justlog(){
name=$(basename "$1")
log=~/logs/${name}-$(iso8601)
"$@" > "$log" 2>&1
}
timelog(){
name=$(basename "$1")
log=~/logs/${name}-$(iso8601)
# https://github.com/wwalker/ilts
# You could replace ilts with ts
# /usr/bin/ts %FT%H:%M:%.S
"$@" |& ilts -S -E > "$log" 2>&1
}
Just run your command like you normally would:
justlog run rcn rcn-work\\\\\* 'ps -ef -o lstart,cmd | grep [s]upervisor'
or
timelog run rcn rcn-work\\\\\* 'ps -ef -o lstart,cmd | grep [s]upervisor'
This just created 2 file called:
wwalker@polonium:~ ✓ $ ls -l ~/logs/run*
-rw-r--r-- 1 wwalker wwalker 10495 2019-12-05 18:21:14.985 /home/wwalker/logs/run-2019-12-05T18:21:13
-rw-r--r-- 1 wwalker wwalker 1694 2019-12-05 18:24:02.878 /home/wwalker/logs/run-2019-12-05T18:24:01
-rw-r--r-- 1 wwalker wwalker 7623 2019-12-05 18:25:07.873 /home/wwalker/logs/run-2019-12-05T18:25:06
-rw-r--r-- 1 wwalker wwalker 10296 2019-12-05 18:34:59.546 /home/wwalker/logs/run-2019-12-05T18:34:57
But, Wait there's more!!
I didn't want to have to do an ls to find the name of the log file that justlog or timelog just created for me. So, I added 3 more functions:
newestlog(){
name=$(basename "$1")
ls ~/logs/"${name}"* | tail -1
}
viewlog(){
name=$(basename "$1")
view $( newestlog "$name" )
}
lesslog(){
name=$(basename "$1")
less $( newestlog "$name" )
}
So, you run your command with justlog (or timelog), and then you just use lesslog or viewlog (I'll probably create an emacs log for Those people):
justlog run rcn rcn-work\\\\\* 'ps -ef -o lstart,cmd | grep [s]upervisor'
lesslog run
That's it, no ls ~/tmp
, no tab completion games to find the file name. Just run lesslog (or viewlog if you like using vim to look at logs).
But, wait! There's more!
"I use grep all the time on my log files" - And the answer is, you guessed it, greplog
First, get the text from all 800 server's /etc/cron.d/atop files that are broken:
justlog fordcrun 'cat /etc/cron.d/atop; md5dum /etc/cron.d/atop'
Then get the hostnames (on the line above the output in the file :-) ) with greplog:
wwalker@polonium:~ ✓ $ greplog fordcrun -B1 -F "0 0 * * root"
int-salt-01:
0 0 * * root systemctl restart atop
--
rcn-pg-01:
0 0 * * root systemctl restart atop
rcn-pg-02:
0 0 * * root systemctl restart atop
rcn-pg-03:
0 0 * * root systemctl restart atop