Skip to main content
Version: Next

Logs

O2ID captures structured log entries — leveled (debug/info/warn/error) and tagged with the resource(s) each entry is about (user, application, role, ...) — that you can query and tail.

note

Reading logs requires a role with the logs:read scope — see Managing Roles for how to create and assign roles.

What gets captured

  • Auth-flow events (login attempts, token issuance, consent decisions).
  • One entry per mutating management API request (POST/PATCH/PUT/ DELETE), tagged with the resource type and ID from the request path.

Enabling and disabling levels

Which levels are captured is an explicit list rather than a min-level threshold — so you can enable non-contiguous combinations (e.g. debug and error without info/warn) if that's what you want, not just "this level and everything above it". A level left off the list is entirely off: no entries at that level are recorded, streamed, or shipped to remote sinks.

Levels are per-tenant, the same way remote log publishing already is — useful if one tenant wants debug-level detail flowing to their own log-webhook destination while others don't. Set them with:

o2idctl tenant-settings update --log-level info --log-level warn --log-level error

Repeat --log-level to enable more than one. This takes effect immediately — no restart required.

o2idctl tenant-settings update --clear-log-levels

Falls this tenant back to the platform's own default level set, configured platform-wide in o2id.toml:

[logging]
levels = ["info", "warn", "error"] # default for tenants with no override
retention = "168h" # how long entries are kept (7 days)
stdout = true # also print every entry to stdout

retention and stdout apply to every tenant sharing the process and require restarting o2id serve to change — there's no live config reload for those. levels in o2id.toml only matters as the fallback for a tenant that hasn't set its own override.

debug entries include request-flow detail (usernames, request internals) you generally don't want captured by default — enable it only while diagnosing an issue, and disable it again afterward.

Listing entries

o2idctl logs list
o2idctl logs list --level info --level error --component users
o2idctl logs list --user <user-id>
o2idctl logs list --since 2026-01-01T00:00:00Z --limit 50

Results are newest first. Resource flags: --user, --application, --role, --agent, --resource-server, --connection, --authenticator, --flow, --organization.

Tailing entries live

o2idctl logs tail
o2idctl logs tail --component oauth2 --application <application-id>

Streams newly captured entries matching the given filters until you stop it with Ctrl-C.

Shipping logs to a remote destination

Configure a log-webhook connection to deliver every captured entry to an HTTPS endpoint of your choice, HMAC-signed so the receiver can verify it came from your tenant:

o2idctl connections add --type log-webhook --name "SIEM Export" \
--field url=https://siem.example.com/ingest

See Managing Connections for how connections work generally.