sdeboy      2003/06/05 22:33:04

  Modified:    src/java/org/apache/log4j/jdbc JDBCReceiver.java
  Log:
  Updated JDBCReceiver documentation.
  
  What doesn't work:
  * Can't reconstruct the event's timestamp if patternlayout's timestamp was used to 
store the data - ISO8601DateFormat can't convert the string back to a date.
  * No exception support in jdbcappender
  * No properties support in patternlayout
  However, both fields are supported in the receiver, so users can add properties to 
the SQL statement if they want events routed to unique tabs in Chainsaw V2).
  
  Revision  Changes    Path
  1.2       +89 -15    
jakarta-log4j-sandbox/src/java/org/apache/log4j/jdbc/JDBCReceiver.java
  
  Index: JDBCReceiver.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-log4j-sandbox/src/java/org/apache/log4j/jdbc/JDBCReceiver.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- JDBCReceiver.java 5 Jun 2003 05:19:05 -0000       1.1
  +++ JDBCReceiver.java 6 Jun 2003 05:33:04 -0000       1.2
  @@ -70,6 +70,48 @@
   import java.util.StringTokenizer;
   
   
  +/**
  + * Convert Log data stored in a database into LoggingEvents.
  + *
  + * This receiver executes the SQL statement defined in the plugin configuration 
once,
  + * converting the rows it finds into LoggingEvents, and then ends.
  + *
  + * The configuration of this plugin is very similar to the JDBCAppender, however a 
  + * SELECT statement must be provided instead of an INSERT statement.
  + *
  + * The select statement must provide all fields which define a LoggingEvent, with 
  + * the column names matching this list: LOGGER, TIMESTAMP, LEVEL, THREAD, MESSAGE, 
  + * NDC, MDC, CLASS, METHOD, FILE, LINE, PROPERTIES, EXCEPTION
  + *
  + * If the source table doesn't provide a column for any of the fields, the field 
must 
  + * still be provided in the SELECT statement.  For example, if a JDBCAppender was 
used 
  + * to write only a timestamp, level and patternlayout combination of message and 
other 
  + * fields, here is a sample SQL statement you would provide as the plugin 'sql' 
param:
  + *
  + * param name="sql" value='select "" as LOGGER, timestamp as TIMESTAMP, level as 
LEVEL, 
  + * "" as THREAD, message as MESSAGE, "" as NDC, "" as MDC, "" as CLASS, "" as 
METHOD, 
  + * "" as FILE, "" as LINE, "{{log4japp,databaselogs,log4jmachinename,mymachine}}" 
  + * as PROPERTIES, "" as EXCEPTION from logtable'
  + *
  + * In other words, if a number of LoggingEvent properties were combined into one 
field 
  + * in the database, the combined field should be set as the MESSAGE column in the 
  + * SELECT statement.  Missing columns should be set to "".
  + * 
  + * Make sure to alias the column names if needed to match the list provided above.
  + *
  + * NOTE: Patternlayout doesn't support Properties and JDBCAppender doesn't support 
  + * exceptions, but the fields can be defined in the SQL statement and included in 
  + * the event.
  + * 
  + * This means that log4japp and/or log4jmachinename properties can be provided and 
  + * the properties may be used to create a unique tab for the events.
  + * 
  + * Both {{name, value, name2, value2}} formats and formats without the double 
braces 
  + * are supported for MDC and properties fields.
  + *
  + *  @author Scott Deboy <[EMAIL PROTECTED]>
  + *
  + */
   public class JDBCReceiver extends Receiver {
     private boolean isActive = false;
   
  @@ -93,6 +135,9 @@
     public JDBCReceiver() {
     }
   
  +  /**
  +   * Start a thread which will handle the retrieval.
  +   */
     public void activateOptions() {
       new JDBCReceiverThread().start();
     }
  @@ -149,22 +194,22 @@
       databaseUser = user;
     }
   
  -  public void setURL(String url) {
  -    databaseURL = url;
  -  }
  -
  -  public void setPassword(String password) {
  -    databasePassword = password;
  -  }
  -
     public String getUser() {
       return databaseUser;
     }
   
  +  public void setURL(String url) {
  +    databaseURL = url;
  +  }
  +
     public String getURL() {
       return databaseURL;
     }
   
  +  public void setPassword(String password) {
  +    databasePassword = password;
  +  }
  +
     public String getPassword() {
       return databasePassword;
     }
  @@ -211,6 +256,13 @@
           while (rs.next()) {
             logger = Logger.getLogger(rs.getString("LOGGER"));
   
  +               //TIMESTAMP PARSING IS NOT WORKING for the default format.
  +
  +               //The default timestamp format, ISO8601DateFormat, doesn't have a
  +               //parse method to convert the format back to a date.  
  +               //This parse process just tries to use the default dateformat parse 
  +               //methods set to Lenient to convert it back to a date.
  +               //if that fails, it will use the current time as the timestamp
             DateFormat df = DateFormat.getDateInstance(DateFormat.LONG);
             df.setLenient(true);
   
  @@ -229,29 +281,51 @@
             mdc = new Hashtable();
   
             if (mdcString != null) {
  +            //support MDC being wrapped in {{name, value}} or just name, value
               if (
                 (mdcString.indexOf("{{") > -1) && (mdcString.indexOf("}}") > -1)) {
                 mdcString =
                   mdcString.substring(
                     mdcString.indexOf("{{") + 2, mdcString.indexOf("}}"));
  +            }
   
  -              StringTokenizer tok = new StringTokenizer(mdcString, ",");
  +            StringTokenizer tok = new StringTokenizer(mdcString, ",");
   
  -              while (tok.countTokens() > 1) {
  -                mdc.put(tok.nextToken(), tok.nextToken());
  -              }
  +            while (tok.countTokens() > 1) {
  +              mdc.put(tok.nextToken(), tok.nextToken());
               }
             }
   
  -          //exception not supported for now - but a placeholder is here for when it 
is supported
  -          //exception = new String[] {rs.getString("EXCEPTION")};
  +          //although exception is not supported by jdbcappender, it needs to be 
provided in the SQL string
  +          exception = new String[] {rs.getString("EXCEPTION")};
             className = rs.getString("CLASS");
             methodName = rs.getString("METHOD");
             fileName = rs.getString("FILE");
             lineNumber = rs.getString("LINE");
   
  -          //properties not supported for now
  +          //although properties are not supported by JDBCAppender, if they are 
provided in the 
  +          //SQL they can be used here (for example, to route events to a unique tab 
if 
  +          //the machinename and/or appname property are set)
  +          String propertiesString = rs.getString("PROPERTIES");
             properties = new Hashtable();
  +
  +          if (propertiesString != null) {
  +            //support properties being wrapped in {{name, value}} or just name, 
value
  +            if (
  +              (propertiesString.indexOf("{{") > -1)
  +                && (propertiesString.indexOf("}}") > -1)) {
  +              propertiesString =
  +                propertiesString.substring(
  +                  propertiesString.indexOf("{{") + 2,
  +                  propertiesString.indexOf("}}"));
  +            }
  +
  +            StringTokenizer tok2 = new StringTokenizer(propertiesString, ",");
  +
  +            while (tok2.countTokens() > 1) {
  +              properties.put(tok2.nextToken(), tok2.nextToken());
  +            }
  +          }
   
             Level levelImpl = Level.toLevel(level);
   
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to