Event Format
SpecMon monitors applications by processing streams of events. This page describes the structure of events and how to provide them to SpecMon.
Event structure
Section titled “Event structure”Events are JSON objects with a timestamp and event data:
{ "time": 1700000000000000000, "event": { "name": "function_name", "type": "function", "args": [...] }}Fields
Section titled “Fields”| Field | Type | Description |
|---|---|---|
time | integer | Timestamp in nanoseconds (Unix epoch) |
event | object | The event data |
event.name | string | Name of the operation |
event.type | string | Always "function" |
event.args | array | Arguments to the operation |
Argument types
Section titled “Argument types”Arguments can be constants or nested function calls:
Constants
Section titled “Constants”Concrete values like keys, messages, or bytes:
{ "value": "0x1234abcd", "type": "constant"}- Hex strings (starting with
0x) represent byte arrays - Plain strings represent text values
- Integers can be JSON numbers or strings (go-annotate emits strings)
Functions
Section titled “Functions”Nested function calls with their own arguments:
{ "name": "hash", "type": "function", "args": [ {"value": "0x6d657373616765", "type": "constant"} ]}Common event patterns
Section titled “Common event patterns”Function call with return value
Section titled “Function call with return value”Most events represent a function call paired with its return value using the pair wrapper:
{ "time": 1700000000000000000, "event": { "name": "pair", "type": "function", "args": [ { "name": "hash", "type": "function", "args": [ {"value": "0x68656c6c6f", "type": "constant"} ] }, {"value": "0x2cf24dba...", "type": "constant"} ] }}This represents: hash("hello") = 0x2cf24dba...
The pair structure is: <function_call, return_value>
Input sources
Section titled “Input sources”SpecMon accepts events from multiple sources:
File input
Section titled “File input”specmon monitor protocol.spthy --in events.jsonOr via stdin:
cat events.json | specmon monitor protocol.spthy --in -Here --in - is optional.
TCP socket
Section titled “TCP socket”specmon monitor protocol.spthy --in localhost:8080SpecMon listens on the socket and the application connects to send events.
Pre-trace events
Section titled “Pre-trace events”Load initial state before processing live events:
specmon monitor protocol.spthy --pre-trace setup.json --in live-events.jsonPre-trace events establish facts (like long-term keys) before monitoring begins.
Requirements
Section titled “Requirements”- Use line-delimited JSON: One JSON object per line (lines starting with
//are ignored) - Use hex encoding for bytes: Prefix with
0xfor binary data - Pair function calls with results: Use the
pairwrapper consistently - Include timestamps: Allow per-event timing analysis
- Match specification names: Event function names should match rule triggers
- Handle encoding consistently: Use the same encoding throughout
Debugging events
Section titled “Debugging events”Validate format
Section titled “Validate format”Check that events are valid JSON:
cat events.json | jq .Inspect with verbose mode
Section titled “Inspect with verbose mode”specmon monitor --verbose protocol.spthy < events.jsonThis shows each event as it’s processed and which rules fire.
Common issues
Section titled “Common issues”Events not matching rules:
- Check function names match specification
- Verify argument order and types
- Ensure
pairwrapper is present for function calls with results
Timestamp issues:
- Use nanoseconds precision
- Check for clock skew in distributed systems
Encoding problems:
- Use
0xprefix for hex-encoded bytes - Ensure consistent string encoding (UTF-8)
Next steps
Section titled “Next steps”- Using go-annotate — Automatic Go instrumentation
- Using Frida — Dynamic instrumentation
- CLI Commands — Monitor command options