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