Change the log level programatically in Confluence at runtime

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?

2 Likes

@aragot Did you ever find a solution for this? We have a cross product app that we would like to have some automatically configured extra logging turned on when customers need help debugging. We have it working for every product / version except for Confluence 8.0+

Nope, I haven’t.

I’m starting to move towards writing a logger myself that writes into Confluence’s, so that I can log all INFO messages as ERROR to ensure that Confluence writes them, when the customers wants to do a capture.

2 Likes

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)