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.