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.
_______________________________________________
dev mailing list
[email protected]
http://slf4j.org/mailman/listinfo/dev