/** easy to use logger */
public class Log {
- public static boolean on = true;
- public static boolean rpc = false;
- 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 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;
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;
while((s = br.readLine()) != null) m += s + "\n";
if (m.length() > 0) log(o, m.substring(0, m.length() - 1), level);
} catch (IOException e) {
- logstream.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;