CompositeConfiguration tries to merge attributes for elements with the same 
name. CompositeConfiguration can be configured with a MergeStrategy to handle 
merging nodes in the configuration. It uses the DefaultMergeStrategy by 
default. See 
http://logging.apache.org/log4j/2.x/manual/configuration.html#CompositeConfiguration
 
<http://logging.apache.org/log4j/2.x/manual/configuration.html#CompositeConfiguration>
 for details on how it works. If you don’t like something in the way it works 
you can copy it, modify it, give it a new Plugin name and then configure it to 
be used.

Ralph

> On Feb 9, 2018, at 3:02 PM, Mike Kienenberger <mkien...@gmail.com> wrote:
> 
> Ralph,
> Thank for looking at it.
> I will give your method for cloning and compositeConfiguring a try
> when I get a chance.
> What will happen if the local (2nd) configuration file has a root
> logger entry?  What gotchas should I worry about when merging two
> configurations together with a CompositeConfiguration?
> 
> Am I reading it right that the last configuration specified would be
> used to provide the root logger?
> 
> So for my example, I would want to make the cloned existing
> configuration the last one added in order to preserve the root logger
> from EVIL.jar?
> 
> 
> 
> On Fri, Feb 9, 2018 at 4:50 PM, Ralph Goers <ralph.go...@dslextreme.com> 
> wrote:
>> You are starting the local configuration. This is a bit of a problem. On the 
>> one hand it is calling the start method of all the components you want to 
>> add, so that is nice. On the other hand if your configuration specifies a 
>> monitorInterval a WatchManager is going to be started to monitor that file. 
>> If someone changes that file it will not properly reconfigure. We might also 
>> add other things to the start method of AbstractConfiguration. These are all 
>> going to be orphaned when the reference to the local configuration is lost. 
>> So I really wouldn’t recommend calling start. In fact, I really think the 
>> approach of copying the current configuration and using the 
>> CompositeConfiguration is the safest way to accomplish what you are wanting.
>> 
>> Ralph
>> 
>> 
>> 
>>> On Feb 9, 2018, at 10:58 AM, Mike Kienenberger <mkien...@gmail.com> wrote:
>>> 
>>> Ralph,
>>> 
>>> I was able to accomplish what I needed.   I think I prefer what I've
>>> done over trying to create a CompositeConfiguration as my current
>>> approach doesn't re-initialize the existing configuration and it gives
>>> me more control over how the additional configuration is merged into
>>> the existing configuration.
>>> 
>>> I'm sure that the down-side is that I'm accessing non-public api and
>>> it will probably break down the road.
>>> 
>>> I'm attaching the method I created.   Apologies for the braces on
>>> separate lines (code style of this project) and it's a little long but
>>> I think it's worth putting in the archives for future reference.
>>> 
>>>   /**
>>>    * Reads file log4jConfigFile as an xml configuration file.
>>>    * Adds Appenders and non-root loggers to the existing logging
>>> Configuration.
>>>    * Root logger is ignored.
>>>    * Currently does not support Filters or properties on Loggers.
>>>    *
>>>    * @param log4jConfigFile file name to read.
>>>    */
>>>   private static void updateLog4jConfiguration(final String log4jConfigFile)
>>>   {
>>>       try
>>>       {
>>>           final LoggerContext loggerContext = (LoggerContext)
>>> LogManager.getContext(false);
>>>           final org.apache.logging.log4j.core.config.Configuration
>>> configuration = loggerContext.getConfiguration();
>>>           LoggerConfig parentLoggerConfig = configuration.getRootLogger();
>>> 
>>>           final ConfigurationSource localConfigurationSource = new
>>> ConfigurationSource(new FileInputStream(log4jConfigFile), new
>>> File(log4jConfigFile));
>>>           final XmlConfiguration localXmlConfiguration = new
>>> XmlConfiguration(null, localConfigurationSource);
>>> 
>>>           localXmlConfiguration.initialize();
>>>           localXmlConfiguration.setup();
>>>           localXmlConfiguration.start();
>>> 
>>>           final Map<String, Appender> localAppenders =
>>> localXmlConfiguration.getAppenders();
>>>           final Map<String, LoggerConfig> localLoggers =
>>> localXmlConfiguration.getLoggers();
>>>           final Collection<Appender> localAppenderList =
>>> localAppenders.values();
>>>           for (final Appender appender : localAppenderList)
>>>           {
>>>               configuration.addAppender(appender);
>>>           }
>>> 
>>>           LoggerConfig localRootLoggerConfig = null;
>>>           final List<LoggerConfig> newLoggerConfigList = new ArrayList<>();
>>> 
>>>           for (final LoggerConfig localFileProvidedLoggerConfig :
>>> localLoggers.values())
>>>           {
>>>               final List<AppenderRef> appenderRefsList =
>>> localFileProvidedLoggerConfig.getAppenderRefs();
>>>               final AppenderRef[] appenderRefsArray;
>>>               if (null != appenderRefsList)
>>>               {
>>>                   appenderRefsArray = appenderRefsList.toArray(new
>>> AppenderRef[appenderRefsList.size()]);
>>>               }
>>>               else
>>>               {
>>>                   appenderRefsArray = new AppenderRef[0];
>>>               }
>>>               final List<Property> propertyList =
>>> localFileProvidedLoggerConfig.getPropertyList();
>>>               final Property[] propertyArray;
>>>               if (null != propertyList)
>>>               {
>>>                   propertyArray = propertyList.toArray(new
>>> Property[propertyList.size()]);
>>>               }
>>>               else
>>>               {
>>>                   propertyArray = new Property[0];
>>>               }
>>>               final LoggerConfig newLoggerConfig =
>>> LoggerConfig.createLogger(localFileProvidedLoggerConfig.isAdditive(),
>>>                       localFileProvidedLoggerConfig.getLevel(),
>>>                       localFileProvidedLoggerConfig.getName(),
>>> 
>>> String.valueOf(localFileProvidedLoggerConfig.isIncludeLocation()),
>>>                       appenderRefsArray, propertyArray,
>>>                       configuration,
>>>                       localFileProvidedLoggerConfig.getFilter());
>>> 
>>>               for (final AppenderRef appenderRef : appenderRefsList)
>>>               {
>>>                   final Appender appender =
>>> localAppenders.get(appenderRef.getRef());
>>>                   if (null != appender)
>>>                   {
>>>                       newLoggerConfig.addAppender(appender, null, null);
>>>                   }
>>>                   else
>>>                   {
>>>                       // TODO: handle logger missing appender
>>> configuration error
>>>                   }
>>>               }
>>> 
>>>               if (newLoggerConfig.getName().isEmpty())
>>>               {
>>>                   if (null != localRootLoggerConfig)
>>>                   {
>>>                       // TODO: handle multiple root loggers
>>> configuration error
>>>                   }
>>>                   localRootLoggerConfig = newLoggerConfig;
>>>               }
>>> 
>>>               newLoggerConfig.setLevel(newLoggerConfig.getLevel());
>>>               newLoggerConfigList.add(newLoggerConfig);
>>>           }
>>> 
>>> //            if (null != localRootLoggerConfig)
>>> //            {
>>> //                localRootLoggerConfig.setParent(parentLoggerConfig);
>>> //                parentLoggerConfig = localRootLoggerConfig;
>>> //
>>> configuration.addLogger(localRootLoggerConfig.getName(),
>>> localRootLoggerConfig);
>>> //            }
>>> 
>>>           for (LoggerConfig newLoggerConfig : newLoggerConfigList)
>>>           {
>>>               newLoggerConfig.setParent(parentLoggerConfig);
>>>               configuration.addLogger(newLoggerConfig.getName(),
>>> newLoggerConfig);
>>>           }
>>> 
>>>           loggerContext.updateLoggers();
>>>       }
>>>       catch (final Exception e)
>>>       {
>>>           // TODO: handle configuration error
>>>       }
>>>   }
>>> 
>>> On Fri, Feb 9, 2018 at 12:37 PM, Ralph Goers <ralph.go...@dslextreme.com> 
>>> wrote:
>>>> Would you mind creating a Jira issue requesting that the clone method, or 
>>>> some variation of it, be added to Configuration implementations?
>>>> 
>>>> Ralph
>>>> 
>>>>> On Feb 9, 2018, at 9:14 AM, Mike Kienenberger <mkien...@gmail.com> wrote:
>>>>> 
>>>>> Doh! I thought you had provided me with the magic bullet. :)
>>>>> 
>>>>> Ok. I'll back to programmically registering info read from my
>>>>> XmlConfiguration into the active Context.
>>>>> 
>>>>> On Fri, Feb 9, 2018 at 11:12 AM, Ralph Goers <ralph.go...@dslextreme.com> 
>>>>> wrote:
>>>>>> It occurs to me that there is a problem with my suggest in that you 
>>>>>> cannot create a new Configuration using the currently active 
>>>>>> configuration as that will cause problems. The current configuration 
>>>>>> needs to be cloned. I don’t know if we have an easy way to do that.
>>>>>> 
>>>>>> Ralph
>>>>>> 
>>>>>>> On Feb 9, 2018, at 9:08 AM, Ralph Goers <ralph.go...@dslextreme.com> 
>>>>>>> wrote:
>>>>>>> 
>>>>>>> If you want to add to their configuration then you should use a 
>>>>>>> CompositeConfiguration. In that case I would get the current 
>>>>>>> configuration, create your own Configuration, add them both to a new 
>>>>>>> CompositeConfiguration and then call 
>>>>>>> Configurator.initialize(compositeConfiguration).
>>>>>>> 
>>>>>>> Ralph
>>>>>>> 
>>>>>>>> On Feb 9, 2018, at 9:03 AM, Mike Kienenberger <mkien...@gmail.com> 
>>>>>>>> wrote:
>>>>>>>> 
>>>>>>>> Thanks, Ralph,
>>>>>>>> 
>>>>>>>> While that does work (tested) and could be useful in some instances,
>>>>>>>> it would require that we extract and keep synced the logging
>>>>>>>> configuration from EVIL.jar, then append our own changes to it.  I can
>>>>>>>> see how this will be helpful when I'm doing development in this
>>>>>>>> environment.  But it doesn't meet the need of only changing logging so
>>>>>>>> that our own module logs to a different location.
>>>>>>>> 
>>>>>>>> On Thu, Feb 8, 2018 at 7:26 PM, Ralph Goers 
>>>>>>>> <ralph.go...@dslextreme.com> wrote:
>>>>>>>>> If you want to replace the existing configuration you should be able 
>>>>>>>>> to do:
>>>>>>>>> 
>>>>>>>>> Configurator.initialize(“MyApp”, “app-log4j2.xml”);
>>>>>>>>> 
>>>>>>>>> This will look for a file named app-log4j2.xml on the class path.
>>>>>>>>> 
>>>>>>>>> Ralph
>>>>>>>>> 
>>>>>>>>>> On Feb 8, 2018, at 1:28 PM, Mike Kienenberger <mkien...@gmail.com> 
>>>>>>>>>> wrote:
>>>>>>>>>> 
>>>>>>>>>> As others have reported in years past, the examples in the docs for
>>>>>>>>>> 
>>>>>>>>>> Programmatically Modifying the Current Configuration after 
>>>>>>>>>> Initialization
>>>>>>>>>> 
>>>>>>>>>> are out of date.  They don't compile.  They don't work (affect the
>>>>>>>>>> existing logging) even if you do fix the errors.
>>>>>>>>>> 
>>>>>>>>>> Here's my situation:
>>>>>>>>>> 
>>>>>>>>>> I am working in an environment with EVIL.JAR which includes a 
>>>>>>>>>> log4j2.xml file.
>>>>>>>>>> I can't change the jar.  I can't specific a System Property to 
>>>>>>>>>> override it.
>>>>>>>>>> 
>>>>>>>>>> My code gets called as a loaded module long after the logging system
>>>>>>>>>> is initialized.
>>>>>>>>>> 
>>>>>>>>>> I want logging in my own code to go to a different location, and
>>>>>>>>>> preferably I'd like to read the configuration in from a log4j2.xml
>>>>>>>>>> file so that anyone who uses my module isn't victim to the same evil
>>>>>>>>>> hardcoded-logging practices of EVIL.JAR.
>>>>>>>>>> 
>>>>>>>>>> Creating an XMLConfiguration and initializing it lets me read the xml
>>>>>>>>>> file easily enough.   Looping through the data gets me the Appenders,
>>>>>>>>>> Filters and Loggers.   But I still can't use them to modify the
>>>>>>>>>> existing configuration.
>>>>>>>>>> 
>>>>>>>>>> Another person took the approach of using JUL instead.  I hate JUL 
>>>>>>>>>> and
>>>>>>>>>> I'd really rather not have to go down that route.
>>>>>>>>>> 
>>>>>>>>>> Thanks in advance.
>>>>>>>>>> -Mike
>>>>>>>>>> 
>>>>>>>>>> ---------------------------------------------------------------------
>>>>>>>>>> To unsubscribe, e-mail: log4j-user-unsubscr...@logging.apache.org
>>>>>>>>>> For additional commands, e-mail: log4j-user-h...@logging.apache.org
>>>>>>>>>> 
>>>>>>>>>> 
>>>>>>>>> 
>>>>>>>>> 
>>>>>>>>> 
>>>>>>>>> ---------------------------------------------------------------------
>>>>>>>>> To unsubscribe, e-mail: log4j-user-unsubscr...@logging.apache.org
>>>>>>>>> For additional commands, e-mail: log4j-user-h...@logging.apache.org
>>>>>>>>> 
>>>>>>>> 
>>>>>>>> ---------------------------------------------------------------------
>>>>>>>> To unsubscribe, e-mail: log4j-user-unsubscr...@logging.apache.org
>>>>>>>> For additional commands, e-mail: log4j-user-h...@logging.apache.org
>>>>>>>> 
>>>>>>>> 
>>>>>>> 
>>>>>>> 
>>>>>>> 
>>>>>>> ---------------------------------------------------------------------
>>>>>>> To unsubscribe, e-mail: log4j-user-unsubscr...@logging.apache.org
>>>>>>> For additional commands, e-mail: log4j-user-h...@logging.apache.org
>>>>>>> 
>>>>>>> 
>>>>>> 
>>>>>> 
>>>>>> 
>>>>>> ---------------------------------------------------------------------
>>>>>> To unsubscribe, e-mail: log4j-user-unsubscr...@logging.apache.org
>>>>>> For additional commands, e-mail: log4j-user-h...@logging.apache.org
>>>>>> 
>>>>> 
>>>>> ---------------------------------------------------------------------
>>>>> To unsubscribe, e-mail: log4j-user-unsubscr...@logging.apache.org
>>>>> For additional commands, e-mail: log4j-user-h...@logging.apache.org
>>>>> 
>>>>> 
>>>> 
>>>> 
>>>> 
>>>> ---------------------------------------------------------------------
>>>> To unsubscribe, e-mail: log4j-user-unsubscr...@logging.apache.org
>>>> For additional commands, e-mail: log4j-user-h...@logging.apache.org
>>>> 
>>> 
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: log4j-user-unsubscr...@logging.apache.org
>>> For additional commands, e-mail: log4j-user-h...@logging.apache.org
>>> 
>>> 
>> 
>> 
>> 
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: log4j-user-unsubscr...@logging.apache.org
>> For additional commands, e-mail: log4j-user-h...@logging.apache.org
>> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: log4j-user-unsubscr...@logging.apache.org
> For additional commands, e-mail: log4j-user-h...@logging.apache.org
> 
> 

Reply via email to