/******************************************************************************* * Copyright (c) 2007 Vlad Dumitrescu and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Vlad Dumitrescu *******************************************************************************/ package org.erlide.util; import java.io.IOException; import java.io.PrintWriter; import java.io.StringWriter; import java.text.MessageFormat; import java.util.Date; import java.util.logging.ConsoleHandler; import java.util.logging.FileHandler; import java.util.logging.Formatter; import java.util.logging.Level; import java.util.logging.LogRecord; import java.util.logging.Logger; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.IPath; public class ErlLogger { private static final ErlSimpleFormatter SIMPLE_FORMATTER = new ErlSimpleFormatter(); private static final ErlLogger INSTANCE = new ErlLogger(); private Logger logger; private String logFile; private ConsoleHandler consoleHandler = null; private FileHandler fileHandler = null; public static ErlLogger getInstance() { return INSTANCE; } public void dispose() { logger = null; } public final void setLogFile(final String file) { logger.removeHandler(fileHandler); final IPath wroot = ResourcesPlugin.getWorkspace().getRoot().getLocation(); logFile = file == null ? wroot.append("erlide.log").toPortableString() : file; addFileHandler(logFile, SIMPLE_FORMATTER); } public String getLogFile() { return logFile; } public void log(final Level kind, final String fmt, final Object... o) { final String str = o.length == 0 ? fmt : String.format(fmt, o); final String msg = getCallerMsg(str); if (logger != null) { logger.log(kind, msg); if (logger.getHandlers().length == 0) { System.out.println(msg); } } } public void log(final Level kind, final Throwable exception) { final String str = exception.getMessage(); final String msg = getCallerMsg(str); if (logger != null) { logger.log(kind, msg, exception); if (logger.getHandlers().length == 0) { System.out.println(msg); } } } private String getCallerMsg(final String str) { final StackTraceElement el = getCaller(); final String msg = "(" + el.getFileName() + ":" + el.getLineNumber() + ") : " + str; return msg; } public void erlangLog(final String module, final int line, final String skind, final String fmt, final Object... o) { final Level kind = Level.parse(skind); final String str = o.length == 0 ? fmt : String.format(fmt, o); final String msg = "(" + module + ":" + line + ") : " + str; if (logger != null) { logger.log(kind, msg); if (logger.getHandlers().length == 0) { System.out.println(msg); } } } public static void trace(final String tag, final String fmt, final Object... o) { info("USAGE: " + tag + ": " + fmt, o); } public static void debug(final String fmt, final Object... o) { getInstance().log(Level.FINEST, fmt, o); } public static void info(final String fmt, final Object... o) { getInstance().log(Level.INFO, fmt, o); } public static void warn(final String fmt, final Object... o) { getInstance().log(Level.WARNING, fmt, o); } public static void error(final String fmt, final Object... o) { getInstance().log(Level.SEVERE, fmt, o); } public static void debug(final Throwable e) { getInstance().log(Level.FINEST, e); } public static void info(final Throwable e) { getInstance().log(Level.INFO, e); } public static void warn(final Throwable e) { getInstance().log(Level.WARNING, e); } public static void error(final Throwable exception) { getInstance().log(Level.SEVERE, exception); } private ErlLogger() { logger = Logger.getLogger("org.erlide"); logger.setUseParentHandlers(false); logger.setLevel(java.util.logging.Level.FINEST); addConsoleHandler(SIMPLE_FORMATTER); } private void addConsoleHandler(final ErlSimpleFormatter formatter) { consoleHandler = new ConsoleHandler(); consoleHandler.setFormatter(formatter); final Level lvl = "true".equals(System.getProperty("erlide.logger.console.debug")) ? java.util.logging.Level.FINEST : java.util.logging.Level.WARNING; consoleHandler.setLevel(lvl); logger.addHandler(consoleHandler); } private void addFileHandler(final String fileName, final ErlSimpleFormatter formatter) { try { fileHandler = new FileHandler(fileName); fileHandler.setFormatter(formatter); fileHandler.setLevel(java.util.logging.Level.FINEST); logger.addHandler(fileHandler); } catch (final SecurityException e) { ErlLogger.error(e); } catch (final IOException e) { ErlLogger.error(e); } } private static StackTraceElement getCaller() { final StackTraceElement[] st = new Throwable().getStackTrace(); StackTraceElement el = null; int i = 2; do { el = st[i++]; } while (el.getClassName().contains("Logger")); return el; } public static class ErlSimpleFormatter extends Formatter { Date dat = new Date(); private static final String FORMAT_STRING = "{0,time,HH:mm:ss,SSS}"; private MessageFormat formatter; private final Object[] args = new Object[1]; private final String lineSeparator = System.getProperty("line.separator"); @Override public synchronized String format(final LogRecord record) { final StringBuffer sb = new StringBuffer(); // Minimize memory allocations here. dat.setTime(record.getMillis()); args[0] = dat; final StringBuffer text = new StringBuffer(); if (formatter == null) { formatter = new MessageFormat(FORMAT_STRING); } formatter.format(args, text, null); sb.append(text); sb.append(' '); final String message = formatMessage(record); sb.append(record.getLevel().toString().charAt(0)); sb.append(": "); sb.append(message); sb.append(lineSeparator); if (record.getThrown() != null) { try (final StringWriter sw = new StringWriter(); final PrintWriter pw = new PrintWriter(sw)) { record.getThrown().printStackTrace(pw); sb.append(sw.toString()); } catch (final Exception ex) { // ignore } } return sb.toString(); } } }