Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Request log format

For every HTTP request it serves, the service emits a single structured log line once the response is ready. These lines are emitted on the http.server.response tracing event, at a level derived from the response status code:

  • INFO for 1xx3xx responses,
  • WARN for 4xx responses,
  • ERROR for 5xx responses.

They are designed to be ingested by log analysis systems, to keep an audit trail and to classify activity such as logins, logouts and token issuance. Combined with the client.address and requester fields, each request can be attributed to a client IP and to the user or client that made it.

Example

2026-06-17T10:49:22.419912Z  INFO http.server.response POST-71 - "POST /login HTTP/2.0" 303 See Other "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/26.5 Safari/605.1.15" [polls: 12, cpu: 5.5ms, elapsed: 57.9ms] requester=user:01H8VZ…(alice) client.address=2a01:e0a:f5c:5b02:85c9:3849:4811:4383 trace.id=c8c8fc32288a76693e028ee97a6030a0

Broken down:

PartExampleMeaning
Timestamp2026-06-17T10:49:22.419912ZWhen the line was logged (response time), in UTC.
LevelINFOLog level, derived from the status code (see above).
Eventhttp.server.responseThe event name; filter on this to select request logs.
Request idPOST-71The request method followed by a process-unique counter. Every log line emitted while handling the same request shares this id, so it can be used to correlate them.
Request line"POST /login HTTP/2.0"The HTTP method, path and protocol version. The path does not include the query string.
Status303 See OtherThe response status code and its reason phrase.
User agent"Mozilla/5.0 …"The User-Agent header, or "-" if absent.
Stats[polls: 12, cpu: 5.5ms, elapsed: 57.9ms]How many times the request task was polled, the CPU time it used, and the wall-clock time elapsed handling it.

Fields

The following structured fields are appended to the line. Several are only present when applicable, so a missing field is meaningful in itself.

FieldExampleMeaning
requesteruser:01H8VZ…(alice)Who the request is attributed to. One of user:<id>(<username>), user:<id> (when the username isn’t loaded), oauth2-client:<id>, or homeserver. Absent for unauthenticated requests (e.g. a login page before logging in).
client.address2a01:e0a:…The client IP address (OpenTelemetry client.address), inferred from the connection and the trusted proxy configuration. Absent if it couldn’t be determined.
graphql.operation.typequeryFor /graphql requests only: the type of the executed operation, one of query, mutation or subscription.
graphql.operation.nameCurrentUserGreetingFor /graphql requests only: the name of the executed operation, when the query document names it.
trace.idc8c8fc32…The OpenTelemetry trace id, to correlate the line with a distributed trace.

requester reflects who the request acted as. For a token request it is the OAuth 2.0 client, not the end user the token is for; for the introspection endpoint it is the calling client or the homeserver, not the token’s subject.

Classifying activity

Most activity can be classified from the method, path and status, with the requester field telling you who performed it. A 303 See Other typically means the action succeeded and the browser is being redirected, while a 200 OK on a form-submitting endpoint usually means the form was re-rendered with an error.

ActivityRequestSuccess looks like
Browser loginPOST /login303 See Other with a requester (a 200 OK re-renders the form, e.g. on a wrong password)
Browser logoutPOST /logout303 See Other with the requester being the user that was logged out
RegistrationGET /register/steps/…/finish303 See Other with the newly-created user as requester
Login via an upstream providerPOST /upstream/link/…303 See Other with a requester
Matrix client login (compatibility layer)POST /_matrix/client/*/login200 OK with a requester
Matrix client logoutPOST /_matrix/client/*/logout (and /logout/all)200 OK
Token issuancePOST /oauth2/token200 OK with an oauth2-client: requester
Token revocationPOST /oauth2/revoke200 OK with an oauth2-client: requester
Token introspectionPOST /oauth2/introspect200 OK, requester is the calling client or homeserver
Authorization grantGET/POST /authorizea 303 See Other once the user consents
Account self-service actionPOST /graphql200 OK; the actual activity is in graphql.operation.name (see below)

Account self-service operations (GraphQL)

The account management area (served at /account/) performs its actions (adding an email, changing the password, ending a session, and so on) as GraphQL mutations against POST /graphql, authenticated with the user’s session cookie. They are therefore attributed (the requester is the signed-in user), but the path alone can’t tell them apart: the activity is identified by graphql.operation.name.

The HTTP status is almost always 200 OK for GraphQL, even when the operation fails: GraphQL reports errors in the response body, not the status code. The log line tells you an operation was attempted by a given user, not whether it succeeded.

The notable operations sent by the bundled frontend (a custom client may use different names):

graphql.operation.nameActivity
AddEmail / DoVerifyEmail / RemoveEmailAdd, verify or remove an email address
ChangePassword / RecoverPasswordChange the password, or reset it via a recovery link
SetDisplayNameChange the display name
DeactivateUserDeactivate the account
AllowCrossSigningResetAllow resetting the cross-signing keys
EndBrowserSession / EndCompatSession / EndOAuth2SessionSign out a browser, Matrix-client or OAuth 2.0 session
SetCompatSessionName / SetOAuth2SessionNameRename a session