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ülcü
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 }