It is really hard for system administrators to change the correct log levels before reproducing a bug and sending us the logs, it’s a lot of steps to explain to customers - so we have a UI to change the log levels for them. It was very useful, the customers could really extract logs of excellent quality.
Confluence is removing access to
org.apache.log4j
, so we are not able to change log levels when the administrator clicks in the UI.
Is there any way that a plugin can programatically change the log levels of slf4j/log4j at runtime, in Java?
Hi
@aragot
We found a way but its really not pretty - thought I would share.
Class<?> memoizingComponentReferenceClass = Class.forName("com.atlassian.confluence.util.MemoizingComponentReference");
// Get the containerComponent method
Method containerComponentMethod = memoizingComponentReferenceClass.getMethod("containerComponent", String.class);
// Invoke the containerComponent method to get loggingConfigServiceRef
Object loggingConfigServiceRef = containerComponentMethod.invoke(null, "loggingConfigService");
// Get the get method from loggingConfigServiceRef
Method getMethod = loggingConfigServiceRef.getClass().getMethod("get");
// Invoke the get method to get loggingConfigService
Object loggingConfigService = getMethod.invoke(loggingConfigServiceRef);
// Get the setLevelForLogger method from loggingConfigService
Method setLevelForLoggerMethod = loggingConfigService.getClass().getMethod("setLevelForLogger", String.class, String.class);
// Invoke the setLevelForLogger method
setLevelForLoggerMethod.invoke(loggingConfigService, loggerName, levelName);
Basically there is a service LoggingConfigService - which does indeed work but cant be directly accessed by plugins - the above is a bit of a reflection based hack to make it work. It actually works fairly reliably well for us - but we did have to add some checks earlier in our code to only do via the standard log4j methods (e.g old versions of Confluence)