Event Output Structure¶
Tracee outputs events using the v1beta1.Event protobuf structure, providing a stable, well-documented format for event data across all output formats (JSON, Go templates, webhooks, etc.).
Event Structure Overview¶
The event structure is defined in the API protobuf definitions and consists of several key components:
Core Event Fields¶
message Event {
google.protobuf.Timestamp timestamp = 1; // Event timestamp
EventId id = 2; // Event ID (enum)
string name = 3; // Event name
Policies policies = 4; // Matched policies
Workload workload = 5; // Process/container context
repeated EventValue data = 6; // Event-specific data
Threat threat = 7; // Threat information (detectors)
Event detected_from = 8; // Source event (for detector events)
}
Workload Context¶
Contains information about the process, container, and Kubernetes context:
message Workload {
Process process = 1; // Process information
Container container = 2; // Container information
Pod pod = 3; // Kubernetes pod information
}
Process Information¶
message Process {
Thread thread = 1; // Thread details (name, TID, etc.)
google.protobuf.UInt32Value pid = 2; // Process ID
User real_user = 3; // Real user ID
Executable executable = 4; // Executable path and metadata
repeated Process ancestors = 5; // Process ancestors
// ... other fields
}
JSON Output Example¶
{
"timestamp": {
"seconds": "1732454400",
"nanos": 123456789
},
"id": "sched_process_exec",
"name": "sched_process_exec",
"policies": {
"matched": ["default-policy"]
},
"workload": {
"process": {
"thread": {
"name": "bash",
"start_time": {
"seconds": "1732454350"
},
"unique_id": 1234567890,
"host_tid": 12345,
"tid": 12345,
"syscall": "execve"
},
"pid": {
"value": 12345
},
"real_user": {
"id": {
"value": 1000
}
},
"executable": {
"path": "/usr/bin/bash"
},
"ancestors": [
{
"unique_id": 9876543210,
"host_pid": 1234,
"pid": 1234
}
]
}
},
"data": [
{
"name": "pathname",
"str": "/usr/bin/ls"
},
{
"name": "argv",
"str_array": {
"value": ["ls", "-la", "/tmp"]
}
}
]
}
Threat Detection Events¶
Events generated by detectors include additional threat information:
{
"timestamp": {...},
"id": 6003,
"name": "FILE_MODIFICATION",
"policies": {
"matched": ["file-modification-test"]
},
"workload": {...},
"threat": {
"name": "File Modification Test",
"description": "Instrumentation events E2E Tests: File Modification",
"mitre": {
"tactic": {},
"technique": {}
},
"properties": {
"id": "TRC-5",
"signatureID": "FILE_MODIFICATION"
}
},
"detected_from": {
"id": 776,
"name": "file_modification",
"data": [...]
}
}
Migration Guide for Template Users¶
If you're using Go templates, update your field references:
Field Name Changes¶
| Old Field (trace.Event) | New Field (v1beta1.Event) | Notes |
|---|---|---|
.EventName |
.name |
String, event name |
.Timestamp |
.timestamp.seconds |
Unix timestamp in seconds |
| - | .timestamp.nanos |
Nanosecond fraction |
.ProcessName |
.workload.process.thread.name |
Process/thread name (comm) |
.ProcessID |
.workload.process.pid.value |
Wrapped uint32 |
.UserID |
.workload.process.real_user.id.value |
Wrapped uint32 |
.Args |
.data |
Array of EventValue |
.MatchedPolicies |
.policies.matched |
Array of policy names |
.Container.ID |
.workload.container.id |
Container ID |
.Kubernetes.PodName |
.workload.pod.name |
Pod name |
Template Examples¶
Before:
Event: {{.EventName}}
Process: {{.ProcessName}} (PID: {{.ProcessID}})
Time: {{.Timestamp}}
{{range .Args}}
{{.Name}}: {{.Value}}
{{end}}
After:
Event: {{.name}}
Process: {{if .workload}}{{if .workload.process}}{{if .workload.process.thread}}{{.workload.process.thread.name}}{{end}}{{end}}{{end}} (PID: {{if .workload}}{{if .workload.process}}{{if .workload.process.pid}}{{.workload.process.pid.value}}{{end}}{{end}}{{end}})
Time: {{if .timestamp}}{{.timestamp.seconds}}{{end}}
{{range .data}}
{{.name}}: {{.value}}
{{end}}
Simplified with better null handling:
{{- define "processName" -}}
{{- if and .workload .workload.process .workload.process.thread -}}
{{.workload.process.thread.name}}
{{- else -}}
<unknown>
{{- end -}}
{{- end -}}
{{- define "pid" -}}
{{- if and .workload .workload.process .workload.process.pid -}}
{{.workload.process.pid.value}}
{{- else -}}
0
{{- end -}}
{{- end -}}
Event: {{.name}}
Process: {{template "processName" .}} (PID: {{template "pid" .}})
Time: {{.timestamp.seconds}}.{{.timestamp.nanos}}
{{range .data}}
{{.name}}: {{.value}}
{{end}}
Accessing Event Data¶
Event-specific data is in the .data array. Each item has a .name and a typed .value field:
{{range .data}}
{{if eq .name "pathname"}}
File: {{.str}}
{{else if eq .name "fd"}}
FD: {{.int32}}
{{else if eq .name "count"}}
Count: {{.u_int64}}
{{end}}
{{end}}
Event Value Types¶
The .data array contains EventValue messages with typed union fields:
.str- String value.int32,.int64- Signed integers.u_int32,.u_int64- Unsigned integers.bool- Boolean value.bytes- Raw bytes.str_array- String array.u_int64_array- Uint64 array.sockaddr- Socket address (IP, port).credentials- User credentials.ipv4,.ipv6- IP packet metadata.tcp,.udp,.icmp,.icmpv6- Protocol-specific data.dns_questions,.dns_responses- DNS data.packet_metadata- Packet direction (ingress/egress)
Protobuf Definition¶
For the complete and authoritative event structure, see:
- event.proto - Main event structure
- event_data.proto - EventValue types
- workload.proto - Workload/process context
Backwards Compatibility¶
Signature Development: Signatures still work with the internal trace.Event structure via protocol.Event.Payload. No changes are needed for signature code.
Output Only: The v1beta1.Event structure applies only to output formats (JSON, templates, gRPC, webhooks).
See Also¶
- Output Formats - How to format event output
- Go Templates - Using event fields in templates
- Output Overview - Output system overview
- Events Documentation - Available event types