I've been wanting to logs some shells scripts to a file to be picked up by an agent like Fluentbit and shipped off to Cloudwatch and Datadog.
I found this example on the web which works like a charm using jq.
__timestamp(){
date " %Y%m%dT%H%M%S"
}
__log(){
log_level="$1"
message="$2"
echo '{}' | jq \
--arg timestamp "$(__timestamp)"
--arg log_level "$log_level" \
--arg message "$message" \
'.timestamp=$timestamp|.log_level=$log_level|.message=$message' >> logs.log
}
__log "INFO" "Hello, World!"
The one issue is that the output is rendering a full json with newlines and tabs. Easy on the eyes, but not great for cloud logging services.
{
"timestamp": "20220203T162320",
"log_level": "INFO",
"message": "Hello, World!"
}
How would I modify to render the output on one line like so?
{"timestamp": "20220203T171908","log_level": "INFO","message": "Hello, World!"}
CodePudding user response:
Use the --compact-output or -c option: jq -c --arg … '…' >> logs.log
From the manual:
--compact-output / -c:
By default, jq pretty-prints JSON output. Using this option will
result in more compact output by instead putting each JSON object
on a single line.
Note that instead of echo '{}' | jq … you could also use the --null-input or -n option: jq -n -c --arg …
--null-input/-n:
Don't read any input at all! Instead, the filter is run once using
null as the input. This is useful when using jq as a simple
calculator or to construct JSON data from scratch.
Lastly, the filter .timestamp=$timestamp|.log_level=$log_level|.message=$message could also be simplified to just {$timestamp,$log_level,$message}.
CodePudding user response:
