asmuts 02/01/14 22:47:27
Added: src/java/org/apache/stratum/jcs/utils/log
ILogEventQueue.java ILogListener.java
LogEventQueue.java Logger.java LoggerManager.java
LogUtils.java LogViewer.java
Log:
logger, has a viewer, will migrate to log4j
Revision Changes Path
1.1
jakarta-turbine-stratum/src/java/org/apache/stratum/jcs/utils/log/ILogEventQueue.java
Index: ILogEventQueue.java
===================================================================
package org.apache.stratum.jcs.utils.log;
/** Inteface implemented by a log event queue. */
public interface ILogEventQueue {
/** Adds a request to clear the specified log to the log event queue. */
public void addClearLogEvent(String logname);
/** Adds a request to cycle the specified log to the log event queue. */
public void addCycleLogEvent(String logname);
/** Adds a request to dump the specified log to the log event queue. */
public void addDumpEvent(String logname, StringBuffer sb);
/** Destroys the log event queue. */
public void destroy();
/** Returns true iff the log event queue is alive. */
public boolean isAlive();
}
1.1
jakarta-turbine-stratum/src/java/org/apache/stratum/jcs/utils/log/ILogListener.java
Index: ILogListener.java
===================================================================
package org.apache.stratum.jcs.utils.log;
/** Interface to be implemented by a log event listener to handler log events. */
public interface ILogListener {
/**
* Notifies the subscriber for a log dump.
*/
public void handleDump(String logname, StringBuffer sb);
/**
* Notifies the subscriber for a log recycle.
*/
public void handleCycleLog(String logname);
/**
* Notifies the subscriber for a log removal.
*/
public void handleClearLog(String logname);
}
1.1
jakarta-turbine-stratum/src/java/org/apache/stratum/jcs/utils/log/LogEventQueue.java
Index: LogEventQueue.java
===================================================================
package org.apache.stratum.jcs.utils.log;
import org.apache.stratum.jcs.utils.reuse.*;
import java.util.*;
/**
* The log event queue where all logging requests are queued and processed in FIFO
order.
*/
// Note: don't use Logger in this class. Else may lead to endless recursive loop.
class LogEventQueue implements ILogEventQueue {
private static boolean debug=false;
private ITomcatQueue q = new TomcatJglQueue();
private ILogListener listener;
private boolean destroyed;
private Thread t;
// TODO: parameterize the max q size.
public static int MAX_Q_SIZE = 1024*1024;
/** Constructs with the specified listener and the cache name. */
LogEventQueue(ILogListener listener) {
if (listener == null) {
throw new IllegalArgumentException("listener must not be null");
}
this.listener = listener;
/** Constant running thread to consume each listener event in FIFO order. */
t = new QProcessor();
t.start();
if (debug) {
p("Constructed for " + this);
}
}
public synchronized void destroy() {
if (destroyed) {
return;
}
destroyed = true;
// sychronize the q so the thread will not wait forever.
synchronized(q) {
t.interrupt();
}
t = null;
p("*** Log event queue destroyed " + this);
}
public boolean isAlive() {
return !destroyed;
}
///////////////
/** Requests deleting the log file. */
public synchronized void addClearLogEvent(String logname) {
if (destroyed) {
return;
}
if (debug) {
p("addClearLogEvent>");
}
if (q.size() > MAX_Q_SIZE) {
q.get(); // drop the front item.
p("Log q size exceeded. Dropping front item.");
}
q.put(new ClearLogEvent(logname));
if (debug) {
p("addClearLogEvent done>");
}
}
/** Requests cycling the log file. */
public synchronized void addCycleLogEvent(String logname) {
if (destroyed) {
return;
}
if (debug) {
p("addCycleLogEvent>");
}
if (q.size() > MAX_Q_SIZE) {
q.get(); // drop the front item.
p("Log q size exceeded. Dropping front item.");
}
q.put(new CycleLogEvent(logname));
if (debug) {
p("addCycleLogEvent done>");
}
}
/** Requests output to the log file. */
public synchronized void addDumpEvent(String logname, StringBuffer sb) {
if (destroyed) {
return;
}
if (debug) {
p("addDumpEvent> " + sb);
}
if (q.size() > MAX_Q_SIZE) {
q.get(); // drop the front item.
p("Log q size exceeded. Dropping front item.");
}
q.put(new DumpEvent(logname, sb));
if (debug) {
p("addDumpEvent done>");
}
}
///////////////////////////// Inner classes /////////////////////////////
private class QProcessor extends Thread {
QProcessor() {
setDaemon(true);
setPriority(MIN_PRIORITY);
}
public void run() {
while (!destroyed) {
try {
Runnable r = (Runnable)q.pull();
if (!destroyed) {
r.run();
}
} catch(Exception ex) {
ex.printStackTrace(System.err);
}
}
q = null;
listener = null;
p("QProcessor exiting for " + LogEventQueue.this);
}
}
private class DumpEvent implements Runnable {
String logname;
private StringBuffer sb;
DumpEvent(String logname, StringBuffer sb) {
this.logname = logname;
this.sb = sb;
}
public void run() {
if (debug) {
p("run> sb="+sb);
}
listener.handleDump(logname, sb);
}
private void p(String s) {
System.out.println("DumpEvent:"+s);
}
}
private class CycleLogEvent implements Runnable {
String logname;
CycleLogEvent(String logname) {
this.logname = logname;
}
public void run() {
listener.handleCycleLog(logname);
}
private void p(String s) {
System.out.println("CycleLogEvent:");
}
}
private class ClearLogEvent implements Runnable {
String logname;
ClearLogEvent(String logname) {
this.logname = logname;
}
public void run() {
listener.handleClearLog(logname);
}
private void p(String s) {
System.out.println("ClearLogEvent:");
}
}
private void p(String s) {
System.out.println("LogEventQueue" + s);
}
}
1.1
jakarta-turbine-stratum/src/java/org/apache/stratum/jcs/utils/log/Logger.java
Index: Logger.java
===================================================================
package org.apache.stratum.jcs.utils.log;
import java.io.*;
import java.util.*;
import org.apache.stratum.jcs.utils.data.*;
import org.apache.stratum.jcs.utils.date.*;
import org.apache.stratum.jcs.utils.reuse.*;
import org.apache.stratum.jcs.utils.email.*;
/** The Logger. */
public class Logger {
public static final int NONE = 0;
public static final int ERROR = 1;
public static final int WARN = 2;
public static final int INFO = 3;
public static final int DEBUG = 4;
private static final String ERROR_TEXT = "error";
private static final String WARN_TEXT = "warning";
private static final String INFO_TEXT = "info";
private static final String DEBUG_TEXT = "debug";
private LazyDate lDate = new LazyDate(1000);
// public so it can be accessed quickly
public int logLevel = WARN;
private int maxFileSize = 75000;
private long lastFlushTime = System.currentTimeMillis();
/** Log directory. */
final String logroot;
/** Log directory. */
private File logDir;
/** Archive directory. */
private File archiveDir;
private boolean systemout;
public static final boolean DFLT_SYSOUT = false;
/** Log name. */
final String logname;
static int BUFFER_CAPACITY = 4*1024;
private StringBuffer sb = new StringBuffer(BUFFER_CAPACITY);
/** Lock for the string buffer. */
private final int[] sbLock = new int[0];
public static final boolean FLUSH = true;
public static final boolean CONSOLE = true;
public static final int DFLT_MAX_FILESIZE = 75000;
private static Logger logLogger = LoggerManager.getLogger(Logger.class);
/** Constructs a logger with a log name derived from the given object. */
Logger (Object obj) {
this(obj.getClass());
}
/** Constructs a logger with a log name derived from the given class. */
Logger (Class klass) {
this(LogUtils.getLogFileName(klass));
}
/** Constructs a logger with the given log name. */
Logger (String name) {
//TODO: make severity configurable from prop file.
this(LogUtils.getLogRoot(), name, WARN, DFLT_SYSOUT, DFLT_MAX_FILESIZE);
}
/**
* Constructs a logger.
* @param String logroot root directory of the log.
* @param String logname file name of the log.
* @param int level severity level of the log.
* @param boolean sout true iff system out is used to print.
* @param int maxFileSize the file size threshold beyond which the log will be
archived.
*/
Logger (String logroot, String logname, int level, boolean sout, int maxFileSize) {
this.logroot = logroot;
this.systemout = sout;
this.maxFileSize = maxFileSize;
this.logname = logname;
this.logLevel = level;
setupDir();
if (logLogger != null) {
logLogger.info("making logger " + logname + "@" + logroot);
}
LoggerManager.getInstance().getLogEventQ().addCycleLogEvent(logname);
}
/** Sets up and creates if necessary the log and archive directories. */
private void setupDir () {
if (logDir != null) {
return;
}
logDir = new File(logroot);
logDir.mkdirs();
archiveDir = new File(logDir, "archive");
archiveDir.mkdirs();
}
/**
* Sets the current severity level of the logger.
*/
public void setLogLevel (int logLevel) {
this.logLevel = logLevel;
}
/**
* Gets the current severity level of the logger.
* @return
*/
public int getLogLevel () {
return logLevel;
}
/**
* Sets whether the log will be additionally output to <code>system.out</code>.
*/
public void setSystemOut (boolean b) {
systemout = b;
}
/**
* Returns true iff the log is additionally printed to <code>system.out</code>.
*/
public boolean getSystemOut () {
return systemout;
}
/**
* Sets the severity level to ERROR if the given flag is true,
* or to NONE if the flag is false.
*/
public void setDebug (boolean B) {
logLevel = B ? ERROR : NONE;
}
/**
* Sets the severity level to ERROR if the given flag is true,
* or to NONE if the flag is false.
*/
public void setDebug (String s) {
setDebug((new Boolean(s)).booleanValue());
}
/**
* Outputs the given string buffer to the log file.
*/
void dumpLog (StringBuffer sb) {
setupDir();
BufferedWriter bw = null;
try {
bw = new BufferedWriter(new FileWriter(new File(logDir,
logname).getAbsolutePath(),
true));
bw.write(sb.toString());
bw.newLine();
} catch (IOException e) {
logLogger.logEx(e);
} finally {
if (bw != null) {
try {
bw.close();
} catch (IOException ignore) {}
}
}
lastFlushTime = System.currentTimeMillis();
return;
}
/**
* Deletes the current log file.
*/
void clearLog () {
setupDir();
try {
LogUtils.deleteFile(new File(logDir, logname));
} catch(Exception ex) {
// ignore and proceeed.
}
logLogger.info("Deleted file dir=" + logroot + ", logname=" + logname);
logLogger.flush();
return;
}
/**
* Moves the current log file to the archive directory and starts a new log file.
*/
void cycleLog () {
setupDir();
File logFile = new File(logDir, logname);
if (!logFile.exists()) {
StringBuffer msg = new StringBuffer("");
/*
msg.append(logname);
msg.append(" created.<br>\r");
msg.append(msg);
*/
dumpLog(msg);
return;
}
long len = logFile.length();
if (len < maxFileSize) {
return;
}
File toFile = new File(archiveDir, logname.substring(0, logname.length()
- 4) + GetDate.getFileDate() + ".log");
try {
LogUtils.renameFile(logFile, toFile);
} catch(Exception ex) {
// ignore and proceed.
}
logLogger.info("Cycled log = " + logname + ", original len = " + len +
", new logFile.length() = " + logFile.length() + ", maxFileSize = "
+ maxFileSize);
logLogger.flush();
return;
}
/**
* Logs the given string asynchronously.
*/
public void logIt (String s) {
logItImpl(new String[] {
s
}, !FLUSH, !CONSOLE);
}
/**
* Logs the given list of strings asynchronously.
* @param s list of strings to be logged.
* @param flush true iff the list of strings are to be
* flushed out to disk asap.
* @param console true if also want to output to System.out.
*/
private void logItImpl (String[] s, boolean flush, boolean console) {
if (logLevel <= NONE || s == null)
return;
String date = lDate.todaysDate();
if (systemout || console) {
p(logname);
p(" [");
p(date);
p("] ");
}
synchronized (sbLock) {
sb.append("[");
sb.append(date);
sb.append("] ");
for (int i = 0; i < s.length; i++) {
sb.append(s[i]);
if (systemout || console) {
p(s[i]);
}
}
sb.append("\r <br>");
if (systemout || console) {
pl("");
}
}
dump(flush ? 0 : BUFFER_CAPACITY);
}
/** @deprecated replaced by <code>flush()</code>. */
public void dump () {
dump(0);
}
/**
* Flushes the current log asap but still asynchronously.
*/
public void flush () {
dump(0);
}
/**
* Flushes the current log asynchronously if the size
* of the current internal string buffer exceeds the given threshold.
*/
private void dump (int threshold) {
lastFlushTime = System.currentTimeMillis();
if (sb.length() > threshold) {
synchronized (sbLock) {
if (sb.length() > threshold) {
LoggerManager.getInstance().getLogEventQ().addDumpEvent(logname, sb);
sb = new StringBuffer(BUFFER_CAPACITY);
}
}
}
}
/** Returns true iff the string buffer contains anything not yet flushed to disk.
*/
public boolean isDirty() {
return sb.length() > 0;
}
/**
* Logs the given message asynchronously which will get flushed to disk asap.
*/
public void logDirect (String s) {
logItImpl(new String[] {
s
}, FLUSH, !CONSOLE);
}
/**
* Logs the time asynchronously.
*/
public void logTime () {
logItImpl(new String[] {
"<br><br>", MiscDate.todaysDate()
}, !FLUSH, !CONSOLE);
}
/**
* Logs the given string and the stack trace of
* the given throwable asynchronously which will get flushed to disk asap.
*/
public void logIt (String s, Throwable ex) {
logItImpl(new String[] {
s, stackTrace(ex)
}, FLUSH, CONSOLE);
}
/**
* Logs the given exception and msg asynchronously which will get flushed to disk
asap.
*/
public void logEx (Exception e, String msg) {
String exMsg = e.getMessage();
if (exMsg == null) {
exMsg = "";
}
logItImpl(new String[] {
"<font color=red>Exception ", e.toString(), " ", msg, " \n ", exMsg,
" Stack Trace = ", stackTrace(e), "</font>\n\n"
}, FLUSH, CONSOLE);
}
/**
* Logs the given exception asynchronously which will get flushed to disk asap.
*/
public void logEx (Exception e) {
String exMsg = e.getMessage();
if (exMsg == null) {
exMsg = "";
}
logItImpl(new String[] {
"<font color=red>Exception ", e.toString(), " \n ", exMsg, " Stack Trace = ",
stackTrace(e), "</font>\n\n", "\n\n", System.getProperties().toString()
}, FLUSH, CONSOLE);
}
/**
* Send mail.
*/
public void mailIt (String sender, String recipient, String subject, String
message) {
if (logLevel <= 0)
return;
SendMail sm = new SendMail();
sm.execute(sender, recipient, subject, message);
}
/**
* Send mail.
*/
public void mailIt (String recipient, String message) {
if (logLevel <= 0)
return;
SendMail sm = new SendMail();
sm.execute("Logger", recipient, "Log Email", message);
}
/**
* Returns the stack trace of the given throwable.
*/
public static String stackTrace (Throwable ex) {
StringWriter sw = new StringWriter();
ex.printStackTrace(new PrintWriter(sw));
return sw.toString();
}
/**
* Returns the system property of the
* @param msg
*/
/*
public void properties (String msg) {
logIt(System.getProperties().toString());
}
*/
/**
* Returns the current severity level.
*/
String getSeverityString (int severityLevel) {
switch (severityLevel) {
case ERROR:
return ERROR_TEXT;
case WARN:
return WARN_TEXT;
case INFO:
return INFO_TEXT;
case DEBUG:
return DEBUG_TEXT;
default:
return "Unknown";
}
}
/**
* Logs the given message with the given serverity level asynchronously.
*/
public void logIt (String msg, int severityLevel) {
if (severityLevel <= logLevel) {
logItImpl(new String[] {
getSeverityString(severityLevel), ": ", msg
}, !FLUSH, !CONSOLE);
}
return;
}
/**
* Logs the given message as an error asynchronously.
* Error get flushed to disk asap.
*/
public void error (String msg) {
if (ERROR <= logLevel) {
logItImpl(new String[] {
getSeverityString(ERROR), ": ", msg
}, FLUSH, CONSOLE);
}
return;
}
/**
* Logs the given exception as an error asynchronously.
* Error get flushed to disk asap.
*/
public void error (Exception e) {
if (ERROR <= logLevel) {
logEx(e, getSeverityString(ERROR) + ": ");
}
}
/**
* Logs the given exception and message as an error asynchronously.
* They get flushed to disk asap.
*/
public void error (Exception e, String msg) {
if (ERROR <= logLevel) {
logEx(e, getSeverityString(ERROR) + ": " + msg);
}
}
/**
* Logs the given message as a warning asynchronously.
*/
public void warn (String msg) {
if (WARN <= logLevel) {
logItImpl(new String[] {
getSeverityString(WARN), ": ", msg
}, FLUSH, !CONSOLE);
}
return;
}
/**
* Logs the given message asynchronously.
*/
public void info (String msg) {
if (INFO <= logLevel) {
logItImpl(new String[] {
getSeverityString(INFO), ": ", msg
}, !FLUSH, !CONSOLE);
}
return;
}
/**
* Logs the given debugging message asynchronously.
*/
public void debug (String msg) {
if (DEBUG <= logLevel) {
logItImpl(new String[] {
getSeverityString(DEBUG), ": ", msg
}, !FLUSH, !CONSOLE);
}
return;
}
private static void p(String s) {
System.out.print(s);
}
private static void pl(String s) {
System.out.println(s);
}
long getLastFlushTime() {
return lastFlushTime;
}
}
1.1
jakarta-turbine-stratum/src/java/org/apache/stratum/jcs/utils/log/LoggerManager.java
Index: LoggerManager.java
===================================================================
package org.apache.stratum.jcs.utils.log;
import java.io.*;
import java.io.IOException;
import java.sql.*;
import java.util.*;
import org.apache.stratum.jcs.utils.date.*;
////////////////////////////////////////////////////////////////////////
/**
* @author Aaron Smuts
* @version 1.0
* @author Hanson Char
* @version 1.1
* * make use of the log event queue.
*/
public class LoggerManager
implements ILogListener {
/**
* Minimum flush period is 5 seconds.
* Actual flush period is configured from the sleepInterval in logger.property.
*/
public static long FLUSH_PERIOD = 5 * 1000;
private static LoggerManager instance;
private static int clients;
private static Hashtable loggers = new Hashtable();
/**
* There is only one instance of log event queue for all logs,
* as there is one instance of LoggerManager.
*/
private ILogEventQueue logEventQ;
public LazyDate lDate;
private Logger mgrLog;
////////////////////////////
public static void main (String[] args) {
LoggerManager loggerMgr = LoggerManager.getInstance();
}
///////////////////////////////////////////////////////////////////
private LoggerManager () {
logEventQ = new LogEventQueue(this);
}
/** Returns the per JVM log event queue. */
ILogEventQueue getLogEventQ() {
return logEventQ;
}
/**
* This method must not be included in the constructor to avoid recursive dead
loop -
* LoggerManager.getInstance() will instanciate Logger objects which instanciate
LoggerManager.getInstance().
*/
private void init () {
mgrLog = getLogger(this);
mgrLog.info("intitializing loggers");
lDate = new LazyDate(1000);
Properties loggerProps = new Properties();
InputStream is = getClass().getResourceAsStream("/logger.properties");
try {
loggerProps.load(is);
} catch (Exception e) {
mgrLog.error("Can't read the properties file. " + "Make sure logger.properties
is in the CLASSPATH");
return;
} finally {
if (is != null) {
try {
is.close();
} catch (IOException ignore) {}
}
}
// Configures the Logger buffer capacity.
String bufferCapStr = loggerProps.getProperty("buffer_capacity",
Logger.BUFFER_CAPACITY+"");
int bufferCap = Logger.BUFFER_CAPACITY;
try {
bufferCap = Integer.parseInt(bufferCapStr.trim());
} catch(NumberFormatException ex) {
mgrLog.logEx(ex);
}
Logger.BUFFER_CAPACITY = bufferCap < 0 ? Logger.BUFFER_CAPACITY : bufferCap;
mgrLog.info("Set logger's buffer size to " + Logger.BUFFER_CAPACITY);
createLoggers(loggerProps);
// Configures the period of the flusher thread.
String periodStr = loggerProps.getProperty("sleepInterval", FLUSH_PERIOD+"");
long period = FLUSH_PERIOD;
try {
period = Long.parseLong(periodStr.trim());
} catch(NumberFormatException ex) {
mgrLog.logEx(ex);
}
// Flusher is irrelevant if the buffer capacity is zero.
if (Logger.BUFFER_CAPACITY > 0) {
FLUSH_PERIOD = period > FLUSH_PERIOD ? period : FLUSH_PERIOD;
mgrLog.info("Set periodic log flush to " + FLUSH_PERIOD + " milliseconds.");
Thread t = new Flusher();
t.setPriority(t.MIN_PRIORITY);
t.setDaemon(true);
t.start();
}
}
/////////////////////////////////////////////////////////////
private void createLoggers (Properties props) {
String logroot = LogUtils.getLogRoot();
mgrLog.info("setting logroot = " + logroot);
Enumeration propNames = props.propertyNames();
synchronized (loggers) {
while (propNames.hasMoreElements()) {
String name = (String)propNames.nextElement();
if (name.endsWith(".level")) {
String loggerName = name.substring(0, name.lastIndexOf("."));
String levelS = props.getProperty(loggerName + ".level", "4");
int level;
try {
level = Integer.valueOf(levelS.trim()).intValue();
} catch (NumberFormatException e) {
mgrLog.warn("<br>Invalid level value " + levelS + " for " + loggerName);
level = 4;
}
String systemoutS = props.getProperty(loggerName + ".systemout",
"N");
boolean systemout = false;
if (systemoutS.toUpperCase().equals("Y")) {
systemout = true;
}
String maxfilesizeS = props.getProperty(loggerName + ".maxfilesize",
"75000");
int maxfilesize;
try {
maxfilesize = Integer.valueOf(maxfilesizeS.trim()).intValue();
} catch (NumberFormatException e) {
mgrLog.warn("<br>Invalid level value " + maxfilesizeS + " for "
+ loggerName);
maxfilesize = 75000;
}
String numtocheckS = props.getProperty(loggerName + ".numtocheck",
"500");
int numtocheck;
try {
numtocheck = Integer.valueOf(numtocheckS.trim()).intValue();
} catch (NumberFormatException e) {
mgrLog.warn("<br>Invalid level value " + numtocheckS + " for " +
loggerName);
numtocheck = 500;
}
String temproot = props.getProperty(loggerName + ".logroot", logroot);
loggerName = loggerName + ".log";
Logger logger = new Logger(temproot, loggerName, level, systemout,
maxfilesize);
mgrLog.info("created logger: " + logger.logname + ", level = " +
logger.getSeverityString(logger.getLogLevel()) + ", systemout = "
+ logger.getSystemOut() + ", logroot = " + logger.logroot);
loggers.put(loggerName, logger);
}
}
}
mgrLog.flush();
return;
}
//////////////////////////////////////////////////////
public void handleDump (String logname, StringBuffer sb) {
Logger log = getLogger(logname);
log.cycleLog();
log.dumpLog(sb);
return;
}
///////////////////////////////////////////////////////
public void handleClearLog (String logname) {
getLogger(logname).clearLog();
}
/////////////////////////////////////////////////////////
public void handleCycleLog (String logname) {
getLogger(logname).cycleLog();
}
///////////////////////////////////////////////////////////////////
public static LoggerManager getInstance () {
if (instance == null) {
boolean isNew = false;
synchronized (loggers) {
if (instance == null) {
instance = new LoggerManager();
isNew = true;
}
}
// Note: perform init outside the above synchronization block to avoid any
// potential synchronization dead lock.
if (isNew) {
instance.init();
}
}
clients++;
return instance;
}
/** Returns the logger for the given object. Creates the logger if necessary. */
public static Logger getLogger (Object o) {
return getLogger(o.getClass());
}
/** Returns the logger for the given class. Creates the logger if necessary. */
public static Logger getLogger (Class klass) {
return getLogger(LogUtils.getLogFileName(klass));
}
/** Returns the logger with the given name. Creates the logger if necessary. */
public static Logger getLogger (String name) {
getInstance();
Logger log = (Logger)loggers.get(name);
if (log == null) {
synchronized (loggers) {
log = (Logger)loggers.get(name);
if (log == null) {
log = new Logger(name);
loggers.put(name, log);
if (instance.mgrLog != null) {
instance.mgrLog.info("created logger: " + log.logname + ", level = "
+ log.getSeverityString(log.getLogLevel()) + ", systemout = "
+ log.getSystemOut() + ", logroot = " + log.logroot);
instance.mgrLog.flush();
}
}
}
}
return log;
}
/** Returns the logger for the given object, or null if it does not exist. */
public static Logger peekLogger (Object o) {
return peekLogger(o.getClass());
}
/** Returns the logger for the given class, or null if it does not exist. */
public static Logger peekLogger (Class klass) {
return peekLogger(LogUtils.getLogFileName(klass));
}
/** Returns the logger with the given name, or null if it does not exist. */
public static Logger peekLogger (String name) {
if (instance == null) {
return null;
}
return (Logger)loggers.get(name);
}
/** Periodic log flusher to clean up idle logs in memory. */
private static class Flusher extends Thread {
public void run() {
while (true) {
try {
sleep(FLUSH_PERIOD);
Logger[] loggerList = null;
synchronized(loggers) {
loggerList = (Logger[])loggers.values().toArray(new Logger[0]);
}
long now = System.currentTimeMillis();
for (int i=0; i < loggerList.length; i++) {
Logger log = loggerList[i];
if (log.isDirty()) {
long delta = now - log.getLastFlushTime();
if (delta > FLUSH_PERIOD) {
log.flush();
}
}
}
} catch(Exception ex) {
ex.printStackTrace();
}
}
}
} // end class flusher
} // end logger
1.1
jakarta-turbine-stratum/src/java/org/apache/stratum/jcs/utils/log/LogUtils.java
Index: LogUtils.java
===================================================================
package org.apache.stratum.jcs.utils.log;
import org.apache.stratum.jcs.utils.data.*;
import java.io.*;
/** Loggin utilities. */
public class LogUtils {
private static Logger log = LoggerManager.getLogger(LogUtils.class);
/**
* put your documentation comment here
*/
private LogUtils () {
}
/** Deletes the given file. */
public static void deleteFile (File file) {
if (file == null || !file.exists()) {
return;
}
if (!file.isFile()) {
IllegalArgumentException ex = new IllegalArgumentException("file " +
file.getAbsolutePath() + " must be a file.");
log.error(ex);
throw ex;
}
int i = 0;
for (; i < 10 && !file.delete(); i++) {
log.warn("Failed to delete file " + file.getAbsolutePath() + "...retrying "
+ i);
try {
Thread.currentThread().sleep(1000);
} catch (InterruptedException ignore) {}
}
if (i == 10) {
IllegalStateException ex = new IllegalStateException("Failed to delete file "
+ file.getAbsolutePath());
log.error(ex);
throw ex;
}
return;
}
/** Renames the from-file to the to-file. */
public static void renameFile (File from, File to) {
if (from == null || to == null || !from.exists() || !from.isFile()) {
IllegalArgumentException ex = new IllegalArgumentException("From and to file
must not be null.");
log.error(ex);
throw ex;
}
if (!from.exists() || !from.isFile()) {
IllegalArgumentException ex = new IllegalArgumentException("From file does not
exist or not a file.");
log.error(ex);
throw ex;
}
deleteFile(to);
int i = 0;
for (; i < 10 && !from.renameTo(to); i++) {
log.warn("Failed to rename file from " + from.getAbsolutePath() + "to "
+ to.getAbsolutePath() + "...retrying " + i);
try {
Thread.currentThread().sleep(1000);
} catch (InterruptedException ignore) {}
}
if (i == 10) {
IllegalStateException ex = new IllegalStateException("Failed to rename file
from "
+ from.getAbsolutePath() + "to " + to.getAbsolutePath());
log.error(ex);
throw ex;
}
return;
}
/** Returns the default root directory, specified in logger.properties, for
logging. */
static String getLogRoot () {
try {
return new PropertyGroups("/logger.properties").getProperty("logroot",
"/");
} catch (Exception e) {
e.printStackTrace();
}
return "/";
}
/** Returns the corresponding log file name for the given object. */
static String getLogFileName (Object c) {
return getLogFileName(c.getClass());
}
/** Returns the corresponding log file name for the given class. */
static String getLogFileName (Class klass) {
String fullName = klass.getName();
int idx = fullName.lastIndexOf('.');
String className = idx == -1 ? fullName : fullName.substring(idx + 1);
String fullPackage = idx == -1 ? "" : fullName.substring(0, idx);
idx = fullPackage.lastIndexOf('.');
String packageName = idx == -1 ? "" : fullPackage.substring(idx + 1);
return packageName.toLowerCase() + "_" + className.toLowerCase() + ".log";
}
}
1.1
jakarta-turbine-stratum/src/java/org/apache/stratum/jcs/utils/log/LogViewer.java
Index: LogViewer.java
===================================================================
package org.apache.stratum.jcs.utils.log;
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
import java.util.*;
import org.apache.stratum.jcs.utils.data.*;
import org.apache.stratum.jcs.utils.date.*;
import org.apache.stratum.jcs.utils.reuse.*;
import org.apache.stratum.jcs.utils.file.*;
import org.apache.stratum.jcs.utils.net.*;
import org.apache.stratum.jcs.utils.text.*;
import org.apache.stratum.jcs.utils.html.*;
//////////////////////////////////////////////////////////////////////////////////
public class LogViewer extends HttpServlet
implements SingleThreadModel {
String server = "";//PortalEnv.server;
String servlet = "/jcs/logs";
String logroot = "";
String full = "N";
String isDefault = "Y";
Logger log;
String logLevelValues[] = {"0", "1", "2", "3", "4"};
String logLevelNames[] = {"None", "Error", "Warn", "Info", "Debug"};
public void init (ServletConfig config) throws ServletException {
// Always pass the ServletConfig object to the super class
super.init(config);
log = LoggerManager.getLogger(this);
log.setLogLevel(4);
try {
PropertyGroups pG = new PropertyGroups("/logger.properties");
logroot = pG.getProperty("logroot", "/");
} catch (Exception e) {
log.error(e);
}
} // end init
//Process the HTTP Get request
public void doGet (HttpServletRequest request, HttpServletResponse response)
throws ServletException,
IOException {
doPost(request, response);
}
//Process the HTTP Post request
public void doPost (HttpServletRequest req, HttpServletResponse res) throws
ServletException,
IOException {
//res.setContentType("text/html");
//CompressResponse compRes = new CompressResponse( req, res );
//PrintWriter out = compRes.getPrintWriter();
res.setContentType("text/html");
PrintWriter out = res.getWriter();
String logFileName=null;
String temp = req.getParameter("logFileName");
logFileName = temp == null ? "Log.log" : temp;
//out.println("<br>*** logFileName="+logFileName);
//String logFilePath2 = logroot;
String logLevel = req.getParameter("logLevel");
temp = req.getParameter("full");
if (temp != null && temp.equals("Y")) {
full = temp;
logroot = "";
}
else {
full = "N";
}
File dir = new File(logroot);
dir.mkdirs();
String logFile = logroot + logFileName;
out.println("<html>");
out.println("<head><title>Log Viewer</title></head>");
if (!logFileName.trim().equals("")) {
File fileTemp = new File(logroot + logFileName);
out.println("<h2>" + logFileName + "</h2>");
if (fileTemp.exists() && fileTemp.isFile()) {
Logger l = LoggerManager.peekLogger(logFileName);
if (l != null) {
l.flush();
log.debug("Flushing log " + logFileName);
log.flush();
if (logLevel != null) {
l.setLogLevel(Integer.parseInt(logLevel));
}
String selectedItem[] = {Integer.toString(l.getLogLevel())};
out.println("<form name=loglevel_form action=" + servlet + " +
method=post>");
out.println("<input type=hidden name=logFileName value='" + logFileName +
"'>");
out.println("Log Level: ");
out.println(ElementBuilder.buildSelect("logLevel", logLevelNames ,
logLevelValues, selectedItem, false));
out.println("<button type=submit>Change Level</button>");
out.println("<br><br>");
}
else {
out.println("Log Level: Unavailable - The log is not
instantiated.<br><br>");
}
out.println("<br>localHost = " + LocalHost.getLocalHostAddress() + "<br>" );
out.println("<a href=\"javascript:history.go(0); \">Update</a> <br><br>");
// + servlet + "?logFileName=" + logFileName + "\">Update</a> ");
//out.println("<br><br>New Log<form><input type=text
name=logFileName></input><input type=submit value=\"get new log\"></input></form>");
//out.println( FileUtil.getTextFile( logFile ) );
}
if (fileTemp.isDirectory()) {
isDefault = "N";
//out.println("<br>*** " + fileTemp.getName() + " showRootFiles logFile=" + logFile
+ ", logFileName="+logFileName+" ***<br>");
out.println(showDir(logroot, logFileName));
}
else {
isDefault = "Y";
out.println("<!-- START PAGE CONTENT //-->");
out.println(FileUtil.getTextFile(logFile));
out.println("<!-- END PAGE CONTENT //-->");
}
}
out.println("<table>");
out.println("<tr><td>");
//out.println("<br>*** showRootFiles " + logroot + " ***<br>");
out.println(showRootFiles(logroot));
out.println("</td></tr>");
out.println("<tr><td>");
out.println("<br><br>");
out.println("localHost = " + LocalHost.getLocalHostAddress() + "<br>" );
out.println("<a href=\"javascript:history.go(0); \">Update</a> ");
// + server + servlet + "?logFileName=" + logFileName + "\">Update</a> ");
//out.println("<br><br>New Log<form><input type=text
name=logFileName></input><input type=submit value=\"get new log\"></input></form>");
out.println("</td></tr>");
out.println("</table>");
out.println("</body></html>");
out.close();
}
////////////////////////////////////////////////////
public String showRootFiles (String filePath) {
StringBuffer strBuf = new StringBuffer();
File logDir = new File(filePath);
if (logDir.exists()) {
String[] logFiles = logDir.list();
logFiles = ArraySorter.sortArray(logFiles);
String directory = "";
if (!(filePath.equals(logroot)) && isDefault.equals("N")) {
directory = filePath + "/"; //.substring(
filePath.lastIndexOf("/") + 1 ) + "/";
}
for (int i = 0; i < logFiles.length; i++) {
Logger log = LoggerManager.peekLogger(directory + logFiles[i]);
strBuf.append("<br>");
//strBuf.append(Integer.toString(log.getLogLevel()) + " ");
strBuf.append("<a href=\"" + servlet + "?logFileName=" + directory
+ logFiles[i] + "&full=" + full + "\">" + logFiles[i] + "</a> ");
if (log != null) {
strBuf.append( " ... " + logLevelNames[log.getLogLevel()] );
}
}
}
return strBuf.toString();
}
public String showDir (String path1, String path2) {
StringBuffer strBuf = new StringBuffer();
String path = path1 + path2;
File logDir = new File(path1 + path2);
if (logDir.exists()) {
String[] logFiles = logDir.list();
logFiles = ArraySorter.sortArray(logFiles);
String directory = "";
for (int i = 0; i < logFiles.length; i++) {
strBuf.append("<br><a href=\"" + servlet + "?logFileName=" + path2 + "/"
+ logFiles[i] + "&full=" + full + "\">" + logFiles[i] + "</a> ");
}
}
return strBuf.toString();
}
////////////////////////////////////////
public void sendMail (Hashtable params) {}
//Get Servlet information
public String getServletInfo () {
return "LogViewer Information";
}
/*
private static void p(String s) {
System.out.println("### >>"+s);
}
*/
}
--
To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>