[slf4j-user] Reconfigure during runtime

Per Lindberg per.lindberg at facilitylabs.com
Wed Feb 17 11:19:36 CET 2010


Ceki Gülcü wrote:
> On 17/02/2010 9:20 AM, Per Lindberg wrote:
>> Ceki Gülcü wrote:
> 
>>> SLF4J loggers do not have setters or getters for levels. You would
>>> need to use the log4j API directly to set logger levels.
>>
>> I hav tried just that, using the code snippet above.
>> It calls log4j directly:
>>
>> org.apache.log4j.Logger root = org.apache.log4j.Logger.getRootLogger();
>> root.setLevel(org.apache.log4j.Level.DEBUG);
>>
>> No luck.
> 
> By default, log4j assigns the DEBUG level to the root logger. Thus,
> the code above is idempotent with respect to a default configuration.
> Just to be sure, when you say "no luck", do you mean that the code has
> no affect (which is normal) or do you mean that it doesn't compile or
> throws an exception? If so, you have probably placed
> log4j-over-slf4j.jar on your class path.

It compiles and runs all right. But it doesn't change the log level.

I have a log4j.properties that sets my default log level to INFO:

   log4j.rootLogger=WARN
   log4j.logger.com.facilitylabs.controlserver=INFO,SERVERLOG

where SERVERLOG is a org.apache.log4j.RollingFileAppender.
Works fine. Now, I have sprinkled my code with slf4j calls.
Every method begins with

   log.debug("fooMethod({},{})", param1, param2);

Now, suppose that I suspect that something is wrong in the running
production server. I don't want to stop it, just tell it to start
logging on DEBUG level for class com.facilitylabs.foo.barServlet .
Via the web GUI I POST a command to the above code. But no debug
messages are written to my log file. (INFO messages work fine,
as usual).

Is this because I change log level in the log4j layer,
but not in the slf4j layer?

> Which jar files do you have on your class path?

Among others:
   log4j-1.2.15.jar
   slf4j-log4j12-1.5.6.jar
   slf4j-api-1.5.6.jar

>> (I had then plans to do it more specifically by passing request
>> parameters with specific log level and class path:
>>
>> org.apache.log4j.Logger logger =
>> org.apache.log4j.Logger.getLogger(classPath);
>> org.apache.log4j.Level level = org.apache.log4j.Level.toLevel(logLevel);
>> logger.setLevel(level);
>>
>> Since I import slf4j, I of course must specify the full package
>> qualification for the log4j calls.)
> 
> If in the particular class where the log4j configuration calls are made, 
> you do not invoke SLF4J, you could avoid the SLF4J imports but import 
> log4j classes instead. However, if you are using both, you need to refer 
> to the class of the non-imported package in fully qualified form.
> 
>>> This would tie your code to log4j.
>>
>> Ah, you mean that I would have to throw out slf4j,
>> and use log4j directly for logging?
> 
> No, that's not what I meant. SLF4J gives you the ability to easily
> switch logging frameworks. If you use SLF4J as your logging API, you
> can switch from one logging framework, say from log4j to j.u.l, or
> from log4j to logback, within minutes, unless your code makes direct
> calls to the underlying logging framework, log4j in your case. The
> more direct calls you make to the underlying logging framework, the
> harder it is to switch.

Yes, that's precicely why I use slf4j. Also because of the smart
parameter passing that only evaluates when needed. (Variants with
up to, say, five parameters would be nice, though).

>>> However, it would do so at one single point
>>> instead of throughout your application.
>>
>> Sorry, I didn't understand that.
> 
> I hope the previous paragraph explains it a bit better.

And I hope that I have come a little bit further in explaining
what I'm trying to do, and why.

Best regards,
Per Lindberg




More information about the slf4j-user mailing list