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 = 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 }