JSON layout

Match the JSON bytes Tracemill sends to the layout your SIEM actually indexes.

The same event can reach a SIEM as differently formatted JSON, depending on the collection path. Most of the time that makes no difference. It does matter when an add-on extracts fields with regular expressions over the raw text instead of parsing the JSON, because then the bytes decide which fields exist at search time and which detections can fire.

Layout is a property of the destination, not of the job or scenario. The same job runs unchanged against two destinations and can get different verdicts, because each destination reproduces a different collection path.

Settings

SettingCLI flagPipeline configValues
JSON separators--json-separatorsjson_separatorscompact (default), spaced
HEC event embedding--hec-eventhec_event (HEC only)object (default), string
  • compact writes JSON with no whitespace ({"Name":"Role","Value":"X"}). This is what vendor APIs return, and what pipelines that parse and re-emit JSON (Cribl, OpenTelemetry Collector, Vector, Fluent Bit) produce.
  • spaced writes ": " after each key and ", " between items ({"Name": "Role", "Value": "X"}). This is the layout Splunk add-on collectors produce, because they re-serialize every record with Python's json.dumps.
  • object embeds the event in the HEC envelope as a JSON object.
  • string sends the rendered event as the HEC event string, so Splunk indexes _raw byte for byte as Tracemill rendered it.

Separators apply to the HEC, HTTP, TCP and stdout destinations. S3 and Google Cloud Pub/Sub emit the source's own format and do not take the setting.

Choosing a value

Check what you actually index, and match it. Run this search against the production data for the source you are testing. It classifies each event by its first separator:

index=* sourcetype=o365:management:activity
| eval layout=if(match(_raw,"^\{\"[^\"]+\": "),"spaced","compact")
| stats count by index, layout

Swap in the sourcetype you care about. If an index shows spaced, set json_separators: spaced on the pipeline that delivers that source. If it shows compact, keep the default.

A target can have several pipelines. If one source arrives through an add-on and everything else through a pipeline, create a second HEC pipeline with spaced and bind that source's workloads to it.

Example: the Microsoft 365 add-on

Collected by the Splunk Add-on for Microsoft Office 365, O365 management activity is indexed spaced. The add-on's [extended_properties] transform promotes {"Name": "X", "Value": "Y"} pairs to top-level fields such as Name, Role, AccessRights and SessionId, and its regex only matches the spaced form. On compact data those fields are never extracted, so detections that key on them cannot fire.

  • If you collect O365 with the add-on, set json_separators: spaced on the pipeline that carries your O365 workloads.
  • If O365 reaches Splunk through Cribl or another pipeline that keeps or re-emits compact JSON, keep compact. A detection that fails there is showing you the same failure your production data has.

A layout setting reproduces the bytes, not the collector. It does not model what a pipeline itself does to events, such as pack transforms, masking or dropped events. Sending Tracemill's events through your real pipeline remains the most faithful setup.