X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=src%2Forg%2Fibex%2Futil%2FLog.java;h=70f105452d3314a5c9477b1e3df9a0c3133cd5b8;hb=fffcafc33aa4066bdf85da7a32e1a1cdb9db2d6f;hp=e90b77432e9bbd37f5e3d9431d0b0ffc1658509c;hpb=ef73cbdf9c1fc30f4bc59453c7e759e0a507580f;p=org.ibex.core.git diff --git a/src/org/ibex/util/Log.java b/src/org/ibex/util/Log.java index e90b774..70f1054 100644 --- a/src/org/ibex/util/Log.java +++ b/src/org/ibex/util/Log.java @@ -9,16 +9,63 @@ package org.ibex.util; import org.ibex.js.*; import java.io.*; import java.util.*; +import java.net.*; /** easy to use logger */ public class Log { - public static boolean on = true; - public static boolean color = false; - public static boolean verbose = false; - public static boolean logDates = false; + public static boolean on = System.getProperty("ibex.log.on", "true").equals("true"); + public static boolean color = System.getProperty("ibex.log.color", "true").equals("true"); + public static boolean verbose = System.getProperty("ibex.log.verbose", "false").equals("true"); + public static boolean logDates = System.getProperty("ibex.log.dates", "false").equals("true"); + public static boolean notes = System.getProperty("ibex.log.notes.on", "true").equals("true"); + public static int maximumNoteLength = Integer.parseInt(System.getProperty("ibex.log.notes.maximumLength", (1024 * 32)+"")); + public static boolean rpc = false; public static Date lastDate = null; + public static PrintStream logstream = System.err; + + public static void flush() { logstream.flush(); } + public static void email(String address) { throw new Error("FIXME not supported"); } + public static void file(String filename) throws IOException { + // FIXME security + logstream = new PrintStream(new FileOutputStream(filename)); + } + public static void tcp(String host, int port) throws IOException { + // FIXME security + logstream = new PrintStream(new Socket(InetAddress.getByName(host), port).getOutputStream()); + } + + private static Hashtable threadAnnotations = new Hashtable(); + public static void setThreadAnnotation(String s) { threadAnnotations.put(Thread.currentThread(), s); } + + /** + * Notes can be used to attach log messages to the current thread + * if you're not sure you want them in the log just yet. + * Originally designed for retroactively logging socket-level + * conversations only if an error is encountered + */ + public static void note(String s) { + if (!notes) return; + StringBuffer notebuf = notebuf(); + notebuf.append(s); + if (notebuf.length() > maximumNoteLength) { + notebuf.reverse(); + notebuf.setLength(maximumNoteLength * 3 / 4); + notebuf.reverse(); + } + } + public static void clearnotes() { if (!notes) return; notebuf().setLength(0); } + private static Hashtable notebufs = new Hashtable(); + private static StringBuffer notebuf() { + StringBuffer ret = (StringBuffer)notebufs.get(Thread.currentThread()); + if (ret == null) { + ret = new StringBuffer(16 * 1024); + notebufs.put(Thread.currentThread(), ret); + } + return ret; + } + /** true iff nothing has yet been logged */ public static boolean firstMessage = true; @@ -35,10 +82,12 @@ public class Log { private static final int ECHO = -1; // the usual log4j levels, minus FAIL (we just throw an Error in that case) - private static final int DEBUG = 0; - private static final int INFO = 1; - private static final int WARN = 2; - private static final int ERROR = 3; + public static final int DEBUG = 0; + public static final int INFO = 1; + public static final int WARN = 2; + public static final int ERROR = 3; + public static final int SILENT = Integer.MAX_VALUE; + public static int level = INFO; private static final int BLUE = 34; private static final int GREEN = 32; @@ -58,10 +107,14 @@ public class Log { private static String lastClassName = null; private static synchronized void log(Object o, Object message, int level) { + if (level < Log.level) return; if (firstMessage && !logDates) { firstMessage = false; - System.err.println(colorize(GREEN, false, "===========================================================================")); - diag(Log.class, "Logging enabled at " + new java.util.Date()); + logstream.println(colorize(GREEN, false, "===========================================================================")); + + // FIXME later: causes problems with method pruning + //diag(Log.class, "Logging enabled at " + new java.util.Date()); + if (color) diag(Log.class, "logging messages in " + colorize(BLUE, true, "c") + colorize(RED, true, "o") + @@ -71,14 +124,16 @@ public class Log { } String classname; - if (o instanceof Class) classname = ((Class)o).getName(); + if (o instanceof Class) { + classname = ((Class)o).getName(); + if (classname.indexOf('.') != -1) classname = classname.substring(classname.lastIndexOf('.') + 1); + } else if (o instanceof String) classname = (String)o; else classname = o.getClass().getName(); if (classname.equals(lastClassName)) classname = ""; else lastClassName = classname; - if (classname.indexOf('.') != -1) classname = classname.substring(classname.lastIndexOf('.') + 1); if (classname.length() > (logDates ? 14 : 20)) classname = classname.substring(0, (logDates ? 14 : 20)); while (classname.length() < (logDates ? 14 : 20)) classname = " " + classname; classname = classname + (classname.trim().length() == 0 ? " " : ": "); @@ -89,33 +144,46 @@ public class Log { Date d = new Date(); if (lastDate == null || d.getYear() != lastDate.getYear() || d.getMonth() != lastDate.getMonth() || d.getDay() != lastDate.getDay()) { String now = new java.text.SimpleDateFormat("EEE dd MMM yyyy").format(d); - System.err.println(); - System.err.println(colorize(GRAY, false, "=== " + now + " ==========================================================")); + logstream.println(); + logstream.println(colorize(GRAY, false, "=== " + now + " ==========================================================")); } java.text.DateFormat df = new java.text.SimpleDateFormat("[EEE HH:mm:ss] "); classname = df.format(d) + classname; lastDate = d; } + String annot = (String)threadAnnotations.get(Thread.currentThread()); + if (annot != null) classname += annot; if (message instanceof Throwable) { if (level < ERROR) level = WARN; ByteArrayOutputStream baos = new ByteArrayOutputStream(); ((Throwable)message).printStackTrace(new PrintStream(baos)); + if (notes && notebuf().length() > 0) { + PrintWriter pw = new PrintWriter(baos); + pw.println(); + pw.println("Thread notes:"); + pw.println(notebuf().toString()); + clearnotes(); + pw.flush(); + } byte[] b = baos.toByteArray(); BufferedReader br = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(b))); String s = null; try { String m = ""; while((s = br.readLine()) != null) m += s + "\n"; - log(o, m.substring(0, m.length() - 1), level); + if (m.length() > 0) log(o, m.substring(0, m.length() - 1), level); } catch (IOException e) { - System.err.println(colorize(RED, true, "Logger: exception thrown by ByteArrayInputStream -- this should not happen")); + // FEATURE: use org.ibex.io.Stream's here + logstream.println(colorize(RED, true, "Logger: exception thrown by ByteArrayInputStream; this should not happen")); } + lastClassName = ""; return; } String str = message.toString(); + if (str.indexOf('\n') != -1) lastClassName = ""; while(str.indexOf('\t') != -1) str = str.substring(0, str.indexOf('\t')) + " " + str.substring(str.indexOf('\t') + 1); @@ -132,12 +200,12 @@ public class Log { } while(str.indexOf('\n') != -1) { - System.err.println(classname + colorize(levelcolor, bright, str.substring(0, str.indexOf('\n')))); + logstream.println(classname + colorize(levelcolor, bright, str.substring(0, str.indexOf('\n')))); classname = logDates ? " " : " "; classname = colorize(GRAY,false,classname); str = str.substring(str.indexOf('\n') + 1); } - System.err.println(classname + colorize(levelcolor, bright, str)); + logstream.println(classname + colorize(levelcolor, bright, str)); } public static void recursiveLog(String indent, String name, Object o) throws JSExn {