0

I have an enteresting TODO that I'd like some eyes on. I'm using journalctl to grab system journal entries and output as JSON. journalctl outputs as JSON objects separated by a newline.

Here's a sample of a JSON object outputted from journalctl:

{ "__CURSOR" : "s=bd3afe956aec45d89cf3939e839c3647;i=3e084;b=6dd8a3060bdb448d848f4694339c6e94;m=5d0fd53a6;t=5c797ae76d38f;x=6cdb742ba83df8f5", "__REALTIME_TIMES
TAMP" : "1626829164613612", "__MONOTONIC_TIMESTAMP" : "24980054950", "_BOOT_ID" : "6dd8a3030bdb446d858f4694337c6e94", "PRIORITY" : "6", "SYSLOG_FACILITY" : "3",
"CODE_FILE" : "../src/core/job.c", "CODE_LINE" : "845", "CODE_FUNC" : 
"job_log_status_message", "SYSLOG_IDENTIFIER" : "systemd", "JOB_TYPE" : "start", "JOB_RES
ULT" : "done", "MESSAGE_ID" : "39f53479d3a045ac8e11786248231fbf", "_TRANSPORT" : "journal", "_PID" : "11282", "_UID" : "1162", "_GID" : "1162", "_COMM" : "syste
md", "_EXE" : "/lib/systemd/systemd", "_CMDLINE" : "/lib/systemd/systemd --user", "_CAP_EFFECTIVE" : "0", "_SELINUX_CONTEXT" : "unconfined\n", "_AUDIT_SESSION"
: "974", "_AUDIT_LOGINUID" : "1162", "_SYSTEMD_CGROUP" : "/user.slice/user-1162.slice/user@1162.service/init.scope", "_SYSTEMD_OWNER_UID" : "1162", "_SYSTEMD_UN
IT" : "user@1162.service", "_SYSTEMD_USER_UNIT" : "init.scope", "_SYSTEMD_SLICE" : "user-1162.slice", "_SYSTEMD_USER_SLICE" : "-.slice", "_SYSTEMD_INVOCATION_ID
" : "1f72568e79c34f14a525f98ce6a151c2", "_MACHINE_ID" : "32c9faf3dd90422881ce03690ebf0015", "_HOSTNAME" : "ip-192-168-22-27", "MESSAGE" : "Listening on port.", "USER_UNIT" : "dirmngr.socket", "USER_INVOCATION_ID" : 
"7c1e914aada947cd80a45d68275751dc", "_SOURCE_REALTIME_TIMESTAMP" :
"1626829165607533" }

I'm using --after-cursor to get a subset of the journal. There is no --before-cursor option afaik so I'm trying to find a way to stop at a specific cursor and search the JSON objects between the first and last cursor.

At the moment I'm using the following snippet (sloppy by my own admission) to search the journal after a cursor and count the objects where a match is found.

journalctl -u my-service --after-cursor="$FIRST_CURSOR" -o json | jq -n 'inputs|select(.MESSAGE|test(".*My search string .*")) | jq length | wc -l

I'd like to do this more intelligently with possibly an if/else statement but I'm a jq novice.

Ken Jenney
  • 422
  • 7
  • 15

1 Answers1

0
  1. A jq-only solution would be:
[inputs|select(.MESSAGE|test("My search string")) | length] | length
  1. Notice there is no need for the initial or final .* in the regex

  2. For future reference, please follow the "mcve" guidelines at http://stackoverflow.com/help/mcve . In particular, your JSON got mangled while copying-and-pasting into SO; and an actual example, with expected output, would be appreciated.

peak
  • 105,803
  • 17
  • 152
  • 177