Configuring logging

Configure logging for Keycloak.

Logging is a key mechanism for understanding and operating Keycloak. It should help you to monitor Keycloak’s health, debug issues, and maintain an audit trail of important events.

You can configure logging for the root log level or for more specific categories such as org.hibernate or org.keycloak. It is also possible to tailor log levels for each particular log handler.

In Keycloak, logging goes beyond setting log levels — you can direct output to different handlers, use asynchronous logging for performance, capture HTTP access logs, and more. These features make it possible to adapt logging to your operational needs and integrate with observability platforms.

Keycloak uses the JBoss Logging framework under the hood.

Available log handlers

Console
Logs to standard output

File
Persists logs to disk

Syslog
Sends logs to Syslog server

To enable log handlers, enter the following command:

bin/kc.[sh|bat] start --log="<handler1>,<handler2>"

For more details on how to configure specific log handlers, see:

Log levels

The following table defines the available log levels.

Level Description

FATAL

Critical failures with complete inability to serve any kind of request.

ERROR

A significant error or problem leading to the inability to process requests.

WARN

A non-critical error or problem that might not require immediate correction.

INFO

Keycloak lifecycle events or important information. Low frequency.

DEBUG

More detailed information for debugging purposes, such as database logs. Higher frequency.

TRACE

Most detailed debugging information. Very high frequency.

ALL

Special level for all log messages.

OFF

Special level to turn logging off entirely (not recommended).

Configuring the root log level

When no log level configuration exists for a more specific category logger, the enclosing category is used instead. When there is no enclosing category, the root logger level is used.

To set the root log level, enter the following command:

bin/kc.[sh|bat] start --log-level=<root-level>

Use these guidelines for this command:

  • For <root-level>, supply a level defined in the preceding table.

  • The log level is case-insensitive. For example, you could either use DEBUG or debug.

  • If you were to accidentally set the log level twice, the last occurrence in the list becomes the log level. For example, if you included the syntax --log-level="info,…​,DEBUG,…​", the root logger would be DEBUG.

Configuring category-specific log levels

You can set different log levels for specific areas in Keycloak. Use this command to provide a comma-separated list of categories for which you want a different log level:

bin/kc.[sh|bat] start --log-level="<root-level>,<org.category1>:<org.category1-level>"

A configuration that applies to a category also applies to its sub-categories unless you include a more specific matching sub-category.

Example
bin/kc.[sh|bat] start --log-level="INFO,org.hibernate:debug,org.hibernate.hql.internal.ast:info"

This example sets the following log levels:

  • Root log level for all loggers is set to INFO.

  • The hibernate log level in general is set to debug.

  • To keep SQL abstract syntax trees from creating verbose log output, the specific subcategory org.hibernate.hql.internal.ast is set to info. As a result, the SQL abstract syntax trees are omitted instead of appearing at the debug level.

Configuring levels as individual options

When configuring category-specific log levels, you can also set the log levels as individual log-level-<category> options instead of using the log-level option for that. This is useful when you want to set the log levels for selected categories without overwriting the previously set log-level option.

Example

If you start the server as:

bin/kc.[sh|bat] start --log-level="INFO,org.hibernate:debug"

you can then set an environmental variable KC_LOG_LEVEL_ORG_KEYCLOAK=trace to change the log level for the org.keycloak category.

The log-level-<category> options take precedence over log-level. This allows you to override what was set in the log-level option. For instance if you set KC_LOG_LEVEL_ORG_HIBERNATE=trace for the CLI example above, the org.hibernate category will use the trace level instead of debug.

Bear in mind that when using the environmental variables, the category name must be in uppercase and the dots must be replaced with underscores. When using other config sources, the category name must be specified "as is", for example:

bin/kc.[sh|bat] start --log-level="INFO,org.hibernate:debug" --log-level-org.keycloak=trace

Specify log level for each handler

The log-level property specifies the global root log level and levels for selected categories. However, a more fine-grained approach for log levels is necessary to comply with the modern application requirements.

To set log levels for particular handlers, properties in format log-<handler>-level (where <handler> is available log handler) were introduced.

It means properties for log level settings look like this:

  • log-console-level - Console log handler

  • log-file-level - File log handler

  • log-syslog-level - Syslog log handler

The log-<handler>-level properties are available only when the particular log handlers are enabled. More information in log handlers settings below.

Only log levels specified in Log levels section are accepted, and must be in lowercase. There is no support for specifying particular categories for log handlers yet.

General principle

It is necessary to understand that setting the log levels for each particular handler does not override the root level specified in the log-level property. Log handlers respect the root log level, which represents the maximal verbosity for the whole logging system. It means individual log handlers can be configured to be less verbose than the root logger, but not more.

