Hi all, just wanted to share a great tip I uncovered last week. Lots of us use shell scripts and use echo to debug in the console. If you want to take it a bit further and capture your script logs in a structure JSON way, especially if you’re shipping those logs off to Cloudwatch, Datadog, Splunk, etc. this might be useful.
What I like about this approach, all you have to do is drop these functions at the top of your script and swap out your echo
lines with either info
or error
followed by your message.
# Define the timestamp function
# Customize the date formatter as needed.
function timestamp(){
date "+%s" # Here we're using unix timestamp
}
function info(){
message="$1"
level=INFO
echo '{}' | \
jq --monochrome-output \
--compact-output \
--raw-output \
--arg timestamp "$(timestamp)" \
--arg level "$level" \
--arg message "$message" \
--arg user "$USER" \
--arg file $(basename $BASH_SOURCE) \
'.timestamp=$timestamp|.level=$level|.message=$message|.user=$user|.file=$file' >> logs.log
echo "$level: $message"
}
function error(){
message="$1"
level=ERROR
echo '{}' | \
jq --monochrome-output \
--compact-output \
--raw-output \
--arg timestamp "$(timestamp)" \
--arg level "$level" \
--arg message "$message" \
--arg user "$USER" \
--arg file $(basename $BASH_SOURCE) \
'.timestamp=$timestamp|.level=$level|.message=$message|.user=$user|.file=$file' >> logs.log
echo "\033[91m$level: $message\033[0m"
}
info "this is an info message"
error "this is an error message"
Above defines two log levels INFO
and ERROR
.
You can define more, but for simple shell scripts it’s unlikely you need more that those two levels.
Result in logs.log
:
{"timestamp":"1644062249","level":"INFO","message":"this is an info message","user":"admin","file":"logstest.sh"}
{"timestamp":"1644062249","level":"ERROR","message":"this is an error message","user":"admin","file":"logstest.sh"}
And results in console:
INFO: this is an info message
ERROR: this is an error message