GitHub user ppkarwasz added a comment to the discussion: Help with migrating from log4j to log4j2 (we also use a slf4j -> log4j)
Hi @paladox, The only supported API for changing log levels at runtime in Log4j Core is [`Configurator`](https://logging.apache.org/log4j/2.x/javadoc/log4j-core/org/apache/logging/log4j/core/config/Configurator.html). The simplest form is: ```java Configurator.setLevel(name, newLevel); ``` This works only if **Log4j Core** is the actual implementation of the Log4j API. Since that might not always be the case, it’s good practice to guard the call: ```java try { Configurator.setLevel(name, newLevel); } catch (LinkageError | ClassCastException e) { // Log4j Core is not available or not the active implementation } ``` What this does: 1. Retrieves (or creates) a `LoggerConfig` for `name`. 2. Updates its level. 3. Propagates the configuration change to all affected loggers (any logger **without** a more specific config inherits this new level). ### About your current code ```java config.getLoggers().forEach((loggerName, loggerConfig) -> { if (!loggerName.isEmpty() && (name == null || loggerName.contains(name))) { loggerConfig.setLevel(newLevel); stdout.println("Updated Log4j2 LoggerConfig: " + loggerName + " -> " + newLevel); } }); ctx.updateLoggers(); ``` This approach differs from `Configurator` in two important ways: 1. It does **not** create a new `LoggerConfig` if one doesn’t already exist for `name`. 2. It **overrides** the level of all explicitly configured child loggers. For example, if `foo` has no config but `foo.bar` and `foo.baz` do, then: * `foo.bar` and `foo.baz` levels will be overridden. * `foo` itself will remain unchanged (inheriting from root). ### Adjusting whole hierarchies If you want to update an entire logger hierarchy, `Configurator.setAllLevels` is the intended API: ```java try { Configurator.setAllLevels(name, newLevel); } catch (LinkageError | ClassCastException e) { // Log4j Core is not available or not the active implementation } ``` ### Key difference from Log4j 1 This is probably the root cause of your migration issues: * In **Log4j 1**, the `Logger` object itself held both runtime state and configuration, and parent loggers always existed (`foo.bar` implied `foo`). * In **Log4j 2 Core**, loggers and their configuration are separate (see [Architecture](https://logging.apache.org/log4j/2.x/manual/architecture.html)). Only: * loggers you actually request in code, and * configurations explicitly defined in your config file are created. So, to affect loggers that don’t have an explicit configuration, you need to use the `Configurator` API rather than directly iterating over existing `LoggerConfig`s. > [!NOTE] > A **Logger Admin API** is planned (see > [apache/logging-admin](https://github.com/apache/logging-admin)) to provide a > standard, implementation-independent way of managing logger levels. However, > development capacity is currently limited, so this is not yet available. GitHub link: https://github.com/apache/logging-log4j2/discussions/3914#discussioncomment-14307854 ---- This is an automatically sent email for [email protected]. To unsubscribe, please send an email to: [email protected]
