Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- * 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.logging.log4j.core;
- import java.io.ObjectStreamException;
- import java.io.Serializable;
- import java.util.ArrayList;
- import java.util.Iterator;
- import java.util.List;
- import java.util.Map;
- import org.apache.logging.log4j.Level;
- import org.apache.logging.log4j.Marker;
- import org.apache.logging.log4j.core.config.Configuration;
- import org.apache.logging.log4j.core.config.LoggerConfig;
- import org.apache.logging.log4j.core.config.ReliabilityStrategy;
- import org.apache.logging.log4j.core.filter.CompositeFilter;
- import org.apache.logging.log4j.message.Message;
- import org.apache.logging.log4j.message.MessageFactory;
- import org.apache.logging.log4j.message.SimpleMessage;
- import org.apache.logging.log4j.spi.AbstractLogger;
- import org.apache.logging.log4j.util.Strings;
- import org.apache.logging.log4j.util.Supplier;
- /**
- * The core implementation of the {@link org.apache.logging.log4j.Logger} interface. Besides providing an implementation
- * of all the Logger methods, this class also provides some convenience methods for Log4j 1.x compatibility as well as
- * access to the {@link org.apache.logging.log4j.core.Filter Filters} and {@link org.apache.logging.log4j.core.Appender
- * Appenders} associated with this Logger. Note that access to these underlying objects is provided primarily for use in
- * unit tests or bridging legacy Log4j 1.x code. Future versions of this class may or may not include the various
- * methods that are noted as not being part of the public API.
- *
- * TODO All the isEnabled methods could be pushed into a filter interface. Not sure of the utility of having isEnabled
- * be able to examine the message pattern and parameters. (RG) Moving the isEnabled methods out of Logger noticeably
- * impacts performance. The message pattern and parameters are required so that they can be used in global filters.
- */
- public class Logger extends AbstractLogger implements Supplier<LoggerConfig> {
- private static final long serialVersionUID = 1L;
- /**
- * Config should be consistent across threads.
- */
- protected volatile PrivateConfig privateConfig;
- // FIXME: ditto to the above
- private final LoggerContext context;
- /**
- * The constructor.
- *
- * @param context The LoggerContext this Logger is associated with.
- * @param messageFactory The message factory.
- * @param name The name of the Logger.
- */
- protected Logger(final LoggerContext context, final String name, final MessageFactory messageFactory) {
- super(name, messageFactory);
- this.context = context;
- privateConfig = new PrivateConfig(context.getConfiguration(), this);
- }
- protected Object writeReplace() throws ObjectStreamException {
- return new LoggerProxy(getName(), getMessageFactory());
- }
- /**
- * This method is only used for 1.x compatibility. Returns the parent of this Logger. If it doesn't already exist
- * return a temporary Logger.
- *
- * @return The parent Logger.
- */
- public Logger getParent() {
- final LoggerConfig lc = privateConfig.loggerConfig.getName().equals(getName()) ? privateConfig.loggerConfig
- .getParent() : privateConfig.loggerConfig;
- if (lc == null) {
- return null;
- }
- final String lcName = lc.getName();
- final MessageFactory messageFactory = getMessageFactory();
- if (context.hasLogger(lcName, messageFactory)) {
- return context.getLogger(lcName, messageFactory);
- }
- return new Logger(context, lcName, messageFactory);
- }
- /**
- * Returns the LoggerContext this Logger is associated with.
- *
- * @return the LoggerContext.
- */
- public LoggerContext getContext() {
- return context;
- }
- /**
- * This method is not exposed through the public API and is provided primarily for unit testing.
- * <p>
- * If the new level is null, this logger inherits the level from its parent.
- * </p>
- *
- * @param level The Level to use on this Logger, may be null.
- */
- public synchronized void setLevel(final Level level) {
- if (level == getLevel()) {
- return;
- }
- Level actualLevel;
- if (level != null) {
- actualLevel = level;
- } else {
- final Logger parent = getParent();
- actualLevel = parent != null ? parent.getLevel() : privateConfig.loggerConfigLevel;
- }
- privateConfig = new PrivateConfig(privateConfig, actualLevel);
- }
- /*
- * (non-Javadoc)
- *
- * @see org.apache.logging.log4j.util.Supplier#get()
- */
- @Override
- public LoggerConfig get() {
- return privateConfig.loggerConfig;
- }
- @Override
- public void logMessage(final String fqcn, final Level level, final Marker marker, final Message message,
- final Throwable t) {
- final Message msg = message == null ? new SimpleMessage(Strings.EMPTY) : message;
- final ReliabilityStrategy strategy = privateConfig.loggerConfig.getReliabilityStrategy();
- strategy.log(this, getName(), fqcn, marker, level, msg, t);
- }
- @Override
- public boolean isEnabled(final Level level, final Marker marker, final String message, final Throwable t) {
- return privateConfig.filter(level, marker, message, t);
- }
- @Override
- public boolean isEnabled(final Level level, final Marker marker, final String message) {
- return privateConfig.filter(level, marker, message);
- }
- @Override
- public boolean isEnabled(final Level level, final Marker marker, final String message, final Object... params) {
- return privateConfig.filter(level, marker, message, params);
- }
- @Override
- public boolean isEnabled(final Level level, final Marker marker, final Object message, final Throwable t) {
- return privateConfig.filter(level, marker, message, t);
- }
- @Override
- public boolean isEnabled(final Level level, final Marker marker, final Message message, final Throwable t) {
- return privateConfig.filter(level, marker, message, t);
- }
- /**
- * This method is not exposed through the public API and is used primarily for unit testing.
- *
- * @param appender The Appender to add to the Logger.
- */
- public void addAppender(final Appender appender) {
- privateConfig.config.addLoggerAppender(this, appender);
- }
- /**
- * This method is not exposed through the public API and is used primarily for unit testing.
- *
- * @param appender The Appender to remove from the Logger.
- */
- public void removeAppender(final Appender appender) {
- privateConfig.loggerConfig.removeAppender(appender.getName());
- }
- /**
- * This method is not exposed through the public API and is used primarily for unit testing.
- *
- * @return A Map containing the Appender's name as the key and the Appender as the value.
- */
- public Map<String, Appender> getAppenders() {
- return privateConfig.loggerConfig.getAppenders();
- }
- /**
- * This method is not exposed through the public API and is used primarily for unit testing.
- *
- * @return An Iterator over all the Filters associated with the Logger.
- */
- // FIXME: this really ought to be an Iterable instead of an Iterator
- public Iterator<Filter> getFilters() {
- final Filter filter = privateConfig.loggerConfig.getFilter();
- if (filter == null) {
- return new ArrayList<Filter>().iterator();
- } else if (filter instanceof CompositeFilter) {
- return ((CompositeFilter) filter).iterator();
- } else {
- final List<Filter> filters = new ArrayList<>();
- filters.add(filter);
- return filters.iterator();
- }
- }
- /**
- * Gets the Level associated with the Logger.
- *
- * @return the Level associate with the Logger.
- */
- @Override
- public Level getLevel() {
- return privateConfig.loggerConfigLevel;
- }
- /**
- * This method is not exposed through the public API and is used primarily for unit testing.
- *
- * @return The number of Filters associated with the Logger.
- */
- public int filterCount() {
- final Filter filter = privateConfig.loggerConfig.getFilter();
- if (filter == null) {
- return 0;
- } else if (filter instanceof CompositeFilter) {
- return ((CompositeFilter) filter).size();
- }
- return 1;
- }
- /**
- * This method is not exposed through the public API and is used primarily for unit testing.
- *
- * @param filter The Filter to add.
- */
- public void addFilter(final Filter filter) {
- privateConfig.config.addLoggerFilter(this, filter);
- }
- /**
- * This method is not exposed through the public API and is present only to support the Log4j 1.2 compatibility
- * bridge.
- *
- * @return true if the associated LoggerConfig is additive, false otherwise.
- */
- public boolean isAdditive() {
- return privateConfig.loggerConfig.isAdditive();
- }
- /**
- * This method is not exposed through the public API and is present only to support the Log4j 1.2 compatibility
- * bridge.
- *
- * @param additive Boolean value to indicate whether the Logger is additive or not.
- */
- public void setAdditive(final boolean additive) {
- privateConfig.config.setLoggerAdditive(this, additive);
- }
- /**
- * Associates this Logger with a new Configuration. This method is not
- * exposed through the public API.
- * <p>
- * There are two ways this could be used to guarantee all threads are aware
- * of changes to config.
- * <ol>
- * <li>Synchronize this method. Accessors don't need to be synchronized as
- * Java will treat all variables within a synchronized block as volatile.
- * </li>
- * <li>Declare the variable volatile. Option 2 is used here as the
- * performance cost is very low and it does a better job at documenting how
- * it is used.</li>
- *
- * @param newConfig
- * The new Configuration.
- */
- protected void updateConfiguration(final Configuration newConfig) {
- this.privateConfig = new PrivateConfig(newConfig, this);
- }
- /**
- * The binding between a Logger and its configuration.
- */
- protected class PrivateConfig {
- // config fields are public to make them visible to Logger subclasses
- /** LoggerConfig to delegate the actual logging to. */
- public final LoggerConfig loggerConfig; // SUPPRESS CHECKSTYLE
- /** The current Configuration associated with the LoggerConfig. */
- public final Configuration config; // SUPPRESS CHECKSTYLE
- private final Level loggerConfigLevel;
- private final int intLevel;
- private final Logger logger;
- public PrivateConfig(final Configuration config, final Logger logger) {
- this.config = config;
- this.loggerConfig = config.getLoggerConfig(getName());
- this.loggerConfigLevel = this.loggerConfig.getLevel();
- this.intLevel = this.loggerConfigLevel.intLevel();
- this.logger = logger;
- }
- public PrivateConfig(final PrivateConfig pc, final Level level) {
- this.config = pc.config;
- this.loggerConfig = pc.loggerConfig;
- this.loggerConfigLevel = level;
- this.intLevel = this.loggerConfigLevel.intLevel();
- this.logger = pc.logger;
- }
- public PrivateConfig(final PrivateConfig pc, final LoggerConfig lc) {
- this.config = pc.config;
- this.loggerConfig = lc;
- this.loggerConfigLevel = lc.getLevel();
- this.intLevel = this.loggerConfigLevel.intLevel();
- this.logger = pc.logger;
- }
- // LOG4J2-151: changed visibility to public
- public void logEvent(final LogEvent event) {
- loggerConfig.log(event);
- }
- boolean filter(final Level level, final Marker marker, final String msg) {
- final Filter filter = config.getFilter();
- if (filter != null) {
- final Filter.Result r = filter.filter(logger, level, marker, msg);
- if (r != Filter.Result.NEUTRAL) {
- return r == Filter.Result.ACCEPT;
- }
- }
- return level != null && intLevel >= level.intLevel();
- }
- boolean filter(final Level level, final Marker marker, final String msg, final Throwable t) {
- final Filter filter = config.getFilter();
- if (filter != null) {
- final Filter.Result r = filter.filter(logger, level, marker, msg, t);
- if (r != Filter.Result.NEUTRAL) {
- return r == Filter.Result.ACCEPT;
- }
- }
- return level != null && intLevel >= level.intLevel();
- }
- boolean filter(final Level level, final Marker marker, final String msg, final Object... p1) {
- final Filter filter = config.getFilter();
- if (filter != null) {
- final Filter.Result r = filter.filter(logger, level, marker, msg, p1);
- if (r != Filter.Result.NEUTRAL) {
- return r == Filter.Result.ACCEPT;
- }
- }
- return level != null && intLevel >= level.intLevel();
- }
- boolean filter(final Level level, final Marker marker, final Object msg, final Throwable t) {
- final Filter filter = config.getFilter();
- if (filter != null) {
- final Filter.Result r = filter.filter(logger, level, marker, msg, t);
- if (r != Filter.Result.NEUTRAL) {
- return r == Filter.Result.ACCEPT;
- }
- }
- return level != null && intLevel >= level.intLevel();
- }
- boolean filter(final Level level, final Marker marker, final Message msg, final Throwable t) {
- final Filter filter = config.getFilter();
- if (filter != null) {
- final Filter.Result r = filter.filter(logger, level, marker, msg, t);
- if (r != Filter.Result.NEUTRAL) {
- return r == Filter.Result.ACCEPT;
- }
- }
- return level != null && intLevel >= level.intLevel();
- }
- }
- /**
- * Serialization proxy class for Logger. Since the LoggerContext and config information can be reconstructed on the
- * fly, the only information needed for a Logger are what's available in AbstractLogger.
- *
- * @since 2.5
- */
- protected static class LoggerProxy implements Serializable {
- private static final long serialVersionUID = 1L;
- private final String name;
- private final MessageFactory messageFactory;
- public LoggerProxy(String name, MessageFactory messageFactory) {
- this.name = name;
- this.messageFactory = messageFactory;
- }
- protected Object readResolve() throws ObjectStreamException {
- return new Logger(LoggerContext.getContext(), name, messageFactory);
- }
- }
- /**
- * Returns a String representation of this instance in the form {@code "name:level[ in context_name]"}.
- *
- * @return A String describing this Logger instance.
- */
- @Override
- public String toString() {
- final String nameLevel = Strings.EMPTY + getName() + ':' + getLevel();
- if (context == null) {
- return nameLevel;
- }
- final String contextName = context.getName();
- return contextName == null ? nameLevel : nameLevel + " in " + contextName;
- }
- @Override
- public boolean equals(final Object o) {
- if (this == o) {
- return true;
- }
- if (o == null || getClass() != o.getClass()) {
- return false;
- }
- final Logger that = (Logger) o;
- return getName().equals(that.getName());
- }
- @Override
- public int hashCode() {
- return getName().hashCode();
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement