You are viewing a plain text version of this content. The canonical link for it is here.
Posted to log4j-user@logging.apache.org by "Reeves, Russ" <Ru...@usa.xerox.com> on 2002/10/29 17:11:04 UTC

Custom Levels with Custom Filters

I'm trying to get an extended LevelMatchFilter class and and extended Levels
class working so I can send particular log messages to particular
FileAppenders. I've read the examples that come with log4j and I bought the
manual which have sections on "Writing your own Levels" and "Writing your
own Logger class" both of which are blank. 

I'm using version 1.2.6 

I've extended the Logger class so I can have methods like
log.removed(String). Here's the class:
package com.xerox.world.privacy;

import org.apache.log4j.*;

class CPLogger extends Logger {
    static String FQCN = EmailToXML.class.getName() + ".";

    private static CPLoggerFactory cpFactory = new CPLoggerFactory();

    public CPLogger(String name) {
        super(name);
    }

    public void debug(Object message) {
        super.log(FQCN, Level.DEBUG, message + " from CPLogger.debug.",
null);
    }

    public static Category getInstance(String name) {
        return Logger.getLogger(name, cpFactory);
    }

    public static Logger getLogger(String name) {
        return Logger.getLogger(name, cpFactory);
    }

    public void ignore(Object message) {
        super.log(FQCN, CPLevel.IGNORE, message, null);
    }

    public void removed(Object message) {
        System.out.println("CPLogger.removed called");
        super.log(FQCN, CPLevel.REMOVED, message, null);
    }

    public void notRemoved(Object message) {
        super.log(FQCN, CPLevel.NOTREMOVED, message, null);
    }

    public void undeliverable(Object message) {
        super.log(FQCN, CPLevel.UNDELIVERABLE, message, null);
    }

    public void unprocessed(Object message) {
        System.out.println("CPLogger.unprocessed
called:FQCN,CPLevel.UNPROCESSED:" + FQCN + " " + CPLevel.UNPROCESSED);
        super.log(FQCN, CPLevel.UNPROCESSED, message, null);
    }

}
And of course you need to extend the factory:
package com.xerox.world.privacy;

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

class CPLoggerFactory implements LoggerFactory {
    public CPLoggerFactory() {
    }

    public Logger makeNewLoggerInstance(String name) {
        return new CPLogger(name);
    }
}
Here's the extended Level class:
package com.xerox.world.privacy;

import org.apache.log4j.*;

class CPLevel extends Level {
    public final static int IGNORE_INT        = Level.DEBUG_INT -1;
    public final static int REMOVED_INT       = Level.DEBUG_INT -2;
    public final static int NOTREMOVED_INT    = Level.DEBUG_INT -3;
    public final static int UNDELIVERABLE_INT = Level.DEBUG_INT -4;
    public final static int UNPROCESSED_INT   = Level.DEBUG_INT -5;

    public final static String IGNORE_STR        = "IGNORE";
    public final static String REMOVED_STR       = "REMOVED";
    public final static String NOTREMOVED_STR    = "NOTREMOVED";
    public final static String UNDELIVERABLE_STR = "UNDELIVERABLE";
    public final static String UNPROCESSED_STR   = "UNPROCESSED";

    public final static CPLevel IGNORE = new CPLevel(IGNORE_INT, IGNORE_STR,
0);
    public final static CPLevel REMOVED = new CPLevel(REMOVED_INT,
REMOVED_STR, 1);
    public final static CPLevel NOTREMOVED = new CPLevel(NOTREMOVED_INT,
NOTREMOVED_STR, 2);
    public final static CPLevel UNDELIVERABLE = new
CPLevel(UNDELIVERABLE_INT, UNDELIVERABLE_STR, 3);
    public final static CPLevel UNPROCESSED = new CPLevel(UNPROCESSED_INT,
UNPROCESSED_STR, 4);

    CPLevel(int level, String levelStr, int syslogEquivalent) {
        super(level, levelStr, syslogEquivalent);
 
System.out.println("CPLevel:CPLevel:level,levelStr,syslogEquivalent:\n" +
level + " " + levelStr + " " + syslogEquivalent);
    }

    public static Level toLevel(String sArg) {
        System.out.println("CPLevel:toLevel(String):sArg:" + sArg);
        return (Level) toLevel(sArg, CPLevel.UNPROCESSED);
    }

    public static Level toLevel(String sArg, Level defaultValue) {
        System.out.println("CPLevel:toLevel:sArg,defaultValue:" + sArg + " "
+ defaultValue);
        if (sArg == null) {
            return defaultValue;
        }
        String stringVal = sArg.toUpperCase();
        if (stringVal.equals(IGNORE_STR)) {
            return CPLevel.IGNORE;
        } else if (stringVal.equals(REMOVED_STR)) {
            return CPLevel.REMOVED;
        } else if (stringVal.equals(NOTREMOVED_STR)) {
            return CPLevel.NOTREMOVED;
        } else if (stringVal.equals(UNDELIVERABLE_STR)) {
            return CPLevel.UNDELIVERABLE;
        } else if (stringVal.equals(UNPROCESSED_STR)) {
            return CPLevel.UNPROCESSED;
        }
        return Level.toLevel(sArg, (Level) defaultValue);
    }

    public static Level toLevel(int i) throws IllegalArgumentException {
        System.out.println("CPLevel:toLevel(int):i:" + i);
        switch(i) {
            case IGNORE_INT: return CPLevel.IGNORE;
            case REMOVED_INT: return CPLevel.REMOVED;
            case NOTREMOVED_INT: return CPLevel.NOTREMOVED;
            case UNDELIVERABLE_INT: return CPLevel.UNDELIVERABLE;
            case UNPROCESSED_INT: return CPLevel.UNPROCESSED;
        }
        return Level.toLevel(i);
    }
}
I had to extend the LevelMatchFilter as well:
package com.xerox.world.privacy;

import org.apache.log4j.varia.*;
import org.apache.log4j.helpers.*;
import org.apache.log4j.*;

public class CPLevelMatchFilter extends LevelMatchFilter {

    Level levelToMatch;

    public void setLevelToMatch(String level) {
        //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 = CPLevel.toLevel(level, null);
            }
        }
    }
    
    public String getLevelToMatch() {
        return levelToMatch == null ? null : levelToMatch.toString();
    }
  
}
And here's the xml config file:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">

<log4j:configuration debug="true"
xmlns:log4j="http://jakarta.apache.org/log4j/">

        
  <appender name="A1" class="org.apache.log4j.FileAppender">
     <param name="file" value="EmailToXMLErrors.log"/> 
     <param name="Append" value="true"/> 
     <param name="Threshold" value="DEBUG"/> 
     <layout class="org.apache.log4j.SimpleLayout">
     </layout>
  </appender>

  <appender name="removed" class="org.apache.log4j.FileAppender">
     <param name="file" value="removed.log"/> 
     <param name="Append" value="true"/> 
     <param name="Threshold" value="ALL"/> 
     <layout class="org.apache.log4j.SimpleLayout"></layout>
     <filter class="com.xerox.world.privacy.CPLevelMatchFilter">
       <param name="LevelToMatch" value="REMOVED"/>
       <param name="AcceptOnMatch" value="true"/>
     </filter>
     <filter class="org.apache.log4j.varia.DenyAllFilter"/>
  </appender>

  <appender name="notRemoved" class="org.apache.log4j.FileAppender">
     <param name="file" value="notRemoved.log"/> 
     <param name="Append" value="true"/> 
     <param name="Threshold" value="ALL"/> 
     <layout class="org.apache.log4j.SimpleLayout"></layout>
     <filter class="com.xerox.world.privacy.CPLevelMatchFilter">
       <param name="LevelToMatch" value="NOTREMOVED"/>
       <param name="AcceptOnMatch" value="true"/>
     </filter>
     <filter class="org.apache.log4j.varia.DenyAllFilter"/>
  </appender>

  <appender name="ignore" class="org.apache.log4j.FileAppender">
     <param name="file" value="ignore.log"/> 
     <param name="Append" value="true"/> 
     <param name="Threshold" value="ALL"/> 
     <layout class="org.apache.log4j.SimpleLayout"></layout>
     <filter class="com.xerox.world.privacy.CPLevelMatchFilter">
       <param name="LevelToMatch" value="IGNORE"/>
       <param name="AcceptOnMatch" value="true"/>
     </filter>
     <filter class="org.apache.log4j.varia.DenyAllFilter"/>
  </appender>

  <appender name="unprocessed" class="org.apache.log4j.FileAppender">
     <param name="file" value="unprocessed.log"/> 
     <param name="Append" value="true"/> 
     <param name="Threshold" value="ALL"/> 
     <layout class="org.apache.log4j.SimpleLayout"></layout>
     <filter class="com.xerox.world.privacy.CPLevelMatchFilter">
       <param name="LevelToMatch" value="UNPROCESSED"/>
       <param name="AcceptOnMatch" value="true"/>
     </filter>
     <filter class="org.apache.log4j.varia.DenyAllFilter"/>
  </appender>

  <appender name="undeliverable" class="org.apache.log4j.FileAppender">
     <param name="file" value="undeliverable.log"/> 
     <param name="Append" value="true"/> 
     <param name="Threshold" value="ALL"/> 
     <layout class="org.apache.log4j.SimpleLayout"></layout>
     <filter class="com.xerox.world.privacy.CPLevelMatchFilter">
       <param name="LevelToMatch" value="UNDELIVERABLE"/>
       <param name="AcceptOnMatch" value="true"/>
     </filter>
     <filter class="org.apache.log4j.varia.DenyAllFilter"/>
  </appender>

  <logger name="com.xerox.world.privacy.EmailToXML">
    <appender-ref ref="removed"/>
    <appender-ref ref="notRemoved"/>
    <appender-ref ref="ignore"/>
    <appender-ref ref="unprocessed"/>
    <appender-ref ref="undeliverable"/>
  </logger>

  <root>
    <level value ="all" />
    <!--<appender-ref ref="unprocessed"/>-->
  </root>

</log4j:configuration>


In the class that uses all this I can verify that the filter is getting
setup correctly but the calls like log.unprocessed(String) are not getting
logged.

Has anyone been successful with this?
Any ideas how to set me straight?
Is the manual going to be updated any time soon?


Many thanks,
Russ



--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: Custom Levels with Custom Filters

Posted by Ceki Gülcü <ce...@qos.ch>.
The updated version of the complete manual will cover extending Level class 
and wrapping the Logger class among other things. It will come out fairly 
soon, i.e. within the next 10 days or so.

Your code looks OK to me. What is not working exactly? Can you show your 
test code?

At 11:11 29.10.2002 -0500, you wrote:
>I'm trying to get an extended LevelMatchFilter class and and extended Levels
>class working so I can send particular log messages to particular
>FileAppenders. I've read the examples that come with log4j and I bought the
>manual which have sections on "Writing your own Levels" and "Writing your
>own Logger class" both of which are blank.
>
>I'm using version 1.2.6
>
>I've extended the Logger class so I can have methods like
>log.removed(String). Here's the class:
>package com.xerox.world.privacy;
>
>import org.apache.log4j.*;
>
>class CPLogger extends Logger {
>     static String FQCN = EmailToXML.class.getName() + ".";
>
>     private static CPLoggerFactory cpFactory = new CPLoggerFactory();
>
>     public CPLogger(String name) {
>         super(name);
>     }
>
>     public void debug(Object message) {
>         super.log(FQCN, Level.DEBUG, message + " from CPLogger.debug.",
>null);
>     }
>
>     public static Category getInstance(String name) {
>         return Logger.getLogger(name, cpFactory);
>     }
>
>     public static Logger getLogger(String name) {
>         return Logger.getLogger(name, cpFactory);
>     }
>
>     public void ignore(Object message) {
>         super.log(FQCN, CPLevel.IGNORE, message, null);
>     }
>
>     public void removed(Object message) {
>         System.out.println("CPLogger.removed called");
>         super.log(FQCN, CPLevel.REMOVED, message, null);
>     }
>
>     public void notRemoved(Object message) {
>         super.log(FQCN, CPLevel.NOTREMOVED, message, null);
>     }
>
>     public void undeliverable(Object message) {
>         super.log(FQCN, CPLevel.UNDELIVERABLE, message, null);
>     }
>
>     public void unprocessed(Object message) {
>         System.out.println("CPLogger.unprocessed
>called:FQCN,CPLevel.UNPROCESSED:" + FQCN + " " + CPLevel.UNPROCESSED);
>         super.log(FQCN, CPLevel.UNPROCESSED, message, null);
>     }
>
>}
>And of course you need to extend the factory:
>package com.xerox.world.privacy;
>
>import org.apache.log4j.Logger;
>import org.apache.log4j.spi.LoggerFactory;
>
>class CPLoggerFactory implements LoggerFactory {
>     public CPLoggerFactory() {
>     }
>
>     public Logger makeNewLoggerInstance(String name) {
>         return new CPLogger(name);
>     }
>}
>Here's the extended Level class:
>package com.xerox.world.privacy;
>
>import org.apache.log4j.*;
>
>class CPLevel extends Level {
>     public final static int IGNORE_INT        = Level.DEBUG_INT -1;
>     public final static int REMOVED_INT       = Level.DEBUG_INT -2;
>     public final static int NOTREMOVED_INT    = Level.DEBUG_INT -3;
>     public final static int UNDELIVERABLE_INT = Level.DEBUG_INT -4;
>     public final static int UNPROCESSED_INT   = Level.DEBUG_INT -5;
>
>     public final static String IGNORE_STR        = "IGNORE";
>     public final static String REMOVED_STR       = "REMOVED";
>     public final static String NOTREMOVED_STR    = "NOTREMOVED";
>     public final static String UNDELIVERABLE_STR = "UNDELIVERABLE";
>     public final static String UNPROCESSED_STR   = "UNPROCESSED";
>
>     public final static CPLevel IGNORE = new CPLevel(IGNORE_INT, IGNORE_STR,
>0);
>     public final static CPLevel REMOVED = new CPLevel(REMOVED_INT,
>REMOVED_STR, 1);
>     public final static CPLevel NOTREMOVED = new CPLevel(NOTREMOVED_INT,
>NOTREMOVED_STR, 2);
>     public final static CPLevel UNDELIVERABLE = new
>CPLevel(UNDELIVERABLE_INT, UNDELIVERABLE_STR, 3);
>     public final static CPLevel UNPROCESSED = new CPLevel(UNPROCESSED_INT,
>UNPROCESSED_STR, 4);
>
>     CPLevel(int level, String levelStr, int syslogEquivalent) {
>         super(level, levelStr, syslogEquivalent);
>
>System.out.println("CPLevel:CPLevel:level,levelStr,syslogEquivalent:\n" +
>level + " " + levelStr + " " + syslogEquivalent);
>     }
>
>     public static Level toLevel(String sArg) {
>         System.out.println("CPLevel:toLevel(String):sArg:" + sArg);
>         return (Level) toLevel(sArg, CPLevel.UNPROCESSED);
>     }
>
>     public static Level toLevel(String sArg, Level defaultValue) {
>         System.out.println("CPLevel:toLevel:sArg,defaultValue:" + sArg + " "
>+ defaultValue);
>         if (sArg == null) {
>             return defaultValue;
>         }
>         String stringVal = sArg.toUpperCase();
>         if (stringVal.equals(IGNORE_STR)) {
>             return CPLevel.IGNORE;
>         } else if (stringVal.equals(REMOVED_STR)) {
>             return CPLevel.REMOVED;
>         } else if (stringVal.equals(NOTREMOVED_STR)) {
>             return CPLevel.NOTREMOVED;
>         } else if (stringVal.equals(UNDELIVERABLE_STR)) {
>             return CPLevel.UNDELIVERABLE;
>         } else if (stringVal.equals(UNPROCESSED_STR)) {
>             return CPLevel.UNPROCESSED;
>         }
>         return Level.toLevel(sArg, (Level) defaultValue);
>     }
>
>     public static Level toLevel(int i) throws IllegalArgumentException {
>         System.out.println("CPLevel:toLevel(int):i:" + i);
>         switch(i) {
>             case IGNORE_INT: return CPLevel.IGNORE;
>             case REMOVED_INT: return CPLevel.REMOVED;
>             case NOTREMOVED_INT: return CPLevel.NOTREMOVED;
>             case UNDELIVERABLE_INT: return CPLevel.UNDELIVERABLE;
>             case UNPROCESSED_INT: return CPLevel.UNPROCESSED;
>         }
>         return Level.toLevel(i);
>     }
>}
>I had to extend the LevelMatchFilter as well:
>package com.xerox.world.privacy;
>
>import org.apache.log4j.varia.*;
>import org.apache.log4j.helpers.*;
>import org.apache.log4j.*;
>
>public class CPLevelMatchFilter extends LevelMatchFilter {
>
>     Level levelToMatch;
>
>     public void setLevelToMatch(String level) {
>         //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 = CPLevel.toLevel(level, null);
>             }
>         }
>     }
>
>     public String getLevelToMatch() {
>         return levelToMatch == null ? null : levelToMatch.toString();
>     }
>
>}
>And here's the xml config file:
><?xml version="1.0" encoding="UTF-8" ?>
><!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
>
><log4j:configuration debug="true"
>xmlns:log4j="http://jakarta.apache.org/log4j/">
>
>
>   <appender name="A1" class="org.apache.log4j.FileAppender">
>      <param name="file" value="EmailToXMLErrors.log"/>
>      <param name="Append" value="true"/>
>      <param name="Threshold" value="DEBUG"/>
>      <layout class="org.apache.log4j.SimpleLayout">
>      </layout>
>   </appender>
>
>   <appender name="removed" class="org.apache.log4j.FileAppender">
>      <param name="file" value="removed.log"/>
>      <param name="Append" value="true"/>
>      <param name="Threshold" value="ALL"/>
>      <layout class="org.apache.log4j.SimpleLayout"></layout>
>      <filter class="com.xerox.world.privacy.CPLevelMatchFilter">
>        <param name="LevelToMatch" value="REMOVED"/>
>        <param name="AcceptOnMatch" value="true"/>
>      </filter>
>      <filter class="org.apache.log4j.varia.DenyAllFilter"/>
>   </appender>
>
>   <appender name="notRemoved" class="org.apache.log4j.FileAppender">
>      <param name="file" value="notRemoved.log"/>
>      <param name="Append" value="true"/>
>      <param name="Threshold" value="ALL"/>
>      <layout class="org.apache.log4j.SimpleLayout"></layout>
>      <filter class="com.xerox.world.privacy.CPLevelMatchFilter">
>        <param name="LevelToMatch" value="NOTREMOVED"/>
>        <param name="AcceptOnMatch" value="true"/>
>      </filter>
>      <filter class="org.apache.log4j.varia.DenyAllFilter"/>
>   </appender>
>
>   <appender name="ignore" class="org.apache.log4j.FileAppender">
>      <param name="file" value="ignore.log"/>
>      <param name="Append" value="true"/>
>      <param name="Threshold" value="ALL"/>
>      <layout class="org.apache.log4j.SimpleLayout"></layout>
>      <filter class="com.xerox.world.privacy.CPLevelMatchFilter">
>        <param name="LevelToMatch" value="IGNORE"/>
>        <param name="AcceptOnMatch" value="true"/>
>      </filter>
>      <filter class="org.apache.log4j.varia.DenyAllFilter"/>
>   </appender>
>
>   <appender name="unprocessed" class="org.apache.log4j.FileAppender">
>      <param name="file" value="unprocessed.log"/>
>      <param name="Append" value="true"/>
>      <param name="Threshold" value="ALL"/>
>      <layout class="org.apache.log4j.SimpleLayout"></layout>
>      <filter class="com.xerox.world.privacy.CPLevelMatchFilter">
>        <param name="LevelToMatch" value="UNPROCESSED"/>
>        <param name="AcceptOnMatch" value="true"/>
>      </filter>
>      <filter class="org.apache.log4j.varia.DenyAllFilter"/>
>   </appender>
>
>   <appender name="undeliverable" class="org.apache.log4j.FileAppender">
>      <param name="file" value="undeliverable.log"/>
>      <param name="Append" value="true"/>
>      <param name="Threshold" value="ALL"/>
>      <layout class="org.apache.log4j.SimpleLayout"></layout>
>      <filter class="com.xerox.world.privacy.CPLevelMatchFilter">
>        <param name="LevelToMatch" value="UNDELIVERABLE"/>
>        <param name="AcceptOnMatch" value="true"/>
>      </filter>
>      <filter class="org.apache.log4j.varia.DenyAllFilter"/>
>   </appender>
>
>   <logger name="com.xerox.world.privacy.EmailToXML">
>     <appender-ref ref="removed"/>
>     <appender-ref ref="notRemoved"/>
>     <appender-ref ref="ignore"/>
>     <appender-ref ref="unprocessed"/>
>     <appender-ref ref="undeliverable"/>
>   </logger>
>
>   <root>
>     <level value ="all" />
>     <!--<appender-ref ref="unprocessed"/>-->
>   </root>
>
></log4j:configuration>
>
>
>In the class that uses all this I can verify that the filter is getting
>setup correctly but the calls like log.unprocessed(String) are not getting
>logged.
>
>Has anyone been successful with this?
>Any ideas how to set me straight?
>Is the manual going to be updated any time soon?
>
>
>Many thanks,
>Russ

--
Ceki

TCP implementations will follow a general principle of robustness: be
conservative in what you do, be liberal in what you accept from
others. -- Jon Postel, RFC 793



--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>