That design should be fine but you will need to implement your own ContextSelector to locate the LoggerContext from the Map. You will also need to make sure the application id is available whenever something needs to locate the LoggerContext via the ContextSelector.
As I have said previously, loggerContext.updateLoggers() does not “change an application’s configuration”. It causes the Loggers to be remapped to the appropriate LoggerContext. You can get the current configuration for the LoggerContext and then modify the existing configuration if you do it carefully. Whether you need to call updateLoggers depends on what you are modifying in the configuration. It only needs to be called if you are adding or removing LoggerConfigs or are changing their logging level. If your applications call LogManager getLogger() your approach may have problems. Applications that call that will typically save the Logger that is returned and never call getLogger() again. That won’t work since you want different Loggers associated with different LoggerContexts based on the application id. The way you have it coded below should work though. Ralph > On Oct 2, 2020, at 6:01 AM, Jochen Wiedmann <[email protected]> wrote: > > Hi, > > consider a logging server. Let's say, there's a REST service "log", > accepting the following parameters: > > - applicationId > - category > - level > - message > > The purpose here is to use the application id as identification of a > log4j configuration. So, the implementation would look roughly like > this: > > private static final ConcurrentHashMap<String,LoggerContext> > applications = new ConcurrentHashMap<>(); > public void log(String pApplicationId, String pCategory, > String pLevel, String pMessage) { > final LoggerContext lc = > applications.computeIfAbsent(pApplicationId, > (id) -> newLoggerContext(id)); > final Logger logger = lc.getLogger(pCategory) > logger.log(pLevel, message); > } > > I hope, I can make myself understandable. Questions: > > 1.) Is that design appropriate? In particular, is the mapping between > application id, and the LoggerContext (as a representation of the > log4j configuration) appropriate? > 2.) Assuming, that I want to change an applications configuration: Is > loggerContext.updateLoggers(Configuration) > the proper way to do that? If so, is it possible to obtain the current > Configuration, modifying it, and then do the update? > 3.) Did I consider multi-threading properly? Basically, my idea is, that > using a ConcurrentHashMap, and computeIfAbsent is sufficient to > obtain a LoggerContext. From that point, I would trust in the > multi-threading abilities of Log4J. > > Thanks, > > Jochen > > -- > > Look, that's why there's rules, understand? So that you think before > you break 'em. > > -- (Terry Pratchett, Thief of Time) >
