Re: [PROPOSAL] Implementing the SLF4J API directly

2008-12-09 Thread Curt Arnold


On Dec 9, 2008, at 4:58 AM, Thorbjørn Ravn Andersen wrote:
There was a request recently to make the argument replacement  
mechanism more powerful in either slf4j or logback (cannot remember)  
where Ceki mentioned that one of the major benefits of the {}- 
approach was that it was measurably faster than the StringFormatter  
in Java.


For this particular purpose I suggest that the fastest approach is  
chosen as it will apply to all events actually processed.   Would  
lifting the slf4j code into log4j be an option - I believe that the  
license allows it.




There are two formatters in the Java API, java.text.MessageFormat   
(since JDK 1) and java.util.Formatter (since JDK 5).  The SLF4J format  
specifier resembles, but is incompatible with, the format specifier of  
java.text.MessageFormat.


Actually the SLF4J formatting code (as far as I can tell) was  
originally written as part of log4j 1.3 and already is used in LogSF  
in the extras companion.  LogMF provides the same services but uses  
java.text.MessageFormat format specifiers.  While these were in the  
sandbox, there was a LogF which provided the same services using the  
java.util.Formatter, however their wasn't sufficient demand to polish  
that up for release.  Still very doable.


LogMF and LogSF provided highly optimized message parameterization  
compatible with log4j 1.2.8 and later.  Keeping message formatting  
distinct from the logger class allows supporting different formatters.


The supposed performance benefit of the SLF4J formatter over the  
java.text.MessageFormat only occurs when you compare the performance  
against naive use of java.text.MessageFormat.  LogMF handles the  
simplest pattern specifications (those just involving {0}, {1}, etc)  
internally and only delegates to java.text.MessageFormat for more  
complex pattern specifications, resulting in equivalent performance to  
the SLF4J formatter on functionally equivalent format specifiers while  
still supporting the full java.text.MessageFormat capabilities.


This very early thread on slf4j-dev (http://marc.info/?l=slf4j-dev&m=112327572703543&w=2 
) discussed the potential use of java.text.MessageFormat pattern  
specifiers long before SLF4J was frozen.



-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



Re: [PROPOSAL] Implementing the SLF4J API directly

2008-12-09 Thread Thorbjørn Ravn Andersen

Paul Smith skrev  den 09-12-2008 02:46:


private static String getFormattedMessage(String message, 
Object... args) {

String formattedMessage = message;
if (args != null && args.length > 0) {
formattedMessage = String.format(message, args);
}
return formattedMessage;
}
..


Then the code is changed to:

LogUtils.debug(LOG, "Hello %s, your age is %d", name, age);


Now, that bypasses slf4j completely, and maintains source & 
binary compatibly, and can easily be migrated to.
There was a request recently to make the argument replacement mechanism 
more powerful in either slf4j or logback (cannot remember) where Ceki 
mentioned that one of the major benefits of the {}-approach was that it 
was measurably faster than the StringFormatter in Java.


For this particular purpose I suggest that the fastest approach is 
chosen as it will apply to all events actually processed.   Would 
lifting the slf4j code into log4j be an option - I believe that the 
license allows it.


--
 Thorbjørn Ravn Andersen  "...plus... Tubular Bells!"


-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



Re: [PROPOSAL] Implementing the SLF4J API directly

2008-12-09 Thread Ceki Gulcu



Paul Smith wrote:


If logger implements org.slf4j.Logger, then one can write

String name = "Scott";
logger.debug("Hello Scott");
logger.debug("Hello {}", name);

Both log statements will print as "Hello Scott". However, the latter
log statement will contain 'name' as a parameter. The SLF4J
implementation can choose to preserve or to discard this parameter in
the LoggingEvent.

SLF4J allows for 0,1,2 or an array of parameters. Thus, you can write

 Map aMap = ...;
 List aList = ...;
 logger.debug("Hello", new Object[]{new Integer(37), aMap, aList});



First off, I've come back from some leave, and prior to that was 
extremely overloaded at work, so my attention to detail on this thread 
is limited.  

Am I correct in distilling that the crux of the _driver_ to do this is 
to support the above, and only that feature? This is 'nice' but really 
not that high a priority I would have thought..  Given the vast majority 
of people are on Java5+ platforms, a source and binary compatible way is 
to introduce a simple 'log4j-java5plus' extension jar that has something 
like this:


Support for parameterized logging is helpful. However, the main impetus is to 
converge on a logging API for benefit of the java community. The benefit for 
log4j may not be obvious at first, but the fact that it natively implements 
SLF4J will enhance log4j's stature as well. This may be doubtful coming from me, 
the author of SLF4J, but also log4j. Nevertheless, if you stop and think for a 
second, it makes sense. My proposal is not only about log4j but about logging in 
java. As log4j committer, here is your chance to shape the future of java 
logging in a constructive way.


Of course, there is the temptation to believe that log4j is such a grand name 
that it does need to adapt to changing circumstances. Don't succumb to that.




public class LogUtils {
..
public static void debug(Logger log, String message, Object... args) {
if (!log.isDebugEnabled()) {
return;
}
log.debug(getFormattedMessage(message, args));
}
..
private static String getFormattedMessage(String message, Object... 
args) {

String formattedMessage = message;
if (args != null && args.length > 0) {
formattedMessage = String.format(message, args);
}
return formattedMessage;
}
..


Then the code is changed to:

LogUtils.debug(LOG, "Hello %s, your age is %d", name, age);


SLF4J's message formatting mechanism is extremely simple and very fast. It is 
also very convenient, considering the most common cases. Your suggestion, offers 
more flexibility and power, but which is not needed under most circumstances.


Now, that bypasses slf4j completely, and maintains source & 
binary compatibly, and can easily be migrated to.  My point is not to 
suggest log4j introduce the above, or to dissuade from considering slf4j 
integration more generally, but if the above feature is it... it really 
doesn't seem like a massive driver that breaks binary compatibility and 
possibly alienate a whole bunch of people (which it could, and that 
could badly tarnish the log4j 'brand' as it were).


Quoting LOG4J2-27:

There is actually a way to maintain 100% source code compatibility. The 
org.apache.log4j.Logger/Category classes would retain their existing method 
signatures but would delegate to org.apache.log4j.impl.Logger class which would 
implement the org.slf4j.Logger interface. This is feasible as demonstrated by 
the log4j-over-slf4j module in SLF4J. See


  http://slf4j.org/legacy.html#log4j-over-slf4j

Clients wishing to use the existing log4j classes could continue to do so. Those 
wishing to standardize on the SLF4J API could do so as well.  Direct use of 
org.apache.log4j.impl.Logger would technically be possible but discouraged.



So I'm not in favour of rushing any decision at all.


The SLF4J debate has been ongoing for several years. Now that it has established 
itself as a credible API,  it is time to reconsider the question under new light.



Paul


--
Ceki Gülcü

-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]