changeset 1448:6fc083e1d08c

start logger
author Franklin Schmidt <fschmidt@gmail.com>
date Sun, 23 Feb 2020 18:14:32 -0700
parents 851b9a48cc44
children dd14d2dce7ee
files src/goodjava/logger/Appender.java src/goodjava/logger/ConsoleAppender.java src/goodjava/logger/DateLayout.java src/goodjava/logger/GoodLogger.java src/goodjava/logger/GoodLoggerFactory.java src/goodjava/logger/Layout.java src/goodjava/logger/Layouts.java src/goodjava/logger/Level.java src/goodjava/logger/ListLayout.java src/goodjava/logger/LoggingEvent.java src/goodjava/logger/WriterAppender.java src/goodjava/logging/ILoggerFactory.java src/goodjava/logging/Log4jFactory.java src/goodjava/logging/Logger.java src/goodjava/logging/LoggerFactory.java
diffstat 15 files changed, 346 insertions(+), 15 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/goodjava/logger/Appender.java	Sun Feb 23 18:14:32 2020 -0700
@@ -0,0 +1,7 @@
+package goodjava.logger;
+
+
+public interface Appender {
+	public void append(LoggingEvent event);
+	public void close();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/goodjava/logger/ConsoleAppender.java	Sun Feb 23 18:14:32 2020 -0700
@@ -0,0 +1,14 @@
+package goodjava.logger;
+
+import java.io.PrintStream;
+import java.io.OutputStreamWriter;
+
+
+public final class ConsoleAppender extends WriterAppender {
+
+	public ConsoleAppender(Layout layout,PrintStream ps) {
+		super( layout, new OutputStreamWriter(ps) );
+	}
+
+	public void close() {}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/goodjava/logger/DateLayout.java	Sun Feb 23 18:14:32 2020 -0700
@@ -0,0 +1,20 @@
+package goodjava.logger;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+
+public final class DateLayout implements Layout {
+	private final Date date = new Date();
+	private final DateFormat dateFormat;
+
+	public DateLayout(String pattern) {
+		dateFormat = new SimpleDateFormat(pattern);
+	}
+
+	public synchronized String format(LoggingEvent event) {
+		date.setTime(event.time);
+		return dateFormat.format(date);
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/goodjava/logger/GoodLogger.java	Sun Feb 23 18:14:32 2020 -0700
@@ -0,0 +1,72 @@
+package goodjava.logger;
+
+import goodjava.logging.Logger;
+
+
+public final class GoodLogger implements Logger {
+	public final String name;
+	public volatile int level = Level.INFO;
+	public volatile Appender appender = DEFAULT_APPENDER;
+
+	GoodLogger(String name) {
+		this.name = name;
+	}
+
+	private void log(int level,String msg,Throwable t) {
+		if( level < this.level )
+			return;
+		LoggingEvent event = new LoggingEvent(this,level,msg,t);
+		appender.append(event);
+	}
+
+
+	@Override public void error(String msg) {
+		error(msg,null);
+	}
+
+	@Override public void error(String msg,Throwable t) {
+		log(Level.ERROR,msg,t);
+	}
+
+	@Override public void warn(String msg) {
+		warn(msg,null);
+	}
+
+	@Override public void warn(String msg,Throwable t) {
+		log(Level.WARN,msg,t);
+	}
+
+	@Override public void info(String msg) {
+		info(msg,null);
+	}
+
+	@Override public void info(String msg,Throwable t) {
+		log(Level.INFO,msg,t);
+	}
+
+	@Override public boolean isInfoEnabled() {
+		return isEnabled(Level.INFO);
+	}
+
+	@Override public void debug(String msg) {
+		debug(msg,null);
+	}
+
+	@Override public void debug(String msg,Throwable t) {
+		log(Level.DEBUG,msg,t);
+	}
+
+	@Override public boolean isDebugEnabled() {
+		return isEnabled(Level.DEBUG);
+	}
+
+	private boolean isEnabled(int level) {
+		return true;
+	}
+
+
+	private static final Layout DEFAULT_LAYOUT 
+		= new ListLayout(Layouts.LEVEL," - ",Layouts.MESSAGE,"\n",Layouts.THROWABLE);
+
+	private static final WriterAppender DEFAULT_APPENDER = new ConsoleAppender(DEFAULT_LAYOUT,System.err);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/goodjava/logger/GoodLoggerFactory.java	Sun Feb 23 18:14:32 2020 -0700
@@ -0,0 +1,20 @@
+package goodjava.logger;
+
+import java.util.Map;
+import java.util.HashMap;
+import goodjava.logging.ILoggerFactory;
+import goodjava.logging.Logger;
+
+
+public class GoodLoggerFactory implements ILoggerFactory {
+	private final Map<String,GoodLogger> map = new HashMap<String,GoodLogger>();
+
+	@Override public synchronized Logger getLogger(String name) {
+		GoodLogger logger = map.get(name);
+		if( logger == null ) {
+			logger = new GoodLogger(name);
+			map.put(name,logger);
+		}
+		return logger;
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/goodjava/logger/Layout.java	Sun Feb 23 18:14:32 2020 -0700
@@ -0,0 +1,6 @@
+package goodjava.logger;
+
+
+public interface Layout {
+	public String format(LoggingEvent event);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/goodjava/logger/Layouts.java	Sun Feb 23 18:14:32 2020 -0700
@@ -0,0 +1,51 @@
+package goodjava.logger;
+
+import java.io.StringWriter;
+import java.io.PrintWriter;
+
+
+public final class Layouts {
+	private Layouts() {}  // never
+
+	public static final Layout MESSAGE = new Layout() {
+		public String format(LoggingEvent event) {
+			return event.message;
+		}
+	};
+
+	public static final Layout LOGGER = new Layout() {
+		public String format(LoggingEvent event) {
+			return event.logger.name;
+		}
+	};
+
+	public static final Layout LEVEL = new Layout() {
+		public String format(LoggingEvent event) {
+			return Level.toString(event.level);
+		}
+	};
+
+	public static final Layout LEVEL_PADDED = new Layout() {
+		public String format(LoggingEvent event) {
+			return Level.toPaddedString(event.level);
+		}
+	};
+
+	public static final Layout THROWABLE = new Layout() {
+		public String format(LoggingEvent event) {
+			if( event.throwable == null )
+				return "";
+			StringWriter stringWriter = new StringWriter();
+			PrintWriter printWriter = new PrintWriter(stringWriter);
+			event.throwable.printStackTrace(printWriter);
+			return stringWriter.toString();
+		}
+	};
+
+	public static final Layout THREAD = new Layout() {
+		public String format(LoggingEvent event) {
+			return Thread.currentThread().getName();
+		}
+	};
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/goodjava/logger/Level.java	Sun Feb 23 18:14:32 2020 -0700
@@ -0,0 +1,23 @@
+package goodjava.logger;
+
+
+final class Level {
+	public final static int DEBUG = 0;
+	public final static int INFO = 1;
+	public final static int WARN = 2;
+	public final static int ERROR = 3;
+	public final static int OFF = 4;
+
+	private static final String[] names = {"DEBUG","INFO","WARN","ERROR"};
+
+	public static String toString(int level) {
+		return names[level];
+	}
+
+	private static final String[] paddedNames = {"DEBUG","INFO ","WARN ","ERROR"};
+
+	public static String toPaddedString(int level) {
+		return paddedNames[level];
+	}
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/goodjava/logger/ListLayout.java	Sun Feb 23 18:14:32 2020 -0700
@@ -0,0 +1,40 @@
+package goodjava.logger;
+
+
+public final class ListLayout implements Layout {
+	private final Layout[] layouts;
+
+	public ListLayout(final Object... args) {
+		layouts = new Layout[args.length];
+		for( int i=0; i<args.length; i++ ) {
+			Object obj = args[i];
+			if( obj instanceof Layout ) {
+				layouts[i] = (Layout)obj;
+			} else if( obj instanceof String ) {
+				layouts[i] = new StringLayout((String)obj);
+			} else {
+				throw new IllegalArgumentException("arg "+i);
+			}
+		}
+	}
+
+	public String format(LoggingEvent event) {
+		StringBuilder sb = new StringBuilder();
+		for( Layout layout : layouts ) {
+			sb.append( layout.format(event) );
+		}
+		return sb.toString();
+	}
+
+	private static final class StringLayout implements Layout {
+		final String s;
+
+		StringLayout(String s) {
+			this.s = s;
+		}
+
+		public String format(LoggingEvent event) {
+			return s;
+		}
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/goodjava/logger/LoggingEvent.java	Sun Feb 23 18:14:32 2020 -0700
@@ -0,0 +1,17 @@
+package goodjava.logger;
+
+
+public final class LoggingEvent {
+	public final GoodLogger logger;
+	public final int level;
+	public final String message;
+	public final Throwable throwable;
+	public final long time = System.currentTimeMillis();
+
+	LoggingEvent(GoodLogger logger,int level,String message,Throwable throwable) {
+		this.logger = logger;
+		this.level = level;
+		this.message = message;
+		this.throwable = throwable;
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/goodjava/logger/WriterAppender.java	Sun Feb 23 18:14:32 2020 -0700
@@ -0,0 +1,40 @@
+package goodjava.logger;
+
+import java.io.Writer;
+import java.io.IOException;
+
+
+public class WriterAppender implements Appender {
+	protected final Layout layout;
+	protected Writer writer;
+
+	public WriterAppender(Layout layout,Writer writer) {
+		this.layout = layout;
+		this.writer = writer;
+	}
+
+	public synchronized void append(LoggingEvent event) {
+		try {
+			writer.write( layout.format(event) );
+			flush();
+		} catch(IOException e) {
+			printStackTrace(e);
+		}
+	}
+
+	protected void flush() throws IOException {
+		writer.flush();
+	}
+
+	public void close() {
+		try {
+			writer.close();
+		} catch(IOException e) {
+			printStackTrace(e);
+		}
+	}
+
+	protected void printStackTrace(IOException e) {
+		e.printStackTrace();
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/goodjava/logging/ILoggerFactory.java	Sun Feb 23 18:14:32 2020 -0700
@@ -0,0 +1,6 @@
+package goodjava.logging;
+
+
+public interface ILoggerFactory {
+	public Logger getLogger(String name);
+}
--- a/src/goodjava/logging/Log4jFactory.java	Tue Feb 18 14:54:35 2020 -0700
+++ b/src/goodjava/logging/Log4jFactory.java	Sun Feb 23 18:14:32 2020 -0700
@@ -1,7 +1,7 @@
 package goodjava.logging;
 
 
-public final class Log4jFactory extends LoggerFactory {
+public final class Log4jFactory implements ILoggerFactory {
 	private static final class Log4jLogger implements Logger {
 		final org.apache.log4j.Logger log4j;
 
@@ -33,6 +33,10 @@
 			log4j.info(msg,t);
 		}
 
+		@Override public boolean isInfoEnabled() {
+			return log4j.isInfoEnabled();
+		}
+
 		@Override public void debug(String msg) {
 			log4j.debug(msg);
 		}
@@ -40,13 +44,13 @@
 		@Override public void debug(String msg,Throwable t) {
 			log4j.debug(msg,t);
 		}
+
+		@Override public boolean isDebugEnabled() {
+			return log4j.isDebugEnabled();
+		}
 	}
 
-	@Override protected Logger getLoggerImpl(Class cls) {
-		return new Log4jLogger(org.apache.log4j.Logger.getLogger(cls));
-	}
-
-	@Override protected Logger getLoggerImpl(String name) {
+	@Override public Logger getLogger(String name) {
 		return new Log4jLogger(org.apache.log4j.Logger.getLogger(name));
 	}
 }
--- a/src/goodjava/logging/Logger.java	Tue Feb 18 14:54:35 2020 -0700
+++ b/src/goodjava/logging/Logger.java	Sun Feb 23 18:14:32 2020 -0700
@@ -9,6 +9,8 @@
 	public void warn(String msg,Throwable t);
 	public void info(String msg);
 	public void info(String msg,Throwable t);
+	public boolean isInfoEnabled();
 	public void debug(String msg);
 	public void debug(String msg,Throwable t);
+	public boolean isDebugEnabled();
 }
--- a/src/goodjava/logging/LoggerFactory.java	Tue Feb 18 14:54:35 2020 -0700
+++ b/src/goodjava/logging/LoggerFactory.java	Sun Feb 23 18:14:32 2020 -0700
@@ -1,17 +1,26 @@
 package goodjava.logging;
 
 
-public abstract class LoggerFactory {
-	public static LoggerFactory implementation = new Log4jFactory();
-
-	protected abstract Logger getLoggerImpl(Class cls);
-	protected abstract Logger getLoggerImpl(String name);
-
-	public static Logger getLogger(Class cls) {
-		return implementation.getLoggerImpl(cls);
+public final class LoggerFactory {
+	public static final ILoggerFactory implementation;
+	static {
+		String s = System.getProperty("goodjava.logger","goodjava.logging.Log4jFactory");
+		try {
+			implementation = (ILoggerFactory)Class.forName(s).newInstance();
+		} catch(ClassNotFoundException e) {
+			throw new RuntimeException(e);
+		} catch(InstantiationException e) {
+			throw new RuntimeException(e);
+		} catch(IllegalAccessException e) {
+			throw new RuntimeException(e);
+		}
 	}
 
 	public static Logger getLogger(String name) {
-		return implementation.getLoggerImpl(name);
+		return implementation.getLogger(name);
+	}
+
+	public static Logger getLogger(Class cls) {
+		return getLogger(cls.getName());
 	}
 }