Search code examples
javaloggingdropwizard

Dropwizard logging instance in filename with multiple appenders


This is using Dropwizard's logging with Yaml file and some java.

I wanted to add an instance field in the Dropwizard filename, so that the logs can go handle multiple instances. This was not too difficult. I build a FileAppenderFactory and on buildAppender I just getCurrentLogFilename(), modify it for the instance number, and then setIt. Ditto for the archived name. All well and good.

The problem was when I wanted to add a second file appender (for metrics).

So before I had

logging:
  loggers:
    // etc etc
  appenders:
    - type: file
    // etc etc

Now I have:

logging:
  loggers:
    // etc etc
    my.metrics.logger:
      additive: false
      //etc etc
      appenders:
      - type: file
      // etc etc -- I can't modify this name
  appenders:
    - type: file
    // etc etc -- I see this name when it's built!

I would have expected the FileAppenderFactory to be called twice (once for the appenders for all the loggers, and once for the non-additive appender for metrics), but it is still only called once, so I can't intercept the name for the metrics file to fix.

I've looked in the logging context and I could go context --> loggerCache --> my.metrics.logger --> aai --> appenderList (AsyncAppender) --> aai --> appenderList (RollingFileAppender) and fix that fileName (and rolling policy), assuming that I can access that, but that's a big hack.

Is there something I'm missing? How are multiple file appenders created if the MyFileAppenderFactory's build method is only called once.

Update -- I do see that that the other one is being built through the default FileAppenderFactory, but I've no idea why its going through the default FileAppenderFactory when I've mapped "file" to MyFileAppenderFactory.class .... which again worked for the other appender.


Solution

  • The answer is complex.

    For the additive appender (above) the ObjectMapper that is used to do it is created in DiscoverableSubtypeResolver and not in the base deserializer. So you cannot register your factory programatically, but must instead add it to the META-INF\services\io.dropwizard.logging.AppenderFactory file (which you will need to copy from the dropwizard jar and then add your factory).

    That will at least get your factory hit (although there are other dropwizard problems that you may encounter, but they are beyond the scope of this question).