SOLVED:
A few months ago, I gain interest in logging in shell scripts.
The first idea was a manual logging function such as this one:
add2log() {
printf "$(date)\tINFO\t%s\t%s\n" "$1" "$2" >>"$logPATH"
}
But I wanted to automatise it, such as that STDERR would be automatically logged.
It's been some time now that I've found a satisfying answer, and I'm finally taking the time to share it.
For each of my shell script, I now use a "main.sh" that holds the log functions as well as the config (setting up log and config files). Here's what it looks like:
#!/bin/bash
###################################################################
# MY HEADERS
###################################################################
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#~~~~~~~~~~~~~~~~~~Global vars
mainScriptNAME=$(basename "$0")
mainScriptNAME="${mainScriptNAME%.*}"
mainScriptDIR=$(dirname "$0")
version="v0.0"
scriptsDIR="$mainScriptDIR/SCRIPTS"
addonsDIR="$mainScriptDIR/ADDONS"
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#~~~~~~~~~~~~~~~~~~LOGGER FUNCS
manualLogger() {
# $1=PRIORITY $2=FUNCNAME $3=message
printf "$(date)\t%s\t%s()\t%s\n" "$1" "$2" "$3" >>"$logFilePATH"
}
stdoutLogger() {
# $1=message
printf "$(date)\tSTDOUT\t%s\n" "$1" >>"$logFilePATH"
}
stderrLogger() {
# $1=message
printf "$(date)\tSTDERR\t%s\n" "$1" >>"$logFilePATH"
}
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#~~~~~~~~~~~~~~~~~~LOG & CONF
createLog() {
# code to set and touch logFilePATH & confFilePATH
manualLogger "INFO" "${FUNCNAME[0]}" "Log file created."
}
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#~~~~~~~~~~~~~~~~~~MAIN
#
createLog
#run scripts
{
#
source "$scriptsDIR/file1.sh"
doSomthing1
doSomthing2
#
source "$scriptsDIR/file2.sh"
anotherFunction1
anotherFunction2
...
} 2> >(while read -r line; do stderrLogger "$line"; done) \
1> >(while read -r line; do stdoutLogger "$line"; done)
In other words:
- all scripts/functions I want to run are in separate files in a ./SCRIPTS folder (so my main.sh is almost always the same)
- I call all these scripts in a group { ... } to catch their STDOUT and STDERR
- their STDOUT and STDERR are redirect to their respective logger functions
The log file looks like this (examples of one manual logger, one STDOUT logger, one STDERR logger):
Lun 23 mai 2022 12:20:42 CEST INFO createLog() Log file created.
Lun 23 mai 2022 12:20:42 CEST STDOUT Some standard output
Lun 23 mai 2022 12:20:42 CEST STDERR ls: sadsdasd: No such file or directory
The group makes it that ALL output is gathered in log.
Instead, you obviously could use the redirect 2> >(while read ...
and 1> >(while read ...
as you wish for each function.
Such as doSomthing1
as its STDOUT and STDERR going to log, but doSomthing2
only has its STDERR redirect.
logger
command for a starting point