/* * Copyright (C) 2004-2008 Jive Software. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jivesoftware.util; import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.PrintWriter; import java.io.StringWriter; import java.util.ArrayList; import java.util.List; import java.util.Map; /** * Openfire makes use of a logging facade (slf4j) to manage its log output. The * facade is backed up by Log4j by default. This class provides utility methods. * <p> * Additionally, this class provides methods that can be used to record logging * statements. These methods are exact duplicates of the previous Log * implementation of Openfire and are kept for backwards-compatibility (the are * deprecated). These methods will delegate logging functionality to slf4j. * Instead of these methods, slf4j logging functionality should be used * directly. * * @author Guus der Kinderen, guus.der.kinderen@gmail.com * @see <a href="http://www.slf4j.org/">http://www.slf4j.org/</a> */ public class Log { private static final org.slf4j.Logger Logger = org.slf4j.LoggerFactory.getLogger(Log.class); public static final String LOG_DEBUG_ENABLED = "log.debug.enabled"; // listen for changes to the log.debug.enabled property static { PropertyEventDispatcher.addListener(new PropertyEventListener() { @Override public void propertySet(String property, Map<String, Object> params) { enableDebugLog(property, Boolean.parseBoolean(params.get("value").toString())); } @Override public void propertyDeleted(String property, Map<String, Object> params) { enableDebugLog(property, false); } // ignore these events @Override public void xmlPropertySet(String property, Map<String, Object> params) { } @Override public void xmlPropertyDeleted(String property, Map<String, Object> params) { } private void enableDebugLog(String property, boolean enabled) { if ((LOG_DEBUG_ENABLED).equals(property)) { Log.setDebugEnabled(enabled); } } }); } /** * @deprecated replaced by {@link org.slf4j.Logger#isErrorEnabled()}. * Functionality of this method is delegated there. */ @Deprecated public static boolean isErrorEnabled() { return Logger.isErrorEnabled(); } /** * @deprecated replaced by {@link org.slf4j.Logger#isDebugEnabled()}. * Functionality of this method is delegated there. */ @Deprecated public static boolean isDebugEnabled() { return Logger.isDebugEnabled(); } public static void setDebugEnabled(boolean enabled) { // SLF4J doesn't provide a hook into the logging implementation. We'll have to do this 'direct', bypassing slf4j. final org.apache.log4j.Level newLevel; if (enabled) { newLevel = org.apache.log4j.Level.ALL; } else { newLevel = org.apache.log4j.Level.INFO; } org.apache.log4j.LogManager.getRootLogger().setLevel(newLevel); } /** * @deprecated replaced by {@link org.slf4j.Logger#isInfoEnabled()}. * Functionality of this method is delegated there. */ @Deprecated public static boolean isInfoEnabled() { return Logger.isInfoEnabled(); } /** * @deprecated replaced by {@link org.slf4j.Logger#isWarnEnabled()}. * Functionality of this method is delegated there. */ @Deprecated public static boolean isWarnEnabled() { return Logger.isWarnEnabled(); } /** * @deprecated replaced by {@link org.slf4j.Logger#debug(String)}. * Functionality of this method is delegated there. */ @Deprecated public static void debug(String s) { if (isDebugEnabled()) { Logger.debug(s); } } /** * @deprecated replaced by {@link org.slf4j.Logger#debug(String, Throwable)}. * Functionality of this method is delegated there. */ @Deprecated public static void debug(Throwable throwable) { if (isDebugEnabled()) { Logger.debug("", throwable); } } /** * @deprecated replaced by {@link org.slf4j.Logger#debug(String, Throwable)}. * Functionality of this method is delegated there. */ @Deprecated public static void debug(String s, Throwable throwable) { if (isDebugEnabled()) { Logger.debug(s, throwable); } } public static void markDebugLogFile(String username) { String message = getMarkMessage(username); debug(message); } public static void rotateDebugLogFile() { // SLF4J doesn't provide a hook into the logging implementation. We'll have to do this 'direct', bypassing slf4j. File logFile = new File(Log.getLogDirectory(), "debug.log"); emptyFile(logFile); } /** * @deprecated replaced by {@link org.slf4j.Logger#info(String)}. * Functionality of this method is delegated there. */ @Deprecated public static void info(String s) { if (isInfoEnabled()) { Logger.info(s); } } /** * @deprecated replaced by {@link org.slf4j.Logger#info(String, Throwable)}. * Functionality of this method is delegated there. */ @Deprecated public static void info(Throwable throwable) { if (isInfoEnabled()) { Logger.info("", throwable); } } /** * @deprecated replaced by {@link org.slf4j.Logger#info(String, Throwable)}. * Functionality of this method is delegated there. */ @Deprecated public static void info(String s, Throwable throwable) { if (isInfoEnabled()) { Logger.info(s, throwable); } } public static void markInfoLogFile(String username) { String message = getMarkMessage(username); info(message); } public static void rotateInfoLogFile() { // SLF4J doesn't provide a hook into the logging implementation. We'll have to do this 'direct', bypassing slf4j. File logFile = new File(Log.getLogDirectory(), "info.log"); emptyFile(logFile); } /** * @deprecated replaced by {@link org.slf4j.Logger#warn(String)}. * Functionality of this method is delegated there. */ @Deprecated public static void warn(String s) { if (isWarnEnabled()) { Logger.warn(s); } } /** * @deprecated replaced by {@link org.slf4j.Logger#warn(String, Throwable)}. * Functionality of this method is delegated there. */ @Deprecated public static void warn(Throwable throwable) { if (isWarnEnabled()) { Logger.warn("", throwable); } } /** * @deprecated replaced by {@link org.slf4j.Logger#debug(String, Throwable)}. * Functionality of this method is delegated there. */ @Deprecated public static void warn(String s, Throwable throwable) { if (isWarnEnabled()) { Logger.warn(s, throwable); } } public static void markWarnLogFile(String username) { String message = getMarkMessage(username); warn(message); } public static void rotateWarnLogFile() { // SLF4J doesn't provide a hook into the logging implementation. We'll have to do this 'direct', bypassing slf4j. File logFile = new File(Log.getLogDirectory(), "warn.log"); emptyFile(logFile); } /** * @deprecated replaced by {@link org.slf4j.Logger#error(String)}. * Functionality of this method is delegated there. */ @Deprecated public static void error(String s) { if (isErrorEnabled()) { Logger.error(s); if (isDebugEnabled()) { printToStdErr(s, null); } } } /** * @deprecated replaced by {@link org.slf4j.Logger#error(String, Throwable)}. * Functionality of this method is delegated there. */ @Deprecated public static void error(Throwable throwable) { if (isErrorEnabled()) { Logger.error("", throwable); if (isDebugEnabled()) { printToStdErr(null, throwable); } } } /** * @deprecated replaced by {@link org.slf4j.Logger#error(String, Throwable)}. * Functionality of this method is delegated there. */ @Deprecated public static void error(String s, Throwable throwable) { if (isErrorEnabled()) { Logger.error(s, throwable); if (isDebugEnabled()) { printToStdErr(s, throwable); } } } public static void markErrorLogFile(String username) { String message = getMarkMessage(username); error(message); } public static void rotateErrorLogFile() { // SLF4J doesn't provide a hook into the logging implementation. We'll have to do this 'direct', bypassing slf4j. File logFile = new File(Log.getLogDirectory(), "error.log"); emptyFile(logFile); } /** * Returns the directory that log files exist in. The directory name will * have a File.separator as the last character in the string. * * @return the directory that log files exist in. */ public static String getLogDirectory() { // SLF4J doesn't provide a hook into the logging implementation. We'll have to do this 'direct', bypassing slf4j. final StringBuilder sb = new StringBuilder(); sb.append(JiveGlobals.getHomeDirectory()); if (!sb.substring(sb.length()-1).startsWith(File.separator)) { sb.append(File.separator); } sb.append("logs"); sb.append(File.separator); return sb.toString(); } private static String getMarkMessage(String username) { final List<String> args = new ArrayList<>(); args.add(username); args.add(JiveGlobals.formatDateTime(new java.util.Date())); return LocaleUtils.getLocalizedString("log.marker_inserted_by", args); } private static void printToStdErr(String s, Throwable throwable) { if (s != null) { System.err.println(s); } if (throwable != null) { StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw); throwable.printStackTrace(pw); System.err.print(sw.toString()); System.err.print("\n"); } } private static void emptyFile(File logFile) { BufferedWriter out = null; try { out = new BufferedWriter(new FileWriter(logFile)); out.write(""); } catch (IOException ex) { Log.warn("Could not empty file " + logFile.getName(), ex); } finally { if (out != null) { try { out.close(); } catch (IOException ex) { Log.warn("Could not close file.", ex); } } } } }