From: pcm <pcm...@us...> - 2005-05-18 06:41:58
|
Update of /cvsroot/javapathfinder/javapathfinder/src/gov/nasa/jpf/tools In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv30521/src/gov/nasa/jpf/tools Modified Files: SearchMonitor.java Added Files: LogConsole.java Log Message: this is the advent of the Debug replacement. We are using a conventional log scheme that actually piggybacks on java.util.logging, even though we don't really use logger hierarchies, we have our own initialization scheme, and we use our own log handler class. The reason for this is that we still want to maintain a single configuration scheme, and we want to be able to log to three different output destinations (hostname:port, file, out/err) without requiring to change class names in a logging.properties file. The handler is still very primitive in terms of output formatting, and the config consists of the following entries # what is our default level for unspecified loggers log.level=<defaultLevel> # where to log to log.output=<filename> | out | err | <hostname>:<port> # logger specific levels log.severe=<logger-pattern>{:<logger-pattern> log.warning=.. log.info=.. log.config=.. log.fine=.. log.finer=.. log.finest=.. There is a new class gov.nasa.jpf.tools.LogConsole that can be used to display socket logging. This is now also meant to be used for the SearchMonitor. With this in place, Debug statements will now be replaced with the standard java.util.logging.Logger API, i.e. static Logger log = JPF.getLogger("gov.nasa.jpf.<whatever>"); .. log.severe(msg); .. log.info(msg); .. There is one caveat to notice: since Config results are reported by means of the logging facility, but the logging is configured via Config (single source), the Config initialization (ctor) is not allowed to produce logging output, but rather has to preserve all states, failures etc. for subsequent reporting (by JPF). This is less than optimal from a design point of view (cyclic dependency), but the user-friendly pinciple of a single config source overrides this. Second caveat is that log output should be event based, not line-by-line, which means there is an increased tendency to see hidden StringBuffer use. If there is a good chance the log level will not be set, this should be wrapped for efficiency reasons in if (logger.isLoggable(Level.<whatever>)) { logger.fine("Blah " + gna + '\n' + "another line"); } The scheme could be extended to enable logger specific output (i.e. one console for vm, another one for a listener etc.) , and the console to allow multiple simultaneous connects, but we leave that for later (if it really makes sense). For now it is important that we can replace the Debug statements. --- NEW FILE: LogConsole.java --- // //Copyright (C) 2005 United States Government as represented by the //Administrator of the National Aeronautics and Space Administration //(NASA). All Rights Reserved. // //This software is distributed under the NASA Open Source Agreement //(NOSA), version 1.3. The NOSA has been approved by the Open Source //Initiative. See the file NOSA-1.3-JPF at the top of the distribution //directory tree for the complete NOSA document. // //THE SUBJECT SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY OF ANY //KIND, EITHER EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT //LIMITED TO, ANY WARRANTY THAT THE SUBJECT SOFTWARE WILL CONFORM TO //SPECIFICATIONS, ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR //A PARTICULAR PURPOSE, OR FREEDOM FROM INFRINGEMENT, ANY WARRANTY THAT //THE SUBJECT SOFTWARE WILL BE ERROR FREE, OR ANY WARRANTY THAT //DOCUMENTATION, IF PROVIDED, WILL CONFORM TO THE SUBJECT SOFTWARE. // package gov.nasa.jpf.tools; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.ServerSocket; import java.net.Socket; /** * simple logging facility that listens on a socket (e.g. for log output display) */ public class LogConsole { static int DEF_PORT = 20000; // keep this in sync with the gov.nasa.jpf.util.LogHandler class ShutdownHook implements Runnable { public void run () { if (running) { // not very threadsafe, but worst thing that can happen is we close twice killed = true; System.out.println("\nLogConsole killed, shutting down"); } try { cs.close(); ss.close(); } catch (Throwable t) { // not much we can do here anyway } } } boolean running; int port; boolean autoclose; boolean killed; ServerSocket ss; Socket cs; public void run () { running = true; Runtime.getRuntime().addShutdownHook(new Thread(new ShutdownHook())); if (port == 0) { port = DEF_PORT; } try { ss = new ServerSocket(port); try { do { System.out.println("LogConsole listening on port: " + port); cs = ss.accept(); BufferedReader in = new BufferedReader( new InputStreamReader(cs.getInputStream())); String msg; System.out.println("LogConsole connected"); System.out.println("--------------------------------------------------------------------------------"); try { while ((msg = in.readLine()) != null) { System.out.println(msg); } System.out.println("--------------------------------------------------------------------------------"); System.out.println("LogConsole disconnected"); } catch (IOException iox) { System.err.println(iox); } in.close(); cs.close(); } while (!autoclose); System.out.println("LogConsole closing"); } catch (IOException iox) { if (!killed) { System.err.println("Error: LogConsole accept failed on port: " + port); } } } catch (IOException iox) { System.err.println("Error: LogConsole cannot listen on port: " + port); } running = false; } public void showUsage () { System.out.println("LogConsole: socket based console logger"); System.out.println(" usage: java gov.nasa.jpf.tools.LogConsole {flags} [<port>]"); System.out.println(" args: -help show this message"); System.out.println(" -autoclose close the application upon disconnect"); System.out.println(" <port> optional port number, default: " + DEF_PORT); } boolean processArgs (String[] args) { for (int i=0; i<args.length; i++) { if (args[i].charAt(0) == '-') { if (args[i].equals("-autoclose")) { args[i] = null; autoclose = true; } else if (args[i].equals("-help")) { showUsage(); return false; } else { System.err.println("Warning: unknown argument (see -help for usage): " + args[i]); } } else { if (args[i].matches("[0-9]+")) { if (port != 0) { System.err.println("Error: only one port parameter allowed (see -help for usage): " + args[i]); return false; } try { port = Integer.parseInt(args[i]); } catch (NumberFormatException nfx) { System.err.println("Error: illegal port spec: " + args[i]); return false; } } else { System.out.println("Error: unknown argument: " + args[i]); return false; } } } return true; } public static void main (String[] args) { LogConsole console = new LogConsole(); if (console.processArgs(args)) { console.run(); } } } Index: SearchMonitor.java =================================================================== RCS file: /cvsroot/javapathfinder/javapathfinder/src/gov/nasa/jpf/tools/SearchMonitor.java,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -d -r1.1.1.1 -r1.2 --- SearchMonitor.java 26 Apr 2005 19:44:22 -0000 1.1.1.1 +++ SearchMonitor.java 18 May 2005 06:41:45 -0000 1.2 @@ -41,17 +41,19 @@ */ public class SearchMonitor implements SearchListener { - boolean logger; // true if this is just listening & reporting on an externally running JPF - boolean autoclose = false; - String host = "localhost"; - int port = 5556; + static final String DEF_HOSTNAME = "localhost"; + static final int DEF_PORT = 20000; + static final int DEF_INTERVAL = 1000; // min duration in ms between reports + + String hostName = DEF_HOSTNAME; + int port = DEF_PORT; Socket sock; PrintWriter out; int reportNumber; - int interval = 1000; // min duration in ms between reports + int interval = DEF_INTERVAL; long time; long lastTime; long startTime; @@ -247,36 +249,60 @@ out.println(); } + int consumeIntArg (String[] args, int i, String varName, int def) { + int ret = def; + + args[i] = null; + if (i < args.length-1){ + i++; + try { + ret = Integer.parseInt(args[i]); + args[i] = null; + } catch (NumberFormatException nfx) { + System.err.print("Warning: illegal " + varName + " specification: " + args[i] + + " using default " + ret); + } + } + + return ret; + } + void filterArgs (String[] args) { for (int i=0; i<args.length; i++) { - if (args[i].equals("-logger")) { - args[i] = null; - logger = true; - } else if (args[i].equals("-autoclose")) { + if (args[i].equals("-port")) { + port = consumeIntArg(args, i++, "port", DEF_PORT); + } else if (args[i].equals("-interval")) { + interval = consumeIntArg(args, i++, "interval", DEF_INTERVAL); + } else if (args[i].equals("-hostname")) { args[i] = null; - autoclose = true; + if (i < args.length-1){ + i++; + hostName = args[i]; + args[i] = null; + } } } } static void printUsage () { System.out.println("SearchMonitor - a JPF listener tool to monitor JPF searches"); - System.out.println("usage: java gov.nasa.jpf.tools.SearchMonitor <jpf-options> <monitor-options> <class>"); + System.out.println("usage: java gov.nasa.jpf.tools.SearchMonitor <jpf-options> <monitor-options> <class>"); System.out.println("<monitor-options>:"); - System.out.println(" -logger : run as a logger (don't run JPF)"); - System.out.println(" -autoclose : terminate logger after disconnect"); + System.out.println(" -hostname <name> : connect to host <name>, default: " + DEF_HOSTNAME); + System.out.println(" -port <num> : connect to port <num>, default: " + DEF_PORT); + System.out.println(" -interval <num> : report every <num> msec, default: " + DEF_INTERVAL); } void connect () { try { - sock = new Socket(host, port); + sock = new Socket(hostName, port); out = new PrintWriter(sock.getOutputStream(), true); } catch (UnknownHostException uhx) { - System.err.println("unknown log host: " + host + ", using System.out"); + System.err.println("Warning: unknown log host: " + hostName + ", using System.out"); } catch (ConnectException cex) { - System.err.println("no log host detected, using System.out"); + System.err.println("Warning: no log host detected, using System.out"); } catch (IOException iox) { System.err.println(iox); } @@ -286,60 +312,11 @@ } } - void log () { - try { - ServerSocket ss = new ServerSocket(port); - - try { - do { - System.out.println("logger listening on port: " + port); - - Socket cs = ss.accept(); - BufferedReader in = new BufferedReader( new InputStreamReader(cs.getInputStream())); - String msg; - - System.out.println("logger connected"); - System.out.println("------------------------------"); - try { - - while ((msg = in.readLine()) != null) { - System.out.println(msg); - } - - System.out.println("------------------------------"); - System.out.println("logger disconnected"); - } catch (IOException iox) { - System.err.println(iox); - } finally { - try { - in.close(); - cs.close(); - } catch (IOException iox) { - } - } - - } while (!autoclose); - - } catch (IOException iox) { - System.err.println("error: accept failed on port: " + port); - } finally { - ss.close(); - } - } catch (IOException iox) { - System.err.println("error: cannot listen on port: " + port); - } - } - public void run (Config conf) { - if (logger) { - log(); - - } else { - JPF jpf = new JPF(conf); - jpf.addSearchListener(this); + JPF jpf = new JPF(conf); + jpf.addSearchListener(this); - jpf.run(); - } + jpf.run(); } public static void main (String[] args) { @@ -348,29 +325,16 @@ return; } - SearchMonitor listener = new SearchMonitor(); - listener.filterArgs(args); - Config conf = JPF.createConfig(args); - listener.initFromConfig(conf); - + SearchMonitor listener = new SearchMonitor(conf); + + listener.filterArgs(args); listener.run(conf); } - void initFromConfig (Config config) { - host = config.getString("monitor.log_hostname", host); - port = config.getInt("monitor.log_port", port); - interval = config.getInt("monitor.interval", port); - } - - public SearchMonitor () { - // nothing to do here - } - - /** - * that is our JPF instantiation ctor - */ public SearchMonitor (Config config) { - initFromConfig(config); - } + hostName = config.getString("monitor.hostname", DEF_HOSTNAME); + port = config.getInt("monitor.port", DEF_PORT); + interval = config.getInt("monitor.interval", DEF_INTERVAL); + } } |