Looks like a bug in Sling Logback integration. What happens here is that

1. On initial registration of Appender the AppenderTracker in Sling Commons
Log would "start" the appender and attach it to logger

2. When you change the log level  via global config it kinds of reset the
Logback. In reset it would "stop" the appender and detach it

3. Post reset Sling Commons Log would again "attach" the appender but would
not start it again.

Now for in memory appenders this would not cause issue. But for async
appender once it is stopped the backing thread is shutdown and as there is
no further start the thread does not get started again.

Can you open a bug for this in Sling?

For now you can go for workaround

1. Implement a LoggerContextListener [1] and have its isResetResistant
return true
2. Register this listener with LoggerContext - You can get that via casting
org.slf4j.LoggerFactory.getILoggerFactory()
3. Then onReset you start the appender again

Or you eat out the stop call and stop it upon your component deactivation!

Chetan Mehrotra

[1]
http://logback.qos.ch/apidocs/ch/qos/logback/classic/spi/LoggerContextListener.html

On Wed, Jun 1, 2016 at 3:49 PM, piyush goyal <coolpiyus...@gmail.com> wrote:

> Hi Team,
>
> We are trying to writing our custom appenders on top of sling in AEM and
> referred to documentation
> <
> https://sling.apache.org/documentation/development/logging.html#appenders-as-osgi-services
> >.
> We want to send logs of the configured loggers to redis. For this, we wrote
> a custom Redis Appender extending UnsynchronizedAppenderBase which would
> just send the logs to redis. This redis appender is wrapped inside an async
> appender which is getting registered as an OSGI service after reading the
> redis related configurations from config manager page. Below is a small
> snapshot of the custom code:
>
>        redisAppender = new RedisAppender(host, port, redisList);
> asyncAppender = new AsyncAppender();
>         asyncAppender.setName("ASYNC");
>         asyncAppender.setDiscardingThreshold(0);
>         asyncAppender.addAppender(this.redisAppender);
>
>         Dictionary<String, Object> asyncProps = new Hashtable<String,
> Object>();
>
>         String[] loggers = {
>                 "com.foo.base"
>         };
>
>         asyncAppenderRegistration =
> bundleContext.registerService(Appender.class.getName(), asyncAppender,
> asyncProps);
>
>
>   As soon as the async appender is registered as a service, we can see our
> logs reaching the redis instance. Since no logging level is defined for the
> logger, it inherits from the ROOT logger which is by default INFO. The
> problem comes when we try to change the log level of ROOT logger. We saw
> that when we change the log level, logbackManager class is called and a
> context reset method is executed. After this process, although Async
> Appender is still linked to the defined loggers, but async appender looses
> the redis appender attached to it.
>
> I tried doing the same process with config fragment as well, but everytime
> a change in log level causes redis appender to be detached from the async
> appender. I even tried creating factory.config so that I can directly
> change the logger level of the my logger and not inheriting it from ROOT
> level. But here also async appender detaches the redis appender attached to
> it.
>
> What could be the reason behind it? And what should be the correct approach
> to be taken so that after changing the log level, async appender does not
> detach redis appender.
>
> Thanks and Regards
> Piyush Goyal
>

Reply via email to