Skip to main content

Telemetry Export

Stream your dedicated cluster's Keycloak logs and authentication events to your own observability system over OTLP, the OpenTelemetry wire protocol. You give us an endpoint and a token; we deliver continuously.

This is for teams who already run an observability stack and want Keycloak data alongside everything else — correlated with application traces, retained under their own policy, queried with their own tools.

Available on Enterprise. Your logs and events keep working exactly as they are — upgrading adds the ability to stream them to a destination you operate. Compare plans or change your plan from Clusters > Cluster > Config > Subscription.

Experimental

Telemetry Export is experimental and unsupported. The record shape, the attribute names, and the configuration options may change in a backwards-incompatible way. Do not build production alerting or compliance reporting on it yet, and tell us at support@phasetwo.io if you want to try it — it is not enabled on every account, even on Enterprise.

What you need

  • An Enterprise dedicated cluster. The Logs → Export page shows an upgrade note on Starter and Premium, and the API refuses the request with a 403.
  • An HTTPS OTLP logs endpoint, reachable from the public internet, with a certificate signed by a public CA. Certificates are verified — a self-signed certificate will not work.
  • A bearer token for that endpoint.

The endpoint must resolve to a public address. Private, loopback, link-local, and reserved ranges are rejected, and so is any hostname that fails to resolve at all. If your collector sits inside a private network, put a public gateway in front of it and allowlist our egress IP addresses.

Turning it on

  1. Open your cluster in the self-service dashboard and go to Logs → Export.
  2. Switch on Enable export.
  3. Enter your Endpoint, for example https://otel.example.com:443.
  4. Choose a ProtocolOTLP over HTTP (recommended) or OTLP over gRPC. HTTP traverses load balancers, proxies, and WAFs far more reliably.
  5. Paste your Authorization token. It is sent as Authorization: Bearer <token>, stored encrypted, and never displayed again.
  6. Use Test endpoint to check the address before committing to it. This changes nothing.
  7. Save.

Changes take a couple of minutes to take effect, not seconds. Configuration propagates to the export service in your cluster's region and is applied without restarting anything.

The endpoint path

For OTLP over HTTP, the logs path is appended for you. Give us the base URL — https://otel.example.com:443 becomes https://otel.example.com:443/v1/logs. If your collector serves OTLP under a prefix, include it (https://otel.example.com/telemetry) and we will append /v1/logs to that.

What you receive

Everything arrives as the OTLP logs signal. Keycloak authentication events are delivered as structured log records, not as traces or metrics.

Resource attributes

Set once per batch, on every record:

AttributeValue
service.namekeycloak
service.namespacephasetwo
deployment.environment.nameproduction
phasetwo.cluster.idyour cluster name
phasetwo.regionthe region your cluster runs in

Nothing about Phase Two's own infrastructure is included — no pod names, node names, internal addresses, or account identifiers.

Telling logs and events apart

Every record body carries phasetwo.signal, which is log or event. This is the field to filter on first:

phasetwo.signal:"event" AND keycloak.event.type:"LOGIN_ERROR"

Log records

Keycloak server logs, scoped to the org.keycloak.* and io.phasetwo.* loggers. JVM, Quarkus, connection-pool, and clustering internals are not exported.

FieldContains
log_messagethe log message
loggerNamethe Java logger
threadNamethe emitting thread
mdcKeycloak's mapped diagnostic context — realm, user, client where present
stackTrace, exception.type, exception.messagepresent on errors
phasetwo.signallog

SeverityText and SeverityNumber come from the log level, so severity >= WARN works in your backend.

Event records

Authentication and admin events, rebuilt from Keycloak's event data into flat attributes so you can query them semantically rather than pattern-matching log text.

AttributeFrom
keycloak.event.classUSER or ADMIN
keycloak.event.typeLOGIN, LOGIN_ERROR, REGISTER, LOGOUT, …
keycloak.event.idevent id
keycloak.event.errorerror code, when the event failed
keycloak.realm.id, keycloak.realm.namethe realm
keycloak.user.idthe end user
keycloak.client.idthe OIDC client
keycloak.session.idthe session
client.addressthe end user's IP address
keycloak.event.detailsthe event details, as a JSON string
phasetwo.signalevent

Admin events additionally carry keycloak.operation.type, keycloak.resource.type, keycloak.resource.path, keycloak.auth.user.id, keycloak.auth.client.id, keycloak.auth.realm.id, keycloak.auth.realm.name, keycloak.event.representation, and client.address for the acting administrator.

keycloak.event.details and keycloak.event.representation stay JSON strings rather than being flattened. Their shape varies by event type, and expanding them would produce an unbounded set of fields — expensive on a metrics-billed backend, and enough to breach field limits on some search backends. Parse them on your side if you need them.

Event timestamps are the event's own time, not the time the log line was written.

Event severity is derived, not inherited. Keycloak logs a failed login at INFO, which is not useful to you. We set WARN when the event carries an error and INFO otherwise, so severity >= WARN is a working filter for authentication failures.

Events contain end-user data

Exported events include end-user IP addresses and user IDs in the clear. This is the same data Keycloak records internally. Make sure the destination is an appropriate place for it under your own data-protection obligations before you enable export.

Where it works

Anything that accepts OTLP logs. Customers are running it against:

An OpenTelemetry Collector in front of your own storage is the most flexible option: it gives you a place to re-map attributes, drop fields, or fan out to more than one destination without changing anything here.

Delivery, retries, and failure

Delivery is continuous and buffered, per cluster.

  • If your endpoint is slow or briefly unavailable, records queue on disk and are retried until it comes back. Nothing is lost, and delivery to other customers is unaffected.
  • If your endpoint stays unavailable for a long time, the queue eventually reaches its limit and the oldest records are discarded. How long that takes depends on your cluster's volume — typically days, not hours.
  • Turning export off stops delivery immediately and discards anything still queued. That is deliberate: a destination you have switched off should stop receiving data.

Phase Two alerts internally when a cluster's export stops delivering or starts dropping records, and we will get in touch. We cannot tell whether your backend accepted a record after we delivered it — a token your collector rejects looks like a failed delivery; a record your pipeline silently drops does not. Check your own backend after enabling export rather than assuming success.

The Delivery status panel on the export page does not yet report live delivery state. Treat it as unimplemented for now.

Current limitations

These are real and deliberate. All of them are things we expect to change.

  • Enterprise only. Not available on Starter or Premium.
  • Logs and events are all or nothing. You cannot export events without logs, or the reverse.
  • Scope is Keycloak only. JVM and container internals are never exported and cannot be requested.
  • Logs signal only. No metrics, no traces. Keycloak does not emit traces, and metrics export is separate work.
  • One destination per cluster. Fan out on your side with a collector.
  • No filtering or sampling before delivery. Everything in scope is sent.
  • No redaction option. Records are exported as Keycloak produces them.