[slf4j-dev] Re: Beta 4 and the new method signatures

Greg Wilkins gregw at mortbay.com
Tue Jul 12 16:06:11 CEST 2005


Ceki wrote:
> To be more specific, say the thin API is:
>
> public interface Log {
>  public boolean isEnabled();
>  public void log(Object);
> }
>
> For developers logs, one can case String instances to Object. For
> request logs, you'd need to cast a HttpRequest, HttpResponse pair into
> object, which cannot be done unless the server developer creates an
> object array of size two:
>
>  logger.log(new Array[] {request, request});
>
> Admittedly, this is feasible. However, as far as the logging system is
> concerned, if it is generic, it now has to deal with two objects of
> fundamentally different nature. Do you see why it's a road to avoid?

Ceki,

I'm in total agreement that passing Objects into the
fundamental log is not the way to go.   That way lies a
nightmare of versioning, classloaders and configuration.

But if you did, one could do

   logger.log(new NCSAFormat(request,response));

and the toString method of that class can deal with the
formatting.

However, I would still be happy with a thin API of

  public interface Log {
    public boolean isEnabled();
    public void log(String s);
  }

and then I can do

  if (logger.isEnabled())
    logger.log(NCSAFormat.format(request,response));

and I can throw away all my code that does aging of
request log files.....


If we want to give Throwables a special place in the API:
  public interface Log {
    public boolean isEnabled();
    public void log(String s, Throwable th);
  }
where the th can be passed as null.


I see this as a pretty fundamental interface and the contract
would simply be that any logged to this instance would be
treated exactly the same as anything else logged to the same
instance in a serial ordering.

Any log levels, markers, etc. etc. are associated with the
instance of the Log and not the call to the Log.

A minimal slf4j API that has both think and thin APIs could be

  public interface Log {
    public boolean isEnabled();
    public void log(String s, Throwable th);
  }

  public interface Logger {
    public Log getDebug();
    public Log getInfo();
    public Log getWarn();
    public Log getError();

    /* conveniance methods */

    public boolean isDebugEnabled();
    public void debug(String msg);
    public void debug(String msg, Throwable th);
    public void debug(String fmt, Object arg);

    ...

}

with a helper class for implementations:

public abstract class AbstractLogger implements Logger
{
    public boolean isDebugEnabled()
    {
       getDebug().isEnabled();
    }

    public void debug(String msg)
    {
       getDebug().log(msg,null);
    }

    public void debug(String msg, Throwable th)
    {
      getDebug().log(msg,th);
    }

    public void debug(String fmt, Object arg)
    {
       if(getDebug().isEnabled())
          getDebug().log(LogUtil.format(fmt,arg),null);
    }

I would also argue to include trace - simply to make porting
from commons-logging trivial.

cheers















--
Greg Wilkins <gregw at mortbay.com>


----------------------------------------------------------------
This message was sent using IMP, the Internet Messaging Program.




More information about the slf4j-dev mailing list