/*
* RapidMiner
*
* Copyright (C) 2001-2011 by Rapid-I and the contributors
*
* Complete list of developers available at our web site:
*
* http://rapid-i.com
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see http://www.gnu.org/licenses/.
*/
package com.rapidminer.tools;
import java.io.OutputStream;
import java.util.logging.ConsoleHandler;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.rapidminer.RapidMiner;
import com.rapidminer.gui.tools.LeanFormatter;
/**
* <p>Utility class providing static methods for logging.<br>
* Parameters read from the XML process configuration file:</p>
* <ul>
* <li>logfile (filename or "stdout" or "stderr")</li>
* <li>logverbosity (possible values are in
* {@link LogService#LOG_VERBOSITY_NAMES}</li>
* </ul>
*
* <p>Beside the <b>local</b> log service associated with a concrete process and which will
* be automatically initialized during the setup phase, one <b>global</b> log service exist
* which is used for generic log messages not bound to the operators used in a process.
* This global log service is usually initialized to log messages on system out (at least during the
* basic initialization phase of RapidMiner). After the basic intialization phase,
* the global messages will be presented in the message viewer (if the RapidMiner GUI
* is used) or still printed to system out or in any other stream defined via the
* method {@link #initGlobalLogging(OutputStream, int)}. Alternatively, one could also define an
* environment variable named {@link RapidMiner#PROPERTY_RAPIDMINER_GLOBAL_LOG_FILE}.</p>
*
* <p>Usually, operators should only use the log verbosities MINIMUM for messages
* with a low priority and STATUS for normal information messages. In rare cases, the
* verbosity level NOTE could be used for operators stating some message more
* important then STATUS (hence the user should see the message for the default
* log verbosity level of INIT) but not as important then WARNING. The verbosity
* levels WARNING, EXCEPTION, and ERROR should be used in error cases. All other
* log verbosity levels should only be used by internal RapidMiner classes and not by
* user written operators.</p>
*
* <p>We recommend to set the parameter for the log verbosity level to INIT for the
* process design phase (eventually STATUS for debugging) and to the log verbosity
* level WARNING in the production phase. This way it is ensured that not too many logging
* messages are produced in the production phase.</p>
*
* <p>Log messages can be formatted by using the following macros:</p>
* <ul>
* <li>"$b" and "^b" start and end bold mode respectively</li>
* <li>"$i" and "^i" start and end italic mode respectively</li>
* <li>"$m" and "^m" start and end monospace mode respectively</li>
* <li>"$n" and "^n" start and end note color mode respectively</li>
* <li>"$w" and "^w" start and end warning color mode respectively</li>
* <li>"$e" and "^e" start and end error color mode respectively</li>
* </ul>
*
* @author Ingo Mierswa
*/
public class LogService extends WrapperLoggingHandler {
// -------------------- Verbosity Level --------------------
/** Indicates an unknown verbosity level. */
public static final int UNKNOWN_LEVEL = -1;
/**
* Indicates the lowest log verbosity. Should only be used for very detailed
* but not necessary logging.
*/
public static final int MINIMUM = 0;
/**
* Indicates log messages concerning in- and output. Should only be used by
* the class Operator itself and not by its subclasses.
*/
public static final int IO = 1;
/** The default log verbosity for all logging purposes of operators. */
public static final int STATUS = 2;
/**
* Only the most important logging messaged should use this log verbosity.
* Currently used only by the LogService itself.
*/
public static final int INIT = 3;
/** Use this log verbosity for logging of important notes, i.e. things less important than warnings
* but important enough to see for all not interested in the detailed status messages. */
public static final int NOTE = 4;
/** Use this log verbosity for logging of warnings. */
public static final int WARNING = 5;
/** Use this log verbosity for logging of errors. */
public static final int ERROR = 6;
/**
* Use this log verbosity for logging of fatal errors which will stop
* process running somewhere in the future.
*/
public static final int FATAL = 7;
/**
* Normally this log verbosity should not be used by operators. Messages
* with this verbosity will always be displayed.
*/
public static final int MAXIMUM = 8;
/** For switching off logging during testing. */
public static final int OFF = 9;
public static final String LOG_VERBOSITY_NAMES[] = { "all", "io", "status", "init", "notes", "warning", "error", "fatal", "almost_none", "off" };
/** The prefix used to indicate the global logger. */
public static final String GLOBAL_PREFIX = "$gG^g";
private static final Logger GLOBAL_LOGGER = Logger.getLogger("com.rapidminer");
private static final LogService GLOBAL_LOGGING = new LogService(GLOBAL_LOGGER);
// ------ methods for init -------
private LogService(Logger logger) {
super(logger);
// we install the default logging properties only if not overridden by the user at startup
if ((System.getProperty("java.util.logging.config.file") != null) &&
(System.getProperty("java.util.logging.config.class") != null)) {
getRoot().setLevel(Level.CONFIG);
for (Handler handler : Logger.getLogger("").getHandlers()) {
handler.setLevel(Level.CONFIG);
if (handler instanceof ConsoleHandler) {
handler.setFormatter(new LeanFormatter());
}
}
}
}
/** Returns the global logging. If no logging was otherwise create, this
* method creates the default standard out log service if no log file
* was defined in the property {@link RapidMiner#PROPERTY_RAPIDMINER_GLOBAL_LOG_FILE}.
* Alternatively, developers can invoke the method {@link #initGlobalLogging(OutputStream, int)}. */
public static LogService getGlobal() {
return GLOBAL_LOGGING;
}
public static Logger getRoot() {
return GLOBAL_LOGGER;
}
// private void addConsole(Level level) {
// StreamHandler handler = new ConsoleHandler();
// handler.setLevel(Level.ALL);
// getRoot().setLevel(level);
// getRoot().addHandler(handler);
// }
public void setVerbosityLevel(int level) {
getRoot().setLevel(LEVELS[level]);
}
/**
* @deprecated Use {@link Logger#isLoggable(Level)}
*/
@Deprecated
public boolean isSufficientLogVerbosity(int level) {
return GLOBAL_LOGGER.isLoggable(LEVELS[level]);
}
// -------------------- Methoden zum Protokollieren --------------------
/**
* Writes the message to the output stream if the verbosity level is high
* enough.
*
* @deprecated please do not use this log method any longer, use the method {@link #log(String, int)} instead
*/
@Deprecated
public static void logMessage(String message, int verbosityLevel) {
getGlobal().log(message, verbosityLevel);
}
}