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

de.carne.boot.logging.ProxyHandler Maven / Gradle / Ivy

/*
 * Copyright (c) 2018-2019 Holger de Carne and contributors, All Rights Reserved.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see .
 */
package de.carne.boot.logging;

import java.util.logging.ErrorManager;
import java.util.logging.Formatter;
import java.util.logging.Handler;
import java.util.logging.LogManager;
import java.util.logging.LogRecord;

import org.eclipse.jdt.annotation.Nullable;

import de.carne.boot.logging.proxy.AutoProxy;
import de.carne.boot.logging.proxy.Log4j2Proxy;
import de.carne.boot.logging.proxy.Proxy;
import de.carne.boot.logging.proxy.Slf4jProxy;

/**
 * A {@linkplain Handler} implementation used to forward log records to a 3rd party logging framework.
 */
public class ProxyHandler extends Handler {

	/**
	 * The type of logging framework to forward leg records to.
	 */
	private enum Type {

		/**
		 * Auto detect which of the supported logging frameworks is available.
		 */
		AUTO(AutoProxy.class),

		/**
		 * Log4j 2 (https://logging.apache.org/log4j/2.x/).
		 */
		LOG4J2(Log4j2Proxy.class),

		/**
		 * SLF4J (https://www.slf4j.org).
		 */
		SLF4J(Slf4jProxy.class);

		private final Class proxyClass;

		private Type(Class proxyClass) {
			this.proxyClass = proxyClass;
		}

		/**
		 * Gets the {@linkplain Proxy} implementation to use for this type.
		 *
		 * @return the {@linkplain Proxy} implementation to use for this type.
		 */
		public Class proxyClass() {
			return this.proxyClass;
		}

	}

	private static final Formatter DEFAULT_FORMATTER = new Formatter() {

		@Override
		public String format(@Nullable LogRecord record) {
			return formatMessage(record);
		}

	};

	private final Proxy proxy;

	/**
	 * Constructs {@linkplain ProxyHandler}.
	 */
	public ProxyHandler() {
		LogManager manager = LogManager.getLogManager();
		String propertyBase = getClass().getName();
		Type type = getTypeProperty(manager, propertyBase + ".type", Type.AUTO);

		this.proxy = getProxyInstance(type.proxyClass());
	}

	@Override
	public void publish(@Nullable LogRecord record) {
		if (record != null) {
			Formatter formatter = getFormatter();

			this.proxy.publish(record, (formatter != null ? formatter : DEFAULT_FORMATTER));
		}
	}

	@Override
	public void flush() {
		// Nothing to do here
	}

	@Override
	public void close() {
		// Nothing to do here
	}

	private static Type getTypeProperty(LogManager manager, String name, Type defaultValue) {
		String typeName = Logs.getStringProperty(manager, name, defaultValue.name());
		Type type = defaultValue;

		try {
			type = Type.valueOf(typeName);
		} catch (IllegalArgumentException e) {
			Logs.DEFAULT_ERROR_MANAGER.error("Invalid type property " + name, e, ErrorManager.GENERIC_FAILURE);
		}
		return type;
	}

	private static Proxy getProxyInstance(Class proxyClass) {
		Proxy proxy;

		try {
			proxy = proxyClass.getConstructor().newInstance();
		} catch (ReflectiveOperationException e) {
			Logs.DEFAULT_ERROR_MANAGER.error("Failed to instanticate proxy class " + proxyClass.getName(), e,
					ErrorManager.GENERIC_FAILURE);
			proxy = new AutoProxy();
		}
		return proxy;
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy