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

java.util.logging.MemoryHandler Maven / Gradle / Ivy

package java.util.logging;

public class MemoryHandler extends Handler {

	// default maximum buffered number of LogRecord
	private static final int DEFAULT_SIZE = 1000;

	// target handler
	private Handler target;

	// buffer size
	private int size = DEFAULT_SIZE;

	// push level
	private Level push = Level.SEVERE;

	// LogManager instance for convenience
	private final LogManager manager = LogManager.getLogManager();

	// buffer
	private LogRecord[] buffer;

	// current position in buffer
	private int cursor;

	/**
	 * Default constructor, construct and init a {@code MemoryHandler} using
	 * {@code LogManager} properties or default values.
	 *
	 * @throws RuntimeException
	 *             if property value are invalid and no default value could be
	 *             used.
	 */
	public MemoryHandler() {
		String className = this.getClass().getName();
		// init target
		final String targetName = manager.getProperty(className + ".target");
		try {
			ClassLoader loader = Thread.currentThread().getContextClassLoader();
			if (loader == null) {
				loader = ClassLoader.getSystemClassLoader();
			}
			Class targetClass = loader.loadClass(targetName);
			target = (Handler) targetClass.newInstance();
		} catch (Exception e) {
			throw new RuntimeException("Cannot load target handler '" + targetName + "'");
		}
		// init size
		String sizeString = manager.getProperty(className + ".size");
		if (sizeString != null) {
			try {
				size = Integer.parseInt(sizeString);
				if (size <= 0) {
					size = DEFAULT_SIZE;
				}
			} catch (Exception e) {
				printInvalidPropMessage(className + ".size", sizeString, e);
			}
		}
		// init push level
		String pushName = manager.getProperty(className + ".push");
		if (pushName != null) {
			try {
				push = Level.parse(pushName);
			} catch (Exception e) {
				printInvalidPropMessage(className + ".push", pushName, e);
			}
		}
		// init other properties which are common for all Handler
		initProperties("ALL", null, "java.util.logging.SimpleFormatter", null);
		buffer = new LogRecord[size];
	}

	/**
	 * Construct and init a {@code MemoryHandler} using given target, size and
	 * push level, other properties using {@code LogManager} properties or
	 * default values.
	 *
	 * @param target
	 *            the given {@code Handler} to output
	 * @param size
	 *            the maximum number of buffered {@code LogRecord}, greater than
	 *            zero
	 * @param pushLevel
	 *            the push level
	 * @throws IllegalArgumentException
	 *             if {@code size <= 0}
	 * @throws RuntimeException
	 *             if property value are invalid and no default value could be
	 *             used.
	 */
	public MemoryHandler(Handler target, int size, Level pushLevel) {
		if (size <= 0) {
			throw new IllegalArgumentException("size <= 0");
		}
		target.getLevel();
		pushLevel.intValue();
		this.target = target;
		this.size = size;
		this.push = pushLevel;
		initProperties("ALL", null, "java.util.logging.SimpleFormatter", null);
		buffer = new LogRecord[size];
	}

	/**
	 * Close this handler and target handler, free all associated resources.
	 */
	@Override
	public void close() {
		manager.checkAccess();
		target.close();
		setLevel(Level.OFF);
	}

	/**
	 * Call target handler to flush any buffered output. Note that this doesn't
	 * cause this {@code MemoryHandler} to push.
	 */
	@Override
	public void flush() {
		target.flush();
	}

	/**
	 * Put a given {@code LogRecord} into internal buffer. If given record is
	 * not loggable, just return. Otherwise it is stored in the buffer.
	 * Furthermore if the record's level is not less than the push level, the
	 * push action is triggered to output all the buffered records to the target
	 * handler, and the target handler will publish them.
	 *
	 * @param record
	 *            the log record
	 */
	@Override public synchronized void publish(LogRecord record) {
		if (!isLoggable(record)) {
			return;
		}
		if (cursor >= size) {
			cursor = 0;
		}
		buffer[cursor++] = record;
		if (record.getLevel().intValue() >= push.intValue()) {
			push();
		}
	}

	/**
	 * Return the push level.
	 *
	 * @return the push level
	 */
	public Level getPushLevel() {
		return push;
	}

	/**
	 * Check if given {@code LogRecord} would be put into this
	 * {@code MemoryHandler}'s internal buffer.
	 * 

* The given {@code LogRecord} is loggable if and only if it has appropriate * level and it pass any associated filter's check. *

* Note that the push level is not used for this check. * * @param record * the given {@code LogRecord} * @return the given {@code LogRecord} if it should be logged, {@code false} * if {@code LogRecord} is {@code null}. */ @Override public boolean isLoggable(LogRecord record) { return super.isLoggable(record); } /** * Triggers a push action to output all buffered records to the target handler, * and the target handler will publish them. Then the buffer is cleared. */ public void push() { for (int i = cursor; i < size; i++) { if (buffer[i] != null) { target.publish(buffer[i]); } buffer[i] = null; } for (int i = 0; i < cursor; i++) { if (buffer[i] != null) { target.publish(buffer[i]); } buffer[i] = null; } cursor = 0; } /** * Set the push level. The push level is used to check the push action * triggering. When a new {@code LogRecord} is put into the internal * buffer and its level is not less than the push level, the push action * will be triggered. Note that set new push level won't trigger push action. * * @param newLevel * the new level to set. */ public void setPushLevel(Level newLevel) { manager.checkAccess(); newLevel.intValue(); this.push = newLevel; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy