下面自定义一个EMAIL级别
经过查看源码找到了一个简单的新增自定义level的方式
org.apache.log4j.helpers.OptionConverter#toLevel
Level toLevel(String value, Level defaultValue) {
if(value == null)
return defaultValue;
value = value.trim();
int hashIndex = value.indexOf('#');
if (hashIndex == -1) {
if("NULL".equalsIgnoreCase(value)) {
return null;
} else {
// no class name specified : use standard Level class
return(Level) Level.toLevel(value, defaultValue);
}
}
Level result = defaultValue;
String clazz = value.substring(hashIndex+1);
String levelName = value.substring(0, hashIndex);
// This is degenerate case but you never know.
if("NULL".equalsIgnoreCase(levelName)) {
return null;
}
LogLog.debug("toLevel" + ":class=[" + clazz + "]"
+ ":pri=[" + levelName + "]");
try {
Class customLevel = Loader.loadClass(clazz);
// get a ref to the specified class' static method
// toLevel(String, org.apache.log4j.Level)
Class[] paramTypes = new Class[] { String.class,
org.apache.log4j.Level.class
};
java.lang.reflect.Method toLevelMethod =
customLevel.getMethod("toLevel", paramTypes);
// now call the toLevel method, passing level string + default
Object[] params = new Object[] {levelName, defaultValue};
Object o = toLevelMethod.invoke(null, params);
result = (Level) o;
} catch(ClassNotFoundException e) {
LogLog.warn("custom level class [" + clazz + "] not found.");
} catch(NoSuchMethodException e) {
LogLog.warn("custom level class [" + clazz + "]"
+ " does not have a class function toLevel(String, Level)", e);
} catch(java.lang.reflect.InvocationTargetException e) {
if (e.getTargetException() instanceof InterruptedException
|| e.getTargetException() instanceof InterruptedIOException) {
Thread.currentThread().interrupt();
}
LogLog.warn("custom level class [" + clazz + "]"
+ " could not be instantiated", e);
} catch(ClassCastException e) {
LogLog.warn("class [" + clazz
+ "] is not a subclass of org.apache.log4j.Level", e);
} catch(IllegalAccessException e) {
LogLog.warn("class ["+clazz+
"] cannot be instantiated due to access restrictions", e);
} catch(RuntimeException e) {
LogLog.warn("class ["+clazz+"], level ["+levelName+
"] conversion failed.", e);
}
return result;
}
从源码可以看出自定义level是通过#来分割level名称和class
-----------------
然后自定义了一个 EmailLogger
public class EmailLogger extends Logger {
private static final String FQCN = EmailLogger.class.getName();
private static Logger log = Logger.getLogger(EmailLogger.class);
protected EmailLogger(String name) {
super(name);
}
public static void email(Object message){
log.log(FQCN, EZheLogLevel.EMAIL, message, null);
}
public void email(Object message, Throwable t){
log.log(FQCN, EZheLogLevel.EMAIL, message, t);
}
}
log4j.xml
<appender name="EMAIL_APPENDER" class="com.gozap.logging.log4j.EmailAppender">
<param name="Threshold" value="EMAIL#com.xxx.logging.log4j.EmailLogLevel" />
<triggeringPolicy class="com.gozap.logging.log4j.EmailEventTriggering">
<param name="level" value="EMAIL#com.xxx.logging.log4j.EmailLogLevel" />
</triggeringPolicy>
</appender>
public final static int EMAIL_INT = 45000;
public static Level EMAIL = new Level(EMAIL_INT, "EMAIL", 2);