Turn off logback logging for other libraries while in certain class

johnktims picture johnktims · Nov 14, 2013 · Viewed 14.4k times · Source

I am successfully using Spring's @Scheduled annotation to execute a method every few seconds. The only issue is that I get a lot of log messages about transactions, etc from Hibernate and Spring because of this method.

I want to keep the logging levels the same because I like to receive this information for other transactions in the application.

Is there a way in logback to temporarily suppress another library's logging while a specific method is executing?

Answer

durron597 picture durron597 · May 22, 2014

Yes this can be done on a per-thread basis.

You need to use Filters and MDC (Mapped Diagnostic Context). This solution will only affect the logging that occurs on the thread that is executing the @Scheduled method.

Overview of steps

  1. In your @Scheduled method, add an entry to the MDC of that thread.
  2. Create an implementation of ch.qos.logback.core.filter.Filter<ILoggingEvent>, which will return FilterReply.DENY if that entry is set in the MDC
  3. Add a reference to that filter in your <appender> entry in logback.xml

Step 1

Make your @Scheduled method look like this:

@Scheduled(fixedRate=30000)
public void scheduledMethod () {
    try{
        MDC.put("scheduled", "true");

        // Your code here
    }finally{
        MDC.remove("scheduled");
    }
}

I should mention that removing the key is important because Spring may reuse the thread and the MDC would keep the value otherwise.

Step 2

Your filter should look something like this:

package my.domain.application.logging;

import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.filter.Filter;
import ch.qos.logback.core.spi.FilterReply;

public class MDCFilter extends Filter<ILoggingEvent> {

  @Override
  public FilterReply decide(ILoggingEvent event) {    
    String scheduled = event.getMDCPropertyMap().get("scheduled");
    if ("true".equals(scheduled)) {
      return FilterReply.DENY;
    } else {
      return FilterReply.NEUTRAL;
    }
  }
}

Step 3

Add the following to your logback.xml

<appender name="myAppender" class="ch.qos.logback.core.ConsoleAppender">
    <filter class="my.domain.application.logging.MDCFilter" />
    <!-- the rest of your appender -->
</appender>