Log4j擴充套件使用--自定義輸出
阿新 • • 發佈:2019-01-09
package org.apache.log4j.config; import org.apache.log4j.Appender; import org.apache.log4j.Level; import org.apache.log4j.Priority; import org.apache.log4j.helpers.LogLog; import org.apache.log4j.helpers.OptionConverter; import org.apache.log4j.spi.OptionHandler; import org.apache.log4j.spi.ErrorHandler; import java.beans.BeanInfo; import java.beans.IntrospectionException; import java.beans.Introspector; import java.beans.PropertyDescriptor; import java.io.InterruptedIOException; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Enumeration; import java.util.Properties; /** * General purpose Object property setter. Clients repeatedly invokes * {@link #setProperty setProperty(name,value)} in order to invoke setters * on the Object specified in the constructor. This class relies on the * JavaBeans {@link Introspector} to analyze the given Object Class using * reflection. * * <p> * Usage: * * <pre> * PropertySetter ps = new PropertySetter(anObject); * ps.set("name", "Joe"); * ps.set("age", "32"); * ps.set("isMale", "true"); * </pre> * * will cause the invocations anObject.setName("Joe"), anObject.setAge(32), * and setMale(true) if such methods exist with those signatures. * Otherwise an {@link IntrospectionException} are thrown. * * @author Anders Kristensen * @since 1.1 */ public class PropertySetter { protected Object obj; protected PropertyDescriptor[] props; /** * Create a new PropertySetter for the specified Object. This is done * in prepartion for invoking {@link #setProperty} one or more times. * * @param obj * the object for which to set properties */ public PropertySetter(Object obj) { this.obj = obj; } /** * Uses JavaBeans {@link Introspector} to computer setters of object to be * configured. */ protected void introspect() { try { BeanInfo bi = Introspector.getBeanInfo(obj.getClass()); props = bi.getPropertyDescriptors(); } catch (IntrospectionException ex) { LogLog.error("Failed to introspect " + obj + ": " + ex.getMessage()); props = new PropertyDescriptor[0]; } } /** * Set the properties of an object passed as a parameter in one * go. The <code>properties</code> are parsed relative to a * <code>prefix</code>. * * @param obj * The object to configure. * @param properties * A java.util.Properties containing keys and values. * @param prefix * Only keys having the specified prefix will be set. */ public static void setProperties(Object obj, Properties properties, String prefix) { new PropertySetter(obj).setProperties(properties, prefix); } /** * Set the properites for the object that match the * <code>prefix</code> passed as parameter. * * */ public void setProperties(Properties properties, String prefix) { int len = prefix.length(); for (Enumeration e = properties.propertyNames(); e.hasMoreElements();) { String key = (String) e.nextElement(); // handle only properties that start with the desired frefix. if (key.startsWith(prefix)) { // ignore key if it contains dots after the prefix if (key.indexOf('.', len + 1) > 0) { // System.err.println("----------Ignoring---["+key // +"], prefix=["+prefix+"]."); continue; } String value = OptionConverter.findAndSubst(key, properties); key = key.substring(len); if (("layout".equals(key) || "errorhandler".equals(key)) && obj instanceof Appender) { continue; } // // if the property type is an OptionHandler // (for example, triggeringPolicy of org.apache.log4j.rolling.RollingFileAppender) PropertyDescriptor prop = getPropertyDescriptor(Introspector.decapitalize(key)); if (prop != null && OptionHandler.class.isAssignableFrom(prop.getPropertyType()) && prop.getWriteMethod() != null) { OptionHandler opt = (OptionHandler) OptionConverter.instantiateByKey(properties, prefix + key, prop.getPropertyType(), null); PropertySetter setter = new PropertySetter(opt); setter.setProperties(properties, prefix + key + "."); try { Method writeMethod = prop.getWriteMethod(); System.out.println("woqu=" + writeMethod); prop.getWriteMethod().invoke(this.obj, new Object[] { opt }); } catch (IllegalAccessException ex) { LogLog.warn("Failed to set property [" + key + "] to value \"" + value + "\". ", ex); } catch (InvocationTargetException ex) { if (ex.getTargetException() instanceof InterruptedException || ex.getTargetException() instanceof InterruptedIOException) { Thread.currentThread().interrupt(); } LogLog.warn("Failed to set property [" + key + "] to value \"" + value + "\". ", ex); } catch (RuntimeException ex) { LogLog.warn("Failed to set property [" + key + "] to value \"" + value + "\". ", ex); } continue; } setProperty(key, value); } } activate(); } /** * Set a property on this PropertySetter's Object. If successful, this * method will invoke a setter method on the underlying Object. The * setter is the one for the specified property name and the value is * determined partly from the setter argument type and partly from the * value specified in the call to this method. * * <p> * If the setter expects a String no conversion is necessary. * If it expects an int, then an attempt is made to convert 'value' * to an int using new Integer(value). If the setter expects a boolean, * the conversion is by new Boolean(value). * * @param name * name of the property * @param value * String value of the property */ public void setProperty(String name, String value) { if (value == null) { return; } name = Introspector.decapitalize(name); PropertyDescriptor prop = getPropertyDescriptor(name); // LogLog.debug("---------Key: "+name+", type="+prop.getPropertyType()); if (prop == null) { LogLog.warn("No such property [" + name + "] in " + obj.getClass().getName() + "."); } else { try { setProperty(prop, name, value); } catch (PropertySetterException ex) { LogLog.warn("Failed to set property [" + name + "] to value \"" + value + "\". ", ex.rootCause); } } } /** * Set the named property given a {@link PropertyDescriptor}. * * @param prop * A PropertyDescriptor describing the characteristics * of the property to set. * @param name * The named of the property to set. * @param value * The value of the property. */ public void setProperty(PropertyDescriptor prop, String name, String value) throws PropertySetterException { Method setter = prop.getWriteMethod(); if (setter == null) { throw new PropertySetterException("No setter for property [" + name + "]."); } Class[] paramTypes = setter.getParameterTypes(); if (paramTypes.length != 1) { throw new PropertySetterException("#params for setter != 1"); } Object arg; try { arg = convertArg(value, paramTypes[0]); } catch (Throwable t) { throw new PropertySetterException("Conversion to type [" + paramTypes[0] + "] failed. Reason: " + t); } if (arg == null) { throw new PropertySetterException("Conversion to type [" + paramTypes[0] + "] failed."); } LogLog.debug("Setting property [" + name + "] to [" + arg + "]."); try { setter.invoke(obj, new Object[] { arg }); } catch (IllegalAccessException ex) { throw new PropertySetterException(ex); } catch (InvocationTargetException ex) { if (ex.getTargetException() instanceof InterruptedException || ex.getTargetException() instanceof InterruptedIOException) { Thread.currentThread().interrupt(); } throw new PropertySetterException(ex); } catch (RuntimeException ex) { throw new PropertySetterException(ex); } } /** * Convert <code>val</code> a String parameter to an object of a * given type. */ protected Object convertArg(String val, Class type) { if (val == null) { return null; } String v = val.trim(); if (String.class.isAssignableFrom(type)) { return val; } else if (Integer.TYPE.isAssignableFrom(type)) { return new Integer(v); } else if (Long.TYPE.isAssignableFrom(type)) { return new Long(v); } else if (Boolean.TYPE.isAssignableFrom(type)) { if ("true".equalsIgnoreCase(v)) { return Boolean.TRUE; } else if ("false".equalsIgnoreCase(v)) { return Boolean.FALSE; } } else if (Priority.class.isAssignableFrom(type)) { return OptionConverter.toLevel(v, Level.DEBUG); } else if (ErrorHandler.class.isAssignableFrom(type)) { return OptionConverter.instantiateByClassName(v, ErrorHandler.class, null); } return null; } protected PropertyDescriptor getPropertyDescriptor(String name) { if (props == null) { introspect(); } for (int i = 0; i < props.length; i++) { if (name.equals(props[i].getName())) { return props[i]; } } return null; } public void activate() { if (obj instanceof OptionHandler) { ((OptionHandler) obj).activateOptions(); } } }