Specifically, when an arbitrary log level is defined for the handler, it does not mean the log records with the log level will be present in the output. In that case, the root log-level must also be assessed. Log handler levels provide the restriction for the root log level, and the default log level for log handlers is all - without any restriction.

Examples

Example: debug for file handler, but info for console handler:
bin/kc.[sh|bat] start --log=console,file --log-level=debug --log-console-level=info

The root log level is set to debug, so every log handler inherits the value - so does the file log handler. To hide debug records in the console, we need to set the minimal (least severe) level to info for the console handler.

Example: warn for all handlers, but debug for file handler:
bin/kc.[sh|bat] start --log=console,file,syslog --log-level=debug --log-console-level=warn --log-syslog-level=warn

The root level must be set to the most verbose required level (debug in this case), and other log handlers must be amended accordingly.

Example: info for all handlers, but debug+org.keycloak.events:trace for Syslog handler:
bin/kc.[sh|bat] start --log=console,file,syslog --log-level=debug,org.keycloak.events:trace, --log-syslog-level=trace --log-console-level=info --log-file-level=info

In order to see the org.keycloak.events:trace, the trace level must be set for the Syslog handler.

Adding context for log messages

Mapped Diagnostic Context (MDC) information in logs is Preview and is not fully supported. This feature is disabled by default.

To enable start the server with --features=preview or --features=log-mdc

You can enable additional context information for each log line like the current realm and client that is executing the request.

Use the option log-mdc-enabled to enable it.

Example configuration
bin/kc.[sh|bat] start --features=log-mdc --log-mdc-enabled=true
Example output
2025-06-20 14:13:01,772 {kc.clientId=security-admin-console, kc.realmName=master} INFO ...

Specify which keys to be added by setting the configuration option log-mdc-keys.

Use different JSON format for log handlers

Every log handler provides the ability to have structured log output in JSON format. It can be enabled by properties in the format log-<handler>-output=json (where <handler> is a log handler).

If you need a different format of the produced JSON, you can leverage the following JSON output formats:

  • default (default)

  • ecs

The ecs value refers to the ECS (Elastic Common Schema).

ECS is an open-source, community-driven specification that defines a common set of fields to be used with Elastic solutions. The ECS specification is being converged with OpenTelemetry Semantic Conventions with the goal of creating a single standard maintained by OpenTelemetry.

In order to change the JSON output format, properties in the format log-<handler>-json-format (where <handler> is a log handler) were introduced:

  • log-console-json-format - Console log handler

  • log-file-json-format - File log handler

  • log-syslog-json-format - Syslog log handler

Example

If you want to have JSON logs in ECS (Elastic Common Schema) format for the console log handler, you can enter the following command:

bin/kc.[sh|bat] start --log-console-output=json --log-console-json-format=ecs
Example Log Message
{"@timestamp":"2025-02-03T14:53:22.539484211+01:00","event.sequence":9608,"log.logger":"io.quarkus","log.level":"INFO","message":"Keycloak 999.0.0-SNAPSHOT on JVM (powered by Quarkus 3.17.8) started in 4.615s. Listening on: http://0.0.0.0:8080","process.thread.name":"main","process.thread.id":1,"mdc":{},"ndc":"","host.hostname":"host-name","process.name":"/usr/lib/jvm/jdk-21.0.3+9/bin/java","process.pid":77561,"data_stream.type":"logs","ecs.version":"1.12.2","service.environment":"prod","service.name":"Keycloak","service.version":"999.0.0-SNAPSHOT"}

Asynchronous logging

Keycloak supports asynchronous logging, which might be useful for deployments requiring high throughput and low latency. Asynchronous logging uses a separate thread to take care of processing all log records. The logging handlers are invoked in exactly the same way as with synchronous logging, only done in separate threads. You can enable asynchronous logging for all Keycloak log handlers. A dedicated thread will be created for every log handler with enabled asynchronous logging.

The underlying mechanism for asynchronous logging uses a queue for processing log records. Every new log record is added to the queue and then published to the particular log handler with enabled asynchronous logging. Every log handler has a different queue.

If the queue is already full, it blocks the main thread and waits for free space in the queue.

When to use asynchronous logging

  • You need lower latencies for incoming requests

  • You need higher throughput

  • You have small worker thread pool and want to offload logging to separate threads

  • You want to reduce the impact of I/O-heavy log handlers

  • You are logging to remote destinations (e.g., network syslog servers) and want to avoid blocking worker threads

