package com.spun.util.logger;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Vector;
import com.spun.util.DateDifference;
import com.spun.util.ObjectUtils;
import com.spun.util.ThreadUtils;
public class SimpleLoggerInstance
{
public static class Symbols
{
public static String markerIn = "=> ";
public static String markerOut = "<= ";
public static final String event = "Event: ";
public static String variable = "Variable: ";
public static String sql = "Sql: ";
}
public static final int IN = 1;
public static final int OUT = -1;
public boolean marker = true;
public boolean event = true;
public boolean variable = true;
public boolean query = true;
public boolean timestamp = true;
public boolean stacktraces = true;
public int hourGlass = 0;
public int hourGlassWrap = 100;
private int m_indent = 0;
private long lastTime = System.currentTimeMillis();
private Appendable logTo = System.out;
private int wrapperLevels;
public SimpleLoggerInstance()
{
this(0);
}
public SimpleLoggerInstance(int wrapperLevels)
{
this.wrapperLevels = wrapperLevels;
}
public void toggleAll(boolean t)
{
marker = t;
event = t;
variable = t;
query = t;
}
private void clearHourGlass()
{
if (hourGlass > 0)
{
logLine("");
hourGlass = 0;
}
}
public void setHourGlassWrap(int numberOfDots)
{
hourGlassWrap = numberOfDots;
}
public void hourGlass()
{
if (hourGlassWrap <= hourGlass)
{
clearHourGlass();
}
if (hourGlass == 0)
{
log(timeStampTextOnly());
}
hourGlass++;
String mark = ((hourGlass % 10) == 0) ? ("" + (hourGlass / 10)) : ".";
log(mark);
}
public long startTimer()
{
return System.currentTimeMillis();
}
public void stopTimer(long startTime, long maxTime, String function)
{
long diff = (System.currentTimeMillis() - startTime);
if (diff > maxTime)
{
warning("Time Limit Exceeded - " + function + " [" + new DateDifference(diff).getStandardTimeText(2) + " > "
+ maxTime + "]");
}
}
public void markerIn(String statement)
{
if (!marker) { return; }
logLine(timeStamp() + Symbols.markerIn + statement + " - IN");
m_indent++;
}
private String extractMarkerText()
{
try
{
StackTraceElement trace[] = ThreadUtils.getStackTrace();
StackTraceElement element = trace[4 + wrapperLevels];
String className = element.getClassName();
className = className.substring(className.lastIndexOf(".") + 1);
return className + "." + element.getMethodName() + "()";
}
catch (Throwable t)
{
return "Can't Inspect Stack Trace";
}
}
private String getIndent()
{
if (m_indent == 0) { return ""; }
String theIndention = "";
for (int i = 0; i < m_indent; i++)
{
theIndention += " ";
}
return theIndention;
}
private String timeStamp()
{
clearHourGlass();
return timeStampTextOnly();
}
private String timeStampTextOnly()
{
String text = "";
long current = System.currentTimeMillis();
if (timestamp)
{
java.text.DateFormat df = java.text.DateFormat.getDateTimeInstance();
text = "[" + df.format(new java.util.Date(current)) + " ~" + padNumber(current - lastTime) + "ms] ";
}
text += getIndent();
lastTime = current;
return text;
}
private String padNumber(long number)
{
String text = "" + number;
while (text.length() < 6)
{
text = "0" + text;
}
return text;
}
private String indentMessage(String message)
{
Vector<Integer> v = new Vector<Integer>();
int place = 0;
while ((place = message.indexOf('\n', place + 1)) != -1)
{
v.addElement(place);
}
if (v.size() == 0)
{
// no '\n'
return message;
}
String theIndention = getIndent();
StringBuffer buffer = new StringBuffer(message);
for (int i = (v.size() - 1); i >= 0; i--)
{
int tempplace = ((Integer) v.elementAt(i)).intValue();
buffer.insert(tempplace + 1, theIndention);
}
return buffer.toString();
}
public synchronized void markerOut(String text)
{
if (!marker) { return; }
m_indent--;
logLine(timeStamp() + Symbols.markerOut + text + " - OUT");
}
public synchronized void query(String sqlQuery)
{
if (!query) { return; }
logLine(timeStamp() + Symbols.sql + sqlQuery);
}
/**
* Prints to screen any variable information to be viewed.
* @param Statement The statement to print
**/
public synchronized void query(String queryName, Object sqlQuery)
{
if (!query) { return; }
logLine(timeStamp() + Symbols.sql + "[" + queryName + "] - " + sqlQuery);
}
public void variableFormated(String string, Object... parameters)
{
variable(String.format(string, parameters));
}
public synchronized void variable(String statement)
{
if (!variable) { return; }
logLine(timeStamp() + Symbols.variable + statement);
}
/**
* Prints to screen any variable information to be viewed.
* @param Statement The statement to print
**/
public synchronized void variable(String name, Object value)
{
if (!variable) { return; }
logLine(timeStamp() + Symbols.variable + name + " = '" + value + "'");
}
private void logLine(String text)
{
log(text + "\n");
}
private void log(String with) throws Error
{
try
{
logTo.append(with);
}
catch (IOException e)
{
throw ObjectUtils.throwAsError(e);
}
}
public synchronized void variable(String name, Object array[])
{
if (!variable) { return; }
name = (name == null ? "array" : name);
if (array == null)
{
array = new Object[0];
}
logLine(timeStamp() + Symbols.variable + name + ".length = " + array.length);
for (int i = 0; i < array.length; i++)
{
logLine(timeStamp() + name + "[" + i + "] = " + array[i]);
}
}
public synchronized <T> void variable(T array[])
{
variable(null, array);
}
public synchronized void message(String Statement)
{
logLine(timeStamp() + indentMessage(Statement));
}
public void event(String Statement)
{
if (!event) { return; }
logLine(timeStamp() + Symbols.event + Statement);
}
public synchronized void warning(String statement)
{
warning(statement, null);
}
public synchronized void warning(Throwable throwable)
{
warning(null, throwable);
}
public synchronized void warning(String statement, Throwable throwable)
{
clearHourGlass();
logLine("******************************************************************************************");
logLine(timeStamp());
if (statement != null)
{
logLine(statement);
}
printFullTrace(throwable, false);
if (throwable instanceof OutOfMemoryError)
{
logMemoryStatus();
}
logLine("******************************************************************************************");
}
private void printFullTrace(Throwable throwable, boolean causedBy)
{
if (throwable != null)
{
logLine((causedBy ? "Caused by : " : "") + throwable.getClass().getName() + " - " + throwable.getMessage());
printStackTrace(throwable);
if (throwable.getCause() != null)
{
printFullTrace(throwable.getCause(), true);
}
}
}
private void printStackTrace(Throwable throwable)
{
if (!stacktraces) { return; }
if (logTo instanceof PrintStream)
{
throwable.printStackTrace((PrintStream) logTo);
}
else if (logTo instanceof PrintStream)
{
throwable.printStackTrace((PrintWriter) logTo);
}
else
{
throwable.printStackTrace(new PrintWriter(new AppendableWriter(logTo)));
}
}
/************************************************************************/
/**
* Logs the current memory status [total, used, free].
* This forces garbage collection to run first.
**/
public void logMemoryStatus()
{
String memory = getMemoryStatus();
logLine(memory);
}
private String getMemoryStatus()
{
System.gc();
java.text.NumberFormat format = java.text.NumberFormat.getNumberInstance();
long freeMemory = Runtime.getRuntime().freeMemory();
long totalMemory = Runtime.getRuntime().totalMemory();
long usedMemory = totalMemory - freeMemory;
String statement = "Memory [total, used, free] = [" + format.format(totalMemory) + " , "
+ format.format(usedMemory) + " , " + format.format(freeMemory) + "]";
return statement;
}
/**
* <pre>
* {@code
* try (Markers m = SimpleLogger.useMarkers();)
* {
* }
*
* </pre>
*/
public Markers useMarkers()
{
final String text = extractMarkerText();
return new Markers(text);
}
/***********************************************************************/
/***********************************************************************/
public StringBuffer logToString()
{
marker = true;
event = true;
variable = true;
query = true;
timestamp = false;
stacktraces = false;
StringBuffer buffer = new StringBuffer();
logTo = buffer;
return buffer;
}
public void useOutputFile(String file, boolean addDateStamp)
{
try
{
logTo = new FileWriter(addDatestampToFile(file, addDateStamp), false);
}
catch (IOException e)
{
throw ObjectUtils.throwAsError(e);
}
}
private String addDatestampToFile(String file, boolean addDateStamp)
{
if (!addDateStamp) { return file; }
String date = ".[" + new SimpleDateFormat("yyyy_MM_dd").format(new Date()) + "]";
int seperator = file.lastIndexOf('.');
if (0 < seperator)
{
file = file.substring(0, seperator) + date + file.substring(seperator);
}
else
{
file += System.currentTimeMillis() + ".log";
}
return file;
}
public void logTo(Appendable writer)
{
logTo = writer;
}
public Appendable getLogTo()
{
return logTo;
}
}