Uploaded image for project: 'Log4j 2'
  1. Log4j 2
  2. LOG4J2-3469

Create new builder from existing Appender

    XMLWordPrintableJSON

Details

    • New Feature
    • Status: Open
    • Minor
    • Resolution: Unresolved
    • 2.17.2
    • None
    • None

    Description

       

      The documentation covers both Initialize Log4j by Combining Configuration File with Programmatic Configuration and Programmatically Modifying the Current Configuration after Initialization

      However both these techniques are limited as to what they can accomplish:

      • MyXMLConfiguration.doConfigure() is shown adding an appender, via addLogger method
      • A custom configuration super.setup() method is shown using config.addLogger() and then ctx.updateLoggers().

      My challenge is to programatically update the configuration to:

      • Override logfile output location, either directly modifying appender, or modifying config property used by appender.
      • Optionally Filter out any RollingFileAppender or FileAppender appenders
      • Optionally suppress (filter out) any Console loggers if asked

      I am seeking an api used to pre-process configuration objects if one is available.

      In the past when using a fluent / builder API there is an option to jump-start a builder with the configuration of an existing object. This approach would allow a builder to be loaded with an existing appender; revised, and a new appender generated as a replacement.

      @Override protected void doConfigure() {
          super.doConfigure();
      
          getProperties().put("GEOSERVER_LOG_LOCATION","geoserver.log");
      
          Appender appender = getAppenders("geoserverlogfile");
          if( appender instanceof RollingFileAppender){
               RollingFileAppender fileAppender =(RollingFileAppender) appender;
      
               RollingFileAppender replacement = RollingFileAppender.newBuilder(fileAppender)
                  .withFileName("${GEOSERVER_LOG_LOCATION}.log")
                  .withFilePattern("${GEOSERVER_LOG_LOCATION}-%i.log")
                  .build();
              
               getAppenders().remove("geoserverlogfile");
               addAppender(replacement);
          }
      }

      The alternative is verbose and may miss copying new parameters added over time.

      Alternatives considered:

      MyXMLConfiguration.setup() prior to super.setup(): Unclear how easy/safe it is to to modify rootNode structure directly? Is this what is intended by the documentation.

      public void setup() {
          for( Node child : rootNode.getChildren()){
              if ("Properties".equals(child.getName())){
                  for( Node property : child.getChildren() ){
                      if( property.getAttributes().containsKey("name") &&
                              property.getAttributes().get("name").equals("GEOSERVER_LOG_LOCATION")) {
                          // override value with current GEOSERVER_LOG_LOCATION
                          property.setValue("foo.log");
                      }
                  }
              }
          }
          super.setup();
      }

      MyXMLConfiguration.doConfigure() before super.doConfigure(): should be able to modify rootNode and make any changes required. Unclear how easy/safe it is to to modify node structure directly?

      MyXMLConfiguration.doConfigure()  after super.doConfigure(): is too late as shown above.

      • Can add loggers and appenders
      • Modifications to config.getProperties() are not reflected in appender configuration 
      • Modifications to existing appenders cannot be accomplished

      MyXMLConfiguration.preConfigure(Node) allows xml to be rewritten just-in-time:

      @Overrideprotected void preConfigure(Node node) {
          if( !node.isRoot() && node.getName().equals("Property")){
              if( node.getAttributes().containsKey("name") &&
                      node.getAttributes().get("name").equals("GEOSERVER_LOG_LOCATION")) {
                  // override value with current GEOSERVER_LOG_LOCATION
                  node.setValue("foo.log");
              }
          }
          super.preConfigure(node);
      } 

      For reference see attached DEFAULT_LOGGING.xml.

      Attachments

        1. DEFAULT_LOGGING.xml
          3 kB
          Jody Garnett

        Activity

          People

            Unassigned Unassigned
            jodygarnett Jody Garnett
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated: