org.browsermob.proxy.jetty.log.LogImpl Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of browsermob-proxy Show documentation
Show all versions of browsermob-proxy Show documentation
A programmatic HTTP/S designed for performance and functional testing
The newest version!
// ========================================================================
// Copyright (c) 1997 MortBay Consulting, Sydney
// $Id: LogImpl.java,v 1.6 2005/08/13 00:01:27 gregwilkins Exp $
// ========================================================================
package org.browsermob.proxy.jetty.log;
import org.browsermob.proxy.jetty.util.Loader;
import java.util.ArrayList;
import java.util.StringTokenizer;
/*-----------------------------------------------------------------------*/
/** A Commons Log implementation for Jetty logs.
*
* The log can contain multiple log syncs.
* The following system properties can be used to control the configuration:
* DEBUG - if set debugging is output is enabled.
* DEBUG_PATTERNS - A list of substring patterns used to match against log information for
* fine grained control of debug logging.
* DEBUG_VERBOSE - If set to a positive integer, trace and info are enabled.
* If set to zero, then info is enabled.
* LOG_SINKS - List of class names used to instantiate the log sinks.
*
* This logger can be configured with the org.mortbay.log.Factory
*
* @see org.browsermob.proxy.jetty.log.LogFactory
*/
public class LogImpl implements org.apache.commons.logging.Log
{
/*-------------------------------------------------------------------*/
public final static String DEBUG= "DEBUG ";
public final static String INFO= "INFO ";
public final static String TRACE= "TRACE ";
public final static String FAIL= "FAIL!! ";
public final static String WARN= "WARN!! ";
public final static String ERROR= "ERROR! ";
/*-------------------------------------------------------------------*/
boolean _debugOn=false;
private ArrayList _debugPatterns=null;
private boolean _initialized = false;
private String _patterns=null;
/*-------------------------------------------------------------------*/
public LogSink[] _sinks = null;
private boolean _suppressWarnings=false;
private int _verbose=0;
/*-------------------------------------------------------------------*/
/** Construct the shared instance of Log that decodes the
* options setup in the environments properties.
*/
public LogImpl()
{
try{
_debugOn= System.getProperty("DEBUG") != null;
setDebugPatterns(System.getProperty("DEBUG_PATTERNS"));
setVerbose(Integer.getInteger("DEBUG_VERBOSE",0).intValue());
}
catch (Exception e)
{
System.err.println("Exception from getProperty!\n"+
"Probably running in applet\n"+
"Use Code.initParamsFromApplet or Code.setOption to control debug output.");
}
}
/* ------------------------------------------------------------ */
/** Add a Log Sink.
* @param logSink
*/
public synchronized void add(LogSink logSink)
throws Exception
{
logSink.setLogImpl(this);
if (!logSink.isStarted())
logSink.start();
if (_sinks==null)
{
_sinks=new LogSink[1];
_sinks[0]=logSink;
}
else
{
boolean slotFree = false;
for( int i=_sinks.length; i-->0; )
{
if( _sinks[i] == null )
{
slotFree = true;
_sinks[i] = logSink;
break;
}
}
if( !slotFree )
{
LogSink[] ns = new LogSink[_sinks.length+1];
for (int i=_sinks.length;i-->0;)
ns[i]=_sinks[i];
ns[_sinks.length]=logSink;
_sinks=ns;
}
}
_initialized = true;
info("added "+logSink);
}
/* ------------------------------------------------------------ */
/** Add a Log Sink.
* @param logSinkClass The logsink classname or null for the default.
*/
public synchronized void add(String logSinkClass)
{
try
{
if (logSinkClass==null || logSinkClass.length()==0)
logSinkClass="org.browsermob.proxy.jetty.log.OutputStreamLogSink";
Class sinkClass = Loader.loadClass(this.getClass(),logSinkClass);
LogSink sink=(LogSink)sinkClass.newInstance();
add(sink);
}
catch(Exception e)
{
message(WARN,e,2);
throw new IllegalArgumentException(e.toString());
}
}
/* (non-Javadoc)
* @see org.apache.commons.logging.Log#debug(java.lang.Object)
*/
public void debug(Object m)
{
if (_debugOn)
{
Frame frame = new Frame(1,true);
if (isDebugOnFor(frame))
{
frame.complete();
message(DEBUG,m,frame);
}
}
}
/* (non-Javadoc)
* @see org.apache.commons.logging.Log#debug(java.lang.Object, java.lang.Throwable)
*/
public void debug(Object m, Throwable ex)
{
if (_debugOn)
{
Frame frame = new Frame(1,true);
if (isDebugOnFor(frame))
{
frame.complete();
message(DEBUG,new Object[]{m,ex},frame);
}
}
}
/*-------------------------------------------------------------------*/
/** Default initialization is used the first time we have to log
* unless a sink has been added with add(). _needInit allows us to
* distinguish between initial state and disabled state.
*/
private synchronized void defaultInit()
{
if (!_initialized)
{
_initialized = true;
String sinkClasses = System.getProperty("LOG_SINKS","org.browsermob.proxy.jetty.log.OutputStreamLogSink");
StringTokenizer sinkTokens = new StringTokenizer(sinkClasses, ";, ");
LogSink sink= null;
while (sinkTokens.hasMoreTokens())
{
String sinkClassName = sinkTokens.nextToken();
try
{
Class sinkClass = Loader.loadClass(this.getClass(),sinkClassName);
if (org.browsermob.proxy.jetty.log.LogSink.class.isAssignableFrom(sinkClass)) {
sink = (LogSink)sinkClass.newInstance();
sink.start();
add(sink);
}
else
// Can't use Code.fail here, that's what we're setting up
System.err.println(sinkClass+" is not a org.browsermob.proxy.jetty.log.LogSink");
}
catch (Exception e) {
e.printStackTrace();
}
}
}
}
/* ------------------------------------------------------------ */
/**
*/
public synchronized void deleteStoppedLogSinks()
{
if (_sinks!=null)
{
for (int s=_sinks.length;s-->0;)
{
if (_sinks[s]==null)
continue;
if (!_sinks[s].isStarted())
_sinks[s]=null;
}
}
}
/* ------------------------------------------------------------ */
/** No logging.
* All log sinks are stopped and removed.
*/
public synchronized void reset()
{
info("reset");
if (_sinks!=null) {
for (int s=_sinks.length;s-->0;)
{
try{
if (_sinks[s]!=null)
_sinks[s].stop();
_sinks[s]=null;
}
catch(InterruptedException e)
{
if (getDebug() && getVerbose()>0)
message("WARN",e);
}
}
_sinks=null;
}
_initialized=true;
}
/* (non-Javadoc)
* @see org.apache.commons.logging.Log#error(java.lang.Object)
*/
public void error(Object arg0)
{
message(ERROR,arg0,new Frame(1));
}
/* (non-Javadoc)
* @see org.apache.commons.logging.Log#error(java.lang.Object, java.lang.Throwable)
*/
public void error(Object arg0, Throwable arg1)
{
message(ERROR,new Object[]{arg0,arg1},new Frame(1));
}
/* (non-Javadoc)
* @see org.apache.commons.logging.Log#fatal(java.lang.Object)
*/
public void fatal(Object arg0)
{
message(FAIL,arg0,new Frame(1));
}
/* (non-Javadoc)
* @see org.apache.commons.logging.Log#fatal(java.lang.Object, java.lang.Throwable)
*/
public void fatal(Object arg0, Throwable arg1)
{
message(FAIL,new Object[]{arg0,arg1},new Frame(1));
}
/* ------------------------------------------------------------ */
/** Get the debug status.
* @return the debug status
*/
public boolean getDebug()
{
return _debugOn;
}
/* ------------------------------------------------------------ */
/** Get the debug patterns.
* @return Coma separated list of debug patterns
*/
public String getDebugPatterns()
{
return _patterns;
}
/* ------------------------------------------------------------ */
public LogSink[] getLogSinks()
{
return _sinks;
}
/* ------------------------------------------------------------ */
/** Get the warnings suppression status.
* @return the warnings suppression status
*/
public boolean getSuppressWarnings()
{
return _suppressWarnings;
}
/* ------------------------------------------------------------ */
/** Get the verbosity level.
* @return the verbosity level
*/
public int getVerbose()
{
return _verbose;
}
/* (non-Javadoc)
* @see org.apache.commons.logging.Log#info(java.lang.Object)
*/
public void info(Object arg0)
{
if (isInfoEnabled())
message(INFO,arg0,new Frame(1));
}
/* (non-Javadoc)
* @see org.apache.commons.logging.Log#info(java.lang.Object, java.lang.Throwable)
*/
public void info(Object arg0, Throwable arg1)
{
if (isInfoEnabled())
message(INFO,new Object[]{arg0,arg1},new Frame(1));
}
/* (non-Javadoc)
* @see org.apache.commons.logging.Log#isDebugEnabled()
*/
public boolean isDebugEnabled()
{
return _debugOn;
}
/* (non-Javadoc)
* @see org.apache.commons.logging.Log#isErrorEnabled()
*/
public boolean isErrorEnabled()
{
return !_suppressWarnings;
}
/* (non-Javadoc)
* @see org.apache.commons.logging.Log#isFatalEnabled()
*/
public boolean isFatalEnabled()
{
return true;
}
/* (non-Javadoc)
* @see org.apache.commons.logging.Log#isInfoEnabled()
*/
public boolean isInfoEnabled()
{
return _verbose>=0;
}
/* (non-Javadoc)
* @see org.apache.commons.logging.Log#isTraceEnabled()
*/
public boolean isTraceEnabled()
{
return _verbose>0;
}
/* (non-Javadoc)
* @see org.apache.commons.logging.Log#isWarnEnabled()
*/
public boolean isWarnEnabled()
{
return !_suppressWarnings;
}
/*-------------------------------------------------------------------*/
public void message(String tag,
Object msg,
Frame frame)
{
long time = System.currentTimeMillis();
message(tag,msg,frame,time);
}
/* ------------------------------------------------------------ */
/** Log a message.
* @param tag Tag for type of log
* @param msg The message
* @param frame The frame that generated the message.
* @param time The time stamp of the message.
*/
public synchronized void message(String tag,
Object msg,
Frame frame,
long time)
{
if (!_initialized)
defaultInit();
boolean logged=false;
if (_sinks!=null)
{
for (int s=_sinks.length;s-->0;)
{
if (_sinks[s]==null)
continue;
if (_sinks[s].isStarted())
{
logged=true;
_sinks[s].log(tag,msg,frame,time);
}
}
}
if (!logged)
System.err.println(time+": "+tag+":"+msg+" @ "+frame);
}
/* ------------------------------------------------------------ */
/** Log a message.
* @param tag Tag for type of log
* @param msg The message
*/
public synchronized void message(String tag,
Object msg)
{
message(tag,msg,new Frame(1),System.currentTimeMillis());
}
/* ------------------------------------------------------------ */
/** Log a message.
* @param tag Tag for type of log
* @param msg The message
*/
public synchronized void message(String tag,
Object msg,
int depth)
{
message(tag,msg,new Frame(depth),System.currentTimeMillis());
}
/* ------------------------------------------------------------ */
/** Set if debugging is on or off.
* @param debug
*/
public synchronized void setDebug(boolean debug)
{
boolean oldDebug=_debugOn;
if (_debugOn && !debug)
this.message(DEBUG,"DEBUG OFF");
_debugOn=debug;
if (!oldDebug && debug)
this.message(DEBUG,"DEBUG ON");
}
/* ------------------------------------------------------------ */
/** Set debug patterns.
* @param patterns comma separated string of patterns
*/
public void setDebugPatterns(String patterns)
{
_patterns=patterns;
if (patterns!=null && patterns.length()>0)
{
_debugPatterns = new ArrayList();
StringTokenizer tok = new StringTokenizer(patterns,", \t");
while (tok.hasMoreTokens())
{
String pattern = tok.nextToken();
_debugPatterns.add(pattern);
}
}
else
_debugPatterns = null;
}
/* ------------------------------------------------------------ */
/** Set warning suppression.
* @param warnings Warnings suppress if this is true and debug is false
*/
public void setSuppressWarnings(boolean warnings)
{
_suppressWarnings=warnings;
}
/* ------------------------------------------------------------ */
/** Set verbosity level.
* @param verbose
*/
public void setVerbose(int verbose)
{
_verbose=verbose;
}
/* (non-Javadoc)
* @see org.apache.commons.logging.Log#trace(java.lang.Object)
*/
public void trace(Object arg0)
{
if (isTraceEnabled())
message(TRACE,arg0,new Frame(1));
}
/* (non-Javadoc)
* @see org.apache.commons.logging.Log#trace(java.lang.Object, java.lang.Throwable)
*/
public void trace(Object arg0, Throwable arg1)
{
if (isTraceEnabled())
message(TRACE,new Object[]{arg0,arg1},new Frame(1));
}
/* (non-Javadoc)
* @see org.apache.commons.logging.Log#warn(java.lang.Object)
*/
public void warn(Object arg0)
{
if (!_suppressWarnings)
message(WARN,arg0,new Frame(1));
}
/* (non-Javadoc)
* @see org.apache.commons.logging.Log#warn(java.lang.Object, java.lang.Throwable)
*/
public void warn(Object arg0, Throwable arg1)
{
if (!_suppressWarnings)
message(WARN,new Object[]{arg0,arg1},new Frame(1));
}
/*-------------------------------------------------------------------*/
private boolean isDebugOnFor(Frame frame)
{
if (_debugOn)
{
if (_debugPatterns==null)
return true;
else
{
for (int i = _debugPatterns.size();--i>=0;)
{
if(frame.getWhere().indexOf((String)_debugPatterns
.get(i))>=0)
return true;
}
}
}
return false;
}
}