Audit Logs
The Logs page (/logs) combines immutable audit history with live operational logs for incident response and governance.
Audit trail
The audit tab records every state-changing action in the system. Each entry is immutable and timestamped.
Audit event structure
{
"id": "evt_a1b2c3d4",
"timestamp": "2026-02-21T14:32:10Z",
"actor": {
"type": "user",
"id": "usr_abc123",
"email": "alice@acme.com"
},
"action": "model.version.published",
"resource": {
"type": "model_version",
"id": "mv_xyz789",
"name": "classifier-v2.1.0"
},
"result": "success",
"metadata": {
"previous_version": "2.0.0",
"rollout_percentage": 10,
"ip_address": "203.0.113.42"
}
}
Filtering
Filter the audit feed by:
| Filter | Description | Example |
|---|---|---|
| Actor | User, API key, or system | alice@acme.com |
| Action | Event type | model.deployed, device.registered, round.completed |
| Resource | Resource type or ID | model_version, mv_xyz789 |
| Result | Success or failure | failure |
| Time window | Date range | Last 24 hours, last 7 days, custom range |
Common audit actions
| Action | Description |
|---|---|
model.version.created | New model version uploaded |
model.version.published | Version marked as available |
model.deployed | Rollout started |
model.rollback | Version rolled back |
round.started | Training round initiated |
round.completed | Training round finished |
device.registered | New device registered |
device.revoked | Device token revoked |
api_key.created | New API key generated |
api_key.revoked | API key revoked |
privacy.config.updated | Privacy settings changed |
Operational logs
The operational tab shows live server logs for debugging.
Fields
- Service — which server component emitted the log
- Level —
debug,info,warning,error - Request ID — correlates logs from a single API request
- Trace ID — correlates logs across distributed components
- Message — log content and structured payload
Investigating an incident
- Filter by level: error and the relevant time window.
- Copy the request ID from the error log.
- Filter by that request ID to see the full request lifecycle.
- Check the audit tab for the corresponding state change (or lack thereof).
Data export
Export audit logs as CSV
Click Export > CSV in the audit tab. The export includes all events matching your current filters.
Export operational logs as JSON
Click Export > JSON in the operational tab. Each line is a JSON object for easy ingestion into external SIEM tools (Splunk, Datadog, Elastic).
API export
Export audit events for the last 7 days:
- cURL
- Python
- JavaScript
curl "https://api.octomil.com/api/v1/audit/export?from=2026-02-14&to=2026-02-21&format=csv" \
-H "Authorization: Bearer edg_..." \
-o audit-export.csv
import requests
response = requests.get(
"https://api.octomil.com/api/v1/audit/export",
headers={"Authorization": "Bearer edg_..."},
params={"from": "2026-02-14", "to": "2026-02-21", "format": "csv"},
)
with open("audit-export.csv", "wb") as f:
f.write(response.content)
const params = new URLSearchParams({
from: "2026-02-14",
to: "2026-02-21",
format: "csv",
});
const response = await fetch(
`https://api.octomil.com/api/v1/audit/export?${params}`,
{
headers: { "Authorization": "Bearer edg_..." },
}
);
const blob = await response.blob();
// Save blob as audit-export.csv
Export operational logs:
- cURL
- Python
- JavaScript
curl "https://api.octomil.com/api/v1/logs/export?level=error&from=2026-02-20&format=json" \
-H "Authorization: Bearer edg_..." \
-o error-logs.json
import requests
response = requests.get(
"https://api.octomil.com/api/v1/logs/export",
headers={"Authorization": "Bearer edg_..."},
params={"level": "error", "from": "2026-02-20", "format": "json"},
)
with open("error-logs.json", "wb") as f:
f.write(response.content)
const params = new URLSearchParams({
level: "error",
from: "2026-02-20",
format: "json",
});
const response = await fetch(
`https://api.octomil.com/api/v1/logs/export?${params}`,
{
headers: { "Authorization": "Bearer edg_..." },
}
);
const blob = await response.blob();
// Save blob as error-logs.json
Real-time log streaming
For continuous log export (not just one-time downloads), configure log integrations in Settings > Log exports or via the CLI/SDK:
| Destination | Integration type | Format |
|---|---|---|
| Splunk HEC | splunk | hec |
| Elasticsearch | elasticsearch | json |
| Datadog | datadog | json |
| CloudWatch | cloudwatch | json |
| OTLP Collector | otlp | otlp |
| Custom webhook | webhook | json or syslog |
The easiest way to get started is the unified OTLP collector:
octomil integrations connect-otlp --endpoint http://otel-collector:4318
This configures both metrics and log export in one step. See Export Metrics for details.
Compliance and retention
Audit retention policy is configured in Workspace Settings:
| Preset | Retention period | Use case |
|---|---|---|
| Default | 90 days | Standard operations |
| HIPAA | 6 years | Healthcare compliance |
| GDPR | Per data subject request | EU data privacy |
| SOC 2 | 1 year | Security audits |
Audit events are stored immutably — they cannot be edited or deleted within the retention window. After the retention period expires, events are purged automatically.