logging-log4j-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Tarun Sharma <tarun.k.sha...@oracle.com>
Subject RE: Configuring log4j2 using a dynamic changing properties read from a properties file
Date Mon, 28 Nov 2016 05:20:10 GMT
Hi Matt,

Thank you again.
I just tried the second approach too, which is using the BasicContextSelector. I hear you
when you say that implementing a custom ContextSelector could be beneficial.
I do not have web projects. So, I do not need to worry about multiple class loaders.

So, I will try it out and see how it goes.

Best Regards,
Tarun

-----Original Message-----
From: Matt Sicker [mailto:boards@gmail.com] 
Sent: Sunday, November 27, 2016 11:24 PM
To: Log4J Users List
Subject: Re: Configuring log4j2 using a dynamic changing properties read from a properties
file

Depending on your use case, implement a ContextSelector might be the best way to go. If you're
linking LoggerContexts to ClassLoaders (e.g., one context per .war file), then there are easier
ways to do this using the existing functionality. If your LoggerContexts will all be in the
same ClassLoader, then you'll need to either maintain per-thread contexts or some custom ContextSelector.

On 27 November 2016 at 10:10, Tarun Sharma <tarun.k.sharma@oracle.com>
wrote:

> Thank you Matt.
>
> I tried the first way and was able to get it working. But as you 
> rightly said, I need to always use my wrappers. But this will not be the case.
>
> So, I am going to try the other two approaches that you have suggested.
>
>
> Best Regards,
> Tarun
>
> -----Original Message-----
> From: Matt Sicker [mailto:boards@gmail.com]
> Sent: Friday, November 25, 2016 10:37 PM
> To: Log4J Users List
> Subject: Re: Configuring log4j2 using a dynamic changing properties 
> read from a properties file
>
> I think you have a couple ways you could go about resolving this issue:
>
> 1. Save the LoggerContext created by Configurator and only use that to 
> get Logger objects in that context. This would work well if you only 
> use your wrappers and never use the LogManager.getLogger() APIs.
> 2. Use BasicContextSelector instead of the default and set
> ContextAnchor.THREAD_CONTEXT.set(yourContext) to the LoggerContext. 
> This would work if you only have a single LoggerContext you wish to 
> use per thread.
> 3. Implement a custom ContextSelector class to save your 
> LoggerContexts and select them dynamically.
>
> On 25 November 2016 at 02:24, Gary Gregory <garydgregory@gmail.com> wrote:
>
> > You should know that version 2.7 has some support for reading log4j 
> > 1 properties configuration files.
> >
> > Gary
> >
> > On Nov 24, 2016 11:31 PM, "Tarun Sharma" <tarun.k.sharma@oracle.com>
> > wrote:
> >
> > > Hi Matt,
> > >
> > > Your guess is correct. The LoggerContext that I get while logging 
> > > is the Default Logger context and not the context that I 
> > > initialize from the configuration.
> > >
> > > My bad. I messed up while copying .
> > >
> > > Here's the missing constructors from Log4JTracer  which wrap the
> logger.
> > >
> > > /**
> > >      * Constructs new logger.
> > >      *
> > >      * @param name internally used by log4j.
> > >      */
> > >
> > >     protected Log4JTracer(String name) {
> > >         Logger logger = LogManager.getLogger(name);
> > >         log = new ExtendedLoggerWrapper((ExtendedLogger) logger, 
> > > logger.getName(), logger.getMessageFactory());
> > >     }
> > >
> > >     /**
> > >      *
> > >      * @param clazz
> > >      */
> > >     public Log4JTracer(Class<?> clazz)
> > >     {
> > >         Logger logger = LogManager.getLogger(clazz);
> > >         log = new ExtendedLoggerWrapper((ExtendedLogger) logger, 
> > > logger.getName(), logger.getMessageFactory());
> > >     }
> > >
> > >
> > > Regards,
> > > Tarun
> > >
> > >
> > >
> > > -----Original Message-----
> > > From: Matt Sicker [mailto:boards@gmail.com]
> > > Sent: Friday, November 25, 2016 12:55 PM
> > > To: Log4J Users List
> > > Subject: Re: Configuring log4j2 using a dynamic changing 
> > > properties read from a properties file
> > >
> > > My guess is that the LoggerContext you're creating in the 
> > > initialization isn't the one being used by the 
> > > ExtendedLoggerWrapper constructor later
> > on,
> > > though it's hard to tell because I don't think the code snippet 
> > > you included shows where the original Logger object comes from. If 
> > > you're
> > using
> > > LogManager instead of the LoggerContext from the initializer, then 
> > > this could potentially cause you to create a default 
> > > LoggerContext, though I'm not entirely sure.
> > >
> > > On 25 November 2016 at 00:35, Tarun Sharma 
> > > <tarun.k.sharma@oracle.com>
> > > wrote:
> > >
> > > > Hi Gary,
> > > >
> > > > It’s the security policies of the team I work with. They have 
> > > > cleared the
> > > > 2.5 version for upgrade.
> > > >
> > > > Best Regards,
> > > > Tarun
> > > >
> > > > -----Original Message-----
> > > > From: Gary Gregory [mailto:garydgregory@gmail.com]
> > > > Sent: Friday, November 25, 2016 12:04 PM
> > > > To: Log4J Users List
> > > > Subject: Re: Configuring log4j2 using a dynamic changing 
> > > > properties read from a properties file
> > > >
> > > > Quick note: why not 2.7?
> > > >
> > > > Gary
> > > >
> > > > On Nov 24, 2016 9:57 PM, "Tarun Sharma"
> > > > <tarun.k.sharma@oracle.com>
> > > wrote:
> > > >
> > > > > Hello All,
> > > > >
> > > > >
> > > > >
> > > > > I am upgrading a 1.x version log4j product to 2.5
> > > > >
> > > > >
> > > > >
> > > > > We have a single properties file which holds various
> configurations.
> > > > > A sample configuration(trace.properties) is as below:
> > > > >
> > > > >
> > > > >
> > > > > cfg_test.status=debug
> > > > > cfg_test.appenders=rolling
> > > > > cfg_test.appender.rolling.type=RollingFile
> > > > > cfg_test.appender.rolling.name=RollingFile_TEST
> > > > > cfg_test.appender.rolling.fileName=D:/log/test.log
> > > > > cfg_test.appender.rolling.filePattern=D:/log/test_%d{MMdd}.log
> > > > > cfg_test.appender.rolling.layout.type=PatternLayout
> > > > > cfg_test.appender.rolling.layout.pattern=%d %-5p %m%n 
> > > > > cfg_test.appender.rolling.policies.type = Policies 
> > > > > cfg_test.appender.rolling.policies.time.type = 
> > > > > TimeBasedTriggeringPolicy 
> > > > > cfg_test.appender.rolling.policies.time.interval = 1 
> > > > > cfg_test.appender.rolling.policies.time.modulate = true 
> > > > > cfg_test.appender.rolling.policies.size.type = 
> > > > > SizeBasedTriggeringPolicy 
> > > > > cfg_test.appender.rolling.policies.size.size=100MB
> > > > > cfg_test.appender.rolling.strategy.type = 
> > > > > DefaultRolloverStrategy cfg_test.appender.rolling.strategy.max 
> > > > > =
> > > > > 5
> > > > >
> > > > > cfg_test.rootLogger.level=debug 
> > > > > cfg_test.rootLogger.appenderRefs=test
> > > > > cfg_test.rootLogger.appenderRef.test.ref=RollingFile_TEST
> > > > >
> > > > >
> > > > >
> > > > > cfg_crp.rootLogger.level=info
> > > > > cfg_crp.rootLogger.appenderRefs=crp, stdout 
> > > > > cfg_crp.rootLogger.appenderRef.crp.ref=RollingFile_CRP
> > > > > cfg_crp.rootLogger.appenderRef.stdout.ref=STDOUT
> > > > >
> > > > >
> > > > >
> > > > >
> > > > >
> > > > > Here cfg_test is a test configuration and cfg_crp is a 
> > > > > configuration for a functionality in product which is launched 
> > > > > as a separate
> > module.
> > > > >
> > > > >
> > > > >
> > > > > I have a custom factory as below:
> > > > >
> > > > >
> > > > >
> > > > > public class TraceFactory {
> > > > >
> > > > >   private static boolean isInitialized = false;
> > > > >
> > > > >
> > > > >   /**
> > > > >    * intializes the trace with the given trace key.
> > > > >    * <p/>
> > > > >    * If if the trace key is null, we will use the console trace
> > > > >    *
> > > > >    * @param traceKey trace key
> > > > >    */
> > > > >   public static void initialize(String traceKey) {
> > > > >     initPrefix(traceKey != null ? "cfg_" + traceKey + "." :
> > > > > null, PropertiesUtils.readFromClassPath("properties/trace"));
> > > > >   }
> > > > >
> > > > >   private static void initPrefix(String prefix, Properties
> > properties)
> > > {
> > > > >     if (isInitialized) {
> > > > >       return;
> > > > >     }
> > > > >
> > > > >     if (prefix == null) {
> > > > >       TraceFactory.initializeAsConsoleTracer();
> > > > >       return;
> > > > >     }
> > > > >
> > > > >     Properties cfg = new Properties();
> > > > >
> > > > >     for (Map.Entry<Object, Object> objectObjectEntry :
> > > > > properties.entrySet()) {
> > > > >       Map.Entry entry = (Map.Entry) objectObjectEntry;
> > > > >       String key = (String) entry.getKey();
> > > > >       String value = (String) entry.getValue();
> > > > >
> > > > >       if (key.startsWith(prefix)) {
> > > > >         cfg.put(key.substring(prefix.length()), value);
> > > > >       }
> > > > >     }
> > > > >
> > > > >     PropertiesConfigurationFactory factory = new
> > > > > PropertiesConfigurationFactory();   // This line and the try catch
> > > below
> > > > > replace the
> > > > >     try {
> > > > >       ConfigurationSource configSrc =
> > > > > createConfigurationSource(cfg)
> > ;
> > > > >             //PropertyConfigurator.configure(cfg); from 
> > > > > log4j1.2
> > > > >
> > > > >       Configuration conf = factory.getConfiguration(configSrc);
> > > > >       LoggerContext  ctx = Configurator.initialize(conf);
> > > > >
> > > > >       ctx.reconfigure();
> > > > >     }
> > > > >     catch (IOException io)
> > > > >     {
> > > > >
> > > > >     }
> > > > >
> > > > >     isInitialized = true;
> > > > >   }
> > > > >
> > > > >   /**
> > > > >    *
> > > > >    * @param cfg the log4j configuration as a properties bundle 
> > > > > read from a properties file.
> > > > >    * @return {@link ConfigurationSource} object
> > > > >    * @throws IOException
> > > > >    */
> > > > >   private static ConfigurationSource 
> > > > > createConfigurationSource(Properties
> > > > > cfg) throws IOException {
> > > > >
> > > > >     ByteArrayOutputStream out = new ByteArrayOutputStream();
> > > > >     cfg.store(out, null);
> > > > >     InputStream in = new ByteArrayInputStream(out.toByteArray());
> > > > >     return new ConfigurationSource(in);
> > > > >   }
> > > > >
> > > > >
> > > > >
> > > > >   public static TraceInterface getTracer(Class class_) {
> > > > >     if (useConsoleTracer) {
> > > > >       return new ConsoleTracer(null);
> > > > >     }
> > > > >     return Log4JTracer.getTracer(class_);
> > > > >   }
> > > > >
> > > > >
> > > > >   public static TraceInterface getTracer(String name) {
> > > > >     if (useConsoleTracer) {
> > > > >       return new ConsoleTracer(null);
> > > > >     }
> > > > >     return Log4JTracer.getTracer(name);
> > > > >   }
> > > > > }
> > > > >
> > > > > My LogWrapper Log4JTracer is :-
> > > > >
> > > > > public class Log4JTracer implements TraceInterface {
> > > > >
> > > > >
> > > > >   private static final String FQCN = 
> > > > > Log4JTracer.class.getName();
> > > > >
> > > > >   /**
> > > > >    * extended logger wrapper
> > > > >    */
> > > > >   private final ExtendedLoggerWrapper log;
> > > > >
> > > > >
> > > > >   private Log4JTracer(final Logger logger) {
> > > > >     this.log = new 
> > > > > ExtendedLoggerWrapper((AbstractLogger)logger,
> > > > > logger.getName(), logger.getMessageFactory());
> > > > >   }
> > > > >
> > > > >
> > > > >
> > > > >   /**
> > > > >    * {@inheritDoc}
> > > > >    */
> > > > >   public void debug(Object message) {
> > > > >     debug(message, null);
> > > > >   }
> > > > >
> > > > >   /**
> > > > >    * {@inheritDoc}
> > > > >    */
> > > > >   public void debug(Object message, Throwable t) {
> > > > >     log.logIfEnabled(FQCN, Level.DEBUG, null, message, t);
> > > > >   }
> > > > >
> > > > >
> > > > >   /**
> > > > >    * {@inheritDoc}
> > > > >    */
> > > > >   public void info(Object message) {
> > > > >     info(message, null);
> > > > >   }
> > > > >
> > > > >   /**
> > > > >    * {@inheritDoc}
> > > > >    */
> > > > >   public void info(Object message, Throwable t) {
> > > > >     log.logIfEnabled(FQCN, Level.INFO, null, message, t);
> > > > >   }
> > > > >
> > > > >
> > > > >
> > > > >   /**
> > > > >    * {@inheritDoc}
> > > > >    */
> > > > >   public boolean isWarnEnabled() {
> > > > >     return log.isWarnEnabled();
> > > > >   }
> > > > >
> > > > >
> > > > >   /**
> > > > >    * {@inheritDoc}
> > > > >    */
> > > > >   public void warn(Object message) {
> > > > >     warn(message, null);
> > > > >   }
> > > > >
> > > > >   /**
> > > > >    * {@inheritDoc}
> > > > >    */
> > > > >   public void warn(Object message, Throwable t) {
> > > > >     log.logIfEnabled(FQCN, Level.WARN, null, message, t);
> > > > >
> > > > >
> > > > >   /**
> > > > >    * {@inheritDoc}
> > > > >    */
> > > > >   public boolean isErrorEnabled() {
> > > > >     return log.isErrorEnabled();
> > > > >   }
> > > > >
> > > > >   /**
> > > > >    * {@inheritDoc}
> > > > >    */
> > > > >   public void error(Object message) {
> > > > >     error(message, null);
> > > > >   }
> > > > >
> > > > >   /**
> > > > >    * {@inheritDoc}
> > > > >    */
> > > > >   public void error(Object message, Throwable t) {
> > > > >     log.logIfEnabled(FQCN, Level.ERROR, null, message, t);
> > > > >   }
> > > > >
> > > > >     /**
> > > > >    * {@inheritDoc}
> > > > >    */
> > > > >   public boolean isFatalEnabled() {
> > > > >     return log.isFatalEnabled();
> > > > >   }
> > > > >
> > > > >
> > > > >
> > > > >
> > > > >   /**
> > > > >    * {@inheritDoc}
> > > > >    */
> > > > >   public void fatal(Object message, Throwable t) {
> > > > >     log.logIfEnabled(FQCN, Level.FATAL, null, message, t);
> > > > >   }
> > > > >
> > > > >
> > > > >   /**
> > > > >    * {@inheritDoc}
> > > > >    */
> > > > >   @Override
> > > > >   public boolean isDebugEnabled() {
> > > > >     return log.isDebugEnabled();
> > > > >   }
> > > > >
> > > > >   /**
> > > > >    * {@inheritDoc}
> > > > >    */
> > > > >   @Override
> > > > >   public boolean isInfoEnabled() {
> > > > >     return log.isInfoEnabled();
> > > > >   }
> > > > >
> > > > >
> > > > >   public static Log4JTracer getTracer(Class cl) {
> > > > >     return new Log4JTracer(cl);
> > > > >   }
> > > > >
> > > > >
> > > > >   public static Log4JTracer getTracer(String name) {
> > > > >     return new Log4JTracer(name);
> > > > >   }
> > > > >
> > > > > }
> > > > >
> > > > >
> > > > > Now when I try to use a logger from a class as below, It does 
> > > > > not get the logger according to the config:
> > > > >
> > > > >
> > > > >
> > > > > Public class Test {
> > > > >
> > > > >
> > > > >
> > > > > Private TraceInterface trace;
> > > > >
> > > > >
> > > > >
> > > > > Public void execute() {
> > > > >
> > > > >
> > > > >
> > > > > TraceFactory.initialize("test");
> > > > >
> > > > > trace = TraceFactory.getTracer();
> > > > >
> > > > > trace.debug("testing..");   // this never prints. Although a
> test.log
> > > is
> > > > > created with zero size as soon as the TraceFactory.initialize 
> > > > > method finshes.
> > > > >
> > > > >
> > > > >
> > > > >
> > > > >
> > > > > Thanks and Regards,
> > > > >
> > > > > Tarun
> > > > >
> > > >
> > > > ----------------------------------------------------------------
> > > > --
> > > > --- To unsubscribe, e-mail:
> > > > log4j-user-unsubscribe@logging.apache.org
> > > > For additional commands, e-mail:
> > > > log4j-user-help@logging.apache.org
> > > >
> > > >
> > >
> > >
> > > --
> > > Matt Sicker <boards@gmail.com>
> > >
> > > ------------------------------------------------------------------
> > > --
> > > - To unsubscribe, e-mail: 
> > > log4j-user-unsubscribe@logging.apache.org
> > > For additional commands, e-mail: 
> > > log4j-user-help@logging.apache.org
> > >
> > >
> >
>
>
>
> --
> Matt Sicker <boards@gmail.com>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: log4j-user-unsubscribe@logging.apache.org
> For additional commands, e-mail: log4j-user-help@logging.apache.org
>
>


--
Matt Sicker <boards@gmail.com>

---------------------------------------------------------------------
To unsubscribe, e-mail: log4j-user-unsubscribe@logging.apache.org
For additional commands, e-mail: log4j-user-help@logging.apache.org


Mime
View raw message