Export Audit Log
Filter audit events by time range, level, and action, iterate all pages, and serialize the results to JSON or CSV.
The Management API exposes every audited action taken against your project. This recipe shows you how to filter events by time range, level, and action category, then export them to JSON or CSV.
Setup
from datetime import datetime, timezone
from optixlog import SDKClient
from optixlog.management import Management
client = SDKClient(
base_url="https://optixlog.leidos.com",
api_key="sk-opt-xxxx",
)
mgmt = Management(client)
project = mgmt.project("proj_grating_7f3a")Filtering audit events
All filters are AND-combined. The most common filters are since, until, and level:
from datetime import datetime, timezone
events_page = project.audit_events.list(
since=datetime(2026, 1, 1, tzinfo=timezone.utc),
until=datetime(2026, 6, 1, tzinfo=timezone.utc),
level="warn",
limit=100,
order_by="timestamp",
order="asc",
)
print(f"Found {events_page.total} warn events in range")Available filters:
Prop
Type
Iterating all matching events
Use iter() to walk all pages without tracking cursors:
from datetime import datetime, timezone
events = list(project.audit_events.iter(
since=datetime(2026, 5, 1, tzinfo=timezone.utc),
level="error",
order_by="timestamp",
order="asc",
))
print(f"Collected {len(events)} error events")Exporting to JSON
import json
from datetime import datetime, timezone
events = list(project.audit_events.iter(
since=datetime(2026, 1, 1, tzinfo=timezone.utc),
order_by="timestamp",
order="asc",
))
records = [
{
"id": e.id,
"timestamp": e.timestamp.isoformat(),
"action": e.action,
"description": e.description,
"category": e.category,
"level": e.level,
"actor_id": e.actor_ref.id if e.actor_ref else None,
"actor_name": e.actor_ref.name if e.actor_ref else None,
"target_ids": [t.id for t in e.target_refs],
"request_id": e.request_id,
}
for e in events
]
with open("audit_export.json", "w") as f:
json.dump(records, f, indent=2)
print(f"Exported {len(records)} events to audit_export.json")Exporting to CSV
import csv
from datetime import datetime, timezone
events = list(project.audit_events.iter(
since=datetime(2026, 1, 1, tzinfo=timezone.utc),
order_by="timestamp",
order="asc",
))
fieldnames = ["id", "timestamp", "action", "description", "category",
"level", "actor_id", "actor_name", "request_id"]
with open("audit_export.csv", "w", newline="") as f:
writer = csv.DictWriter(f, fieldnames=fieldnames)
writer.writeheader()
for e in events:
writer.writerow({
"id": e.id,
"timestamp": e.timestamp.isoformat(),
"action": e.action,
"description": e.description,
"category": e.category,
"level": e.level,
"actor_id": e.actor_ref.id if e.actor_ref else "",
"actor_name": e.actor_ref.name if e.actor_ref else "",
"request_id": e.request_id or "",
})
print(f"Exported {len(events)} events to audit_export.csv")Counting events without fetching them
warn_count = project.audit_events.count(level="warn")
error_count = project.audit_events.count(level="error")
print(f"Warnings: {warn_count}, Errors: {error_count}")Looking up a single event
# By id.
event = project.audit_events.get("audit-event-id")
# Find the most recent project update.
latest_update = project.audit_events.first(action="project.updated")
if latest_update:
print(f"Last updated at {latest_update.timestamp}")
# Find exactly one event matching a request_id.
exact = project.audit_events.one(request_id="req-abc123")Audit event order
The default order for audit_events is "desc" (newest first). Pass order="asc" when you want chronological order for export.
List and Iterate Teams
Use the Management API to filter teams with AND filters, iterate all pages with iter(), count members, and read team memberships.
Project Snapshot Report
Use project.snapshot() to pull config, org, teams, members, nodes, and audit events in one call, then build a human-readable report.