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;
    77                  long timeStamp;
    78                  String level;
    79                  String threadName;
    80                  Object message;
    81                  String ndc;
    82                  String className;
    83                  String methodName;
    84                  String fileName;
    85                  String lineNumber;
    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;
    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                 if (!parentDBReceiver.isPaused()) {
    141                     parentDBReceiver.doPost(event);
    142                 }
    143             } // while
    144             statement.close();
    145         } catch (SQLException sqle) {
    146             getLogger().error("Problem receiving events", sqle);
    147         } finally {
    148             closeConnection(connection);
    149         }
    150     }
    151
    152     void closeConnection(Connection connection) {
    153         if (connection != null) {
    154             try {
    155                 //LogLog.warn("closing the connection. ", new Exception("x"));
    156                 connection.close();
    157             } catch (SQLException sqle) {
    158                 // nothing we can do here
    159             }
    160         }
    161     }
    162
    163     /**
    164      * Retrieve the event properties from the logging_event_property table.
    165      *
    166      * @param connection
    167      * @param id
    168      * @param event
    169      * @throws SQLException
    170      */
    171     void getProperties(Connection connection, long id, LoggingEvent event)
    172         throws SQLException {
    173
    174         try (PreparedStatement statement = connection.prepareStatement(sqlProperties)) {
    175             statement.setLong(1, id);
    176             ResultSet rs = statement.executeQuery();
    177
    178             while (rs.next()) {
    179                 String key = rs.getString(1);
    180                 String value = rs.getString(2);
    181                 event.setProperty(key, value);
    182             }
    183         }
    184     }
    185
    186     /**
    187      * Retrieve the exception string representation from the
    188      * logging_event_exception table.
    189      *
    190      * @param connection
    191      * @param id
    192      * @throws SQLException
    193      */
    194     ThrowableInformation getException(Connection connection, long id)
    195         throws SQLException {
    196
    197         PreparedStatement statement = null;
    198
    199         try {
    200             statement = connection.prepareStatement(sqlException);
    201             statement.setLong(1, id);
    202             ResultSet rs = statement.executeQuery();
    203
    204             Vector<String> v = new Vector<>();
    205
    206             while (rs.next()) {
    207                 //int i = rs.getShort(1);
    208                 v.add(rs.getString(1));
    209             }
    210
    211             int len = v.size();
    212             String[] strRep = new String[len];
    213             for (int i = 0; i < len; i++) {
    214                 strRep[i] = v.get(i);
    215             }
    216             // we've filled strRep, we now attach it to the event
    217             return new ThrowableInformation(strRep);
    218         } finally {
    219             if (statement != null) {
    220                 statement.close();
    221             }
    222         }
    223     }
    224 }