Search This Blog

Monday, March 30, 2026

More jq from journalctl

I've found another use case for `jq` when parsing service logs stored with `journald`. This time, I want to extract all non-INFO level logs from the service called slinky. In the previous example, I used `awk` to print only the part of a line that is valid JSON. However, `sed` might be better suited for this task. The following rule removes (replaces with an empty string) the beginning of the line up to the colon followed by a space ": ", which separates the timestamp from the log entry (JSON):

's/^.\+\]:\ //'

Examples

There are two examples of the command pipelines below. 

The first one checks the logs from the last 2 hours:

journalctl --since "2 hours ago" -u slinky.service\
 | sed -e 's/^.\+\]:\ //'\
 | jq 'select(.level != "info") '

The second one continuously prints new entries:

journalctl -f -u slinky.service\
 | stdbuf -oL sed -e 's/^.\+\]:\ //'\
 | jq 'select(.level != "info") '

The `journalctl` command is nearly identical in both examples (`--since` vs. `-f`). The `jq` select statement and the `sed` string replacement are the same. The main difference is that the latter uses the `stdbuf` command. It allows running the following command with modified buffering. The `-oL` option means that the standard output of the `sed` command is flushed line by line, enabling each entry to be passed immediately to `jq`.

No comments: