java-bootstrap-platform/src/bootstrap/logging/Logging.java

239 lines
5.4 KiB
Java

package bootstrap.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.Arrays;
import java.util.Date;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
public class Logging {
private static Logging _inst;
private static PrintStream liveStream;
private PrintStream logStream;
private DateFormat dateFormat;
List<LoggingListener> loggingListeners;
private int limitLogLevel;
private String logFilename;
public Logging(){
setLogFileName("application.log");
initialize();
}
public Logging(String filename){
setLogFileName(filename);
initialize();
}
private void initialize(){
loggingListeners = new LinkedList<LoggingListener>();
limitLogLevel = 10;
dateFormat = DateFormat.getDateTimeInstance();
System.setErr(new PrintStream(new LoggingOutputStream(LogLevel.ERROR)));
System.setOut(new PrintStream(new LoggingOutputStream(LogLevel.INFO)));
}
public PrintStream getLogStream(){
if (this.logStream == null){
try {
logStream = new PrintStream(logFilename);
} catch (FileNotFoundException e){
logStream = liveStream;
log(LogLevel.ERROR,"Logging: setLogFileName(%s) failed:",logFilename);
log(e);
}
}
return logStream;
}
public void setLogFileName(String filename){
this.logFilename = filename;
File f = new File(logFilename);
File fold = new File(String.format("%s.old", logFilename));
if (fold.exists()){
fold.delete();
}
if (f.exists()){
f.renameTo(fold);
}
}
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);
getLogStream().println(formattedLine);
getLogStream().flush();
if (liveStream != null){
liveStream.println(formattedLine);
liveStream.flush();
}
for (LoggingListener l: loggingListeners){
l.logMessageArrived(formattedLine);
}
}
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 public String[] Init(String[] arguments,Class<?> mainClass){
return Init(arguments, mainClass.getCanonicalName() + ".log");
}
static public String[] Init(String[] arguments,String defaultFileName){
LinkedList<String> args = new LinkedList<>();
Iterator<String> i = Arrays.asList(arguments).iterator();
Logging._inst = new Logging();
Logging._inst.setLogFileName(defaultFileName);
while (i.hasNext()){
String option = i.next();
switch (option){
case "--log-filename":
Logging._inst.setLogFileName(i.next());
break;
case "--log-level":
Logging._inst.setLimitLogLevel(Integer.parseInt(i.next()));
break;
default:
args.add(option);
break;
}
}
return args.toArray(new String[0]);
}
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();
}
};
}
}
}