<#import "/templates/guide.adoc" as tmpl>
<#import "/templates/kc.adoc" as kc>
<#import "/templates/links.adoc" as links>
<#import "/templates/profile.adoc" as profile>

<@tmpl.guide
title="Configuring logging"
summary="Learn how to configure Logging"
includedOptions="log log-*">

{project_name} uses the JBoss Logging framework. The following is a high-level overview for the available log handlers:

* root
** console (_default_)
** file
** Syslog

== Logging configuration
Logging is done on a per-category basis in {project_name}. You can configure logging for the root log level or for more specific categories such as `org.hibernate` or `org.keycloak`. This {section} describes how to configure logging.

=== Log levels

The following table defines the available log levels.

[%autowidth]
|===
|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|{project_name} 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:

<@kc.start parameters="--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 {project_name}. Use this command to provide a comma-separated list of categories for which you want a different log level:

<@kc.start parameters="--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
<@kc.start parameters="--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.

== Enabling log handlers
To enable log handlers, enter the following command:

<@kc.start parameters="--log=\"<handler1>,<handler2>\""/>

The available handlers are
<@profile.ifCommunity>
`console`, `file`, `syslog`.
</@profile.ifCommunity>
<@profile.ifProduct>
`console`, `file` and `syslog`.
</@profile.ifProduct>
The more specific handler configuration mentioned below will only take effect when the handler is added to this comma-separated list.

== Console log handler
The console log handler is enabled by default, providing unstructured log messages for the console.

=== Configuring the console log format
{project_name} uses a pattern-based logging formatter that generates human-readable text logs by default.

The logging format template for these lines can be applied at the root level. The default format template is:

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

The format string supports the symbols in the following table:

[%autowidth]
|===
|Symbol|Summary|Description

|%%|%|Renders a simple % character.
|%c|Category|Renders the log category name.
|++%d{xxx}++|Date|Renders a date with the given date format string.String syntax defined by `java.text.SimpleDateFormat`
|%e|Exception|Renders a thrown exception.
|%h|Hostname|Renders the simple host name.
|%H|Qualified host name|Renders the fully qualified hostname, which may be the same as the simple host name, depending on the OS configuration.
|%i|Process ID|Renders the current process PID.
|%m|Full Message|Renders the log message and an exception, if thrown.
|%n |Newline|Renders the platform-specific line separator string.
|%N|Process name|Renders the name of the current process.
|%p|Level|Renders the log level of the message.
|%r|Relative time|Render the time in milliseconds since the start of the application log.
|%s|Simple message|Renders only the log message without exception trace.
|%t|Thread name|Renders the thread name.
|%t++{id}++|Thread ID|Render the thread ID.
|%z{<zone name>}|Timezone|Set the time zone of log output to <zone name>.
|%L|Line number|Render the line number of the log message.
|===

=== Setting the logging format
To set the logging format for a logged line, perform these steps:

. Build your desired format template using the preceding table.
. Enter the following command:
+
<@kc.start parameters="--log-console-format=\"\'<format>\'\""/>

Note that you need to escape characters when invoking commands containing special shell characters such as `;` using the CLI. Therefore, consider setting it in the configuration file instead.

.Example: Abbreviate the fully qualified category name
<@kc.start parameters="--log-console-format=\"\'%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%c{3.}] (%t) %s%e%n\'\""/>

This example abbreviates the category name to three characters by setting `[%c{3.}]` in the template instead of the default `[%c]`.

=== Configuring JSON or plain console logging
By default, the console log handler logs plain unstructured data to the console. To use structured JSON log output instead, enter the following command:

<@kc.start parameters="--log-console-output=json"/>

.Example Log Message
[source, json]
----
{"timestamp":"2022-02-25T10:31:32.452+01:00","sequence":8442,"loggerClassName":"org.jboss.logging.Logger","loggerName":"io.quarkus","level":"INFO","message":"Keycloak 18.0.0-SNAPSHOT on JVM (powered by Quarkus 2.7.2.Final) started in 3.253s. Listening on: http://0.0.0.0:8080","threadName":"main","threadId":1,"mdc":{},"ndc":"","hostName":"host-name","processName":"QuarkusEntryPoint","processId":36946}
----

When using JSON output, colors are disabled and the format settings set by `--log-console-format` will not apply.

To use unstructured logging, enter the following command:

<@kc.start parameters="--log-console-output=default"/>

.Example Log Message
[source]
----
2022-03-02 10:36:50,603 INFO  [io.quarkus] (main) Keycloak 18.0.0-SNAPSHOT on JVM (powered by Quarkus 2.7.2.Final) started in 3.615s. Listening on: http://0.0.0.0:8080
----

=== Colors
Colored console log output for unstructured logs is disabled by default. Colors may improve readability, but they can cause problems when shipping logs to external log aggregation systems. To enable or disable color-coded console log output, enter following command:

<@kc.start parameters="--log-console-color=<false|true>"/>

== File logging
As an alternative to logging to the console, you can use unstructured logging to a file.

=== Enable file logging
Logging to a file is disabled by default. To enable it, enter the following command:

<@kc.start parameters="--log=\"console,file\""/>

A log file named `keycloak.log` is created inside the `data/log` directory of your {project_name} installation.

=== Configuring the location and name of the log file

To change where the log file is created and the file name, perform these steps:

. Create a writable directory to store the log file.
+
If the directory is not writable, {project_name} will start correctly, but it will issue an error and no log file will be created.

. Enter this command:
+
<@kc.start parameters="--log=\"console,file\" --log-file=<path-to>/<your-file.log>"/>

=== Configuring the file handler format
To configure a different logging format for the file log handler, enter the following command:

<@kc.start parameters="--log-file-format=\"<pattern>\""/>

See <<Configuring the console log format>> for more information and a table of the available pattern configuration.

== Centralized logging using Syslog

{project_name} provides the ability to send logs to a remote Syslog server.
It utilizes the protocol defined in https://datatracker.ietf.org/doc/html/rfc5424[RFC 5424].

=== Enable the Syslog handler
To enable logging using Syslog, add it to the list of activated log handlers as follows:

<@kc.start parameters="--log=\"console,syslog\""/>

=== Configuring the Syslog endpoint

To configure the endpoint(_host:port_) of your centralized logging system, enter the following command and substitute the values with your specific values:

<@kc.start parameters="--log=\"console,syslog\" --log-syslog-endpoint=myhost:12345"/>

When the Syslog handler is enabled, the host is using `localhost` as host value.
The Default port is `514`.

=== Configuring the Syslog protocol
Syslog uses TCP as the default protocol for communication.
To use UDP instead of TCP, add the `--log-syslog-protocol` option as follows:

<@kc.start parameters="--log=\"console,syslog\" --log-syslog-protocol=udp"/>

The available protocols are: `tpc`, `udp`, and `ssl-tcp`.

=== Configuring the Syslog log format
To set the logging format for a logged line, perform these steps:

. Build your desired format template using the preceding table.
. Enter the following command:
+
<@kc.start parameters="--log-syslog-format=\"\'<format>\'\""/>

Note that you need to escape characters when invoking commands containing special shell characters such as `;` using the CLI. Therefore, consider setting it in the configuration file instead.

.Example: Abbreviate the fully qualified category name
<@kc.start parameters="--log-syslog-format=\"\'%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%c{3.}] (%t) %s%e%n\'\""/>

This example abbreviates the category name to three characters by setting `[%c{3.}]` in the template instead of the default `[%c]`.

=== Configuring the Syslog structured output
By default, the Syslog log handler sends plain unstructured data to the Syslog server.
To use structured JSON log output instead, enter the following command:

<@kc.start parameters="--log-syslog-output=json"/>

.Example Log Message
[source, bash]
----
2024-04-05T12:32:20.616+02:00 mabartos keycloak 2788276 io.quarkus - {"timestamp":"2024-04-05T12:32:20.616208533+02:00","sequence":9948,"loggerClassName":"org.jboss.logging.Logger","loggerName":"io.quarkus","level":"INFO","message":"Profile prod activated. ","threadName":"main","threadId":1,"mdc":{},"ndc":"","hostName":"host","processName":"QuarkusEntryPoint","processId":2788276}
----

When using JSON output, colors are disabled and the format settings set by `--log-syslog-format` will not apply.

To use unstructured logging, enter the following command:

<@kc.start parameters="--log-syslog-output=default"/>

.Example Log Message
[source, bash]
----
2024-04-05T12:31:38.473+02:00 mabartos keycloak 2787568 io.quarkus - 2024-04-05 12:31:38,473 INFO  [io.quarkus] (main) Profile prod activated.
----

As you can see, the timestamp is present twice, so you can amend it correspondingly via the `--log-syslog-format` property.

</@tmpl.guide>
