I'm trying to find out the reasoning behind the ColorConverter class being treated differently when using logback over log4j2
Logback - ColorConverter Class is not final
Log4j2 - ColorConverter Class is final
I obviously want to override this class and unfortunately I am using log4j2, however if I was using logback it would not be a problem.
So was wondering if you could provide some insight in why they are treated differently? I'm clearly missing something. Is it because of the way they need to be instantiated
Comment From: dreis2211
Not speaking for the team, but to the best of my knowledge log4j2 is scanning for plugins annotated with @Plugin
- which is quite different to the logback approach. Since it is not recommended to specify multiple plugins with the same name, it seems like a sane choice to make it final to avoid possibilities for misconfiguration. If you check log4j2's own plugins, you will notice that a lot of them are final too and unfortunately can't be extended to the full extend either. Again - very subjective take on the topic.
I don't know if this helps you - it probably highly depends on your use case, but maybe delegation instead of inheritance will help for the time being:
@Plugin(name = "customcolor", category = PatternConverter.CATEGORY)
@ConverterKeys({ "customcolor" })
public class CustomColorConverter extends LogEventPatternConverter {
private ColorConverter colorConverter;
private CustomColorConverter(ColorConverter colorConverter) {
super("style", "style");
this.colorConverter = colorConverter;
}
public static CustomColorConverter newInstance(Configuration config, String[] options) {
ColorConverter colorConverter = ColorConverter.newInstance(config, options);
return new CustomColorConverter(colorConverter);
}
@Override
public boolean handlesThrowable() {
return this.colorConverter.handlesThrowable();
}
@Override
public void format(LogEvent event, StringBuilder toAppendTo) {
this.colorConverter.format(event, toAppendTo);
// Maybe do your custom thing instead (or on top)
}
}
Alternatively, you could probably copy the bits and pieces from ColorConverter
and make your adjustments. I don't know what suits your use-case better, but in general it's perfectly possible to develop your own plugin/converter.
Either way, don't forget to specify the packages in your log4j2.xml so Log4j2 can find your custom plugin:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration packages="your.colorconverter.package">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout
pattern="%customcolor{%d{yyyy-MM-dd HH:mm:ss.SSS}}{green} %highlight{%-5level }[%clr{%t}{blue}] %style{%C{1.}}{bright,yellow}: %msg%n%throwable" />
</Console>
</Appenders>
<Loggers>
<!-- LOG everything at INFO level -->
<Root level="info">
<AppenderRef ref="Console" />
</Root>
</Loggers>
</Configuration>
Having that said. There is maybe another reason for the ColorConverter to be final and maybe it's not even a deliberate choice, in which case overriding it can be made possible. But even if it would, you would still need to specify your custom @Plugin
in the end. Hope that helps you a tiny bit.
Cheers, Christoph
Comment From: mbhave
The original commit which made the log4j2 ColorConverter
final
made a bunch of other classes that were introduced in 1.3.0 final
too. So although it doesn't seem like it was made final
for a log4j2 specific reason, based on what @dreis2211 said above, removing final
would provide no real benefit.
@Stexxen Does the solution that Christoph provided above work for you? If not, could you provide more details on how you'd like to use the subclass?
Comment From: spring-projects-issues
If you would like us to look at this issue, please provide the requested information. If the information is not provided within the next 7 days this issue will be closed.
Comment From: Stexxen
@mbhave sorry about the delay. Yes @dreis2211 answer helped me understand. I ended up copying the entire class and giving it another ConverterKey. It may sound trivial but I wanted to change the configuration of one of the static maps, particularly a separate colour for DEBUG messages, and I'd hoped subclassing would allow to take advantage of potential future changes/fixes in ColorConverter, but I've copied the class and it does it's job. so all is good.. (for now) ;-)