Greg, thank you for your input.

In response to the discussions here and previously identified use
cases, I've just committed the Marker, StarMarker and CompositeMarker
classes to the experimental branch [1] of SLF4J. A Marker is
basically a name. Here is a basic (simplified) implementation.

package org.slf4j;

public class Marker {

  static Map markerMap = new Hashtable();
  String name;

  private Marker(String name) {
    this.name = name;
  }

  public static final Marker getMarker(String name) {
    if (name == null) {
      throw new IllegalArgumentException("Marker name cannot be null");
    }

    Marker marker = (Marker) markerMap.get(name);
    if (marker == null) {
      marker = new Marker(name);
      markerMap.put(name, marker);
    }

    return marker;
  }

  public String getName() {
    return name;
  }

  public boolean matches(Marker marker) {
    if ((this == marker)) {
      return true;
    }

    return false;
  }

  public boolean matches(String name) {
    if (this.name.equals(name)) {
      return true;
    }
    return false;
  }
}


Markers allow log statements to be marked in user-chosen ways.

For example, for the HttpRequest class you mentioned, we can now
write:


package org.mortbay.jetty;

import org.slf4j.Marker;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

class HttpRequest {

  Logger logger = LoggerFactory.getLogger(HttpRequest.class);

  static final Marker HEADER = Marker.getMarker("header");

  void doRequest() {
    logger.debug("Request URI is {}", uri);

    logger.debug(HEADER, "Headers follow.");
    for(int i = 0; i < header.length; i++) {
logger.debug(HEADER, "{}: {}", header[i].getName(), header[i].getValue());
    }

    ... do real work
  }
}

If the org.mortbay.jetty.HttpRequest is enabled for the DEBUG level,
than all log statements in doRequest() will be printed. However, the
user can chose to instruct the logging system to those disable log
statements of level DEBUG marked with the HEADER marker.

This approach has the advantage of allowing multiple markings to
co-exist without interference. Nothing prevents the developer from
writing log statements with different markings.

As for the ignore() method, the logging system can be instructed to
ignore the stack traces for a given exception using a special
marking. For example,

 try {
   access some IOStream
 } catch(IOException e) {
   logger.debug(NO_STACK_TRACE, "Exception while talking to peer", e);
 }


One of challenges in the design is to allow for markers to contain child
markers. For example,

  Marker blue = Marker.getMarker("blue");
  Marker red  = Marker.getMarker("red");
  Marker colors = Marker.getCompositeMarker("colors");
  colors.add(blue);
  colors.add(red);

  blue.matches("blue"); // this is true
  red.matches("red"); // also true
  red.matches("blue"); // false
  colors.matches("colors"); // true
  colors.matches("red"); // also true
  colors.matches("blue"); // true


I am tempted to use the Composite pattern from the Go4 book although it
is not totally clear whether the pattern could be judiciously applied
here.

In the HttpRequest example above, some headers could be marked with an
additional marker, say IMPORTANT_HEADER. Thus, the user could chose
between printing all headers, no headers, or only important headers.


So, wdyt?

[1] http://svn.slf4j.org/viewcvs/slf4j/branches/marker-experiment/

At 12:44 AM 7/3/2005, Greg Wilkins wrote:
Ceki Gülcü wrote:

> <request>
>
>   Can anyone think of a class which makes uses of both trace() and
>   debug()? If so, could you please provide a URL?
>
> </request>

The use case I have for trace (or I prefer to call it verbose) is
the case when I have an object that I wish to log, but that I have
a choice of the amount of detail that can be logged.

Examples include:

  HttpRequest:   log just the method and URI or all the headers.
  Document:      log just the URI of the document or dump all of the XML.

I see this as quiet related to ignore, where the developer has
an exception object to log, but has to choose between clogging the
log with excess information or hiding something valuable.

With the case of ignore, the developer has a clear intent that
can be signalled in the signature - to assist a later decision on
how much detail to display.   This can be done because the
logging system has the ability to expand the Exception statck trace or
just call toString on it.

With other objects, the logging system will only call toString on
them, so if the developer wants to report an object in detail then
they must do so explicitly - it would be good if they could protect
that with an if(log.isVerboseEnabled()) or an if(log.isTraceEnabled())

But then another solution would be to have a logger that supports
customizable object formatters....

cheers

--
Ceki Gülcü

  The complete log4j manual: http://www.qos.ch/log4j/


_______________________________________________
dev mailing list
[EMAIL PROTECTED]
http://slf4j.org/mailman/listinfo/dev

Reply via email to