// // Copyright (C) 2006 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.util; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.io.PrintWriter; import java.net.ConnectException; import java.net.Socket; import java.net.UnknownHostException; import java.util.logging.Formatter; import java.util.logging.Handler; import java.util.logging.LogRecord; import java.util.logging.Logger; import gov.nasa.jpf.Config; /** * log handler class that deals with output selection and formatting. This is the * only handler we use for our own logging. We do our own little formatting * on the fly */ public class LogHandler extends Handler { static class DefaultFormatter extends Formatter { boolean format; boolean showName; boolean showLevel; //..and potentially more DefaultFormatter (Config conf) { showName = conf.getBoolean("log.show_name", false); showLevel = conf.getBoolean("log.show_level", true); format = showName || showLevel; } DefaultFormatter (boolean showName, boolean showLevel){ this.showName = showName; this.showLevel = showLevel; format = showName || showLevel; } // we might want to parameterize this public String format (LogRecord r) { if (format) { StringBuilder sb = new StringBuilder(); sb.append('['); if (showLevel) { sb.append(r.getLevel().getName()); } if (showName) { if (showLevel) { sb.append(":"); } sb.append(r.getLoggerName()); } sb.append("] "); String msg = r.getMessage(); Object[] params = r.getParameters(); if (params == null){ sb.append(msg); } else { sb.append(String.format(msg,params)); } return sb.toString(); } else { // raw return r.getMessage(); } } } public static String LOG_HOST = "localhost"; public static int LOG_PORT = 20000; File file; Socket socket; OutputStream ostream; PrintWriter out; public LogHandler (Config conf) { LOG_HOST = conf.getString("log.host", LOG_HOST); LOG_PORT = conf.getInt("log.port", LOG_PORT); String output = conf.getString("log.output", "out"); if (output.matches("[a-zA-Z0-9.]*:[0-9]*")) { // we assume that's a hostname:port spec int idx = output.indexOf(':'); String host = output.substring(0, idx); String port = output.substring(idx+1, output.length()); ostream = connectSocket( host, port); } else if (output.equalsIgnoreCase("socket")){ ostream = connectSocket( LOG_HOST, Integer.toString(LOG_PORT)); } else if (output.equalsIgnoreCase("out") || output.equals("System.out")) { ostream = System.out; } else if (output.equalsIgnoreCase("err") || output.equals("System.err")) { ostream = System.err; } else { ostream = openFile(output); } if (ostream == null) { ostream = System.out; } setFormatter(new DefaultFormatter(conf)); setOutput(ostream); } protected LogHandler() { // for derived classes } OutputStream connectSocket (String host, String portSpec) { int port = -1; if ((host == null) || (host.length() == 0)) { host = LOG_HOST; } if (portSpec != null) { try { port = Integer.parseInt(portSpec); } catch (NumberFormatException x) { // just catch it } } if (port == -1) { port = LOG_PORT; } try { socket = new Socket(host, port); return socket.getOutputStream(); } catch (UnknownHostException uhx) { //System.err.println("unknown log host: " + host); } catch (ConnectException cex) { //System.err.println("no log host detected); } catch (IOException iox) { //System.err.println(iox); } return null; } OutputStream openFile (String fileName) { file = new File(fileName); try { if (file.exists()) { file.delete(); } file.createNewFile(); return new FileOutputStream(file); } catch (IOException iox) { // just catch it } return null; } public void setOutput (OutputStream ostream) { out = new PrintWriter(ostream, true); } public void close () throws SecurityException { if ((ostream != System.err) && (ostream != System.out)) { out.close(); } if (socket != null) { try { socket.close(); } catch (IOException iox) { // not much we can do } } } public void flush () { out.flush(); } public void publish (LogRecord r) { String msg = getFormatter().format(r); out.println(msg); } public void printStatus (Logger log) { if (socket != null) { log.config("logging to socket: " + socket); } else if (file != null) { log.config("logging to file: " + file.getAbsolutePath()); } else if (ostream == System.err) { log.config("logging to System.err"); } else if (ostream == System.out) { log.config("logging to System.out"); } else { log.warning("unknown log destination"); } } // a dfault handler that doesn't need Config public static class DefaultConsoleHandler extends LogHandler { public DefaultConsoleHandler() { ostream = System.out; setFormatter(new DefaultFormatter(false,true)); setOutput(ostream); } } }