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

org.openrdf.util.log.ThreadLog Maven / Gradle / Ivy

The newest version!
/*  Sesame - Storage and Querying architecture for RDF and RDF Schema
 *  Copyright (C) 2001-2006 Aduna
 *
 *  Contact: 
 *  	Aduna
 *  	Prinses Julianaplein 14 b
 *  	3817 CS Amersfoort
 *  	The Netherlands
 *  	tel. +33 (0)33 465 99 87
 *  	fax. +33 (0)33 465 99 87
 *
 *  	http://aduna-software.com/
 *  	http://www.openrdf.org/
 *  
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2.1 of the License, or (at your option) any later version.
 *
 *  This library 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
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

package org.openrdf.util.log;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;

/**
 * Thread-based logging utility. The ThreadLog requires threads to register
 * themselves with the ThreadLog. In this registration procedure, a mapping
 * is made between the thread calling the registration method and an instance
 * of ThreadLog. This mapping is later used in all calls to logging-methods
 * to look-up whether these messages should be logged, and where they should
 * be logged.
 * 

* Log messages are assigned a "level of importance". From high to low, these * levels are ERROR, WARNING, STATUS and TRACE. Messages can be suppressed * based on these levels. If a Thread registers itself with log level WARNING, * only errors and warning will be logged; status messages and traces will be * suppressed. */ public class ThreadLog { /*------------------------------------------------+ | Constants | +------------------------------------------------*/ public static final int NONE = 0; public static final int ERROR = 1; public static final int WARNING = 2; public static final int STATUS = 3; public static final int TRACE = 4; public static final int ALL = 5; /*------------------------------------------------+ | Static variables | +------------------------------------------------*/ static SimpleDateFormat _formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS"); static String[] _levelNames = { "NONE ", "ERROR ", "WARNING", "STATUS ", "TRACE ", "ALL " }; /** Keeps track of which Threads maps to which ThreadLogs. **/ static InheritableThreadLocal _threadContext = new InheritableThreadLocal(); static ThreadLog _defaultThreadLog; /** Maps (absolute) file paths to PrintWriters. **/ static HashMap _writerTable = new HashMap(); /*------------------------------------------------+ | Static methods | +------------------------------------------------*/ /** * Sets a default log file for all threads that have not registered * themselves. Logging calls from any of these threads to ThreadLog * will be logged to the specified log file if their priority is equal * to or higher then the specified log level. If 'logFile' is equal * to 'null', messages will be printed to System.err. * @param logFile The file to log to, or null to log messages * to System.err. * @param logLevel One of the constants ERROR, WARNING, STATUS, TRACE, or ALL. * @see #ERROR * @see #WARNING * @see #STATUS * @see #TRACE * @see #ALL **/ public static void setDefaultLog(String logFile, int logLevel) { if (_defaultThreadLog == null) { _defaultThreadLog = new ThreadLog(); } Writer logWriter = null; try { logWriter = _getLogWriter(logFile); } catch (IOException e) { System.err.println(e.getMessage()); e.printStackTrace(); try { logWriter = _getLogWriter(null); } catch (IOException ignore) { // ignore } } _defaultThreadLog.setLogWriter(logWriter); _defaultThreadLog.setLogLev(logLevel); } /** * Unsets the default log file for all threads that have not * registered themselves. **/ public static void unsetDefaultLog() { _defaultThreadLog = null; } /** * Registers the calling thread with the ThreadLog. Logging calls to * ThreadLog will be logged to the specified log file if their priority is * equal to or higher then the specified log level. If 'logFile' is equal * to 'null', messages will be printed to System.err. * @param logFile The file to log to, or null to log messages * to System.err. * @param logLevel One of the constants ERROR, WARNING, STATUS, TRACE, or ALL. * @see #ERROR * @see #WARNING * @see #STATUS * @see #TRACE * @see #ALL **/ public static void registerThread(String logFile, int logLevel) { ThreadLog threadLog = _createThreadLog(); Writer logWriter = null; try { logWriter = _getLogWriter(logFile); } catch (IOException e) { System.err.println(e.getMessage()); e.printStackTrace(); try { logWriter = _getLogWriter(null); } catch (IOException ignore) { // ignore } } threadLog.setLogWriter(logWriter); threadLog.setLogLev(logLevel); Thread currentThread = Thread.currentThread(); threadLog.setThreadName(currentThread.getName()); } /** * Changes the log level for the calling thread. * @param logLevel One of the constants ERROR, WARNING, STATUS, TRACE, or ALL. * @see #ERROR * @see #WARNING * @see #STATUS * @see #TRACE **/ public static void setLogLevel(int logLevel) { ThreadLog threadLog = null; synchronized (_threadContext) { threadLog = (ThreadLog)_threadContext.get(); } if (threadLog != null) { threadLog.setLogLev(logLevel); } } /** * Creates a ThreadLog for the thread calling this method. If the * thread has already created a ThreadLog before, this existing * ThreadLog will be returned. **/ static ThreadLog _createThreadLog() { ThreadLog threadLog = null; synchronized (_threadContext) { threadLog = (ThreadLog)_threadContext.get(); if (threadLog == null) { threadLog = new ThreadLog(); _threadContext.set(threadLog); } } return threadLog; } /** * Gets a (possibly shared) Writer to the specified logFile. **/ static Writer _getLogWriter(String logFile) throws IOException { Writer logWriter = null; String absPath = null; File file = null; if (logFile != null) { file = new File(logFile); absPath = file.getAbsolutePath(); } synchronized (_writerTable) { logWriter = (Writer)_writerTable.get(absPath); if (logWriter == null) { // Create a new log writer if (absPath != null) { // Check if parent directory exists yet if (!file.getParentFile().exists()) { file.getParentFile().mkdirs(); } logWriter = new FileWriter(absPath, true); } else { logWriter = new OutputStreamWriter(System.err); } _writerTable.put(absPath, logWriter); } } return logWriter; } /** * Deregisters the calling thread with the ThreadLog. Logging calls to * ThreadLog on the calling thread will no longer be logged. **/ public static void deregisterThread() { synchronized (_threadContext) { _threadContext.set(null); } } /** * Gets the ThreadLog for the thread calling this method. If no * ThreadLog is available, null will be returned. **/ static ThreadLog _getThreadLog() { ThreadLog threadLog = null; synchronized (_threadContext) { threadLog = (ThreadLog)_threadContext.get(); } if (threadLog == null) { threadLog = _defaultThreadLog; } return threadLog; } /*------------------------------------------------+ | Variables | +------------------------------------------------*/ /** Writer for the log file. **/ Writer _logWriter; /** Log level **/ int _logLevel; /** * Name of the thread. **/ String _threadName; /*------------------------------------------------+ | Constructors | +------------------------------------------------*/ ThreadLog() { this(null, ALL); } ThreadLog(Writer logWriter) { this(logWriter, ALL); } ThreadLog(Writer logWriter, int logLevel) { setLogWriter(logWriter); setLogLev(logLevel); _threadName = null; } /*------------------------------------------------+ | Methods | +------------------------------------------------*/ void setLogWriter(Writer logWriter) { _logWriter = logWriter; } void setLogLev(int logLevel) { _logLevel = logLevel; } int getLogLevel() { return _logLevel; } void setThreadName(String threadName) { _threadName = threadName; } String getThreadName() { return _threadName; } void doLog(String msg, Object arg, int level) { // First check log level if (_logLevel < level) { return; } // Create log message String logMsg = _createLogMessage(msg, arg, level, _threadName); // Write log message // Synchronize on _logWriter to prevent mixed lines try { synchronized(_logWriter) { _logWriter.write(logMsg); _logWriter.flush(); } } catch(Exception e) { e.printStackTrace(); } } static String _createLogMessage( String msg, Object arg, int level, String threadName) { StringBuffer logMsg = new StringBuffer(128); logMsg.append(_formatter.format(new Date())); if (threadName != null) { logMsg.append(" ["); logMsg.append(threadName); logMsg.append("]"); } logMsg.append(" ["); logMsg.append(_levelNames[level]); logMsg.append("] "); logMsg.append(msg); if (arg != null) { logMsg.append(": "); if (arg instanceof Throwable) { Throwable throwable = (Throwable)arg; logMsg.append(throwable.getMessage()); logMsg.append("\n"); java.io.StringWriter stackTrace = new java.io.StringWriter(); java.io.PrintWriter pw = new java.io.PrintWriter(stackTrace); throwable.printStackTrace(pw); logMsg.append(stackTrace.toString()); } else { logMsg.append(arg); } } logMsg.append("\n"); return logMsg.toString(); } /*------------------------------------------------+ | Static utility methods | +------------------------------------------------*/ /** * Logs an error. * @param msg A indicative message for the error. **/ public static void error(String msg) { _log(msg, null, ERROR); } /** * Logs an error. * @param msg A indicative message for the error. * @param arg An argument related to the error. In case arg is an * instance of java.lang.Throwable, the message and stack trace * of the argument will be logged. **/ public static void error(String msg, Object arg) { _log(msg, arg, ERROR); } /** * Logs a warning. * @param msg A indicative message for the warning. **/ public static void warning(String msg) { _log(msg, null, WARNING); } /** * Logs a warning. * @param msg A indicative message for the warning. * @param arg An argument related to the warning. In case arg is an * instance of java.lang.Throwable, the message and stack trace * of the argument will be logged. **/ public static void warning(String msg, Object arg) { _log(msg, arg, WARNING); } /** * Logs a message. * @param msg A indicative message for the message. **/ public static void log(String msg) { _log(msg, null, STATUS); } /** * Logs a message. * @param msg A indicative message for the message. * @param arg An argument related to the message. In case arg is an * instance of java.lang.Throwable, the message and stack trace * of the argument will be logged. **/ public static void log(String msg, Object arg) { _log(msg, arg, STATUS); } /** * Logs a trace message. * @param msg A indicative message for the trace message. **/ public static void trace(String msg) { _log(msg, null, TRACE); } /** * Logs a trace message. * @param msg A indicative message for the trace message. * @param arg An argument related to the trace message. In case arg is an * instance of java.lang.Throwable, the message and stack trace * of the argument will be logged. **/ public static void trace(String msg, Object arg) { _log(msg, arg, TRACE); } /** * Logs a message on the specified level. * @param msg A indicative message for the trace message. * @param arg An argument related to the trace message. In case arg is an * instance of java.lang.Throwable, the message and stack trace * of the argument will be logged. * @param level One of the constants ERROR, WARNING, STATUS, TRACE, or ALL. * @see #ERROR * @see #WARNING * @see #STATUS * @see #TRACE * @see #ALL **/ protected static void _log(String msg, Object arg, int level) { ThreadLog threadLog = _getThreadLog(); if (threadLog != null) { threadLog.doLog(msg, arg, level); } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy