package iiuf.log; import java.io.ObjectOutputStream; import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.PrintStream; import java.io.OutputStream; import java.io.IOException; import java.net.InetAddress; import java.net.Socket; import java.util.HashMap; import java.util.LinkedList; import iiuf.util.Timer; /** Log client implementation. Set the "log.host" property to set the host where the server is running (default is "localhost"). Set the "log.port" property to set the tcp port used for logging (default is 7659). Set the "log.qsize" property to limit message buffering on the client side (default is 100, use -1 for unlimited buffering). (c) 2000, 2001, IIUF, DIUF<p> @author $Author: ohitz $ @version $Name: $ $Revision: 1.1 $ */ public class Client extends Thread { public static int PORT = 0x1DEB; ObjectOutputStream out; InetAddress server; int port; static Client client; LinkedList queue = new LinkedList(); int MAX_QSIZE; static class State { StringBuffer b = new StringBuffer(); Thread thread; State(Thread t) { thread = t; } void append(int c) { b.append((char)c); if(c == '\n') { String line = b.toString(); if(Client.client == null) { Log.out.print(line); } else Client.client.log(new LogMessage(thread, Const.LOG_INFO, Const.STDOUT, line)); b = new StringBuffer(); } } } static class StdOutStream extends OutputStream { HashMap threads = new HashMap(); public synchronized void write(int c) { Thread curr = Thread.currentThread(); State s = (State)threads.get(curr); if(s == null) { s = new State(curr); threads.put(curr, s); } s.append(c); } } static class ErrorStream extends OutputStream { HashMap threads = new HashMap(); class State implements Runnable { StringBuffer b = new StringBuffer(); Thread thread; String exception = ""; boolean exceptionDump = false; Timer timer = new Timer(this, false); State(Thread t) { thread = t; } void append(int c) { b.append((char)c); if(c == '\n') { String line = b.toString(); if(exceptionDump) { if(line.startsWith("\tat ")) { exception += line; timer.cancel(); timer.schedule(500); } else { exception(); stderr(line); } } else { int idx = line.indexOf(':'); if(idx != -1) { try { if(Throwable.class.isAssignableFrom(Class.forName(line.substring(0, idx)))) { exceptionDump = true; exception += line; } else stderr(line); } catch(Exception e) { stderr(line); } } else { try { if(Throwable.class.isAssignableFrom(Class.forName(line.trim()))) { exceptionDump = true; exception += line; } else stderr(line); } catch(Exception e) { stderr(line); } } } b = new StringBuffer(); } } public void run() { if(exception.length() > 50) exception(); } void exception() { if(Client.client == null) Log.out.print(exception); else Client.client.log(new LogMessage(thread, Const.LOG_ERR, "Runtime Exception", exception)); exception = ""; exceptionDump = false; } void stderr(String line) { if(Client.client == null) Log.out.print(line); else Client.client.log(new LogMessage(thread, Const.LOG_WARNING, Const.STDERR, line)); } } public synchronized void write(int c) { Thread curr = Thread.currentThread(); State s = (State)threads.get(curr); if(s == null) { s = new State(curr); threads.put(curr, s); } s.append(c); } } static { Log.err = System.err; Log.out = System.out; System.setErr(new PrintStream(new ErrorStream())); System.setOut(new PrintStream(new StdOutStream())); } public Client() { this(getHost(), getPort()); } private static InetAddress getHost() { try { return InetAddress.getByName(System.getProperty("log.host")); } catch(Exception e) { try { return InetAddress.getLocalHost(); } catch(Exception ex) { return null; } } } private static int getPort() { try { return Integer.parseInt(System.getProperty("log.port")); } catch(Exception e) { return PORT; } } public Client(InetAddress server_, int port_) { server = server_; port = port_; client = this; MAX_QSIZE = 100; try{MAX_QSIZE = Integer.parseInt(System.getProperty("log.qsize"));} catch(Exception e) {} start(); } public void log(int priority, String message, Throwable exception) { log(new LogMessage(Thread.currentThread(), priority, message, exception)); } synchronized void log(LogMessage m) { m.time = System.currentTimeMillis(); if(MAX_QSIZE > 0 && queue.size() >= MAX_QSIZE) queue.removeFirst(); queue.add(m); notify(); } public synchronized void run() { for(;;) { try{wait(10000);} catch(InterruptedException e) {e.printStackTrace(Log.err);} if(out == null) connect(); if(out != null) { try { while(!queue.isEmpty()) { out.writeObject(queue.getFirst()); queue.removeFirst(); } out.flush(); } catch(Exception e) { out = null; } } } } private synchronized void connect() { try { out = new ObjectOutputStream(new Socket(server, port).getOutputStream()); } catch(Exception e) { out = null; } } public static void main(String[] argv) { try { if(argv.length > 2) { Log.err.println("usage: " + Client.class.getName() + " [server [port]]"); System.exit(1); } Client c = argv.length == 0 ? new Client() : new Client(InetAddress.getByName(argv[0]), argv.length == 2 ? Integer.parseInt(argv[1]) : PORT); BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); for(;;) { String line = in.readLine(); if(line == null || line.equals("")) { break; } try{ int prio = Integer.parseInt(line.substring(0, 1)); if(prio < 0 || prio > 7) throw new IllegalArgumentException("illegal priority value:" + prio); c.log(prio, line.substring(1), null); } catch(Exception e) { c.log(Const.LOG_ERR, line, e); } } } catch(Exception e) { e.printStackTrace(); } } } /* $Log: Client.java,v $ Revision 1.1 2002/07/11 12:24:01 ohitz Initial checkin Revision 1.10 2001/04/11 12:04:44 schubige adapted tinja stuff for semantic checks Revision 1.9 2001/01/17 09:55:45 schubige Logger update Revision 1.8 2001/01/04 16:28:36 schubige Header update for 2001 and DIUF Revision 1.7 2000/11/09 07:48:43 schubige early checkin for DCJava Revision 1.6 2000/10/19 08:03:45 schubige Intermediate graph component related checkin Revision 1.5 2000/10/17 15:35:59 schubige Added watcher preferences Revision 1.4 2000/10/10 16:32:11 schubige Added subtree display to TreeView, fixed some bugs Revision 1.3 2000/10/09 07:29:15 schubige Features, features, features Revision 1.2 2000/10/09 06:47:55 schubige Updated logger stuff Revision 1.1 2000/10/05 14:59:30 schubige Added loging stuff */