NLS in Logger (Re: [slf4j-dev] Logger.debug(String, Object[])?)

Curt Arnold carnold at houston.rr.com
Sat Aug 6 07:30:57 CEST 2005


On Aug 5, 2005, at 11:39 PM, Niclas Hedhman wrote:

> On Saturday 06 August 2005 05:02, Joerg Hohwiller wrote:
>
>> Anyways if you make it this way: the syntax with "{}" for me looks  
>> like
>> you are NOT using java.text.MessageFormat. Why is that? You do not  
>> need
>> to reinvent the wheel here. But maybe I am missing something.
>>
>
> When I asked about this earlier, I was informed it was due to  
> performance
> reasons.
>
> On Saturday 06 August 2005 06:07, Curt Arnold wrote:
>
>> I agree that the number of methods and code duplication is
>> undesirable.  Maybe it would be better to isolate all the formatting
>> variants into a single concrete LogFormat class and have the Logger
>> interface only supply the most basic of the log methods that the
>> actual implementation would need to provide.  Something like:
>>
>> //  direct use of org.slf4j.Logger
>> logger.debug("Hello, world");
>>
>> or
>>
>> LogFormat.debug(logger, "Hello, {}.", location);
>>
>> which could be implemented:
>>
>> public static void debug(Logger logger, String format, Object  
>> param1) {
>>      if (logger.isDebugEnabled()) {
>>           logger.debug(MessageFormat.format(format, param1));
>>      }
>> }
>>
>
> Another neutral observation is that the "format" is only part of  
> the total
> format, as additional format information is associated with the  
> "destination"
> (Log4J lingo --> Appender).

Obviously open to other names.  MessageFormat was used to describe a  
formatter to generate strings for messages, LogFormat was just  
adapting that pattern for a formatter to generate strings for log  
requests.  I wasn't trying to encompass what would be called the  
layout in log4j.

>
> The utility method you are suggesting, is in fact a kind of facade,  
> and we are
> in the "Simple Logging Facade for Java" project. The name seems to  
> suggest a
> single facade, but I am somewhat inclined to believe that a multi-tier
> approach (I think originally suggested by Greg) is probably better.

I would not consider it a facade, I was suggesting a concrete  
implementation.  How MessageFormat would do its work is independent  
of the back-end logging system.


>
> That means that several interfaces are available, for different  
> needs and the
> challenge is about a Factory that can create what I need. I think  
> that a
> *culture* of several but simpler interfaces will foster more  
> invention,
> adaption and 'cheaper' evolution.
>
> public interface PrimordialLogger
> {
>     boolean isEnabled();
>     void log( Object[] data );
>     // effectively the only interface needed, seen from a pure
>     //computing point of view.
> }
>
>
> public interface TraditionalLogger
> {
>     // Full set according to Ceki's evolutionary path.
>     // Markers, many method signatures, i.e a heavy interface.
> }

I'm not comfortable with the "marker" concept, but I have not  
followed the discussion very closely.


>
> public interface SimpleIoCLogger
> {
>     String getName();
>     String getChildLogger( String childname );
>
>     boolean isDebugEnabled();
>     void debug( String message );
>
>     boolean isInfoEnabled();
>     void info( String message );
>
>     boolean isWarningEnabled();
>     void warn( String message );
>     void warn( String message, Throwable e );
>
>     boolean isErrorEnabled();
>     void error( String message );
>     void error( String message, Throwable e );
> }
>


The logger name and relationship methods should be on a different  
interface than the log request methods.  It is clearly possible to  
have a log framework that has the concepts of levels but doesn't  
offer a hierarchy or provide methods to interrogate the relationships  
between loggers.  Since it would be unusual for a single fragment of  
code to want to make log requests AND interrogate the relationship of  
the loggers, splitting these into two different interfaces should not  
complicate the client code.


The balance is finding an interface that is restricted enough that it  
can be implemented on top of a wide variety of underlying  
implementations while offering the essential functionality.  Likely a  
logger with 4 levels is probably the minimum level of service you'd  
offer with the note that some implementations will ignore the level.






> The ILoggerFactory need to be instructed what type to return, so  
> either the
> above interfaces need a supertype, or the factory returns a Object  
> (IMHO,
> same thing, since cast is unavoidable).
>
> public interface ILoggerFactory
> {
>     Object getLogger( String name, Class type );
>
>     // Convenience method;
>     // return (TraditionalLogger) getLogger( name,  
> TraditionalLogger.class );
>     TraditionalLogger getLogger( String name );
> }
>
The choice of logging implementation would dictate the interfaces  
supported by the logger object.   The type doesn't provide any  
information that is useful.   If I have put slf4j-jdk14.jar on my  
path, then its facade over java.util.logging.Logger is going to  
implement all the possible interfaces that could be supported over  
JDK 1.4.  I can query if the returned logger supports some particular  
interface by using "instanceof", but I'm going to get whatever could  
be supported by the underlying implementation.



More information about the slf4j-dev mailing list