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