[
https://issues.apache.org/jira/browse/LOG4J2-3469?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Jody Garnett updated LOG4J2-3469:
---------------------------------
Description:
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}
ConfigurationBuilder<BuiltConfiguration> builder =
ConfigurationBuilderFactory.newConfigurationBuilder();
Appender appender = config.getAppenders("geoserverlogfile");
if( appender instanceof RollingFileAppender){
RollingFileAppender fileAppender =(RollingFileAppender) appender;
AppenderComponentBuilder appenderBuilder = builder.
newAppender("geoserverlogfile", fileAppender)
.addAttribute("fileName", "${GEOSERVER_LOG_LOCATION}.log");
config.getAppenders().remove("geoserverlogfile");
addAppender((Appender) appenderBuilder.build());
}{code}
The alternative is quite verbose and prone may miss copying new parameters
added over time.
Candidates:
*MyXMLConfiguration.setup()* prior to super.setup(): Unclear how easy/safe it
is to to modify _rootNode_ structure directly? Is this what is intended?
{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:
- 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{*}.
was:
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 if one is available.
Candidates:
*MyXMLConfiguration.setup()* prior to super.setup(): Unclear how easy/safe it
is to to modify node structure directly? Is this what is intended?
{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:
- Can only append add loggers and appenders
- Modifications to config.getProperties() are not reflected in appender
configuration.
- Modifications to existing appenders cannot be accomplished
- 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.
{*}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{*}.
> Override configuration file properties and appenders with programmatic
> configuration
> ------------------------------------------------------------------------------------
>
> 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}
> ConfigurationBuilder<BuiltConfiguration> builder =
> ConfigurationBuilderFactory.newConfigurationBuilder();
> Appender appender = config.getAppenders("geoserverlogfile");
> if( appender instanceof RollingFileAppender){
> RollingFileAppender fileAppender =(RollingFileAppender) appender;
>
> AppenderComponentBuilder appenderBuilder = builder.
> newAppender("geoserverlogfile", fileAppender)
> .addAttribute("fileName", "${GEOSERVER_LOG_LOCATION}.log");
>
> config.getAppenders().remove("geoserverlogfile");
> addAppender((Appender) appenderBuilder.build());
> }{code}
> The alternative is quite verbose and prone may miss copying new parameters
> added over time.
>
> Candidates:
> *MyXMLConfiguration.setup()* prior to super.setup(): Unclear how easy/safe it
> is to to modify _rootNode_ structure directly? Is this what is intended?
> {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:
> - 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)