diff --git a/common/src/main/java/org/keycloak/common/Profile.java b/common/src/main/java/org/keycloak/common/Profile.java
index c5cced49a7a..1280e469e4e 100755
--- a/common/src/main/java/org/keycloak/common/Profile.java
+++ b/common/src/main/java/org/keycloak/common/Profile.java
@@ -135,6 +135,8 @@ public class Profile {
ROLLING_UPDATES_V1("Rolling Updates", Type.DEFAULT, 1),
ROLLING_UPDATES_V2("Rolling Updates for patch releases", Type.PREVIEW, 2),
+ LOG_MDC("Mapped Diagnostic Context (MDC) information in logs", Type.PREVIEW),
+
/**
* @see Deprecate for removal the Instagram social broker.
*/
diff --git a/docs/documentation/release_notes/topics/26_4_0.adoc b/docs/documentation/release_notes/topics/26_4_0.adoc
index da03935762c..6c326519200 100644
--- a/docs/documentation/release_notes/topics/26_4_0.adoc
+++ b/docs/documentation/release_notes/topics/26_4_0.adoc
@@ -5,4 +5,11 @@ Read on to learn more about each new feature, and https://www.keycloak.org/docs/
= Option to force management interface to use HTTP.
-There's a new option `http-management-scheme` that may be set to `http` to force the management interface to use HTTP rather than inheriting the HTTPS settings of the main interface.
+There's a new option `http-management-scheme` that may be set to `http` to force the management interface to use HTTP rather than inheriting the HTTPS settings of the main interface.
+
+= Additional context information for log messages (preview)
+
+You can now add context information to each log message like the realm or the client that initiated the request.
+This helps you to track down a warning or error message in the log to a specific caller or environment
+
+For more details on this opt-in feature, see the https://www.keycloak.org/server/logging[Logging guide].
diff --git a/docs/guides/server/logging.adoc b/docs/guides/server/logging.adoc
index 57c396974d7..7762f448be6 100644
--- a/docs/guides/server/logging.adoc
+++ b/docs/guides/server/logging.adoc
@@ -68,6 +68,32 @@ This example sets the following log levels:
* 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.
+=== Adding context for log messages
+
+:tech_feature_name: Log messages with Mapped Diagnostic Context (MDC)
+:tech_feature_id: log-mdc
+
+[NOTE]
+====
+{tech_feature_name} is
+*Preview*
+and is not fully supported. This feature is disabled by default.
+====
+
+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-enable` to enable it.
+
+.Example configuration
+<@kc.start parameters="--features=log-mdc --log-mdc-enable=true"/>
+
+.Example output
+----
+2025-06-20 14:13:01,772 {kc.clientId=security-admin-console, kc.realm=master} INFO ...
+----
+
+Specify which keys to be added by setting the configuration option `log-mdc-keys`.
+
==== Configuring levels as individual options
When configuring category-specific log levels, you can also set the log levels as individual `log-level-` 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.
diff --git a/quarkus/config-api/src/main/java/org/keycloak/config/LoggingOptions.java b/quarkus/config-api/src/main/java/org/keycloak/config/LoggingOptions.java
index c8082b7f61e..e1a573d6025 100644
--- a/quarkus/config-api/src/main/java/org/keycloak/config/LoggingOptions.java
+++ b/quarkus/config-api/src/main/java/org/keycloak/config/LoggingOptions.java
@@ -20,10 +20,9 @@ public class LoggingOptions {
public static final String DEFAULT_LOG_PATH = "data" + File.separator + "log" + File.separator + DEFAULT_LOG_FILENAME;
// Log format + tracing
- private static final Function DEFAULT_LOG_FORMAT_FUNC = (additionalFields) ->
+ public static final Function DEFAULT_LOG_FORMAT_FUNC = (additionalFields) ->
"%d{yyyy-MM-dd HH:mm:ss,SSS} " + additionalFields + "%-5p [%c] (%t) %s%e%n";
public static final String DEFAULT_LOG_FORMAT = DEFAULT_LOG_FORMAT_FUNC.apply("");
- public static final String DEFAULT_LOG_TRACING_FORMAT = DEFAULT_LOG_FORMAT_FUNC.apply("traceId=%X{traceId}, parentId=%X{parentId}, spanId=%X{spanId}, sampled=%X{sampled} ");
public enum Handler {
console,
@@ -125,6 +124,12 @@ public class LoggingOptions {
.defaultValue(true)
.build();
+ public static final Option LOG_CONSOLE_INCLUDE_MDC = new OptionBuilder<>("log-console-include-mdc", Boolean.class)
+ .category(OptionCategory.LOGGING)
+ .description(format("Include mdc information in the console log. If the '%s' option is specified, this option has no effect.", LOG_CONSOLE_FORMAT.getKey()))
+ .defaultValue(true)
+ .build();
+
public static final Option LOG_CONSOLE_COLOR = new OptionBuilder<>("log-console-color", Boolean.class)
.category(OptionCategory.LOGGING)
.description("Enable or disable colors when logging to console.")
@@ -188,6 +193,12 @@ public class LoggingOptions {
.defaultValue(true)
.build();
+ public static final Option LOG_FILE_INCLUDE_MDC = new OptionBuilder<>("log-file-include-mdc", Boolean.class)
+ .category(OptionCategory.LOGGING)
+ .description(format("Include MDC information in the file log. If the '%s' option is specified, this option has no effect.", LOG_FILE_FORMAT.getKey()))
+ .defaultValue(true)
+ .build();
+
public static final Option