From bb4a7c21c7f1ca1efaa78f44dab205f1340face2 Mon Sep 17 00:00:00 2001 From: Eric Scharff Date: Wed, 26 Sep 2007 14:46:21 -0600 Subject: [PATCH] Implemented a simple but working implementation of the java logging API, complete with a test class --- classpath/java/lang/Throwable.java | 4 + classpath/java/util/logging/Handler.java | 6 ++ classpath/java/util/logging/Level.java | 30 ++++++ classpath/java/util/logging/LogRecord.java | 38 ++++++++ classpath/java/util/logging/Logger.java | 67 ++++++++++++++ test/Logging.java | 103 +++++++++++++++++++++ 6 files changed, 248 insertions(+) create mode 100644 classpath/java/util/logging/Handler.java create mode 100644 classpath/java/util/logging/Level.java create mode 100644 classpath/java/util/logging/LogRecord.java create mode 100644 classpath/java/util/logging/Logger.java create mode 100644 test/Logging.java diff --git a/classpath/java/lang/Throwable.java b/classpath/java/lang/Throwable.java index 85cefd8305..921da24ea2 100644 --- a/classpath/java/lang/Throwable.java +++ b/classpath/java/lang/Throwable.java @@ -63,6 +63,10 @@ public class Throwable { return (StackTraceElement[]) trace; } + public StackTraceElement[] getStackTrace() { + return resolveTrace(); + } + public void printStackTrace(PrintStream out) { StringBuilder sb = new StringBuilder(); printStackTrace(sb, System.getProperty("line.separator")); diff --git a/classpath/java/util/logging/Handler.java b/classpath/java/util/logging/Handler.java new file mode 100644 index 0000000000..b152d109ab --- /dev/null +++ b/classpath/java/util/logging/Handler.java @@ -0,0 +1,6 @@ +package java.util.logging; + +public class Handler { + public void publish(LogRecord r) { + } +} diff --git a/classpath/java/util/logging/Level.java b/classpath/java/util/logging/Level.java new file mode 100644 index 0000000000..3c41f3d97a --- /dev/null +++ b/classpath/java/util/logging/Level.java @@ -0,0 +1,30 @@ +package java.util.logging; + +public class Level { + public static final Level FINEST = new Level("FINEST", 300); + public static final Level FINER = new Level("FINER", 400); + public static final Level FINE = new Level("FINE", 500); + public static final Level INFO = new Level("INFO", 800); + public static final Level WARNING = new Level("WARNING", 900); + public static final Level SEVERE = new Level("SEVERE", 1000); + + private final int value; + private final String name; + + private Level(String name, int value) { + this.name = name; + this.value = value; + } + + public int intValue() { + return value; + } + + public String getName() { + return name; + } + + public String toString() { + return name; + } +} diff --git a/classpath/java/util/logging/LogRecord.java b/classpath/java/util/logging/LogRecord.java new file mode 100644 index 0000000000..645b03ca9a --- /dev/null +++ b/classpath/java/util/logging/LogRecord.java @@ -0,0 +1,38 @@ +package java.util.logging; + +public class LogRecord { + private final String loggerName; + private final String message; + private final Throwable thrown; + private final Level level; + private final String methodName; + + LogRecord(String loggerName, String methodName, Level level, String message, + Throwable thrown) { + this.loggerName = loggerName; + this.message = message; + this.thrown = thrown; + this.level = level; + this.methodName = methodName; + } + + public String getLoggerName() { + return loggerName; + } + + public String getMessage() { + return message; + } + + public Throwable getThrown() { + return thrown; + } + + public Level getLevel() { + return level; + } + + public String getSourceMethodName() { + return methodName; + } +} diff --git a/classpath/java/util/logging/Logger.java b/classpath/java/util/logging/Logger.java new file mode 100644 index 0000000000..e0635ee520 --- /dev/null +++ b/classpath/java/util/logging/Logger.java @@ -0,0 +1,67 @@ +package java.util.logging; + +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; + +public class Logger { + private final String name; + private static final ArrayList handlers = new ArrayList(); + + public static Logger getLogger(String name) { + return new Logger(name); + } + + private Logger(String name) { + this.name = name; + } + + public List getHandlers() { + return handlers; + } + + public void addHandler(Handler handler) { + handlers.add(handler); + } + + public void removeHandler(Handler handler) { + handlers.remove(handler); + } + + public void fine(String message) { + log(Level.FINE, Method.getCaller(), message, null); + } + + public void info(String message) { + log(Level.INFO, Method.getCaller(), message, null); + } + + public void warning(String message) { + log(Level.WARNING, Method.getCaller(), message, null); + } + + public void severe(String message) { + log(Level.SEVERE, Method.getCaller(), message, null); + } + + public void log(Level level, String message) { + log(level, Method.getCaller(), message, null); + } + + public void log(Level level, String message, Throwable exception) { + log(level, Method.getCaller(), message, exception); + } + + private void log(Level level, Method caller, String message, + Throwable exception) { + LogRecord r = new LogRecord(name, caller.getName(), level, message, + exception); + for (Handler h : handlers) { + h.publish(r); + } + } + + public void setLevel(Level level) { + // Currently ignored + } +} diff --git a/test/Logging.java b/test/Logging.java new file mode 100644 index 0000000000..6805e43f2b --- /dev/null +++ b/test/Logging.java @@ -0,0 +1,103 @@ +import java.util.logging.Handler; +import java.util.logging.Level; +import java.util.logging.LogRecord; +import java.util.logging.Logger; + +public class Logging { + private static final Logger log = Logger.getLogger("Logging"); + + private static class MyHandler extends Handler { + private static final int NAME_WIDTH = 18; + private static final int METHOD_WIDTH = 20; + private static final int LEVEL_WIDTH = 8; + + public Object clone() { return this; } + public void close() { } + public void flush() { } + + private void maybeLogThrown(StringBuilder sb, Throwable t) { + if (t != null) { + sb.append("\nCaused by: "); + sb.append(t.getClass().getName()); + sb.append(": "); + sb.append(t.getMessage()); + sb.append('\n'); + + for (StackTraceElement elt : t.getStackTrace()) { + sb.append('\t'); + sb.append(elt.getClassName()); + sb.append('.'); + sb.append(elt.getMethodName()); + sb.append('('); + sb.append(elt.getFileName()); + sb.append(':'); + sb.append(elt.getLineNumber()); + sb.append(')'); + sb.append('\n'); + } + maybeLogThrown(sb, t.getCause()); + } + } + + private void indent(StringBuilder sb, int amount) { + do { + sb.append(' '); + } while (--amount > 0); + } + + public void publish(LogRecord r) { + StringBuilder sb = new StringBuilder(); + sb.append(r.getLoggerName()); + indent(sb, NAME_WIDTH - r.getLoggerName().length()); + sb.append(r.getSourceMethodName()); + indent(sb, METHOD_WIDTH - r.getSourceMethodName().length()); + sb.append(r.getLevel().getName()); + indent(sb, LEVEL_WIDTH - r.getLevel().getName().length()); + sb.append(r.getMessage()); + maybeLogThrown(sb, r.getThrown()); + System.out.println(sb.toString()); + } + } + + public void run() { + log.info("Started run"); + a(); + log.info("Ended run"); + } + + private void a() { + log.fine("Started a()"); + b(); + } + + private void b() { + log.info("Started b()"); + c(); + } + + private void c() { + log.warning("Started c()"); + try { + d(); + } catch (Exception ex) { + log.log(Level.SEVERE, "Exception caught in c", ex); + } + } + + private void d() throws Exception { + e(); + } + + private void e() throws Exception { + throw new Exception("Started here"); + } + + public static void main(String args[]) { + Logger root = Logger.getLogger(""); + root.addHandler(new MyHandler()); + for (Handler h : root.getHandlers()) root.removeHandler(h); + root.addHandler(new MyHandler()); + Logging me = new Logging(); + me.run(); + } +}