Be aware that enabling asynchronous logging might bring some additional memory overhead due to the additional separate thread and the inner queue. In that case, it is not recommended to use it for resource-constrained environments. Additionally, unexpected server shutdowns create a risk of losing log records.

Enable asynchronous logging

You can enable asynchronous logging globally for all log handlers by using log-async property as follows:

bin/kc.[sh|bat] start --log-async=true

Or you can enable the asynchronous logging for every specific handler by using properties in the format log-<handler>-async (where <handler> is a log handler). If the property for a specific handler is not set, the value from the parent log-async property is used.

You can use these properties as follows:

bin/kc.[sh|bat] start --log-console-async=true --log-file-async=true --log-syslog-async=true
  • log-console-async - Console log handler

  • log-file-async - File log handler

  • log-syslog-async - Syslog log handler

Change queue length

You can change the size of the queue used for the asynchronous logging. The default size is 512 log records in the queue.

You can change the queue length as follows:

bin/kc.[sh|bat] start --log-console-async-queue-length=512 --log-file-async-queue-length=512 --log-syslog-async-queue-length=512

These properties are available only when asynchronous logging is enabled for these specific log handlers.

HTTP Access Logging

Keycloak supports HTTP access logging to record details of incoming HTTP requests. While access logs are often used for debugging and traffic analysis, they are also important for security auditing and compliance monitoring, helping administrators track access patterns, identify suspicious activity, and maintain audit trails.

These logs are written at the INFO level, so make sure your logging configuration includes this level — either globally (e.g. log-level=info) or specifically for the access log category (e.g. log-level=org.keycloak.http.access-log:info). When HTTP access logs are enabled, they are shown by default, as INFO level is the default log level for Keycloak.

How to enable

You can enable HTTP access logging by using http-access-log-enabled property as follows:

bin/kc.[sh|bat] start --http-access-log-enabled=true

Change log format/pattern

You can change format/pattern of the access log records by using http-access-log-pattern property as follows:

bin/kc.[sh|bat] start --http-access-log-pattern=combined

Predefined named patterns:

  • common (default) - prints basic information about the request

  • combined - prints basic information about the request + information about referer and user agent

  • long - prints comprehensive information about the request with all its headers

You can even specify your own pattern with your required data to be logged, such as:

bin/kc.[sh|bat] start --http-access-log-pattern='%A %{METHOD} %{REQUEST_URL} %{i,User-Agent}'

Consult the Quarkus documentation for the full list of variables that can be used.

Exclude specific URL paths

It is possible to exclude specific URL paths from the HTTP access logging, so they will not be recorded.

You can use regular expressions to exclude them, such as:

bin/kc.[sh|bat] start --http-access-log-exclude='/realms/my-internal-realm/.*'

In this case, all calls to the /realms/my-internal-realm/ and subsequent paths will be excluded from the HTTP Access log.

Relevant options

Type or Values Default

log

Enable one or more log handlers in a comma-separated list.

CLI: --log
Env: KC_LOG

console, file, syslog

console

log-async

Indicates whether to log asynchronously to all handlers.

CLI: --log-async
Env: KC_LOG_ASYNC

true, false

false

log-level

The log level of the root category or a comma-separated list of individual categories and their levels.

For the root category, you don’t need to specify a category.

CLI: --log-level
Env: KC_LOG_LEVEL

List

info

log-level-<category>

The log level of a category.

Takes precedence over the log-level option.

CLI: --log-level-<category>
Env: KC_LOG_LEVEL_<CATEGORY>

off, fatal, error, warn, info, debug, trace, all

Console

Type or Values Default

log-console-async

Indicates whether to log asynchronously to console.

If not set, value from the parent property log-async is used.

CLI: --log-console-async
Env: KC_LOG_CONSOLE_ASYNC

Available only when Console log handler is activated

true, false

false

log-console-async-queue-length

The queue length to use before flushing writing when logging to console.

CLI: --log-console-async-queue-length
Env: KC_LOG_CONSOLE_ASYNC_QUEUE_LENGTH

Available only when Console log handler is activated and asynchronous logging is enabled

Integer

512

log-console-color

Enable or disable colors when logging to console.

If this is not present then an attempt will be made to guess if the terminal supports color.

CLI: --log-console-color
Env: KC_LOG_CONSOLE_COLOR

Available only when Console log handler is activated

true, false

log-console-format

The format of unstructured console log entries.

If the format has spaces in it, escape the value using "<format>".

CLI: --log-console-format
Env: KC_LOG_CONSOLE_FORMAT

Available only when Console log handler is activated

String

%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%c] (%t) %s%e%n

