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
| Setting | CLI flag | Pipeline config | Values |
|---|---|---|---|
| JSON separators | --json-separators | json_separators | compact (default), spaced |
| HEC event embedding | --hec-event | hec_event (HEC only) | object (default), string |
compactwrites 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.spacedwrites": "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'sjson.dumps.objectembeds the event in the HEC envelope as a JSON object.stringsends the rendered event as the HECeventstring, so Splunk indexes_rawbyte 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, layoutSwap 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: spacedon 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.