GitHub user ppkarwasz added a comment to the discussion: Help with migrating 
from log4j to log4j2 (we also use a slf4j -> log4j)

> I guess the reconfigure stops the AsyncAppender somehow?

Yes, that’s exactly what happens: `reconfigure()`  

- Builds and starts a **new configuration**.  
- Updates all loggers to use it.  
- Stops the **old configuration** and its appenders (after flushing any pending 
events).  

Since your code injects events *directly* into an appender and keeps a 
reference to it, you’re effectively writing into an appender that has already 
been stopped. That explains the `AsyncAppender ... is not active` errors. The 
safe approach is to log through a `Logger`. That way Log4j Core manages the 
pipeline, and you don’t risk writing to stale appenders during or after 
reconfiguration.  

> For the migration, I’m trying to keep things as close as possible to the old 
> Log4j 1 code, just updating class and method names.  

That’s understandable, but it’s not a good fit here: Log4j 2’s architecture is 
very different. In Log4j 1, loggers and appenders were tightly coupled. In 
Log4j 2, the Log4j API and the implementation (Log4j Core) are separate 
modules, and in some environments Log4j Core may not even be present. For 
example, if Gerrit runs on WildFly, the container will supply Log4j API but not 
Log4j Core, meaning `LogManager.getContext(false)` won’t return a 
`org.apache.logging.log4j.core.LoggerContext`.  

So I’d recommend:  

1. **Prefer configuration over code.**  
   For your `SshLog`, define a small configuration snippet containing just the 
custom appender and logger, and merge it with the main config. See [Combining 
Multiple 
Configurations](https://logging.apache.org/log4j/2.x/manual/customconfig.html#CompositeConfiguration).
  

2. **Use the Log4j API whenever possible.**  
   This keeps your code portable across logging implementations, not tied to 
Log4j Core internals.  

3. **Isolate Core-specific logic.**  
   If you truly need Log4j Core features, encapsulate them in a single service 
(e.g. `SystemLog`). Use the delegation pattern: one implementation for Log4j 
Core, another no-op fallback if Log4j Core isn’t available. Kafka’s 
[`LoggingController`](https://github.com/apache/kafka/blob/trunk/server/src/main/java/org/apache/kafka/server/logger/LoggingController.java)
 is a good example.  

This way you avoid fragile references to appenders, gain portability, and make 
your migration closer to Log4j 2’s intended design.  


GitHub link: 
https://github.com/apache/logging-log4j2/discussions/3914#discussioncomment-14332346

----
This is an automatically sent email for [email protected].
To unsubscribe, please send an email to: [email protected]

Reply via email to