📄 propertyconfigurator.java
字号:
See {@link #doConfigure(String, LoggerRepository)} for the expected format. */ static public void configure(Properties properties) { new PropertyConfigurator().doConfigure(properties, LogManager.getLoggerRepository()); } /** Like {@link #configureAndWatch(String, long)} except that the default delay as defined by {@link FileWatchdog#DEFAULT_DELAY} is used. @param configFilename A file in key=value format. */ static public void configureAndWatch(String configFilename) { configureAndWatch(configFilename, FileWatchdog.DEFAULT_DELAY); } /** Read the configuration file <code>configFilename</code> if it exists. Moreover, a thread will be created that will periodically check if <code>configFilename</code> has been created or modified. The period is determined by the <code>delay</code> argument. If a change or file creation is detected, then <code>configFilename</code> is read to configure log4j. @param configFilename A file in key=value format. @param delay The delay in milliseconds to wait between each check. */ static public void configureAndWatch(String configFilename, long delay) { PropertyWatchdog pdog = new PropertyWatchdog(configFilename); pdog.setDelay(delay); pdog.start(); } /** Read configuration options from <code>properties</code>. See {@link #doConfigure(String, LoggerRepository)} for the expected format. */ public void doConfigure(Properties properties, LoggerRepository hierarchy) { String value = properties.getProperty(LogLog.DEBUG_KEY); if(value == null) { value = properties.getProperty(LogLog.CONFIG_DEBUG_KEY); if(value != null) LogLog.warn("[log4j.configDebug] is deprecated. Use [log4j.debug] instead."); } if(value != null) { LogLog.setInternalDebugging(OptionConverter.toBoolean(value, true)); } String thresholdStr = OptionConverter.findAndSubst(THRESHOLD_PREFIX, properties); if(thresholdStr != null) { hierarchy.setThreshold(OptionConverter.toLevel(thresholdStr, (Level) Level.ALL)); LogLog.debug("Hierarchy threshold set to ["+hierarchy.getThreshold()+"]."); } configureRootCategory(properties, hierarchy); configureLoggerFactory(properties); parseCatsAndRenderers(properties, hierarchy); LogLog.debug("Finished configuring."); // We don't want to hold references to appenders preventing their // garbage collection. registry.clear(); } /** Read configuration options from url <code>configURL</code>. */ public void doConfigure(java.net.URL configURL, LoggerRepository hierarchy) { Properties props = new Properties(); LogLog.debug("Reading configuration from URL " + configURL); try { props.load(configURL.openStream()); } catch (java.io.IOException e) { LogLog.error("Could not read configuration file from URL [" + configURL + "].", e); LogLog.error("Ignoring configuration file [" + configURL +"]."); return; } doConfigure(props, hierarchy); } // -------------------------------------------------------------------------- // Internal stuff // -------------------------------------------------------------------------- /** Check the provided <code>Properties</code> object for a {@link org.apache.log4j.spi.LoggerFactory LoggerFactory} entry specified by {@link #LOGGER_FACTORY_KEY}. If such an entry exists, an attempt is made to create an instance using the default constructor. This instance is used for subsequent Category creations within this configurator. @see #parseCatsAndRenderers */ protected void configureLoggerFactory(Properties props) { String factoryClassName = OptionConverter.findAndSubst(LOGGER_FACTORY_KEY, props); if(factoryClassName != null) { LogLog.debug("Setting category factory to ["+factoryClassName+"]."); loggerFactory = (LoggerFactory) OptionConverter.instantiateByClassName(factoryClassName, LoggerFactory.class, loggerFactory); PropertySetter.setProperties(loggerFactory, props, FACTORY_PREFIX + "."); } } /* void configureOptionHandler(OptionHandler oh, String prefix, Properties props) { String[] options = oh.getOptionStrings(); if(options == null) return; String value; for(int i = 0; i < options.length; i++) { value = OptionConverter.findAndSubst(prefix + options[i], props); LogLog.debug( "Option " + options[i] + "=[" + (value == null? "N/A" : value)+"]."); // Some option handlers assume that null value are not passed to them. // So don't remove this check if(value != null) { oh.setOption(options[i], value); } } oh.activateOptions(); } */ void configureRootCategory(Properties props, LoggerRepository hierarchy) { String effectiveFrefix = ROOT_LOGGER_PREFIX; String value = OptionConverter.findAndSubst(ROOT_LOGGER_PREFIX, props); if(value == null) { value = OptionConverter.findAndSubst(ROOT_CATEGORY_PREFIX, props); effectiveFrefix = ROOT_CATEGORY_PREFIX; } if(value == null) LogLog.debug("Could not find root logger information. Is this OK?"); else { Logger root = hierarchy.getRootLogger(); synchronized(root) { parseCategory(props, root, effectiveFrefix, INTERNAL_ROOT_NAME, value); } } } /** Parse non-root elements, such non-root categories and renderers. */ protected void parseCatsAndRenderers(Properties props, LoggerRepository hierarchy) { Enumeration enumeration = props.propertyNames(); while(enumeration.hasMoreElements()) { String key = (String) enumeration.nextElement(); if(key.startsWith(CATEGORY_PREFIX) || key.startsWith(LOGGER_PREFIX)) { String loggerName = null; if(key.startsWith(CATEGORY_PREFIX)) { loggerName = key.substring(CATEGORY_PREFIX.length()); } else if(key.startsWith(LOGGER_PREFIX)) { loggerName = key.substring(LOGGER_PREFIX.length()); } String value = OptionConverter.findAndSubst(key, props); Logger logger = hierarchy.getLogger(loggerName, loggerFactory); synchronized(logger) { parseCategory(props, logger, key, loggerName, value); parseAdditivityForLogger(props, logger, loggerName); } } else if(key.startsWith(RENDERER_PREFIX)) { String renderedClass = key.substring(RENDERER_PREFIX.length()); String renderingClass = OptionConverter.findAndSubst(key, props); if(hierarchy instanceof RendererSupport) { RendererMap.addRenderer((RendererSupport) hierarchy, renderedClass, renderingClass); } } } } /** Parse the additivity option for a non-root category. */ void parseAdditivityForLogger(Properties props, Logger cat, String loggerName) { String value = OptionConverter.findAndSubst(ADDITIVITY_PREFIX + loggerName, props); LogLog.debug("Handling "+ADDITIVITY_PREFIX + loggerName+"=["+value+"]"); // touch additivity only if necessary if((value != null) && (!value.equals(""))) { boolean additivity = OptionConverter.toBoolean(value, true); LogLog.debug("Setting additivity for \""+loggerName+"\" to "+ additivity); cat.setAdditivity(additivity); } } /** This method must work for the root category as well. */ void parseCategory(Properties props, Logger logger, String optionKey, String loggerName, String value) { LogLog.debug("Parsing for [" +loggerName +"] with value=[" + value+"]."); // We must skip over ',' but not white space StringTokenizer st = new StringTokenizer(value, ","); // If value is not in the form ", appender.." or "", then we should set // the level of the loggeregory. if(!(value.startsWith(",") || value.equals(""))) { // just to be on the safe side... if(!st.hasMoreTokens()) return; String levelStr = st.nextToken(); LogLog.debug("Level token is [" + levelStr + "]."); // If the level value is inherited, set category level value to // null. We also check that the user has not specified inherited for the // root category. if(INHERITED.equalsIgnoreCase(levelStr) || NULL.equalsIgnoreCase(levelStr)) { if(loggerName.equals(INTERNAL_ROOT_NAME)) { LogLog.warn("The root logger cannot be set to null."); } else { logger.setLevel(null); } } else { logger.setLevel(OptionConverter.toLevel(levelStr, (Level) Level.DEBUG)); } LogLog.debug("Category " + loggerName + " set to " + logger.getLevel()); } // Begin by removing all existing appenders. logger.removeAllAppenders(); Appender appender; String appenderName; while(st.hasMoreTokens()) { appenderName = st.nextToken().trim(); if(appenderName == null || appenderName.equals(",")) continue; LogLog.debug("Parsing appender named \"" + appenderName +"\"."); appender = parseAppender(props, appenderName); if(appender != null) { logger.addAppender(appender); } } } Appender parseAppender(Properties props, String appenderName) { Appender appender = registryGet(appenderName); if((appender != null)) { LogLog.debug("Appender \"" + appenderName + "\" was already parsed."); return appender; } // Appender was not previously initialized. String prefix = APPENDER_PREFIX + appenderName; String layoutPrefix = prefix + ".layout"; appender = (Appender) OptionConverter.instantiateByKey(props, prefix, org.apache.log4j.Appender.class, null); if(appender == null) { LogLog.error( "Could not instantiate appender named \"" + appenderName+"\"."); return null; } appender.setName(appenderName); if(appender instanceof OptionHandler) { if(appender.requiresLayout()) { Layout layout = (Layout) OptionConverter.instantiateByKey(props, layoutPrefix, Layout.class, null); if(layout != null) { appender.setLayout(layout); LogLog.debug("Parsing layout options for \"" + appenderName +"\"."); //configureOptionHandler(layout, layoutPrefix + ".", props); PropertySetter.setProperties(layout, props, layoutPrefix + "."); LogLog.debug("End of parsing for \"" + appenderName +"\"."); } } //configureOptionHandler((OptionHandler) appender, prefix + ".", props); PropertySetter.setProperties(appender, props, prefix + "."); LogLog.debug("Parsed \"" + appenderName +"\" options."); } registryPut(appender); return appender; } void registryPut(Appender appender) { registry.put(appender.getName(), appender); } Appender registryGet(String name) { return (Appender) registry.get(name); }}class PropertyWatchdog extends FileWatchdog { PropertyWatchdog(String filename) { super(filename); } /** Call {@link PropertyConfigurator#configure(String)} with the <code>filename</code> to reconfigure log4j. */ public void doOnChange() { new PropertyConfigurator().doConfigure(filename, LogManager.getLoggerRepository()); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -