[ https://issues.apache.org/jira/browse/LOG4J2-3469?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17519396#comment-17519396 ]
Jody Garnett commented on LOG4J2-3469: -------------------------------------- Still not sure how to use Arbiters to feed in a log file location... Based on: {quote}[SystemPropertyArbiter.isCondition()|https://logging.apache.org/log4j/log4j-2.17.1/log4j-core/apidocs/org/apache/logging/log4j/core/config/arbiters/SystemPropertyArbiter.html#isCondition--] Returns true if either the property name is defined (it has any value) or the property value matches the requested value. {quote} In the very simple case of a system property: {code:java} <Properties> <Select> <SystemPropertyArbiter propertyName="GEOSERVER_LOG_LOCATION" <Property name="GEOSERVER_LOG_LOCATION">${env:GEOSERVER_LOG_LOCATION}</Property> </SystemPropertyArbiter> <DefaultArbiter> <Property name="GEOSERVER_LOG_LOCATION">${web:initParam.GEOSERVER_LOG_LOCATION}</Property> </DefaultArbiter> </Select> </Properties>{code} > Create new builder from existing Appender > ----------------------------------------- > > Key: LOG4J2-3469 > URL: https://issues.apache.org/jira/browse/LOG4J2-3469 > Project: Log4j 2 > Issue Type: New Feature > Components: Configuration, Configurators, Core > Affects Versions: 2.17.2 > Reporter: Jody Garnett > Priority: Minor > Attachments: DEFAULT_LOGGING.xml > > > > The documentation covers both [Initialize Log4j by Combining Configuration > File with Programmatic > Configuration|https://logging.apache.org/log4j/2.x/manual/customconfig.html#Hybrid] > and [Programmatically Modifying the Current Configuration after > Initialization|https://logging.apache.org/log4j/2.x/manual/customconfig.html#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. > {code:java} > @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); > } > }{code} > 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. > {code:java} > 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(); > }{code} > *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: > {code:java} > @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); > } {code} > For reference see attached {*}DEFAULT_LOGGING.xml{*}. -- This message was sent by Atlassian Jira (v8.20.1#820001)