Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache license, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the license for the specific language governing permissions and
* limitations under the license.
*/
package org.apache.log4j;
import java.io.IOException;
import java.io.InputStream;
import java.io.InterruptedIOException;
import java.net.URL;
import java.net.URLConnection;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Map;
import java.util.Properties;
import java.util.StringTokenizer;
import java.util.Vector;
import org.apache.log4j.bridge.FilterAdapter;
import org.apache.log4j.config.PropertiesConfiguration;
import org.apache.log4j.config.PropertySetter;
import org.apache.log4j.helpers.FileWatchdog;
import org.apache.log4j.helpers.LogLog;
import org.apache.log4j.helpers.OptionConverter;
import org.apache.log4j.or.RendererMap;
import org.apache.log4j.spi.Configurator;
import org.apache.log4j.spi.ErrorHandler;
import org.apache.log4j.spi.Filter;
import org.apache.log4j.spi.LoggerFactory;
import org.apache.log4j.spi.LoggerRepository;
import org.apache.log4j.spi.OptionHandler;
import org.apache.log4j.spi.RendererSupport;
import org.apache.log4j.spi.ThrowableRenderer;
import org.apache.log4j.spi.ThrowableRendererSupport;
import org.apache.logging.log4j.core.config.Configuration;
import org.apache.logging.log4j.util.StackLocatorUtil;
/**
* Configures Log4j from properties.
*/
public class PropertyConfigurator implements Configurator {
static class NameValue {
String key, value;
public NameValue(final String key, final String value) {
this.key = key;
this.value = value;
}
@Override
public String toString() {
return key + "=" + value;
}
}
static class PropertyWatchdog extends FileWatchdog {
private final ClassLoader classLoader;
PropertyWatchdog(final String fileName, final ClassLoader classLoader) {
super(fileName);
this.classLoader = classLoader;
}
/**
* Call {@link PropertyConfigurator#configure(String)} with the filename to reconfigure log4j.
*/
@Override
public void doOnChange() {
new PropertyConfigurator().doConfigure(filename, LogManager.getLoggerRepository(), classLoader);
}
}
class SortedKeyEnumeration implements Enumeration {
private final Enumeration e;
public SortedKeyEnumeration(final Hashtable ht) {
final Enumeration f = ht.keys();
final Vector keys = new Vector(ht.size());
for (int i, last = 0; f.hasMoreElements(); ++last) {
final String key = (String) f.nextElement();
for (i = 0; i < last; ++i) {
final String s = (String) keys.get(i);
if (key.compareTo(s) <= 0) {
break;
}
}
keys.add(i, key);
}
e = keys.elements();
}
@Override
public boolean hasMoreElements() {
return e.hasMoreElements();
}
@Override
public Object nextElement() {
return e.nextElement();
}
}
static final String CATEGORY_PREFIX = "log4j.category.";
static final String LOGGER_PREFIX = "log4j.logger.";
static final String FACTORY_PREFIX = "log4j.factory";
static final String ADDITIVITY_PREFIX = "log4j.additivity.";
static final String ROOT_CATEGORY_PREFIX = "log4j.rootCategory";
static final String ROOT_LOGGER_PREFIX = "log4j.rootLogger";
static final String APPENDER_PREFIX = "log4j.appender.";
static final String RENDERER_PREFIX = "log4j.renderer.";
static final String THRESHOLD_PREFIX = "log4j.threshold";
private static final String THROWABLE_RENDERER_PREFIX = "log4j.throwableRenderer";
private static final String LOGGER_REF = "logger-ref";
private static final String ROOT_REF = "root-ref";
private static final String APPENDER_REF_TAG = "appender-ref";
/**
* Key for specifying the {@link org.apache.log4j.spi.LoggerFactory LoggerFactory}. Currently set to
* "log4j.loggerFactory".
*/
public static final String LOGGER_FACTORY_KEY = "log4j.loggerFactory";
/**
* If property set to true, then hierarchy will be reset before configuration.
*/
private static final String RESET_KEY = "log4j.reset";
static final private String INTERNAL_ROOT_NAME = "root";
/**
* Reads configuration options from an InputStream.
*
* @param inputStream The input stream
*/
public static void configure(final InputStream inputStream) {
new PropertyConfigurator().doConfigure(inputStream, LogManager.getLoggerRepository(), StackLocatorUtil.getCallerClassLoader(2));
}
/**
* Reads configuration options from properties.
*
* See {@link #doConfigure(String, LoggerRepository)} for the expected format.
*
* @param properties The properties
*/
public static void configure(final Properties properties) {
new PropertyConfigurator().doConfigure(properties, LogManager.getLoggerRepository(), StackLocatorUtil.getCallerClassLoader(2));
}
/**
* Reads configuration options from configuration file.
*
* @param fileName The configuration file.
*/
public static void configure(final String fileName) {
new PropertyConfigurator().doConfigure(fileName, LogManager.getLoggerRepository(), StackLocatorUtil.getCallerClassLoader(2));
}
/**
* Reads configuration options from url configURL.
*
* @param configURL The configuration URL
*/
public static void configure(final URL configURL) {
new PropertyConfigurator().doConfigure(configURL, LogManager.getLoggerRepository(), StackLocatorUtil.getCallerClassLoader(2));
}
/**
* Like {@link #configureAndWatch(String, long)} except that the default delay as defined by FileWatchdog.DEFAULT_DELAY
* is used.
*
* @param configFilename A file in key=value format.
*/
public static void configureAndWatch(final String configFilename) {
configureAndWatch(configFilename, FileWatchdog.DEFAULT_DELAY, StackLocatorUtil.getCallerClassLoader(2));
}
/**
* Reads the configuration file configFilename if it exists. Moreover, a thread will be created that will
* periodically check if configFilename has been created or modified. The period is determined by the
* delay argument. If a change or file creation is detected, then configFilename is read to
* configure log4j.
*
* @param configFilename A file in key=value format.
* @param delayMillis The delay in milliseconds to wait between each check.
*/
public static void configureAndWatch(final String configFilename, final long delayMillis) {
configureAndWatch(configFilename, delayMillis, StackLocatorUtil.getCallerClassLoader(2));
}
static void configureAndWatch(final String configFilename, final long delay, final ClassLoader classLoader) {
final PropertyWatchdog watchdog = new PropertyWatchdog(configFilename, classLoader);
watchdog.setDelay(delay);
watchdog.start();
}
private static Configuration reconfigure(final Configuration configuration) {
org.apache.logging.log4j.core.config.Configurator.reconfigure(configuration);
return configuration;
}
/**
* Used internally to keep track of configured appenders.
*/
protected Hashtable registry = new Hashtable(11);
private LoggerRepository repository;
protected LoggerFactory loggerFactory = new DefaultCategoryFactory();
/**
* Checks the provided Properties 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(final Properties properties) {
final String factoryClassName = OptionConverter.findAndSubst(LOGGER_FACTORY_KEY, properties);
if (factoryClassName != null) {
LogLog.debug("Setting category factory to [" + factoryClassName + "].");
loggerFactory = (LoggerFactory) OptionConverter.instantiateByClassName(factoryClassName, LoggerFactory.class, loggerFactory);
PropertySetter.setProperties(loggerFactory, properties, FACTORY_PREFIX + ".");
}
}
void configureRootCategory(final Properties properties, final LoggerRepository loggerRepository) {
String effectiveFrefix = ROOT_LOGGER_PREFIX;
String value = OptionConverter.findAndSubst(ROOT_LOGGER_PREFIX, properties);
if (value == null) {
value = OptionConverter.findAndSubst(ROOT_CATEGORY_PREFIX, properties);
effectiveFrefix = ROOT_CATEGORY_PREFIX;
}
if (value == null) {
LogLog.debug("Could not find root logger information. Is this OK?");
} else {
final Logger root = loggerRepository.getRootLogger();
synchronized (root) {
parseCategory(properties, root, effectiveFrefix, INTERNAL_ROOT_NAME, value);
}
}
}
/**
* Reads configuration options from an InputStream.
*
* @param inputStream The input stream
* @param loggerRepository The hierarchy
*/
@Override
public void doConfigure(final InputStream inputStream, final LoggerRepository loggerRepository) {
doConfigure(inputStream, loggerRepository, StackLocatorUtil.getCallerClassLoader(2));
}
Configuration doConfigure(final InputStream inputStream, final LoggerRepository loggerRepository, final ClassLoader classLoader) {
return doConfigure(loadProperties(inputStream), loggerRepository, classLoader);
}
/**
* Reads configuration options from properties.
*
* See {@link #doConfigure(String, LoggerRepository)} for the expected format.
*
* @param properties The properties
* @param loggerRepository The hierarchy
*/
public void doConfigure(final Properties properties, final LoggerRepository loggerRepository) {
doConfigure(properties, loggerRepository, StackLocatorUtil.getCallerClassLoader(2));
}
/**
* Reads configuration options from properties.
*
* See {@link #doConfigure(String, LoggerRepository)} for the expected format.
*
* @param properties The properties
* @param loggerRepository The hierarchy
*/
Configuration doConfigure(final Properties properties, final LoggerRepository loggerRepository, final ClassLoader classLoader) {
final PropertiesConfiguration configuration = new PropertiesConfiguration(LogManager.getContext(classLoader), properties);
configuration.doConfigure();
repository = loggerRepository;
// String value = properties.getProperty(LogLog.DEBUG_KEY);
// if (value == null) {
// value = properties.getProperty("log4j.configDebug");
// if (value != null) {
// LogLog.warn("[log4j.configDebug] is deprecated. Use [log4j.debug] instead.");
// }
// }
//
// if (value != null) {
// LogLog.setInternalDebugging(OptionConverter.toBoolean(value, true));
// }
//
// //
// // if log4j.reset=true then
// // reset hierarchy
// final String reset = properties.getProperty(RESET_KEY);
// if (reset != null && OptionConverter.toBoolean(reset, false)) {
// hierarchy.resetConfiguration();
// }
//
// final 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);
//
// We don't want to hold references to appenders preventing their
// garbage collection.
registry.clear();
return reconfigure(configuration);
}
/**
* Reads configuration options from configuration file.
*
* @param fileName The configuration file
* @param loggerRepository The hierarchy
*/
public void doConfigure(final String fileName, final LoggerRepository loggerRepository) {
doConfigure(fileName, loggerRepository, StackLocatorUtil.getCallerClassLoader(2));
}
/**
* Reads configuration options from configuration file.
*
* @param fileName The configuration file
* @param loggerRepository The hierarchy
*/
Configuration doConfigure(final String fileName, final LoggerRepository loggerRepository, final ClassLoader classLoader) {
try (InputStream inputStream = Files.newInputStream(Paths.get(fileName))) {
return doConfigure(inputStream, loggerRepository, classLoader);
} catch (final Exception e) {
if (e instanceof InterruptedIOException || e instanceof InterruptedException) {
Thread.currentThread().interrupt();
}
LogLog.error("Could not read configuration file [" + fileName + "].", e);
LogLog.error("Ignoring configuration file [" + fileName + "].");
return null;
}
}
/**
* Read configuration options from url configURL.
*
* @param url The configuration URL
* @param loggerRepository The hierarchy
*/
@Override
public void doConfigure(final URL url, final LoggerRepository loggerRepository) {
doConfigure(url, loggerRepository, StackLocatorUtil.getCallerClassLoader(2));
}
Configuration doConfigure(final URL url, final LoggerRepository loggerRepository, final ClassLoader classLoader) {
LogLog.debug("Reading configuration from URL " + url);
try {
final URLConnection urlConnection = url.openConnection();
urlConnection.setUseCaches(false);
try (InputStream inputStream = urlConnection.getInputStream()) {
return doConfigure(inputStream, loggerRepository, classLoader);
}
} catch (final IOException e) {
LogLog.error("Could not read configuration file from URL [" + url + "].", e);
LogLog.error("Ignoring configuration file [" + url + "].");
return null;
}
}
private Properties loadProperties(final InputStream inputStream) {
final Properties loaded = new Properties();
try {
loaded.load(inputStream);
} catch (final IOException | IllegalArgumentException e) {
if (e instanceof InterruptedIOException) {
Thread.currentThread().interrupt();
}
LogLog.error("Could not read configuration file from InputStream [" + inputStream + "].", e);
LogLog.error("Ignoring configuration InputStream [" + inputStream + "].");
return null;
}
return loaded;
}
/**
* Parse the additivity option for a non-root category.
*/
void parseAdditivityForLogger(final Properties properties, final Logger logger, final String loggerName) {
final String value = OptionConverter.findAndSubst(ADDITIVITY_PREFIX + loggerName, properties);
LogLog.debug("Handling " + ADDITIVITY_PREFIX + loggerName + "=[" + value + "]");
// touch additivity only if necessary
if ((value != null) && (!value.equals(""))) {
final boolean additivity = OptionConverter.toBoolean(value, true);
LogLog.debug("Setting additivity for \"" + loggerName + "\" to " + additivity);
logger.setAdditivity(additivity);
}
}
Appender parseAppender(final Properties properties, final String appenderName) {
Appender appender = registryGet(appenderName);
if ((appender != null)) {
LogLog.debug("Appender \"" + appenderName + "\" was already parsed.");
return appender;
}
// Appender was not previously initialized.
final String prefix = APPENDER_PREFIX + appenderName;
final String layoutPrefix = prefix + ".layout";
appender = (Appender) OptionConverter.instantiateByKey(properties, 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()) {
final Layout layout = (Layout) OptionConverter.instantiateByKey(properties, layoutPrefix, Layout.class, null);
if (layout != null) {
appender.setLayout(layout);
LogLog.debug("Parsing layout options for \"" + appenderName + "\".");
// configureOptionHandler(layout, layoutPrefix + ".", props);
PropertySetter.setProperties(layout, properties, layoutPrefix + ".");
LogLog.debug("End of parsing for \"" + appenderName + "\".");
}
}
final String errorHandlerPrefix = prefix + ".errorhandler";
final String errorHandlerClass = OptionConverter.findAndSubst(errorHandlerPrefix, properties);
if (errorHandlerClass != null) {
final ErrorHandler eh = (ErrorHandler) OptionConverter.instantiateByKey(properties, errorHandlerPrefix, ErrorHandler.class, null);
if (eh != null) {
appender.setErrorHandler(eh);
LogLog.debug("Parsing errorhandler options for \"" + appenderName + "\".");
parseErrorHandler(eh, errorHandlerPrefix, properties, repository);
final Properties edited = new Properties();
final String[] keys = new String[] {errorHandlerPrefix + "." + ROOT_REF, errorHandlerPrefix + "." + LOGGER_REF,
errorHandlerPrefix + "." + APPENDER_REF_TAG};
for (final Object element : properties.entrySet()) {
final Map.Entry entry = (Map.Entry) element;
int i = 0;
for (; i < keys.length; i++) {
if (keys[i].equals(entry.getKey())) {
break;
}
}
if (i == keys.length) {
edited.put(entry.getKey(), entry.getValue());
}
}
PropertySetter.setProperties(eh, edited, errorHandlerPrefix + ".");
LogLog.debug("End of errorhandler parsing for \"" + appenderName + "\".");
}
}
// configureOptionHandler((OptionHandler) appender, prefix + ".", props);
PropertySetter.setProperties(appender, properties, prefix + ".");
LogLog.debug("Parsed \"" + appenderName + "\" options.");
}
parseAppenderFilters(properties, appenderName, appender);
registryPut(appender);
return appender;
}
void parseAppenderFilters(final Properties properties, final String appenderName, final Appender appender) {
// extract filters and filter options from props into a hashtable mapping
// the property name defining the filter class to a list of pre-parsed
// name-value pairs associated to that filter
final String filterPrefix = APPENDER_PREFIX + appenderName + ".filter.";
final int fIdx = filterPrefix.length();
final Hashtable filters = new Hashtable();
final Enumeration e = properties.keys();
String name = "";
while (e.hasMoreElements()) {
final String key = (String) e.nextElement();
if (key.startsWith(filterPrefix)) {
final int dotIdx = key.indexOf('.', fIdx);
String filterKey = key;
if (dotIdx != -1) {
filterKey = key.substring(0, dotIdx);
name = key.substring(dotIdx + 1);
}
Vector filterOpts = (Vector) filters.get(filterKey);
if (filterOpts == null) {
filterOpts = new Vector();
filters.put(filterKey, filterOpts);
}
if (dotIdx != -1) {
final String value = OptionConverter.findAndSubst(key, properties);
filterOpts.add(new NameValue(name, value));
}
}
}
// sort filters by IDs, insantiate filters, set filter options,
// add filters to the appender
final Enumeration g = new SortedKeyEnumeration(filters);
Filter head = null;
while (g.hasMoreElements()) {
final String key = (String) g.nextElement();
final String clazz = properties.getProperty(key);
if (clazz != null) {
LogLog.debug("Filter key: [" + key + "] class: [" + properties.getProperty(key) + "] props: " + filters.get(key));
final Filter filter = (Filter) OptionConverter.instantiateByClassName(clazz, Filter.class, null);
if (filter != null) {
final PropertySetter propSetter = new PropertySetter(filter);
final Vector v = (Vector) filters.get(key);
final Enumeration filterProps = v.elements();
while (filterProps.hasMoreElements()) {
final NameValue kv = (NameValue) filterProps.nextElement();
propSetter.setProperty(kv.key, kv.value);
}
propSetter.activate();
LogLog.debug("Adding filter of type [" + filter.getClass() + "] to appender named [" + appender.getName() + "].");
head = FilterAdapter.addFilter(head, filter);
}
} else {
LogLog.warn("Missing class definition for filter: [" + key + "]");
}
}
appender.addFilter(head);
}
/**
* This method must work for the root category as well.
*/
void parseCategory(final Properties properties, final Logger logger, final String optionKey, final String loggerName, final String value) {
LogLog.debug("Parsing for [" + loggerName + "] with value=[" + value + "].");
// We must skip over ',' but not white space
final 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;
}
final 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(properties, appenderName);
if (appender != null) {
logger.addAppender(appender);
}
}
}
/**
* Parse non-root elements, such non-root categories and renderers.
*/
protected void parseCatsAndRenderers(final Properties properties, final LoggerRepository loggerRepository) {
final Enumeration enumeration = properties.propertyNames();
while (enumeration.hasMoreElements()) {
final 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());
}
final String value = OptionConverter.findAndSubst(key, properties);
final Logger logger = loggerRepository.getLogger(loggerName, loggerFactory);
synchronized (logger) {
parseCategory(properties, logger, key, loggerName, value);
parseAdditivityForLogger(properties, logger, loggerName);
}
} else if (key.startsWith(RENDERER_PREFIX)) {
final String renderedClass = key.substring(RENDERER_PREFIX.length());
final String renderingClass = OptionConverter.findAndSubst(key, properties);
if (loggerRepository instanceof RendererSupport) {
RendererMap.addRenderer((RendererSupport) loggerRepository, renderedClass, renderingClass);
}
} else if (key.equals(THROWABLE_RENDERER_PREFIX)) {
if (loggerRepository instanceof ThrowableRendererSupport) {
final ThrowableRenderer tr = (ThrowableRenderer) OptionConverter.instantiateByKey(properties, THROWABLE_RENDERER_PREFIX,
org.apache.log4j.spi.ThrowableRenderer.class, null);
if (tr == null) {
LogLog.error("Could not instantiate throwableRenderer.");
} else {
final PropertySetter setter = new PropertySetter(tr);
setter.setProperties(properties, THROWABLE_RENDERER_PREFIX + ".");
((ThrowableRendererSupport) loggerRepository).setThrowableRenderer(tr);
}
}
}
}
}
private void parseErrorHandler(final ErrorHandler errorHandler, final String errorHandlerPrefix, final Properties props,
final LoggerRepository loggerRepository) {
if (errorHandler != null && loggerRepository != null) {
final boolean rootRef = OptionConverter.toBoolean(OptionConverter.findAndSubst(errorHandlerPrefix + ROOT_REF, props), false);
if (rootRef) {
errorHandler.setLogger(loggerRepository.getRootLogger());
}
final String loggerName = OptionConverter.findAndSubst(errorHandlerPrefix + LOGGER_REF, props);
if (loggerName != null) {
final Logger logger = loggerFactory == null ? loggerRepository.getLogger(loggerName) : loggerRepository.getLogger(loggerName, loggerFactory);
errorHandler.setLogger(logger);
}
final String appenderName = OptionConverter.findAndSubst(errorHandlerPrefix + APPENDER_REF_TAG, props);
if (appenderName != null) {
final Appender backup = parseAppender(props, appenderName);
if (backup != null) {
errorHandler.setBackupAppender(backup);
}
}
}
}
Appender registryGet(final String name) {
return (Appender) registry.get(name);
}
void registryPut(final Appender appender) {
registry.put(appender.getName(), appender);
}
}