Filtering JSON logs with JQ
One of my favorite command line tools is jq
(homepage). It is often very useful to look at structured JSON data.
My most common usage of jq
is very simple. Whenever some command returns a long JSON, it is very handy to pipe the result to jq
. Like this:
curl https://api.github.com/users/fredrikmeyer | jq
Then I get a syntax highligted response that is easy to read (in this case the response was already formatted, but sometimes a JSON response is unformatted).
Another use-case is for looking through logs. As a first step, list all log groups in your AWS account:
> aws logs describe-log-groups | jq '.logGroups | .[] | .logGroupName'
"/aws/apigateway/welcome"
"/aws/lambda/my-first-lambda"
"/aws/lambda/my-second-lambda"
...
A little explanation is in order: the format of the response is a JSON like this:
{
"logGroups": [
{
"logGroupName": "/aws/apigateway/welcome",
"creationTime": 1630789959982,
"metricFilterCount": 0,
"arn": "arn:aws:logs:eu-west-1:12345678910:log-group:defalt-vpc-flow-logs:*",
"storedBytes": 0
}
]
}
The first part (jq '.logGroups'
) chooses the content of the .logGroups
key. The seconds unpacks the array and prints the items after each other. The final .logGroupName
picks out the name of the log group.
To pretty-print JSON logs from AWS Lambda functions, one can run this little beast:
aws logs tail "<log-group-name>" \
--since 1d \
--format short \
| sed 's/^.\{20\}//'
| jq -R "fromjson? | . "
The first thing we do is to get all log messages in the last day from our log group. Since all log messages are prepended with the timestamp, we cut out the timestamp with sed
(thanks, Google!). Then we parse all JSON logs and ignore the rest (thank you Stackoverflow).
If we want to see all error logs, we can just change the above command to
aws logs tail "<log-group-name>" \
--since 1d \
--format short \
| sed 's/^.\{20\}//'
| jq -R 'fromjson? | . | select(.level =="ERROR")'
jq
also supports sorting and lots of much more advanced manipulation of JSON input. Take a look at the manual for more.