package org.hwo.logging; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.io.OutputStream; import java.io.PrintStream; import java.text.DateFormat; import java.util.Date; import java.util.LinkedList; import java.util.List; import org.hwo.exceptions.ExtendedExceptionBase; public class Logging { private static Logging _inst; private static PrintStream liveStream; private PrintStream logStream; private final DateFormat dateFormat; List loggingListeners; private int limitLogLevel; public Logging(String filename){ loggingListeners = new LinkedList(); limitLogLevel = 10; dateFormat = DateFormat.getDateTimeInstance(); try { File f = new File(filename); File fold = new File(String.format("%s.old", filename)); if (fold.exists()){ fold.delete(); } if (f.exists()){ f.renameTo(fold); } logStream = new PrintStream(filename); } catch (FileNotFoundException e) { liveStream.println("----!!!!! LOGGING ERROR !!!!!-----"); e.printStackTrace(); } System.setErr(new PrintStream(new LoggingOutputStream(LogLevel.ERROR))); System.setOut(new PrintStream(new LoggingOutputStream(LogLevel.INFO))); } public int getLimitLogLevel() { return limitLogLevel; } public void setLimitLogLevel(int limitLogLevel) { this.limitLogLevel = limitLogLevel; } public void addLoggingListener(LoggingListener listener){ loggingListeners.add(listener); } public void removeLoggingListener(LoggingListener listener){ loggingListeners.remove(listener); } private void _log(LogLevel logLevel,String message){ String formattedLine; if (logLevel.getLevel() > limitLogLevel) return; formattedLine = String.format("%s [%-12s] %s", dateFormat.format(new Date()),logLevel.toString(),message); logStream.println(formattedLine); logStream.flush(); if (liveStream != null){ liveStream.println(formattedLine); liveStream.flush(); } for (LoggingListener l: loggingListeners){ l.logMessageArrived(formattedLine); } } static public void setLogFileName(String logFileName){ _inst = new Logging(logFileName); } static public void log(LogLevel logLevel,String message){ if (_inst == null){ _inst = new Logging("application.log"); } _inst._log(logLevel, message); } static public void log(String message){ log(LogLevel.INFO,message); } static public void log(LogLevel logLevel,String message,Object... args){ log(logLevel,String.format(message, args)); } static public void log(String message,Object... args){ log(LogLevel.INFO,message,args); } static public void log(Exception e){ log(LogLevel.ERROR,"Exception: %s [%s]",e.getClass().getName(), e.getMessage()); if (ExtendedExceptionBase.class.isInstance(e)){ ExtendedExceptionBase ee = (ExtendedExceptionBase)e; if (ee.getDebugMessage()!=null) log(LogLevel.DEBUG,String.format("%s: %s", e.getClass().getName(),ee.getDebugMessage())); if (ee.getDebugDetails()!=null) log(LogLevel.DEBUGDETAIL,String.format("%s: %s",e.getClass().getName(),ee.getDebugDetails())); } log(LogLevel.DEBUG,formatStackTrace(e.getStackTrace())); } static String formatStackTrace(StackTraceElement[] stackTrace){ StringBuilder sb = new StringBuilder(); for (StackTraceElement ste: stackTrace){ sb.append(String.format("-> %s.%s() = %s:%s\n", ste.getClassName(),ste.getMethodName(),ste.getFileName(),ste.getLineNumber())); } return sb.toString(); } static public Logging getInstance() { return _inst; } static { liveStream = System.out; } public class LoggingOutputStream extends OutputStream { byte[] buffer; int bufferPosition; LogLevel logLevel; public LoggingOutputStream() { buffer = new byte[4096]; bufferPosition = 0; this.logLevel = LogLevel.INFO; } public LoggingOutputStream(LogLevel logLevel) { buffer = new byte[4096]; bufferPosition = 0; this.logLevel = logLevel; } @Override public void flush(){ if (bufferPosition > 0){ _log(this.logLevel,new String(buffer,0,bufferPosition)); bufferPosition = 0; }; } @Override public void write(int b) throws IOException { if (b == 0x0A){ flush(); } else { buffer[bufferPosition++] = new Integer(b).byteValue(); if (bufferPosition == buffer.length){ flush(); } }; } } }