log-console-include-mdc

Include mdc information in the console log.

If the log-console-format option is specified, this option has no effect.

CLI: --log-console-include-mdc
Env: KC_LOG_CONSOLE_INCLUDE_MDC

Available only when Console log handler and MDC logging are activated

true, false

true

log-console-include-trace

Include tracing information in the console log.

If the log-console-format option is specified, this option has no effect.

CLI: --log-console-include-trace
Env: KC_LOG_CONSOLE_INCLUDE_TRACE

Available only when Console log handler and Tracing is activated

true, false

true

log-console-json-format

Set the format of the produced JSON.

CLI: --log-console-json-format
Env: KC_LOG_CONSOLE_JSON_FORMAT

Available only when Console log handler is activated and output is set to 'json'

default, ecs

default

log-console-level

Set the log level for the console handler.

It specifies the most verbose log level for logs shown in the output. It respects levels specified in the log-level option, which represents the maximal verbosity for the whole logging system. For more information, check the Logging guide.

CLI: --log-console-level
Env: KC_LOG_CONSOLE_LEVEL

Available only when Console log handler is activated

off, fatal, error, warn, info, debug, trace, all

all

log-console-output

Set the log output to JSON or default (plain) unstructured logging.

CLI: --log-console-output
Env: KC_LOG_CONSOLE_OUTPUT

Available only when Console log handler is activated

default, json

default

File

Type or Values Default

log-file

Set the log file path and filename.

CLI: --log-file
Env: KC_LOG_FILE

Available only when File log handler is activated

File

data/log/keycloak.log

log-file-async

Indicates whether to log asynchronously to file log.

If not set, value from the parent property log-async is used.

CLI: --log-file-async
Env: KC_LOG_FILE_ASYNC

Available only when File log handler is activated

true, false

false

log-file-async-queue-length

The queue length to use before flushing writing when logging to file log.

CLI: --log-file-async-queue-length
Env: KC_LOG_FILE_ASYNC_QUEUE_LENGTH

Available only when File log handler is activated and asynchronous logging is enabled

Integer

512

log-file-format

Set a format specific to file log entries.

CLI: --log-file-format
Env: KC_LOG_FILE_FORMAT

Available only when File log handler is activated

String

%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%c] (%t) %s%e%n

log-file-include-mdc

Include MDC information in the file log.

If the log-file-format option is specified, this option has no effect.

CLI: --log-file-include-mdc
Env: KC_LOG_FILE_INCLUDE_MDC

Available only when File log handler and MDC logging are activated

true, false

true

log-file-include-trace

Include tracing information in the file log.

If the log-file-format option is specified, this option has no effect.

CLI: --log-file-include-trace
Env: KC_LOG_FILE_INCLUDE_TRACE

Available only when File log handler and Tracing is activated

true, false

true

log-file-json-format

Set the format of the produced JSON.

CLI: --log-file-json-format
Env: KC_LOG_FILE_JSON_FORMAT

Available only when File log handler is activated and output is set to 'json'

default, ecs

default

log-file-level

Set the log level for the file handler.

It specifies the most verbose log level for logs shown in the output. It respects levels specified in the log-level option, which represents the maximal verbosity for the whole logging system. For more information, check the Logging guide.

CLI: --log-file-level
Env: KC_LOG_FILE_LEVEL

Available only when File log handler is activated

off, fatal, error, warn, info, debug, trace, all

all

log-file-output

Set the log output to JSON or default (plain) unstructured logging.

CLI: --log-file-output
Env: KC_LOG_FILE_OUTPUT

Available only when File log handler is activated

default, json

default

Syslog

Type or Values Default

log-syslog-app-name

Set the app name used when formatting the message in RFC5424 format.

CLI: --log-syslog-app-name
Env: KC_LOG_SYSLOG_APP_NAME

Available only when Syslog is activated

String

keycloak

log-syslog-async

Indicates whether to log asynchronously to Syslog.

If not set, value from the parent property log-async is used.

CLI: --log-syslog-async
Env: KC_LOG_SYSLOG_ASYNC

Available only when Syslog is activated

true, false

false

log-syslog-async-queue-length

The queue length to use before flushing writing when logging to Syslog.

CLI: --log-syslog-async-queue-length
Env: KC_LOG_SYSLOG_ASYNC_QUEUE_LENGTH

Available only when Syslog is activated and asynchronous logging is enabled

Integer

512

log-syslog-counting-framing

If true, the message being sent is prefixed with the size of the message.

If protocol-dependent, the default value is true when log-syslog-protocol is tcp or ssl-tcp, otherwise false.

CLI: --log-syslog-counting-framing
Env: KC_LOG_SYSLOG_COUNTING_FRAMING

Available only when Syslog is activated

true, false, protocol-dependent

protocol-dependent

log-syslog-endpoint

Set the IP address and port of the Syslog server.

CLI: --log-syslog-endpoint
Env: KC_LOG_SYSLOG_ENDPOINT

Available only when Syslog is activated

String

localhost:514

log-syslog-format

Set a format specific to Syslog entries.

CLI: --log-syslog-format
Env: KC_LOG_SYSLOG_FORMAT

Available only when Syslog is activated

String

%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%c] (%t) %s%e%n

log-syslog-include-mdc

Include MDC information in the Syslog.

If the log-syslog-format option is specified, this option has no effect.

CLI: --log-syslog-include-mdc
Env: KC_LOG_SYSLOG_INCLUDE_MDC

Available only when Syslog handler and MDC logging are activated

true, false

true

log-syslog-include-trace

Include tracing information in the Syslog.

If the log-syslog-format option is specified, this option has no effect.

CLI: --log-syslog-include-trace
Env: KC_LOG_SYSLOG_INCLUDE_TRACE

Available only when Syslog handler and Tracing is activated

true, false

true

log-syslog-json-format

Set the format of the produced JSON.

CLI: --log-syslog-json-format
Env: KC_LOG_SYSLOG_JSON_FORMAT

Available only when Syslog is activated and output is set to 'json'

default, ecs

default

log-syslog-level

Set the log level for the Syslog handler.

It specifies the most verbose log level for logs shown in the output. It respects levels specified in the log-level option, which represents the maximal verbosity for the whole logging system. For more information, check the Logging guide.

CLI: --log-syslog-level
Env: KC_LOG_SYSLOG_LEVEL

Available only when Syslog is activated

off, fatal, error, warn, info, debug, trace, all

all

log-syslog-max-length

Set the maximum length, in bytes, of the message allowed to be sent.

The length includes the header and the message. If not set, the default value is 2048 when log-syslog-type is rfc5424 (default) and 1024 when log-syslog-type is rfc3164.

CLI: --log-syslog-max-length
Env: KC_LOG_SYSLOG_MAX_LENGTH

Available only when Syslog is activated

String

log-syslog-output

Set the Syslog output to JSON or default (plain) unstructured logging.

CLI: --log-syslog-output
Env: KC_LOG_SYSLOG_OUTPUT

Available only when Syslog is activated

default, json

default

log-syslog-protocol

Set the protocol used to connect to the Syslog server.

CLI: --log-syslog-protocol
Env: KC_LOG_SYSLOG_PROTOCOL

Available only when Syslog is activated

tcp, udp, ssl-tcp

tcp

log-syslog-type

Set the Syslog type used to format the sent message.

CLI: --log-syslog-type
Env: KC_LOG_SYSLOG_TYPE

Available only when Syslog is activated

rfc5424, rfc3164

rfc5424

HTTP Access log

Type or Values Default

http-access-log-enabled

If HTTP access logging is enabled.

By default this will log records in console.

CLI: --http-access-log-enabled
Env: KC_HTTP_ACCESS_LOG_ENABLED

true, false

false

http-access-log-exclude

A regular expression that can be used to exclude some paths from logging.

For instance, /realms/my-realm/.* will exclude all subsequent endpoints for realm my-realm from the log.

CLI: --http-access-log-exclude
Env: KC_HTTP_ACCESS_LOG_EXCLUDE

Available only when HTTP Access log is enabled

String

http-access-log-pattern

The HTTP access log pattern.

You can use the available named formats, or use custom format described in Quarkus documentation.

CLI: --http-access-log-pattern
Env: KC_HTTP_ACCESS_LOG_PATTERN

Available only when HTTP Access log is enabled

common, combined, long, or any

common

Mapped Diagnostic Context (MDC)

Type or Values Default

log-mdc-enabled

Indicates whether to add information about the realm and other information to the mapped diagnostic context.

All elements will be prefixed with kc.

CLI: --log-mdc-enabled
Env: KC_LOG_MDC_ENABLED

Available only when log-mdc preview feature is enabled

true, false

false

log-mdc-keys

Defines which information should be added to the mapped diagnostic context as a comma-separated list.

CLI: --log-mdc-keys
Env: KC_LOG_MDC_KEYS

Available only when MDC logging is enabled

realmName, clientId, userId, ipAddress, org, sessionId, authenticationSessionId, authenticationTabId

realmName,clientId,org,sessionId,authenticationSessionId,authenticationTabId

On this page