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

tuwien.auto.calimero.log.LogService Maven / Gradle / Ivy

There is a newer version: 2.6-rc1
Show newest version
/*
    Calimero 2 - A library for KNX network access
    Copyright (c) 2006, 2014 B. Malinowsky

    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 2 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, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

    Linking this library statically or dynamically with other modules is
    making a combined work based on this library. Thus, the terms and
    conditions of the GNU General Public License cover the whole
    combination.

    As a special exception, the copyright holders of this library give you
    permission to link this library with independent modules to produce an
    executable, regardless of the license terms of these independent
    modules, and to copy and distribute the resulting executable under terms
    of your choice, provided that you also meet, for each linked independent
    module, the terms and conditions of the license of that module. An
    independent module is a module which is not derived from or based on
    this library. If you modify this library, you may extend this exception
    to your version of the library, but you are not obligated to do so. If
    you do not wish to do so, delete this exception statement from your
    version.
*/

package tuwien.auto.calimero.log;

import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Vector;

/**
 * A LogService is used to categorize logging information with regard to logging level and
 * topic, and offer it to its {@link LogWriter}s.
 * 

* The default log level by the LogService is {@link LogLevel#ALL}. This means all log * information levels (except {@link LogLevel#OFF}) will be offered. *

* A LogWriter can register at a log service to receive information the log service is * offering to its writers. *

* Use {@link LogManager} to create new or get existing log services.
* Usage:
* - A log service may be created for different parts of the Calimero library, therefore, * it distinguishes log information by source.
* - A log service may be created for a particular subject, i.e., to divide information * into topics.
* A log service may restrict offered information through its own log level.
* - ... * * @author B. Malinowsky * @see LogLevel * @see LogWriter */ public class LogService { // Interruption policy: drain log event queue and quit private static final class Dispatcher extends Thread { private static final class LogData { final List wr; final String svc; final LogLevel lvl; final String msg; final Throwable trow; final Thread thread; LogData(final List writers, final String service, final LogLevel level, final String message, final Throwable t, final Thread thr) { wr = writers; svc = service; lvl = level; msg = message; trow = t; thread = thr; } } private final List data = new LinkedList(); private volatile boolean quit; Dispatcher() { super("Log dispatcher"); setDaemon(true); start(); } public void run() { try { while (true) { final LogData d; synchronized (data) { while (data.isEmpty()) data.wait(); d = (LogData) data.remove(0); } dispatch(d); } } catch (final InterruptedException ie) { quit = true; } // empty log data list synchronized (data) { while (!data.isEmpty()) dispatch((LogData) data.remove(0)); } } void add(final List writers, final String service, final LogLevel level, final String msg, final Throwable t) { if (!quit) { synchronized (data) { data.add(new LogData(writers, service, level, msg, t, Thread.currentThread())); data.notify(); } } } private void dispatch(final LogData d) { final boolean dev = false; //Settings.getLibraryMode() == Settings.DEV_MODE; final String svc = dev ? ("[" + d.thread.getName() + "] " + d.svc) : d.svc; synchronized (d.wr) { for (final Iterator i = d.wr.iterator(); i.hasNext();) ((LogWriter) i.next()).write(svc, d.lvl, d.msg, d.trow); } } } private static final Dispatcher logger = new Dispatcher(); /** Name of this log service. */ protected final String name; private LogLevel logLevel = LogLevel.ALL; private List writers = new Vector(); /** * Creates a new log service with the specified name. *

* * @param name name of log service */ protected LogService(final String name) { this.name = name; } /** * Creates a new log service with the specified name and log * level. *

* * @param name name of log service * @param level log level for this log service */ protected LogService(final String name, final LogLevel level) { this.name = name; setLogLevel(level); } /** * Returns the name of this log service. *

* * @return the log service name */ public String getName() { return name; } /** * Sets a new log level for this log service. *

* All log information will be checked against and restricted to at most this level.
* Log information not allowed will be ignored. *

* For example: set log level to {@link LogLevel#WARN} to allow log info with * {@link LogLevel#FATAL}, {@link LogLevel#ERROR} and {@link LogLevel#WARN}. * * @param level new log level */ public void setLogLevel(final LogLevel level) { logLevel = level; } /** * Returns the currently set log level of this log service. *

* * @return the log {@link LogLevel} */ public LogLevel getLogLevel() { return logLevel; } /** * Checks whether output with a specified level will be logged by this log service. *

* The level parameter is checked against the currently set log level of * this log service. Only output with a log level specified equal or below the level * of this service is logged, i.e., output of the same or less verbosity.
* Output with assigned log level {@link LogLevel#OFF} is never logged. * * @param level the log level to check for * @return true if output of that level is loggable, false * otherwise */ public final boolean isLoggable(final LogLevel level) { return !level.higher(logLevel) && level != LogLevel.OFF; } /** * Adds the writer to this log service. *

* No check is made to detect (or prevent) duplicate writers. * * @param writer LogWriter to add */ public void addWriter(final LogWriter writer) { writers.add(writer); } /** * Removes writer from this log service. *

* No check is made to detect and remove duplicate writers. * * @param writer LogWriter to remove */ public void removeWriter(final LogWriter writer) { writers.remove(writer); } /** * Removes all registered log writer from this log service. *

* * @param close should the writers be closed before removal */ public void removeAllWriters(final boolean close) { if (close) synchronized (writers) { for (final Iterator i = writers.iterator(); i.hasNext();) ((LogWriter) i.next()).close(); } writers = new Vector(); } /** * Offers msg with log level {@link LogLevel#TRACE}. *

* * @param msg log information */ public void trace(final String msg) { log(LogLevel.TRACE, msg, null); } /** * Offers msg with log level {@link LogLevel#INFO}. *

* * @param msg log information */ public void info(final String msg) { log(LogLevel.INFO, msg, null); } /** * Offers msg with log level {@link LogLevel#WARN}. *

* * @param msg log information */ public void warn(final String msg) { log(LogLevel.WARN, msg, null); } /** * Offers msg and the throwable object with log level * {@link LogLevel#WARN}. *

* * @param msg log information * @param t throwable object */ public void warn(final String msg, final Throwable t) { log(LogLevel.WARN, msg, t); } /** * Offers msg with log level {@link LogLevel#ERROR}. *

* * @param msg log information */ public void error(final String msg) { log(LogLevel.ERROR, msg, null); } /** * Offers msg and the throwable object with log level * {@link LogLevel#ERROR}. *

* * @param msg log information * @param t throwable object */ public void error(final String msg, final Throwable t) { log(LogLevel.ERROR, msg, t); } /** * Offers msg with log level {@link LogLevel#FATAL}. *

* * @param msg log information */ public void fatal(final String msg) { log(LogLevel.FATAL, msg, null); } /** * Offers msg and the throwable object with log level * {@link LogLevel#FATAL}. *

* * @param msg log information * @param t throwable object */ public void fatal(final String msg, final Throwable t) { log(LogLevel.FATAL, msg, t); } /** * Offers msg and the throwable object with log * level. *

* * @param level log level for this message and throwable * @param msg log information * @param t throwable object, can be null */ public void log(final LogLevel level, final String msg, final Throwable t) { if (level != LogLevel.OFF && level.level <= logLevel.level) logger.add(writers, name, level, msg, t); } /* (non-Javadoc) * @see java.lang.Object#toString() */ public String toString() { return name + ", log level " + logLevel + ", " + writers.size() + " log writers"; } static final void stopDispatcher() { logger.interrupt(); while (logger.isAlive()) try { logger.join(); } catch (final InterruptedException ignore) {} } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy