mirror of
https://github.com/rsyslog/rsyslog.git
synced 2025-12-11 05:00:41 +01:00
We want easy nested JSON to match common schemas (e.g., Elastic ECS)
without external processors. This introduces an opt-in mode so existing
jsonf users keep exact behavior while enabling structured output when
requested.
Impact: No change unless option.jsonftree is enabled. With jsonftree,
dotted outnames render as nested objects; empty containers are skipped.
On name collisions (object vs value), we fall back to flat rendering.
Before: jsonf always emitted flat name/value pairs, even for dotted
outnames. After: jsonf remains flat by default; enabling jsonftree makes
"host.hostname" and "host.ip" render as {"host":{"hostname":...,"ip":...}}.
Technically, we add option.jsonftree to templates. When set, we lazily
build a per-template JSON tree (tplJsonNode) from dotted segments and
render it in one pass, reusing existing jsonf formatting for leaves.
The tree state is tracked on the template and freed on template delete.
Config parsing enforces mutual exclusivity among sql, stdsql, json,
jsonf, and jsonftree. Constants record bJSONf to reuse serialized
fragments. Tests cover nested output and pure-json cases using
option.jsonftree.
41 lines
1.3 KiB
Bash
Executable File
41 lines
1.3 KiB
Bash
Executable File
#!/bin/bash
|
|
# added by AI agent to verify nested jsonf output; Released under ASL 2.0
|
|
. ${srcdir:=.}/diag.sh init
|
|
|
|
generate_conf
|
|
add_conf '
|
|
template(name="nested" type="list" option.jsonftree="on") {
|
|
constant(outname="host.hostname" value="testhost" format="jsonf")
|
|
constant(outname="host.ip" value="127.0.0.1" format="jsonf")
|
|
constant(outname="event.dataset.name" value="syslog" format="jsonf")
|
|
property(outname="event.original" name="msg" format="jsonf")
|
|
}
|
|
|
|
local4.* action(type="omfile" file=`echo $RSYSLOG_OUT_LOG` template="nested")
|
|
'
|
|
|
|
startup
|
|
injectmsg 0 1
|
|
shutdown_when_empty
|
|
wait_shutdown
|
|
|
|
export EXPECTED_JSON='{"host": {"hostname": "testhost", "ip": "127.0.0.1"}, "event": {"dataset": {"name": "syslog"}, "original":" msgnum:00000000:"}}'
|
|
python3 - "$RSYSLOG_OUT_LOG" <<'PY'
|
|
import json
|
|
import os
|
|
import sys
|
|
|
|
expected = json.loads(os.environ['EXPECTED_JSON'])
|
|
with open(sys.argv[1], 'r', encoding='utf-8') as fh:
|
|
actual = json.loads(fh.read())
|
|
|
|
if actual != expected:
|
|
print('invalid response generated')
|
|
print('################# actual JSON is:')
|
|
print(json.dumps(actual, indent=2, sort_keys=True))
|
|
print('################# expected JSON was:')
|
|
print(json.dumps(expected, indent=2, sort_keys=True))
|
|
sys.exit(1)
|
|
PY
|
|
exit_test
|