rgoers commented on PR #2419: URL: https://github.com/apache/logging-log4j2/pull/2419#issuecomment-2025463001
@ppkarwasz > The fact that there is only one logger per logger name is not set in stone (unlike in Logback). [LoggerRegistry](https://logging.apache.org/log4j/2.x/javadoc/log4j-api/org/apache/logging/log4j/spi/LoggerRegistry) is a multi-key map with a (String, MessageFactory) key. > > Due to the architectural choices you did at the beginning, Loggers don't even need to form a hierarchy, only LoggerConfigs are hierarchical. Let's profit from that and remove the "singleton" restriction from [LogManager#getLogger](https://logging.apache.org/log4j/2.x/javadoc/log4j-api/org/apache/logging/log4j/LogManager.html#getLogger(java.lang.Class,org.apache.logging.log4j.message.MessageFactory)). It is not a breaking change for the users to allow them to use different MessageFactory instances for the same logger name. While it is a multi-key map you will get warnings if you try to create the same logger with multiple message factories as usually that is going to cause problems. However, I don't see how that helps with what rocketraman is requesting. It is worth repeating that resource Loggers should **NEVER** be added to the LoggerRegistry. Resource Loggers need to have the same lifetime as the resource. Loggers in the registry never go away and so would result in a memory leak. Note that them not being in the registry isn't really a problem as the underlying Logger they use is. That Logger will be reconfigured when needed. > > IMHO, the ParameterizedMapMessage class that you introduce is already half way to meet @rocketraman's expectations: > > by using a special [LogEventFactory](https://logging.apache.org/log4j/2.x/javadoc/log4j-core/org/apache/logging/log4j/core/impl/LogEventFactory) the map data can be added to the context map and the baseMessage can be used as message. Something similar already happens with [TimestampMessage](https://logging.apache.org/log4j/2.x/javadoc/log4j-api/org/apache/logging/log4j/message/TimestampMessage)s that add their own timestamp to the LogEvent, > certainly the specification of [ContextDataInjector#injectContextData](https://logging.apache.org/log4j/2.x/javadoc/log4j-core/org/apache/logging/log4j/core/ContextDataInjector#injectContextData(java.util.List,org.apache.logging.log4j.util.StringMap)) must change: currently it already receives the current context data of the event as reusable parameter, but most implementation ignore it. Sure, you _could_ do this, but I am not sure it is a good idea. There are other uses of MapMessage where you do not want the data merged into the context data. I would be hesitant to always merge it without some indication from the user since there are a lot of cases where that is not what you want. > Is there really such a difference between [Message](https://logging.apache.org/log4j/2.x/javadoc/log4j-api/org/apache/logging/log4j/message/Message) and [LogEvent](https://logging.apache.org/log4j/2.x/javadoc/log4j-core/org/apache/logging/log4j/core/LogEvent)? Did you just answer your own question? Of course there is a difference. A Message is really just a container for the format String and its parameters. The fact that you can make more complex messages like a MapMessage is a perk. But the main difference is that the user really controls the contents of the Message while Log4j controls the LogEvent. Now, we could enhance the transformer to replace logging calls that take parameters with Logging calls that accept LogEvents but a) I believe it would be tough to make that garbage free and b) I am not sure we could always get it right since a lot is determined at run time. The bottom line here is Piotr, I am not sure what to do with your comment. You haven't actually asked for any changes. @rocketraman > in many cases developers have no ability to affect layout at all — all applications across the enterprise use the same layout in order to enforce logging consistency I absolutely understand this. All the Spring Boot and Spring Cloud Config support in Log4j was added by me to support my employer. We have a common logging configuration stored in Spring Cloud Config that all applications share. However, every application can still provide an override that extends capabilities and we take advantage of that. Now this is sort of interesting ``` class ContextLogger { private final Map<String, String> context; private final Logger delegate; void log(...) { setContext(context) try { delegate.log(...) } finally { resetContext() } } } ``` Yes, one could modify ResourceLogger to have ``` public void logMessage(final String fqcn, final Level level, final Marker marker, final Message message, final Throwable t) { ScopedContext.runWhere(this.supplier.get(), () -> logger.logMessage(fqcn, level, marker, message, t)); } ``` However, this has a small side effect that any logging calls that occur from objects passed into the logging call or logging that occurs from Appenders and other components while processing the logevent will also have this context data, despite them using a different logger. If that makes sense I would actually consider this. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
