/* * This file is part of ELKI: * Environment for Developing KDD-Applications Supported by Index-Structures * * Copyright (C) 2017 * ELKI Development Team * * 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 de.lmu.ifi.dbs.elki.logging; import java.util.logging.Level; import java.util.logging.LogRecord; import java.util.logging.Logger; /** * This final class contains some static convenience methods for logging. * * {@link #logExpensive} allows the programmer to easily emit a log message, * however the function is rather expensive and thus should not be used within * loop constructs. * * @author Erich Schubert * @since 0.2 * * @apiviz.uses ELKILogRecord oneway - - «create» */ public final class LoggingUtil { /** * Private constructor. Static methods only. */ private LoggingUtil() { // Do not use. } /** * Expensive logging function that is convenient, but should only be used in * rare conditions. * * For 'frequent' logging, use more efficient techniques, such as explained in * the {@link de.lmu.ifi.dbs.elki.logging logging package documentation}. * * @param level Logging level * @param message Message to log. * @param e Exception to report. */ public static final void logExpensive(Level level, String message, Throwable e) { String[] caller = inferCaller(); if(caller != null) { Logger logger = Logger.getLogger(caller[0]); logger.logp(level, caller[0], caller[1], message, e); } else { Logger.getAnonymousLogger().log(level, message, e); } } /** * Expensive logging function that is convenient, but should only be used in * rare conditions. * * For 'frequent' logging, use more efficient techniques, such as explained in * the {@link de.lmu.ifi.dbs.elki.logging logging package documentation}. * * @param level Logging level * @param message Message to log. */ public static final void logExpensive(Level level, String message) { LogRecord rec = new ELKILogRecord(level, message); String[] caller = inferCaller(); if(caller != null) { rec.setSourceClassName(caller[0]); rec.setSourceMethodName(caller[1]); Logger logger = Logger.getLogger(caller[0]); logger.log(rec); } else { Logger.getAnonymousLogger().log(rec); } } /** * Static version to log a severe exception. * * @param e Exception to log */ public static final void exception(Throwable e) { logExpensive(Level.SEVERE, e.getMessage(), e); } /** * Static version to log a severe exception. * * @param message Exception message, may be null (defaults to e.getMessage()) * @param e causing exception */ public static final void exception(String message, Throwable e) { if(message == null && e != null) { message = e.getMessage(); } logExpensive(Level.SEVERE, message, e); } /** * Static version to log a warning message. * * @param message Warning message. */ public static final void warning(String message) { logExpensive(Level.WARNING, message); } /** * Static version to log a warning message. * * @param message Warning message, may be null (defaults to e.getMessage()) * @param e causing exception */ public static final void warning(String message, Throwable e) { if(message == null && e != null) { message = e.getMessage(); } logExpensive(Level.WARNING, message, e); } /** * Static version to log a 'info' message. * * @param message Warning message. */ public static final void message(String message) { logExpensive(Level.INFO, message); } /** * Static version to log a 'info' message. * * @param message Warning message, may be null (defaults to e.getMessage()) * @param e causing exception */ public static final void message(String message, Throwable e) { if(message == null && e != null) { message = e.getMessage(); } logExpensive(Level.INFO, message, e); } /** * Infer which class has called the logging helper. * * While this looks like duplicated code from ELKILogRecord, it is needed here * to find an appropriate Logger (and check the logging level) for the calling * class, not just to log the right class and method name. * * @return calling class name and calling method name */ private static final String[] inferCaller() { StackTraceElement[] stack = (new Throwable()).getStackTrace(); int ix = 0; while(ix < stack.length) { StackTraceElement frame = stack[ix]; if(!frame.getClassName().equals(LoggingUtil.class.getCanonicalName())) { return new String[] { frame.getClassName(), frame.getMethodName() }; } ix++; } return null; } }