You are viewing a plain text version of this content. The canonical link for it is here.
Posted to log4j-dev@logging.apache.org by Tara Czutno <tc...@lw-lmco.com> on 2003/04/18 19:50:55 UTC

Adding a level below DEBUG

I'm trying to add a level below debug called TRACE and I need some
help.  My team wants to implement log4j now so if there are plans to add
a lower level to the next release of log4j, we can't wait.  I've read
some other postings on this matter.  One posting suggested subclassing
Level, Logger, LoggerFactory and LevelMatchFilter.  I tried that route
but can't get it to work.  I get "log4j:WARN Failed to set property
[filter] to value "rossPkg.log.TLevelMatchFilter".  It may be a
classpath problem or config file.  I don't know.  I saw another posting
that subclassed only Priority and Category (probably a pre Logger
version).

So I'm not sure what classes I need to subclass, what methods I need to
override, or what I need to put in the config file (non-xml one) to
accomplish adding a level below debug.  I want to do it the simplest
best way, of course.  I'd like the rootLogger to recognize trace, if
that's possible.  I also want the users' of my Logger with trace to be
able to have trace(Object message), and trace(Object message, Throwable
t) methods available to them.  That being said do I need to have a
method that will return my specific Logger class and not the general
one?  Like:
public static TLogger getTLogger(String name) {
        return (TLogger) Logger.getLogger(name, tFactory);
    }  Also, the FQCN variable is private in the Logger class so do I
just declare another one for my class?

I've included my classes below and config file.  I'm not sure if I'm on
the right track here.

Thanks in advance.

Tara

//////////////////////////////////////////////////////////////////////////////////////////////////////////

package rossPkg.log;

import org.apache.log4j.Category;
import org.apache.log4j.Logger;
public class TLogger extends org.apache.log4j.Logger {

    private static final String FQCN =  TLevel.class.getName();

    private static TLoggerFactory tFactory = new TLoggerFactory();
    public TLogger(String s) {
        super(s);
    }
    public static TLogger getTLogger(String name) {
        return (TLogger) Logger.getLogger(name, tFactory);
    }
    public void trace(Object message) {
        if (repository.isDisabled(TLevel.TRACE_INT))
            return;
        if (TLevel.TRACE.isGreaterOrEqual(this.getEffectiveLevel())) {
            forcedLog(FQCN, TLevel.TRACE, message, null);
        }
    }
    public void trace(Object message, Throwable t) {
        if (repository.isDisabled(TLevel.TRACE_INT))
            return;
        if (TLevel.TRACE.isGreaterOrEqual(this.getEffectiveLevel()))
            forcedLog(FQCN, TLevel.TRACE, message, t);
    }
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////

package rossPkg.log;

import org.apache.log4j.Category;
import org.apache.log4j.Logger;

public class TLogger extends org.apache.log4j.Logger {

    private static final String FQCN =  TLevel.class.getName();

    private static TLoggerFactory tFactory = new TLoggerFactory();

    public TLogger(String s) {
        super(s);
    }
    // TODO: is this correct? or should it return just Logger
    public static TLogger getTLogger(String name) {
        return (TLogger) Logger.getLogger(name, tFactory);
    }
    public void trace(Object message) {
        if (repository.isDisabled(TLevel.TRACE_INT))
            return;
        if (TLevel.TRACE.isGreaterOrEqual(this.getEffectiveLevel())) {
            forcedLog(FQCN, TLevel.TRACE, message, null);
        }
    }

    public void trace(Object message, Throwable t) {
        if (repository.isDisabled(TLevel.TRACE_INT))
            return;
        if (TLevel.TRACE.isGreaterOrEqual(this.getEffectiveLevel()))
            forcedLog(FQCN, TLevel.TRACE, message, t);
    }
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////

package rossPkg.log;

import org.apache.log4j.Logger;
import org.apache.log4j.spi.LoggerFactory;

class TLoggerFactory implements LoggerFactory {
    public TLoggerFactory() {
    }

    public Logger makeNewLoggerInstance(String name) {
        return new TLogger(name);
    }
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////

package rossPkg.log;

import org.apache.log4j.Level;
import org.apache.log4j.spi.Filter;
import org.apache.log4j.spi.LoggingEvent;
import org.apache.log4j.varia.LevelMatchFilter;


public class TLevelMatchFilter extends LevelMatchFilter {
    /**
     Do we return ACCEPT when a match occurs. Default is
     <code>true</code>.  */
    boolean acceptOnMatch = true;

    Level levelToMatch;

    public void setLevelToMatch(String level) {
        // This code is similar to the below method call
        //levelToMatch = OptionConverter.toLevel(level, null);
        if (level == null) levelToMatch = null;

        int hashIndex = level.indexOf('#');
        if (hashIndex == -1) {
            if ("NULL".equalsIgnoreCase(level)) {
                levelToMatch = null;
            } else {
                // no class name specified : use standard Level class
                levelToMatch = TLevel.toLevel(level, null);
            }
        }
    }

    public String getLevelToMatch() {
        return levelToMatch == null ? null : levelToMatch.toString();
    }

    public int decide(LoggingEvent event) {
        if (this.levelToMatch == null) {
            return Filter.NEUTRAL;
        }

        boolean matchOccured = false;
        if (this.levelToMatch.equals(event.getLevel())) {
            matchOccured = true;
        }

        if (matchOccured) {
            if (this.acceptOnMatch)
                return Filter.ACCEPT;
            else
                return Filter.DENY;
        } else {
            return Filter.NEUTRAL;
        }
    }
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////

# set root level appender
log4j.rootLogger=TRACE, appender1, f1

log4j.appender.appender1=org.apache.log4j.ConsoleAppender
log4j.appender.appender1.layout=org.apache.log4j.PatternLayout
log4j.appender.appender1.layout.ConversionPattern=%d [%t] %5p (%F:%L) %x
- %m%n
log4j.appender.appender1.filter=rossPkg.log.TLevelMatchFilter
log4j.appender.appender1.filter.levelToMatch=TRACE

log4j.appender.f1=org.apache.log4j.RollingFileAppender
log4j.appender.f1.File=config4j.log
log4j.appender.f1.layout=org.apache.log4j.PatternLayout
log4j.appender.f1.layout.ConversionPattern=%d [%t] %5p (%F:%L) %x - %m%n

log4j.appender.f1.filter=rossPkg.log.TLevelMatchFilter
log4j.appender.f1.filter.levelToMatch=TRACE


log4j.appender.f1.MaxFileSize=100KB
# Keep one backup file
log4j.appender.f1.MaxBackupIndex=1

# set root level appenders
log4j.rootLogger= DEBUG,CHAINSAW,appender1, f1
log4j.appender.CHAINSAW=org.apache.log4j.net.SocketAppender
log4j.appender.CHAINSAW.RemoteHost=localhost
log4j.appender.CHAINSAW.Port=4445
log4j.appender.CHAINSAW.LocationInfo=true





---------------------------------------------------------------------
To unsubscribe, e-mail: log4j-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: log4j-dev-help@jakarta.apache.org