View Javadoc

    1   /*
    2    * Licensed to the Apache Software Foundation (ASF) under one or more
    3    * contributor license agreements.  See the NOTICE file distributed with
    4    * this work for additional information regarding copyright ownership.
    5    * The ASF licenses this file to You under the Apache License, Version 2.0
    6    * (the "License"); you may not use this file except in compliance with
    7    * the License.  You may obtain a copy of the License at
    8    *
    9    *      http://www.apache.org/licenses/LICENSE-2.0
    10   *
    11   * Unless required by applicable law or agreed to in writing, software
    12   * distributed under the License is distributed on an "AS IS" BASIS,
    13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14   * See the License for the specific language governing permissions and
    15   * limitations under the License.
    16   */
    17
    18  package org.apache.log4j.db;
    19
    20  import org.apache.log4j.Level;
    21  import org.apache.log4j.Logger;
    22  import org.apache.log4j.scheduler.Job;
    23  import org.apache.log4j.spi.ComponentBase;
    24  import org.apache.log4j.spi.LocationInfo;
    25  import org.apache.log4j.spi.LoggingEvent;
    26  import org.apache.log4j.spi.ThrowableInformation;
    27
    28  import java.sql.Connection;
    29  import java.sql.PreparedStatement;
    30  import java.sql.ResultSet;
    31  import java.sql.SQLException;
    32  import java.util.Hashtable;
    33  import java.util.Vector;
    34
    35  /**
    36   * Actual retrieval of data is made by the instance of DBReceiverJob associated
    37   * with DBReceiver.
    38   *
    39   * @author Ceki G&uuml;lc&uuml;
    40   */
    41  class DBReceiverJob extends ComponentBase implements Job {
    42
    43    String sqlException = "SELECT trace_line FROM logging_event_exception where event_id=? ORDER by i ASC";
    44    String sqlProperties = "SELECT mapped_key, mapped_value FROM logging_event_property WHERE event_id=?";
    45    String sqlSelect =
    46      "SELECT " +
    47      "sequence_number, timestamp, rendered_message, logger_name, " +
    48      "level_string, ndc, thread_name, reference_flag, " +
    49      "caller_filename, caller_class, caller_method, caller_line, " +
    50      "event_id " +
    51      "FROM logging_event " +
    52      "WHERE event_id > ?  ORDER BY event_id ASC";
    53
    54
    55    long lastId = Short.MIN_VALUE;
    56
    57    DBReceiver parentDBReceiver;
    58
    59    DBReceiverJob(DBReceiver parent) {
    60      parentDBReceiver = parent;
    61    }
    62
    63    public void execute() {
    64      getLogger().debug("DBReceiverJob.execute() called");
    65
    66      Connection connection = null;
    67
    68      try {
    69        connection = parentDBReceiver.connectionSource.getConnection();
    70        PreparedStatement statement = connection.prepareStatement(sqlSelect);
    71        statement.setLong(1, lastId);
    72        ResultSet rs = statement.executeQuery();
    73        //rs.beforeFirst();
    74
    75        while (rs.next()) {
    76  	    Logger logger = null;
    77  	    long timeStamp = 0L;
    78  	    String level = null;
    79  	    String threadName = null;
    80  	    Object message = null;
    81  	    String ndc = null;
    82  	    String className = null;
    83  	    String methodName = null;
    84  	    String fileName = null;
    85  	    String lineNumber = null;
    86  	    Hashtable properties = new Hashtable();
    87
    88
    89          //event.setSequenceNumber(rs.getLong(1));
    90          timeStamp = rs.getLong(2);
    91          message = rs.getString(3);
    92  		logger = Logger.getLogger(rs.getString(4));
    93          level = rs.getString(5);
    94  		Level levelImpl = Level.toLevel(level.trim());
    95
    96          ndc = rs.getString(6);
    97          threadName = rs.getString(7);
    98
    99          short mask = rs.getShort(8);
    100
    101         fileName = rs.getString(9);
    102         className = rs.getString(10);
    103         methodName = rs.getString(11);
    104         lineNumber = rs.getString(12).trim();
    105
    106 		LocationInfo locationInfo = null;
    107         if (fileName.equals(LocationInfo.NA)) {
    108           locationInfo = LocationInfo.NA_LOCATION_INFO;
    109         } else {
    110           locationInfo = new LocationInfo(fileName, className,
    111               methodName, lineNumber);
    112         }
    113
    114         long id = rs.getLong(13);
    115         //LogLog.info("Received event with id=" + id);
    116         lastId = id;
    117
    118 		ThrowableInformation throwableInfo = null;
    119         if ((mask & DBHelper.EXCEPTION_EXISTS) != 0) {
    120           throwableInfo = getException(connection, id);
    121         }
    122
    123 	    LoggingEvent event = new LoggingEvent(logger.getName(),
    124 	            logger, timeStamp, levelImpl, message,
    125 	            threadName,
    126 	            throwableInfo,
    127 	            ndc,
    128 	            locationInfo,
    129 	            properties);
    130
    131
    132         // Scott asked for this info to be
    133         event.setProperty("log4jid", Long.toString(id));
    134
    135         if ((mask & DBHelper.PROPERTIES_EXIST) != 0) {
    136           getProperties(connection, id, event);
    137         }
    138
    139
    140
    141
    142         if (!parentDBReceiver.isPaused()) {
    143           parentDBReceiver.doPost(event);
    144         }
    145       } // while
    146       statement.close();
    147       statement = null;
    148     } catch (SQLException sqle) {
    149       getLogger().error("Problem receiving events", sqle);
    150     } finally {
    151       closeConnection(connection);
    152     }
    153   }
    154
    155   void closeConnection(Connection connection) {
    156     if (connection != null) {
    157       try {
    158         //LogLog.warn("closing the connection. ", new Exception("x"));
    159         connection.close();
    160       } catch (SQLException sqle) {
    161         // nothing we can do here
    162       }
    163     }
    164   }
    165
    166   /**
    167    * Retrieve the event properties from the logging_event_property table.
    168    *
    169    * @param connection
    170    * @param id
    171    * @param event
    172    * @throws SQLException
    173    */
    174   void getProperties(Connection connection, long id, LoggingEvent event)
    175       throws SQLException {
    176
    177     PreparedStatement statement = connection.prepareStatement(sqlProperties);
    178     try {
    179       statement.setLong(1, id);
    180       ResultSet rs = statement.executeQuery();
    181
    182       while (rs.next()) {
    183         String key = rs.getString(1);
    184         String value = rs.getString(2);
    185         event.setProperty(key, value);
    186       }
    187     } finally {
    188       statement.close();
    189     }
    190   }
    191
    192   /**
    193    * Retrieve the exception string representation from the
    194    * logging_event_exception table.
    195    *
    196    * @param connection
    197    * @param id
    198    * @throws SQLException
    199    */
    200   ThrowableInformation getException(Connection connection, long id)
    201       throws SQLException {
    202
    203     PreparedStatement statement = null;
    204
    205     try {
    206       statement = connection.prepareStatement(sqlException);
    207       statement.setLong(1, id);
    208       ResultSet rs = statement.executeQuery();
    209
    210       Vector v = new Vector();
    211
    212       while (rs.next()) {
    213         //int i = rs.getShort(1);
    214         v.add(rs.getString(1));
    215       }
    216
    217       int len = v.size();
    218       String[] strRep = new String[len];
    219       for (int i = 0; i < len; i++) {
    220         strRep[i] = (String) v.get(i);
    221       }
    222       // we've filled strRep, we now attach it to the event
    223       return new ThrowableInformation(strRep);
    224     } finally {
    225       if (statement != null) {
    226         statement.close();
    227       }
    228     }
    229   }
    230 }