Search code examples
loggingdropwizard

Log different levels in different files using Dropwizard


The question is similar to one stated under - How to configure log4j to log different log levels to different files for the same logger. The existing questions that I could find here are mostly dealing with logback and log4j configuration. Looking something specifically in Dropwizard configuration for a solution to this problem.

Have tried to look around over the internet and seem like a LevelMatchFilter might be appropriate to use, but couldn't figure out the Dropwizard's documentation around it.

What I have currently is

logging:
  level: INFO
  appenders:
    - type: file
      threshold: INFO
      logFormat: '%date{dd-MM-yyyy HH:mm:ss.SSS} %X{X-Request-Id} [%thread] %-5level %logger{36} - %msg%n'
      currentLogFilename: .../info.log
      archivedLogFilenamePattern: .../info-%i.log.gz
      archivedFileCount: 2
      timeZone: IST
      maxFileSize: 100MB

    - type: file
      threshold: WARN
      currentLogFilename: .../warn.log
      archivedLogFilenamePattern: .../warn-%i.log.gz
      ... other attributes

    - type: file
      threshold: ERROR
      ...similar attributes for error logs

But this results in a log.error being part of three files and what I would intend to perform is to ensure its just part of the error.log file and relevant for others.


Solution

  • Dropwizard has its own logging configuration, and it supports adding filters by writing FilterFactory classes.

    For example, here is a FilterFactory that filters out everything but ERROR level log events:

    @JsonTypeName("error-only")
    public class ErrorLogFilter implements FilterFactory<ILoggingEvent> {
    
        @Override
        public Filter<ILoggingEvent> build() {
            return new Filter<ILoggingEvent>() {
                @Override
                public FilterReply decide(ILoggingEvent event) {
                    if (event.getLevel().equals(Level.ERROR)) {
                        return FilterReply.NEUTRAL;
                    } else {
                        return FilterReply.DENY;
                    }
                }
            };
    
        }
    }
    

    To register a factory, its fully qualified classname must be listed in META-INF/services/io.dropwizard.logging.filter.FilterFactory file.

    And the configuration to get one of the file appenders to use it, would be like this:

      - type: file
        threshold: ERROR
        logFormat: '%date{dd-MM-yyyy HH:mm:ss.SSS} %X{X-Request-Id} [%thread] %-5level %logger{36} - %msg%n'
        currentLogFilename: .../error.log
        archivedLogFilenamePattern: .../error-%i.log.gz
        archivedFileCount: 2
        timeZone: IST
        maxFileSize: 100MB
        filterFactories:
          - type: error-only