// jTDS JDBC Driver for Microsoft SQL Server and Sybase // Copyright (C) 2004 The jTDS Project // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either // version 2.1 of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // package net.sourceforge.jtds.util; import java.sql.*; import java.io.PrintWriter; import java.io.FileOutputStream; import java.io.IOException; /** * Class providing static methods to log diagnostics. * <p> * There are three ways to enable logging: * <ol> * <li>Pass a valid PrintWriter to DriverManager.setLogWriter(). * <li>Pass a valid PrintWriter to DataSource.setLogWriter(). * <li>For backwards compatibility call Logger.setActive(); * </ol> * * @author * Mike Hutchinson, Holger Rehn */ public class Logger { /** PrintWriter stream set by DataSource. */ private static PrintWriter log; /** * Set the logging PrintWriter stream. * * @param out the PrintWriter stream */ public static void setLogWriter(PrintWriter out) { log = out; } /** * Get the logging PrintWriter Stream. * * @return the logging stream as a <code>PrintWriter</code> */ public static PrintWriter getLogWriter() { return log; } /** * Retrieve the active status of the logger. * * @return <code>boolean</code> true if logging enabled */ public static boolean isActive() { return(log != null || DriverManager.getLogWriter() != null); } /** * <p> Print a diagnostic message to the output stream provided by the * {@link DataSource} or the {@link DriverManager}. </p> * * @param message * the diagnostic message to print */ public static void println( String message ) { if( log != null ) { log.println( message ); } else { // get writer, DriverManager isn't thread-safe (see bug #694) PrintWriter pw = DriverManager.getLogWriter(); if( pw != null ) { pw.println( message ); pw.flush(); } } } private static final char hex[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}; /** * Print a dump of the current input or output network packet. * * @param streamId the owner of this packet * @param in true if this is an input packet * @param pkt the packet data */ public static void logPacket(int streamId, boolean in, byte[] pkt) { int len = ((pkt[2] & 0xFF) << 8)| (pkt[3] & 0xFF); StringBuffer line = new StringBuffer(80); line.append("----- Stream #"); line.append(streamId); line.append(in ? " read" : " send"); line.append((pkt[1] != 0) ? " last " : " "); switch (pkt[0]) { case 1: line.append("Request packet "); break; case 2: line.append("Login packet "); break; case 3: line.append("RPC packet "); break; case 4: line.append("Reply packet "); break; case 6: line.append("Cancel packet "); break; case 14: line.append("XA control packet "); break; case 15: line.append("TDS5 Request packet "); break; case 16: line.append("MS Login packet "); break; case 17: line.append("NTLM Authentication packet "); break; case 18: line.append("MS Prelogin packet "); break; default: line.append("Invalid packet "); break; } println(line.toString()); println(""); line.setLength(0); for (int i = 0; i < len; i += 16) { if (i < 1000) { line.append(' '); } if (i < 100) { line.append(' '); } if (i < 10) { line.append(' '); } line.append(i); line.append(':').append(' '); int j = 0; for (; j < 16 && i + j < len; j++) { int val = pkt[i+j] & 0xFF; line.append(hex[val >> 4]); line.append(hex[val & 0x0F]); line.append(' '); } for (; j < 16 ; j++) { line.append(" "); } line.append('|'); for (j = 0; j < 16 && i + j < len; j++) { int val = pkt[i + j] & 0xFF; if (val > 31 && val < 127) { line.append((char) val); } else { line.append(' '); } } line.append('|'); println(line.toString()); line.setLength(0); } println(""); } /** * Print an Exception stack trace to the log. * * @param e * the exception to log */ public static void logException( Exception e ) { if( log != null ) { e.printStackTrace( log ); } else { // get writer, DriverManager isn't thread-safe (see bug #694) PrintWriter pw = DriverManager.getLogWriter(); if( pw != null ) { e.printStackTrace( pw ); pw.flush(); } } } // // Backward compatibility method // /** * Turn the logging on or off. * * @deprecated Use the JDBC standard mechanisms to enable logging. * @param value true to turn on logging */ public static void setActive(boolean value) { if (value && log == null) { try { log = new PrintWriter(new FileOutputStream("log.out"), true); } catch (IOException e) { log = null; // Sorry no logging! } } } }