You are viewing a plain text version of this content. The canonical link for it is here.
Posted to log4j-dev@logging.apache.org by sd...@apache.org on 2003/05/01 06:50:27 UTC

cvs commit: jakarta-log4j-sandbox/src/java/org/apache/log4j/spi ThrowableInformation.java LoggingEvent.java

sdeboy      2003/04/30 21:50:27

  Modified:    src/java/org/apache/log4j/chainsaw WelcomePanel.html
                        DefaultSortTableModel.java LogUI.java FileMenu.java
               src/java/org/apache/log4j/xml XMLDecoder.java
               src/java/org/apache/log4j/spi LoggingEvent.java
  Added:       src/java/org/apache/log4j/spi ThrowableInformation.java
  Log:
  Added save capability - saves all entries for current tab (even those currently filtered).  ThrowableInformation and LoggingEvent constructors were modified to accept a string[] because reconstructing a loggingevent with an exception by generating a new throwable added the xmldecoder's stack to the throwable's trace..
  
  Revision  Changes    Path
  1.4       +1 -0      jakarta-log4j-sandbox/src/java/org/apache/log4j/chainsaw/WelcomePanel.html
  
  Index: WelcomePanel.html
  ===================================================================
  RCS file: /home/cvs/jakarta-log4j-sandbox/src/java/org/apache/log4j/chainsaw/WelcomePanel.html,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- WelcomePanel.html	1 May 2003 04:11:04 -0000	1.3
  +++ WelcomePanel.html	1 May 2003 04:50:25 -0000	1.4
  @@ -54,6 +54,7 @@
   <h2>Quick Help</h2>
   <table border="0" cellspacing="2" cellpadding="2" >
   <tr><td colspan="3"class="TableTitle">Hot Keys</td></td></tr>
  +<tr><td class="HotKey">ALT-S</td><td width="50" align="center">-</td><td>Shows a File Open dialog to save the current tab's displayed events as XML</td></tr>
   <tr><td class="HotKey">ALT-L</td><td width="50" align="center">-</td><td>Shows a File Open dialog to open an XML file of events into Chainsaw</td></tr>
   <tr><td class="HotKey">ALT-C</td><td width="50" align="center">-</td><td>Closes the Welcome panel</td></tr>
   <tr><td class="HotKey">ALT-X</td><td width="50" align="center">-</td><td>Exits the Application</td></tr>
  
  
  
  1.2       +122 -4    jakarta-log4j-sandbox/src/java/org/apache/log4j/chainsaw/DefaultSortTableModel.java
  
  Index: DefaultSortTableModel.java
  ===================================================================
  RCS file: /home/cvs/jakarta-log4j-sandbox/src/java/org/apache/log4j/chainsaw/DefaultSortTableModel.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- DefaultSortTableModel.java	28 Apr 2003 05:44:31 -0000	1.1
  +++ DefaultSortTableModel.java	1 May 2003 04:50:25 -0000	1.2
  @@ -50,15 +50,22 @@
   package org.apache.log4j.chainsaw;
   
   import java.util.Collections;
  +import java.util.Date;
   import java.util.HashMap;
  +import java.util.Hashtable;
   import java.util.Iterator;
   import java.util.ListIterator;
   import java.util.Map;
  +import java.util.StringTokenizer;
   import java.util.Vector;
   
   import javax.swing.SwingUtilities;
   import javax.swing.table.DefaultTableModel;
   
  +import org.apache.log4j.Level;
  +import org.apache.log4j.Logger;
  +import org.apache.log4j.spi.LoggingEvent;
  +
   
   /**
    * A sortable TableModel implementation
  @@ -68,7 +75,6 @@
   */
   public class DefaultSortTableModel extends DefaultTableModel
     implements SortTableModel, FilterChangedListener {
  -  private static final String ID_COL_NAME = "ID";
     private int currentSortColumn;
     private boolean currentSortAscending;
     private boolean sortEnabled;
  @@ -123,7 +129,7 @@
     }
   
     public Vector getColumnNames() {
  -    int col = columnIdentifiers.indexOf(ID_COL_NAME);
  +    int col = columnIdentifiers.indexOf(ChainsawConstants.ID_COL_NAME);
   
       if (col == -1) {
         return columnIdentifiers;
  @@ -134,7 +140,7 @@
   
     public Vector getRow(int row) {
       if ((getDataVector().size() >= row) && (row > -1)) {
  -      int col = columnIdentifiers.indexOf(ID_COL_NAME);
  +      int col = columnIdentifiers.indexOf(ChainsawConstants.ID_COL_NAME);
   
         if (col == -1) {
           Vector v = new Vector();
  @@ -212,7 +218,7 @@
   
       //to get detail text for columns not in the data vector, ID column must be displayed
       synchronized (getDataVector()) {
  -      int col = columnIdentifiers.indexOf(ID_COL_NAME);
  +      int col = columnIdentifiers.indexOf(ChainsawConstants.ID_COL_NAME);
   
         if (col == -1) {
           v = new Vector();
  @@ -295,6 +301,118 @@
       }
     }
   
  +  public Vector getDisplayedEvents() {
  +  	Vector v=new Vector();
  +  	String ID=null;
  +  	int index=columnIdentifiers.indexOf(ChainsawConstants.ID_COL_NAME);
  +  	if (index == -1) {
  +  		return v;
  +  	}
  +  	
  +  	synchronized(getDataVector()) {
  +  		for (int i=0,j=getRowCount()-1;i<j;i++) {
  +  			v.add(getEvent((Integer)getValueAt(i, index)));
  +  		}
  +  	}
  +  	return v;
  +  }
  +  
  +  public Vector getAllEvents() {
  +  	Vector v=new Vector();
  +  	int index=allColumnNames.indexOf(ChainsawConstants.ID_COL_NAME);
  +  	synchronized(getDataVector()) {
  +  		Iterator iter=unfilteredEvents.keySet().iterator();
  +  		while (iter.hasNext()) {
  +  			v.add(getEvent((Integer)iter.next()));
  +  		}
  +  	}
  +  		
  +  	return v;
  +  }
  +
  +  public LoggingEvent getEvent(Integer ID) {
  +    ListIterator iter = allColumnNames.listIterator();
  +    String column = null;
  +    int index = -1;
  +
  +    Vector v=(Vector)unfilteredEvents.get(ID);
  +    //iterate through all column names and set the value from the unfiltered event 
  +
  +    long timeStamp = 0L;
  +    Logger logger=null;
  +    Level level = null;
  +    String threadName = "";
  +    Object message = null;
  +    String ndc = "";
  +    Hashtable mdc = null;
  +    String[] exception = null;
  +    String className = "";
  +    String methodName = "";
  +    String fileName = "";
  +    String lineNumber = "";
  +    Hashtable properties = null;
  +
  +	String value=null;
  +    while (iter.hasNext()) {
  +      column = (String) iter.next();
  +      index=allColumnNames.indexOf(column);
  +      value=v.get(index).toString();
  +
  +      if (column.equalsIgnoreCase(ChainsawConstants.LOGGER_COL_NAME)) {
  +	      logger = Logger.getLogger(value);
  +      }
  +      if (column.equalsIgnoreCase(ChainsawConstants.TIMESTAMP_COL_NAME)) {      
  +	      timeStamp = new Date(value).getTime();
  +      }
  +      if (column.equalsIgnoreCase(ChainsawConstants.LEVEL_COL_NAME)) {      
  +	      level=Level.toLevel(value);
  +      }
  +      if (column.equalsIgnoreCase(ChainsawConstants.THREAD_COL_NAME)) {      
  +	      threadName=value;
  +      }
  +      if (column.equalsIgnoreCase(ChainsawConstants.NDC_COL_NAME)) {      
  +	      ndc=value;
  +      }
  +      if (column.equalsIgnoreCase(ChainsawConstants.MESSAGE_COL_NAME)) {      
  +	      message=value;
  +      }
  +      if (column.equalsIgnoreCase(ChainsawConstants.MDC_COL_NAME)) {      
  +      	mdc=new Hashtable();
  +      	StringTokenizer t=new StringTokenizer(value, ",");
  +      	while (t.hasMoreElements()) {
  +			StringTokenizer t2=new StringTokenizer(t.nextToken(), "=");
  +      		mdc.put(t2.nextToken(), t2.nextToken());
  +      	}
  +      }
  +      if (column.equalsIgnoreCase(ChainsawConstants.THROWABLE_COL_NAME)) {
  +	      exception=new String[]{value};
  +      }
  +      if (column.equalsIgnoreCase(ChainsawConstants.CLASS_COL_NAME)) {      
  +	      className=value;
  +      }
  +      if (column.equalsIgnoreCase(ChainsawConstants.METHOD_COL_NAME)) {      
  +	      methodName=value;
  +      }
  +      if (column.equalsIgnoreCase(ChainsawConstants.FILE_COL_NAME)) {      
  +	      fileName=value;
  +      }
  +      if (column.equalsIgnoreCase(ChainsawConstants.LINE_COL_NAME)) {      
  +	      lineNumber=value;
  +      }
  +
  +      if (column.equalsIgnoreCase(ChainsawConstants.PROPERTIES_COL_NAME)) {      
  +      	properties=new Hashtable();
  +      	StringTokenizer t=new StringTokenizer(value, ",");
  +      	while (t.hasMoreElements()) {
  +			StringTokenizer t2=new StringTokenizer(t.nextToken(), "=");
  +      		properties.put(t2.nextToken(), t2.nextToken());
  +      	}
  +      }
  +    }
  +	return new LoggingEvent(logger.getName(), logger, timeStamp, level, threadName, message, ndc, mdc,
  +        exception, className, methodName, fileName, lineNumber, properties);
  +  }
  +  	
     public boolean isAddRow(Vector v) {
       synchronized (getDataVector()) {
         //set the last field to the 'unfilteredevents size + 1 - an ID based on reception order
  
  
  
  1.12      +16 -1     jakarta-log4j-sandbox/src/java/org/apache/log4j/chainsaw/LogUI.java
  
  Index: LogUI.java
  ===================================================================
  RCS file: /home/cvs/jakarta-log4j-sandbox/src/java/org/apache/log4j/chainsaw/LogUI.java,v
  retrieving revision 1.11
  retrieving revision 1.12
  diff -u -r1.11 -r1.12
  --- LogUI.java	1 May 2003 03:29:02 -0000	1.11
  +++ LogUI.java	1 May 2003 04:50:25 -0000	1.12
  @@ -160,7 +160,6 @@
       
     }
   
  -
     /**
      * Starts Chainsaw by attaching a new instance to the Log4J
      * main root Logger via a ChainsawAppender, and activates itself
  @@ -178,6 +177,15 @@
       activateViewer();
     }
   
  +  public String getActiveTabName() {
  +  	int index=tabbedPane.getSelectedIndex();
  +  	if (index==-1) {
  +  		return null;
  +  	} else {
  +		return tabbedPane.getTitleAt(index);
  +  	}
  +  }
  +  
     /**
      * Activates itself as a viewer by configuring Size, and location of
      * itself, and configures the default Tabbed Pane elements with the correct
  @@ -331,6 +339,13 @@
       }
     }
   
  +  public Vector getAllEvents(String ident) {
  +  	return ((DefaultSortTableModel)tableModelMap.get(ident)).getAllEvents();
  +  }
  +  
  +  public Vector getDisplayedEvents(String ident) {
  +    return ((DefaultSortTableModel)tableModelMap.get(ident)).getDisplayedEvents();
  +  }	
     /**
      * Formats the individual elements of an LoggingEvent by ensuring that
      * there are no null bits, replacing them with EMPTY_STRING
  
  
  
  1.2       +4 -2      jakarta-log4j-sandbox/src/java/org/apache/log4j/chainsaw/FileMenu.java
  
  Index: FileMenu.java
  ===================================================================
  RCS file: /home/cvs/jakarta-log4j-sandbox/src/java/org/apache/log4j/chainsaw/FileMenu.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- FileMenu.java	1 May 2003 03:26:09 -0000	1.1
  +++ FileMenu.java	1 May 2003 04:50:25 -0000	1.2
  @@ -18,9 +18,10 @@
   
     /**
      * The complete File Menu for the main GUI, containing
  -   * the Load, Close Welcome Tab, and Exit actions
  +   * the Load, Save, Close Welcome Tab, and Exit actions
      * 
      * @author Paul Smith <ps...@apache.org>
  +   * @author Scott Deboy <sd...@apache.org>
      */
   class FileMenu extends JMenu {
   
  @@ -31,6 +32,7 @@
       
   
       JMenuItem loadFile = new JMenuItem(new FileLoadAction(logUI));
  +    JMenuItem saveFile = new JMenuItem(new FileSaveAction(logUI));
       
       Action closeAction = new AbstractAction() {
         public void actionPerformed(ActionEvent e) {
  @@ -63,8 +65,8 @@
       
       JMenuItem menuItemExit = new JMenuItem(exitAction);
       
  -    
       add(loadFile);
  +    add(saveFile);
       add(menuItemClose);
       add(new JSeparator());
       add(menuItemExit);
  
  
  
  1.4       +4 -3      jakarta-log4j-sandbox/src/java/org/apache/log4j/xml/XMLDecoder.java
  
  Index: XMLDecoder.java
  ===================================================================
  RCS file: /home/cvs/jakarta-log4j-sandbox/src/java/org/apache/log4j/xml/XMLDecoder.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- XMLDecoder.java	30 Apr 2003 23:25:27 -0000	1.3
  +++ XMLDecoder.java	1 May 2003 04:50:26 -0000	1.4
  @@ -56,7 +56,6 @@
   import java.io.StringReader;
   import java.util.Collections;
   import java.util.Hashtable;
  -import java.util.Iterator;
   import java.util.Map;
   import java.util.Vector;
   
  @@ -241,7 +240,7 @@
       Object message = null;
       String ndc = null;
       Hashtable mdc = null;
  -    Throwable exception = null;
  +    String[] exception = null;
       String className = null;
       String methodName = null;
       String fileName = null;
  @@ -301,8 +300,10 @@
             }
           }
     
  +		//NOTE: this process unfortunately adds the stack trace of the caller because 
  +		//we don't have an ability to modify the stack trace pre jdk1.4 
           if (tagName.equalsIgnoreCase("log4j:throwable")) {
  -          exception = new Throwable(getCData(list.item(y)));
  +          exception = new String[]{getCData(list.item(y))};
           }
     
           if (tagName.equalsIgnoreCase("log4j:locationinfo")) {
  
  
  
  1.2       +28 -0     jakarta-log4j-sandbox/src/java/org/apache/log4j/spi/LoggingEvent.java
  
  Index: LoggingEvent.java
  ===================================================================
  RCS file: /home/cvs/jakarta-log4j-sandbox/src/java/org/apache/log4j/spi/LoggingEvent.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- LoggingEvent.java	28 Apr 2003 05:44:33 -0000	1.1
  +++ LoggingEvent.java	1 May 2003 04:50:27 -0000	1.2
  @@ -293,6 +293,34 @@
       this.mdcCopy = mdc;
       this.properties = properties;
     }
  +  /**
  +   * Alternate constructor to allow a string array to be passed in as the throwable.
  +   */
  +  public LoggingEvent(
  +    String fqnOfCategoryClass, Category logger, long timeStamp,
  +    Priority priority, String threadName, Object message, String ndc,
  +    Hashtable mdc, String[] throwable, String className, String methodName,
  +    String fileName, String lineNumber, Hashtable properties) {
  +    ndcLookupRequired = false;
  +    mdcCopyLookupRequired = false;
  +    this.logger = logger;
  +    this.categoryName = logger.getName();
  +    this.level = priority;
  +    this.message = message;
  +
  +    if (throwable != null) {
  +      this.throwableInfo = new ThrowableInformation(throwable);
  +    }
  +
  +    this.locationInfo =
  +      new LocationInfo(fileName, className, methodName, lineNumber);
  +    this.fqnOfCategoryClass = fqnOfCategoryClass;
  +    this.timeStamp = timeStamp;
  +    this.threadName = threadName;
  +    this.ndc = ndc;
  +    this.mdcCopy = mdc;
  +    this.properties = properties;
  +  }
   
     /**
      * Set the location information for this logging event. The collected
  
  
  
  1.1                  jakarta-log4j-sandbox/src/java/org/apache/log4j/spi/ThrowableInformation.java
  
  Index: ThrowableInformation.java
  ===================================================================
  /*
   * ============================================================================
   *                   The Apache Software License, Version 1.1
   * ============================================================================
   *
   *    Copyright (C) 1999 The Apache Software Foundation. All rights reserved.
   *
   * Redistribution and use in source and binary forms, with or without modifica-
   * tion, are permitted provided that the following conditions are met:
   *
   * 1. Redistributions of  source code must  retain the above copyright  notice,
   *    this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright notice,
   *    this list of conditions and the following disclaimer in the documentation
   *    and/or other materials provided with the distribution.
   *
   * 3. The end-user documentation included with the redistribution, if any, must
   *    include  the following  acknowledgment:  "This product includes  software
   *    developed  by the  Apache Software Foundation  (http://www.apache.org/)."
   *    Alternately, this  acknowledgment may  appear in the software itself,  if
   *    and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "log4j" and  "Apache Software Foundation"  must not be used to
   *    endorse  or promote  products derived  from this  software without  prior
   *    written permission. For written permission, please contact
   *    apache@apache.org.
   *
   * 5. Products  derived from this software may not  be called "Apache", nor may
   *    "Apache" appear  in their name,  without prior written permission  of the
   *    Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
   * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
   * FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
   * APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
   * INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
   * DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
   * OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
   * ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
   * (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
   * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   *
   * This software  consists of voluntary contributions made  by many individuals
   * on  behalf of the Apache Software  Foundation.  For more  information on the
   * Apache Software Foundation, please see <http://www.apache.org/>.
   *
   */
  
  package org.apache.log4j.spi;
  
  import java.io.PrintWriter;
  import java.io.Writer;
  
  import java.util.Vector;
  
  
  /**
    * ThrowableInformation is log4j's internal representation of
    * throwables. It essentially consists of a string array, called
    * 'rep', where the first element, that is rep[0], represents the
    * string representation of the throwable (i.e. the value you get
    * when you do throwable.toString()) and subsequent elements
    * correspond the stack trace with the top most entry of the stack
    * corresponding to the second entry of the 'rep' array that is
    * rep[1].
    *
    * @author Ceki G&uuml;lc&uuml;
    *
    * */
  public class ThrowableInformation implements java.io.Serializable {
    static final long serialVersionUID = -4748765566864322735L;
    private transient Throwable throwable;
    private String[] rep;
  
    public ThrowableInformation(Throwable throwable) {
      this.throwable = throwable;
    }
  
    public ThrowableInformation(String[] rep) {
      this.rep = rep;
    }
  
    public Throwable getThrowable() {
      return throwable;
    }
  
    public String[] getThrowableStrRep() {
      if (rep != null) {
        return (String[]) rep.clone();
      } else {
        VectorWriter vw = new VectorWriter();
        throwable.printStackTrace(vw);
        rep = vw.toStringArray();
  
        return rep;
      }
    }
  }
  
  
  /**
    * VectorWriter is a seemingly trivial implemtantion of PrintWriter.
    * The throwable instance that we are trying to represnt is asked to
    * print itself to a VectorWriter.
    *
    * By our design choice, r string representation of the throwable
    * does not contain any line separators. It follows that println()
    * methods of VectorWriter ignore the 'ln' part.
    * */
  class VectorWriter extends PrintWriter {
    private Vector v;
  
    VectorWriter() {
      super(new NullWriter());
      v = new Vector();
    }
  
    public void print(Object o) {
      v.addElement(o.toString());
    }
  
    public void print(char[] chars) {
      v.addElement(new String(chars));
    }
  
    public void print(String s) {
      v.addElement(s);
    }
  
    public void println(Object o) {
      v.addElement(o.toString());
    }
  
    // JDK 1.1.x apprenly uses this form of println while in
    // printStackTrace()
    public void println(char[] chars) {
      v.addElement(new String(chars));
    }
  
    public void println(String s) {
      v.addElement(s);
    }
  
    public void write(char[] chars) {
      v.addElement(new String(chars));
    }
  
    public void write(char[] chars, int off, int len) {
      v.addElement(new String(chars, off, len));
    }
  
    public void write(String s, int off, int len) {
      v.addElement(s.substring(off, off + len));
    }
  
    public void write(String s) {
      v.addElement(s);
    }
  
    public String[] toStringArray() {
      int len = v.size();
      String[] sa = new String[len];
  
      for (int i = 0; i < len; i++) {
        sa[i] = (String) v.elementAt(i);
      }
  
      return sa;
    }
  }
  
  
  class NullWriter extends Writer {
    public void close() {
      // blank
    }
  
    public void flush() {
      // blank
    }
  
    public void write(char[] cbuf, int off, int len) {
      // blank
    }
  }
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: log4j-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: log4j-dev-help@jakarta.apache.org