client_java
client_java copied to clipboard
Add log4j2 annotation processor so packages is not required
Currently it's necessary to pass the packages attributes via <Configuration packages="io.prometheus.client.log4j2"> in log4j configuration to discover the appender.
That means relying on step 5 of https://logging.apache.org/log4j/2.x/manual/plugins.html for appender discovery (analyzing packages and annotations at startup).
It would seem less error prone and more efficient to add the log4j annotation processor to the Maven compiler plugin, so it builds the metadata META-INF/org/apache/logging/log4j/core/config/plugins/Log4j2Plugins.dat at build time (step1) ?
Would that be something that users of simpleclient_log4j2 need to do, or is that something that we need to do when building simpleclient_log4j2?
It would need to be added in the build of simpleclient_log4j2, so that simpleclient_log4j2.jar in Maven central contains the meatadata file META-INF/org/apache/logging/log4j/core/config/plugins/Log4j2Plugins.dat
Thanks for the response. I didn't work with Log4j2Plugins.dat before. I'm wondering
- What happens if a user wants to create a uber-JAR with the Maven shade plugin, but multiple dependencies have the
Log4j2Plugins.datfile? My guess is that this will fail, because the final JAR will only have oneMETA-INF/org/apache/logging/log4j/core/config/plugins/Log4j2Plugins.datand the Maven shade plugin cannot know which one to choose. That would mean that we break existing builds by addingLog4j2Plugins.dattosimpleclient_log4j2if the existing build already uses another dependency that has aLog4j2Plugins.datfile. - Even if a user does not create a uber-JAR but puts all dependencies in the classpath: Would log4j be able to load all
Log4j2Plugins.datfrom all dependencies? I guess if they loadLog4j2Plugins.datas a classpath resource they will just load the one from the JAR file that happens to be first in the classpath. If that's the case, it will be pretty random whether theLog4j2Plugins.datfromsimpleclient_log4j2gets picked up or not.
It would be great if you could elaborate a bit to help me understand how this will work.
Good points, here's what I've found:
- For uber-jar we're using this transformer to merge the Log4j2Plugins.dat fields: https://github.com/edwgiz/maven-shaded-log4j-transformer. It's calling log4j-core APIs to do the merge and dump the resulting file.
- log4j2 itself is iterating on all the classloader resources and merging plugins in memory: https://github.com/apache/logging-log4j2/blob/f72100df0decc9bda96b4d769822c4e48b2848fc/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/util/PluginRegistry.java#L162
Thanks for looking into this. So it looks like (2) is not a problem.
However, (1) sounds like this would break existing builds if users create uber-JARs but didn't configure the log4j-transformer plugin. I imagine fixing the build will be non-trivial in some cases. Many frameworks like Spring inherit the Maven shade plugin from a parent POM, and it is not straightforward where to put the log4j-transformer plugin configuration.
Using the packages attribute is now deprecated in log4j 2. The attribute will be removed in log4j 3. This should be fixed