Ralph,

I gave it a try, I really did.

It wasn't as straight-forward as all that.

Here's what I finally got to compile, but even so, it never activated
my second configuration file.

At this point, I think I'm done working on the problem.  My other
solution is working.  Your points about not having attributes
specified on the second configuration in the local config file and not
being able to automatically reload have been noted, and I'll put them
into the configuration file.

There's definitely some work to be done to better support this kind of
configuration, and I suspect as we continue down the road that more
situations like this will appear.  Web containers were only the first
wave. :-)

            final LoggerContext loggerContext = (LoggerContext)
LogManager.getContext(false);
            final org.apache.logging.log4j.core.config.Configuration
originalConfiguration = loggerContext.getConfiguration();

            final ConfigurationSource originalConfigurationSource =
originalConfiguration.getConfigurationSource();
            // Can't use originalConfigurationSource directly as the
stream is no longer open.
            final URI originalConfigurationURI =
originalConfigurationSource.getURI();
            org.apache.logging.log4j.core.config.Configuration
originalConfigurationReloaded = null;
            if (originalConfigurationSource != null)
            {
                final String name = "doesn't matter, not used";
                originalConfigurationReloaded =
ConfigurationFactory.getInstance().getConfiguration(loggerContext,
name, originalConfigurationURI);
            }

            final ConfigurationSource localConfigurationSource = new
ConfigurationSource(new FileInputStream(log4jConfigFile), new
File(log4jConfigFile));
            // Warning: current configuration being destroyed at this point.
            final org.apache.logging.log4j.core.config.Configuration
localConfiguration
                =
ConfigurationFactory.getInstance().getConfiguration(loggerContext,
localConfigurationSource);
            // Bad generics.  <Configuration> is not compatible with
<? extends AbstractConfiguration>
            final List configurationList = new ArrayList<>(2);
            configurationList.add(originalConfigurationReloaded);
            configurationList.add(localConfiguration);
            CompositeConfiguration compositeConfiguration = new
CompositeConfiguration(configurationList);

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

---------------------------------------------------------------------
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