Commit dc2a48fd authored by Matt Tucker's avatar Matt Tucker Committed by matt

Applying Log changes from Jive Forums -- adds ability to rotate, mark, etc.


git-svn-id: http://svn.igniterealtime.org/svn/repos/messenger/trunk@72 b35dd754-fafc-0310-a699-88a17e54d16e
parent 0dac604f
...@@ -3,25 +3,23 @@ ...@@ -3,25 +3,23 @@
* $Revision$ * $Revision$
* $Date$ * $Date$
* *
* Copyright (C) 2004 Jive Software. All rights reserved. * Copyright (C) 1999-2004 Jive Software. All rights reserved.
* *
* This software is published under the terms of the GNU Public License (GPL), * This software is the proprietary information of Jive Software.
* a copy of which is included in this distribution. * Use is subject to license terms.
*/ */
package org.jivesoftware.util; package org.jivesoftware.util;
import org.jivesoftware.util.log.Hierarchy; import org.jivesoftware.util.log.*;
import org.jivesoftware.util.log.LogTarget;
import org.jivesoftware.util.log.Logger;
import org.jivesoftware.util.log.Priority;
import org.jivesoftware.util.log.format.ExtendedPatternFormatter;
import org.jivesoftware.util.log.output.io.StreamTarget; import org.jivesoftware.util.log.output.io.StreamTarget;
import org.jivesoftware.util.log.output.io.rotate.RevolvingFileStrategy; import org.jivesoftware.util.log.output.io.rotate.*;
import org.jivesoftware.util.log.output.io.rotate.RotateStrategyBySize; import org.jivesoftware.util.log.format.ExtendedPatternFormatter;
import org.jivesoftware.util.log.output.io.rotate.RotatingFileTarget;
import org.jivesoftware.messenger.JiveGlobals; import org.jivesoftware.messenger.JiveGlobals;
import java.io.File; import org.jivesoftware.messenger.user.User;
import java.io.*;
import java.text.SimpleDateFormat;
/** /**
* Simple wrapper to the incorporated LogKit to log under a single logging name. * Simple wrapper to the incorporated LogKit to log under a single logging name.
...@@ -30,189 +28,380 @@ import java.io.File; ...@@ -30,189 +28,380 @@ import java.io.File;
*/ */
public class Log { public class Log {
private static final Logger infoLog = private static final Logger debugLog = Hierarchy.getDefaultHierarchy().getLoggerFor("Jive-DEBUG");
Hierarchy.getDefaultHierarchy().getLoggerFor("Jive-INFO"); private static final Logger infoLog = Hierarchy.getDefaultHierarchy().getLoggerFor("Jive-INFO");
private static final Logger warnLog = private static final Logger warnLog = Hierarchy.getDefaultHierarchy().getLoggerFor("Jive-WARN");
Hierarchy.getDefaultHierarchy().getLoggerFor("Jive-WARN"); private static final Logger errorLog = Hierarchy.getDefaultHierarchy().getLoggerFor("Jive-ERR");
private static final Logger errorLog =
Hierarchy.getDefaultHierarchy().getLoggerFor("Jive-ERR"); private static String logNameDebug = null;
private static String logNameInfo = null;
private static String logNameWarn = null;
private static String logNameError = null;
private static String debugPattern = null;
private static String infoPattern = null;
private static String warnPattern = null;
private static String errorPattern = null;
private static String logDirectory = null;
private static long maxDebugSize = 1024;
private static long maxInfoSize = 1024;
private static long maxWarnSize = 1024;
private static long maxErrorSize = 1024;
private static boolean debugEnabled;
static { static {
Logger[] loggers = {infoLog, warnLog, errorLog}; initLog();
ExtendedPatternFormatter[] logFormatters = new ExtendedPatternFormatter[3]; }
String[] logNames = {"info", "warn", "error"};
Priority[] logPriority = {Priority.INFO, Priority.WARN, Priority.ERROR}; private Log() { }
String[] logPatterns = {
"%{time:yyyy.MM.dd HH:mm} %{message}\\n%{throwable}",
"%{time:yyyy.MM.dd HH:mm} %{message}\\n%{throwable}",
"%{time:yyyy.MM.dd HH:mm} [%{method}] %{message}\\n%{throwable}"};
for (int i = 0; i < 3; i++) {
String pattern = JiveGlobals.getJiveProperty("log." + logNames[i] + ".format");
if (pattern != null) {
logPatterns[i] = pattern;
}
logFormatters[i] = new ExtendedPatternFormatter(logPatterns[i]);
}
/**
* This method is used to initialize the Log class. For normal operations this method
* should <b>never</b> be called, rather it's only publically available so that the class
* can be reset by the setup process once the jiveHome directory has been specified.
*/
public static void initLog() {
try { try {
logDirectory = JiveGlobals.getLocalProperty("log.directory");
if (logDirectory == null) {
if (JiveGlobals.getJiveHome() != null) {
File jiveHome = new File(JiveGlobals.getJiveHome());
if (jiveHome.exists() && jiveHome.canWrite()) {
logDirectory = (new File(jiveHome, "logs")).toString();
}
}
}
if (!logDirectory.endsWith(File.separator)) {
logDirectory = logDirectory + File.separator;
}
// Make sure the logs directory exists. If not, make it: // Make sure the logs directory exists. If not, make it:
File logDir = new File(JiveGlobals.getJiveHome() + File.separator + "logs"); File logDir = new File(logDirectory);
if (!logDir.exists()) { if (!logDir.exists()) {
try { logDir.mkdir();
logDir.mkdir();
}
catch (SecurityException se) {
System.err.println("Could not create log directory: "
+ logDir.toString() + " "
+ se.getMessage());
}
} }
for (int i = 0; i < 3; i++) {
StreamTarget infoTarget = null; logNameDebug = logDirectory + "jive.debug.log";
if (logDir.exists()) { logNameInfo = logDirectory + "jive.info.log";
String fileName = logDir.getPath() logNameWarn = logDirectory + "jive.warn.log";
+ File.separator logNameError = logDirectory + "jive.error.log";
+ "jive." + logNames[i] + ".log";
String pattern = JiveGlobals.getJiveProperty("log." debugPattern = JiveGlobals.getLocalProperty("log.debug.format");
+ logNames[i] infoPattern = JiveGlobals.getLocalProperty("log.info.format");
+ ".format"); warnPattern = JiveGlobals.getLocalProperty("log.warn.format");
if (pattern != null) { errorPattern = JiveGlobals.getLocalProperty("log.error.format");
logPatterns[i] = pattern;
} try { maxDebugSize = Long.parseLong(JiveGlobals.getLocalProperty("log.debug.size")); }
RevolvingFileStrategy fileStrategy = catch (NumberFormatException e) { /* ignore */ }
new RevolvingFileStrategy(fileName, 5); try { maxInfoSize = Long.parseLong(JiveGlobals.getLocalProperty("log.info.size")); }
RotateStrategyBySize rotateStrategy = catch (NumberFormatException e) { /* ignore */ }
new RotateStrategyBySize(); // 1 meg default try { maxWarnSize = Long.parseLong(JiveGlobals.getLocalProperty("log.warn.size")); }
try { catch (NumberFormatException e) { /* ignore */ }
infoTarget = new RotatingFileTarget(logFormatters[i], try { maxErrorSize = Long.parseLong(JiveGlobals.getLocalProperty("log.error.size")); }
rotateStrategy, catch (NumberFormatException e) { /* ignore */ }
fileStrategy);
} debugEnabled = "true".equals(JiveGlobals.getLocalProperty("log.debug.enabled"));
catch (Exception e) { }
System.err.print("Trouble opening log: " + e.getMessage()); catch (Exception e) {
} // we'll get an exception if jiveHome isn't setup yet - we ignore that since
} // it's sure to be logged elsewhere :)
if (infoTarget == null) { }
infoTarget = new StreamTarget(System.err, logFormatters[i]);
} if (debugPattern == null) {
loggers[i].setLogTargets(new LogTarget[]{infoTarget}); debugPattern = "%{time:yyyy.MM.dd HH:mm:ss} %{message}\\n%{throwable}";
loggers[i].setPriority(logPriority[i]); }
if (infoPattern == null) {
infoPattern = "%{time:yyyy.MM.dd HH:mm:ss} %{message}\\n%{throwable}";
}
if (warnPattern == null) {
warnPattern = "%{time:yyyy.MM.dd HH:mm:ss} %{message}\\n%{throwable}";
}
if (errorPattern == null) {
errorPattern = "%{time:yyyy.MM.dd HH:mm:ss} [%{method}] %{message}\\n%{throwable}";
}
createLogger(debugPattern, logNameDebug, maxDebugSize, debugLog, Priority.DEBUG);
createLogger(infoPattern, logNameInfo, maxInfoSize, infoLog, Priority.INFO);
createLogger(warnPattern, logNameWarn, maxWarnSize, warnLog, Priority.WARN);
createLogger(errorPattern, logNameError, maxErrorSize, errorLog, Priority.ERROR);
}
private static void createLogger(String pattern, String logName, long maxLogSize,
Logger logger, Priority priority)
{
// debug log file
ExtendedPatternFormatter formatter = new ExtendedPatternFormatter(pattern);
StreamTarget target = null;
Exception ioe = null;
try {
// jiveHome was not setup correctly
if (logName == null) {
throw new IOException("LogName was null - JiveHome not set?");
}
else {
RevolvingFileStrategy fileStrategy = new RevolvingFileStrategy(logName, 5);
RotateStrategyBySize rotateStrategy = new RotateStrategyBySize(maxLogSize * 1024);
target = new RotatingFileTarget(formatter, rotateStrategy, fileStrategy);
} }
} }
catch (SecurityException se) { catch (IOException e) {
System.err.println(se.getMessage()); ioe = e;
// can't log to file, log to stderr
target = new StreamTarget(System.err, formatter);
}
logger.setLogTargets(new LogTarget[] { target } );
logger.setPriority(priority);
if (ioe != null) {
logger.debug("Error occurred opening log file: " + ioe.getMessage());
} }
} }
/** public static void setProductName(String productName) {
* <p>Check if the logger at the error level is enabled.</p> debugPattern = productName + " " + debugPattern;
* infoPattern = productName + " " + infoPattern;
* @return True if error logging is enabled warnPattern = productName + " " + warnPattern;
*/ errorPattern = productName + " " + errorPattern;
createLogger(debugPattern, logNameDebug, maxDebugSize, debugLog, Priority.DEBUG);
createLogger(infoPattern, logNameInfo, maxInfoSize, infoLog, Priority.INFO);
createLogger(warnPattern, logNameWarn, maxWarnSize, warnLog, Priority.WARN);
createLogger(errorPattern, logNameError, maxErrorSize, errorLog, Priority.ERROR);
}
public static boolean isErrorEnabled() { public static boolean isErrorEnabled() {
return errorLog.isErrorEnabled(); return errorLog.isErrorEnabled();
} }
/** public static boolean isFatalEnabled() {
* <p>Check if the logger at the info level is enabled.</p> return errorLog.isFatalErrorEnabled();
* }
* @return true if info level is enabled
*/ public static boolean isDebugEnabled() {
return debugEnabled;
}
public static void setDebugEnabled(boolean enabled) {
JiveGlobals.setLocalProperty("log.debug.enabled", Boolean.toString(enabled));
debugEnabled = enabled;
}
public static boolean isInfoEnabled() { public static boolean isInfoEnabled() {
return infoLog.isInfoEnabled(); return infoLog.isInfoEnabled();
} }
/**
* <p>Check if the logger at the warn level is enabled.</p>
*
* @return true if warn level is enabled
*/
public static boolean isWarnEnabled() { public static boolean isWarnEnabled() {
return warnLog.isWarnEnabled(); return warnLog.isWarnEnabled();
} }
/** public static void debug(String s) {
* <p>Log an event at the info level.</p> if (isDebugEnabled()) {
* debugLog.debug(s);
* @param s The string to log }
*/ }
public static void debug(Throwable throwable) {
if (isDebugEnabled()) {
debugLog.debug("", throwable);
}
}
public static void debug(String s, Throwable throwable) {
if (isDebugEnabled()) {
debugLog.debug(s, throwable);
}
}
public static void markDebugLogFile(User user) {
RotatingFileTarget target = (RotatingFileTarget) debugLog.getLogTargets()[0];
SimpleDateFormat sdf = new SimpleDateFormat("hh:mm:ss a yyyy.MM.dd");
String date = sdf.format(new java.util.Date());
String logline = " --- Marker inserted by " + user.getUsername() + " at " + date + " --- \n";
target.write(logline);
}
public static void rotateDebugLogFile() {
RotatingFileTarget target = (RotatingFileTarget) debugLog.getLogTargets()[0];
try {
target.rotate();
}
catch (IOException e) {
System.err.println("Warning: There was an error rotating the Jive debug log file. " +
"Logging may not work correctly until a restart happens.");
}
}
public static void info(String s) { public static void info(String s) {
infoLog.info(s); if (isInfoEnabled()) {
infoLog.info(s);
}
} }
/**
* <p>Log an event at the info level.</p>
*
* @param throwable The exception to log
*/
public static void info(Throwable throwable) { public static void info(Throwable throwable) {
infoLog.info("", throwable); if (isInfoEnabled()) {
infoLog.info("", throwable);
}
} }
/**
* <p>Log an event at the info level.</p>
*
* @param s The string to log
* @param throwable The exception to log
*/
public static void info(String s, Throwable throwable) { public static void info(String s, Throwable throwable) {
infoLog.info(s, throwable); if (isInfoEnabled()) {
infoLog.info(s, throwable);
}
}
public static void markInfoLogFile(User user) {
RotatingFileTarget target = (RotatingFileTarget) infoLog.getLogTargets()[0];
SimpleDateFormat sdf = new SimpleDateFormat("hh:mm:ss a yyyy.MM.dd");
String date = sdf.format(new java.util.Date());
String logline = " --- Marker inserted by " + user.getUsername() + " at " + date + " --- \n";
target.write(logline);
}
public static void rotateInfoLogFile() {
RotatingFileTarget target = (RotatingFileTarget) infoLog.getLogTargets()[0];
try {
target.rotate();
}
catch (IOException e) {
System.err.println("Warning: There was an error rotating the Jive info log file. " +
"Logging may not work correctly until a restart happens.");
}
} }
/**
* <p>Log an event at the warn level.</p>
*
* @param s The string to log
*/
public static void warn(String s) { public static void warn(String s) {
warnLog.warn(s); if (isWarnEnabled()) {
warnLog.warn(s);
}
} }
/**
* <p>Log an event at the warn level.</p>
*
* @param throwable The exception to log
*/
public static void warn(Throwable throwable) { public static void warn(Throwable throwable) {
warnLog.warn("", throwable); if (isWarnEnabled()) {
warnLog.warn("", throwable);
}
} }
/**
* <p>Log an event at the warn level.</p>
*
* @param s The string to log
* @param throwable The exception to log
*/
public static void warn(String s, Throwable throwable) { public static void warn(String s, Throwable throwable) {
warnLog.warn(s, throwable); if (isWarnEnabled()) {
warnLog.warn(s, throwable);
}
}
public static void markWarnLogFile(User user) {
RotatingFileTarget target = (RotatingFileTarget) warnLog.getLogTargets()[0];
SimpleDateFormat sdf = new SimpleDateFormat("hh:mm:ss a yyyy.MM.dd");
String date = sdf.format(new java.util.Date());
String logline = " --- Marker inserted by " + user.getUsername() + " at " + date + " --- \n";
target.write(logline);
}
public static void rotateWarnLogFile() {
RotatingFileTarget target = (RotatingFileTarget) warnLog.getLogTargets()[0];
try {
target.rotate();
}
catch (IOException e) {
System.err.println("Warning: There was an error rotating the Jive warn log file. " +
"Logging may not work correctly until a restart happens.");
}
} }
/**
* <p>Log an event at the error level.</p>
*
* @param s The string to log
*/
public static void error(String s) { public static void error(String s) {
errorLog.error(s); if (isErrorEnabled()) {
errorLog.error(s);
if (isDebugEnabled()) {
printToStdErr(s, null);
}
}
} }
/**
* <p>Log an event at the error level.</p>
*
* @param throwable The exception to log
*/
public static void error(Throwable throwable) { public static void error(Throwable throwable) {
errorLog.error("", throwable); if (isErrorEnabled()) {
errorLog.error("", throwable);
if (isDebugEnabled()) {
printToStdErr(null, throwable);
}
}
}
public static void error(String s, Throwable throwable) {
if (isErrorEnabled()) {
errorLog.error(s, throwable);
if (isDebugEnabled()) {
printToStdErr(s, throwable);
}
}
}
public static void markErrorLogFile(User user) {
RotatingFileTarget target = (RotatingFileTarget) errorLog.getLogTargets()[0];
SimpleDateFormat sdf = new SimpleDateFormat("hh:mm:ss a yyyy.MM.dd");
String date = sdf.format(new java.util.Date());
String logline = " --- Marker inserted by " + user.getUsername() + " at " + date + " --- \n";
target.write(logline);
}
public static void rotateErrorLogFile() {
RotatingFileTarget target = (RotatingFileTarget) errorLog.getLogTargets()[0];
try {
target.rotate();
}
catch (IOException e) {
System.err.println("Warning: There was an error rotating the Jive error log file. " +
"Logging may not work correctly until a restart happens.");
}
}
public static void fatal(String s) {
if (isFatalEnabled()) {
errorLog.fatalError(s);
if (isDebugEnabled()) {
printToStdErr(s, null);
}
}
}
public static void fatal(Throwable throwable) {
if (isFatalEnabled()) {
errorLog.fatalError("", throwable);
if (isDebugEnabled()) {
printToStdErr(null, throwable);
}
}
}
public static void fatal(String s, Throwable throwable) {
if (isFatalEnabled()) {
errorLog.fatalError(s, throwable);
if (isDebugEnabled()) {
printToStdErr(s, throwable);
}
}
} }
/** /**
* <p>Log an event at the error level.</p> * Returns the directory that log files exist in. The directory name will
* have a File.separator as the last character in the string.
* *
* @param s The string to log * @return the directory that log files exist in.
* @param throwable The exception to log
*/ */
public static void error(String s, Throwable throwable) { public static String getLogDirectory() {
errorLog.error(s, throwable); return logDirectory;
}
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");
}
} }
} }
\ No newline at end of file
...@@ -462,12 +462,11 @@ public class Logger { ...@@ -462,12 +462,11 @@ public class Logger {
* Get a copy of log targets for this logger. * Get a copy of log targets for this logger.
* *
* @return the child loggers * @return the child loggers
* @deprecated This method is deprecated and will be removed in Future version.
* Previously it allowed unsafe access to logtargets which permitted
* masqurade attacks. It currently returns a zero sized array.
*/ */
public LogTarget[] getLogTargets() { public LogTarget[] getLogTargets() {
return new LogTarget[0]; // Jive change - we ignore the deprecated warning above and just return the log targets
// since it's a closed system for us anyways
return m_logTargets;
} }
/** /**
......
...@@ -44,7 +44,7 @@ public class RotatingFileTarget extends FileTarget { ...@@ -44,7 +44,7 @@ public class RotatingFileTarget extends FileTarget {
getInitialFile(); getInitialFile();
} }
protected synchronized void rotate() public synchronized void rotate()
throws IOException { throws IOException {
close(); close();
...@@ -56,7 +56,7 @@ public class RotatingFileTarget extends FileTarget { ...@@ -56,7 +56,7 @@ public class RotatingFileTarget extends FileTarget {
/** /**
* Output the log message, and check if rotation is needed. * Output the log message, and check if rotation is needed.
*/ */
protected synchronized void write(final String data) { public synchronized void write(final String data) {
// send the log message // send the log message
super.write(data); super.write(data);
...@@ -87,5 +87,4 @@ public class RotatingFileTarget extends FileTarget { ...@@ -87,5 +87,4 @@ public class RotatingFileTarget extends FileTarget {
openFile(); openFile();
} }
} }
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment