All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sghd.logging.ServerFileAppender Maven / Gradle / Ivy

The newest version!
package com.sghd.logging;

import java.io.IOException;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

import org.apache.log4j.Appender;
import org.apache.log4j.AppenderSkeleton;
import org.apache.log4j.DailyRollingFileAppender;
import org.apache.log4j.Layout;
import org.apache.log4j.Priority;
import org.apache.log4j.helpers.LogLog;
import org.apache.log4j.helpers.OnlyOnceErrorHandler;
import org.apache.log4j.spi.ErrorHandler;
import org.apache.log4j.spi.Filter;
import org.apache.log4j.spi.LoggingEvent;
import org.apache.log4j.spi.OptionHandler;

public class ServerFileAppender implements Appender, OptionHandler {

	private final static Field MESSAGE_FIELD;

	static {
		try {
			MESSAGE_FIELD = LoggingEvent.class.getDeclaredField("renderedMessage");
			MESSAGE_FIELD.setAccessible(true);
		} catch (Exception exception) {
			throw new RuntimeException(exception);
		}
	}

	/**
	 * The layout variable does not need to be set if the appender implementation has its own layout.
	 */
	private Layout layout;

	/** Appenders are named. */
	private String name;

	/**
	 * There is no level threshold filtering by default.
	 */
	private Priority threshold;

	/**
	 * It is assumed and enforced that errorHandler is never null.
	 */
	private ErrorHandler errorHandler = new OnlyOnceErrorHandler();

	/**
	 * Is this appender closed?
	 */
	private boolean closed = false;

	/**
	 * 自定义的Appender映射,每个服对应各自的Appender
	 */
	private Map appenderMap = new HashMap();

	private String datePattern;

	private String directoryName;

	/**
	 * Derived appenders should override this method if option structure requires it.
	 */
	public void activateOptions() {
	}

	/**
	 * Add a filter to end of the filter list.
	 * @since 0.9.0
	 */
	public void addFilter(Filter newFilter) {
		throw new UnsupportedOperationException();
	}

	/**
	 * Clear the filters chain.
	 * @since 0.9.0
	 */
	public void clearFilters() {
		throw new UnsupportedOperationException();
	}

	/**
	 * Finalize this appender by calling the derived class' close method.
	 * @since 0.8.4
	 */
	public void finalize() {
		// An appender might be closed then garbage collected. There is no
		// point in closing twice.
		if (this.closed)
			return;

		LogLog.debug("Finalizing appender named [" + name + "].");
		close();
	}

	/**
	 * Return the currently set {@link ErrorHandler} for this Appender.
	 * @since 0.9.0
	 */
	public synchronized ErrorHandler getErrorHandler() {
		return this.errorHandler;
	}

	/**
	 * Returns the head Filter.
	 * @since 1.1
	 */
	public Filter getFilter() {
		throw new UnsupportedOperationException();
	}

	/**
	 * Return the first filter in the filter chain for this Appender. The return value may be null if no is
	 * filter is set.
	 */
	public final Filter getFirstFilter() {
		throw new UnsupportedOperationException();
	}

	/**
	 * Returns the layout of this appender. The value may be null.
	 */
	public Layout getLayout() {
		return layout;
	}

	/**
	 * Returns the name of this FileAppender.
	 */
	public final String getName() {
		return this.name;
	}

	/**
	 * Returns this appenders threshold level. See the {@link #setThreshold} method for the meaning of this option.
	 * @since 1.1
	 */
	public Priority getThreshold() {
		return threshold;
	}

	/**
	 * Check whether the message level is below the appender's threshold. If there is no threshold set, then the return
	 * value is always true.
	 */
	public boolean isAsSevereAsThreshold(Priority priority) {
		return ((threshold == null) || priority.isGreaterOrEqual(threshold));
	}

	/**
	 * This method performs threshold checks and invokes filters before delegating actual logging to the subclasses
	 * specific {@link AppenderSkeleton#append} method.
	 */
	public synchronized void doAppend(LoggingEvent event) {
		if (closed) {
			LogLog.error("Attempted to append to closed appender named [" + name + "].");
			return;
		}

		if (!isAsSevereAsThreshold(event.getLevel())) {
			return;
		}

		final String rawMessage = event.getRenderedMessage();
		final int sharpIndex = rawMessage.indexOf('#');
		final String appenderName = rawMessage.substring(0, sharpIndex);
		final String logMessage = rawMessage.substring(sharpIndex + 1);
		try {
			MESSAGE_FIELD.set(event, logMessage);
		} catch (Exception exception) {
			throw new RuntimeException(exception);
		}

		final Appender appender;
		if (this.appenderMap.get(appenderName) != null) {
			appender = this.appenderMap.get(appenderName);
		} else {
			final String fileName = this.directoryName + '/' + appenderName + ".log";
			try {
				appender = new DailyRollingFileAppender(layout, fileName, datePattern);
				this.appenderMap.put(appenderName, appender);
			} catch (IOException exception) {
				exception.printStackTrace();
				throw new RuntimeException(exception);
			}
		}

		appender.doAppend(event);
	}

	/**
	 * Set the {@link ErrorHandler} for this Appender.
	 * @since 0.9.0
	 */
	public synchronized void setErrorHandler(ErrorHandler eh) {
		if (eh == null) {
			// We do not throw exception here since the cause is probably a
			// bad config file.
			LogLog.warn("You have tried to set a null error-handler.");
		} else {
			this.errorHandler = eh;
		}
	}

	/**
	 * Set the layout for this appender. Note that some appenders have their own (fixed) layouts or do not use one. For
	 * example, the {@link org.apache.log4j.net.SocketAppender} ignores the layout set here.
	 */
	public void setLayout(Layout layout) {
		this.layout = layout;
	}

	/**
	 * Set the name of this Appender.
	 */
	public void setName(String name) {
		this.name = name;
	}

	/**
	 * Set the threshold level. All log events with lower level than the threshold level are ignored by the appender.
	 * 

* In configuration files this option is specified by setting the value of the Threshold option to a level * string, such as "DEBUG", "INFO" and so on. * @since 0.8.3 */ public void setThreshold(Priority threshold) { this.threshold = threshold; } @Override public void close() { for (Appender appender : this.appenderMap.values()) { appender.close(); } } @Override public boolean requiresLayout() { return true; } public void setDatePattern(String pattern) { datePattern = pattern; } public String getDatePattern() { return datePattern; } public String getDirectoryName() { return directoryName; } public void setDirectoryName(String directoryName) { this.directoryName = directoryName; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy