I was finding it quite frustrating that PropertyConfigurator could not handle the advanced feature handled in DOMConfigurator, namely allowing the use of custom extensions of the Priority class. I am unable to use DOMConfigurator currently in my apps because I rely on some older versions of the XML libraries and am bound to those for the near future. See the attached for a cvs diff. Borrowed a lot of code/ideas for this from DOMConfigurator. I have tested this using the attached classes (test_PropertyConfigurator.java and test_Priority.java) and config file. Please let me know if there is any additional info needed. I will be happy to discuss this further as well. jeff -- Jeffrey & Nikole Bonevich Maxmillian Bonevich Ann Arbor, Michigan [EMAIL PROTECTED] http://www.bonevich.com
Index: PropertyConfigurator.java =================================================================== RCS file: /home/cvspublic/jakarta-log4j/src/java/org/apache/log4j/PropertyConfigurator.java,v retrieving revision 1.18 diff -u -r1.18 PropertyConfigurator.java --- PropertyConfigurator.java 2001/03/20 16:05:35 1.18 +++ PropertyConfigurator.java 2001/04/15 03:27:38 @@ -33,6 +33,7 @@ import java.io.IOException; import java.util.StringTokenizer; import java.util.Hashtable; +import java.lang.reflect.Method; /** Extends {@link BasicConfigurator} to provide configuration from an @@ -52,7 +53,7 @@ <p>The <code>PropertyConfigurator</code> does not handle the advanced configuration features supported by the {@link org.apache.log4j.xml.DOMConfigurator DOMConfigurator} such as support for - sub-classing of the Priority class, {@link org.apache.log4j.spi.Filter + {@link org.apache.log4j.spi.Filter Filters}, custom {@link org.apache.log4j.spi.ErrorHandler ErrorHandlers}, nested appenders such as the {@link org.apache.log4j.AsyncAppender AsyncAppender}, etc. @@ -91,11 +92,17 @@ static final String ADDITIVITY_PREFIX = "log4j.additivity."; static final String ROOT_CATEGORY_PREFIX = "log4j.rootCategory"; static final String APPENDER_PREFIX = "log4j.appender."; + static final String PRIORITY_PREFIX = "log4j.priority."; static final String RENDERER_PREFIX = "log4j.renderer."; static final String CATEGORY_FACTORY_KEY = "log4j.categoryFactory"; static final private String INTERNAL_ROOT_NAME = "root"; + static final private String EXTERNAL_ROOT_NAME = "rootCategory"; + static final private String TO_PRIORITY_METHOD = "toPriority"; + static final Class[] ONE_STRING_PARAM = new Class[] {String.class}; + static final private String EMPTY_STR = ""; + /** Read configuration from a file. The existing configuration is not cleared nor reset. If you require a different call, behaviour, @@ -133,15 +140,18 @@ <p>The syntax for configuring the root category is: <pre> - log4j.rootCategory=[FATAL|ERROR|WARN|INFO|DEBUG], appenderName, appenderName, ... + log4j.rootCategory=[FATAL|ERROR|WARN|INFO|DEBUG|other valid priority], +appenderName, appenderName, ... + log4j.priority.rootCategory=fully.qualified.name.of.Priority.subclass </pre> - <p>This syntax means that one of the strings values ERROR, WARN, - INFO or DEBUG can be supplied followed by appender names separated - by commas. + <p>This syntax means that one of the string values ERROR, WARN, + INFO, DEBUG, or some other priority value for the subclass of + Priority that you have chosen (specified by the priority + property above), can be supplied followed by appender names + separated by commas. - <p>If one of the optional priority values ERROR, WARN, INFO or - DEBUG is given, the root priority is set to the corresponding + <p>If one of the optional priority values (i.e. ERROR, WARN, INFO, + DEBUG, etc.) is given, the root priority is set to the corresponding priority. If no priority value is specified, then the root priority remains untouched. @@ -546,9 +556,35 @@ // root category. if(priorityStr.equalsIgnoreCase(BasicConfigurator.INHERITED) && !catName.equals(INTERNAL_ROOT_NAME)) - cat.setPriority(null); - else - cat.setPriority(Priority.toPriority(priorityStr)); + { + cat.setPriority(null); + } else { + // See if we have a priority subclass + String catNameFixed = catName.equals(INTERNAL_ROOT_NAME) + ? EXTERNAL_ROOT_NAME : catName; + String className = props.getProperty(PRIORITY_PREFIX + catNameFixed); + + if (className!=null && !className.equals(EMPTY_STR)) + { + try { + Class priorityClass = Class.forName(className); + // Cannot instantiate Priority directly - use toProperty method + Method toPriorityMethod = priorityClass.getMethod( + TO_PRIORITY_METHOD, ONE_STRING_PARAM + ); + Priority priorityObj = (Priority)toPriorityMethod.invoke( + null, new Object[] {priorityStr} + ); + cat.setPriority(priorityObj); + } catch(Exception e) { + LogLog.error("Could not create priority ["+priorityStr+ + "] on Priority subclass '" + className + "'. Reported error +follows.", e); + } + } else { + cat.setPriority(Priority.toPriority(priorityStr)); + } + } + LogLog.debug("Category " + catName + " set to " + cat.getPriority()); }
import org.apache.log4j.*; public class test_PropertyConfigurator { public static void main(String[] args) { PropertyConfigurator.configure("/home/jbonevic/jakarta-log4j/dist/classes/log4j_test.properties"); Category root = Category.getRoot(); Category cat1 = Category.getInstance("test1"); Category cat2 = Category.getInstance("test2"); Priority rootPri = root.getPriority(); Priority cat1Pri = cat1.getPriority(); Priority cat2Pri = cat2.getPriority(); System.out.println("root category = " + rootPri.toString() + " [" + rootPri.getClass().getName() + "]"); System.out.println("cat1 category = " + cat1Pri.toString() + " [" + cat1Pri.getClass().getName() + "]"); System.out.println("cat2 category = " + cat2Pri.toString() + " [" + cat2Pri.getClass().getName() + "]"); System.out.println(""); root.log(test_Priority.TEST2,"This message came from root at TEST2!"); root.log(test_Priority.FATAL,"This message came from root at FATAL!"); root.log(test_Priority.DEBUG,"This message came from root at DEBUG!"); root.log(test_Priority.TEST1,"This message came from root at TEST1!"); cat1.log(test_Priority.TEST2,"This message came from cat1 at TEST2!"); cat1.log(test_Priority.FATAL,"This message came from cat1 at FATAL!"); cat1.log(test_Priority.DEBUG,"This message came from cat1 at DEBUG!"); cat1.log(test_Priority.TEST1,"This message came from cat1 at TEST1!"); cat2.log(Priority.FATAL,"This message came from cat2 at FATAL!"); cat2.log(Priority.WARN,"This message came from cat2 at WARN!"); cat2.log(Priority.DEBUG,"This message came from cat2 at DEBUG!"); } }
import org.apache.log4j.Priority; public class test_Priority extends Priority { public static final int TEST1_INT = 1000; public static final int TEST2_INT = 100000; public static final test_Priority TEST1 = new test_Priority(TEST1_INT,"TEST1",10); public static final test_Priority TEST2 = new test_Priority(TEST2_INT,"TEST2",0); protected test_Priority(int lvl, String name, int sysloglvl) { super(lvl,name,sysloglvl); } public static Priority[] getAllPossiblePriorities() { return new Priority[] {test_Priority.TEST2, test_Priority.FATAL, test_Priority.ERROR, test_Priority.WARN, test_Priority.INFO, test_Priority.DEBUG, test_Priority.TEST1}; } public static Priority toPriority(int val) { return toPriority(val,test_Priority.TEST1); } public static Priority toPriority(int val, Priority defaultPriority) { switch(val) { case TEST1_INT: return TEST1; case DEBUG_INT: return DEBUG; case INFO_INT: return INFO; case WARN_INT: return WARN; case ERROR_INT: return ERROR; case FATAL_INT: return FATAL; case TEST2_INT: return TEST2; default: return defaultPriority; } } public static Priority toPriority(String val) { return toPriority(val,test_Priority.TEST1); } public static Priority toPriority(String sArg, Priority defaultPriority) { if(sArg == null) return defaultPriority; String s = sArg.toUpperCase(); if(s.equals("TEST1")) return TEST1; if(s.equals("DEBUG")) return DEBUG; if(s.equals("INFO")) return INFO; if(s.equals("WARN")) return WARN; if(s.equals("ERROR")) return ERROR; if(s.equals("FATAL")) return FATAL; if(s.equals("TEST2")) return TEST2; return defaultPriority; } }
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]