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