I mistyped below - MergeStrategies cannot be specified as Plugins. If you want 
to use a different MergeStrategy you need to specify the class name in a 
property named log4j.mergeStrategy. Note that the documentation at 
http://logging.apache.org/log4j/2.x/manual/configuration.html#SystemProperties 
<http://logging.apache.org/log4j/2.x/manual/configuration.html#SystemProperties>
 is incorrect. log4j2.mergeFactory will not work.

Ralph


> On Feb 9, 2018, at 5:06 PM, Ralph Goers <ralph.go...@dslextreme.com> wrote:
> 
> 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