KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > derby > diag > StatementDuration


1 /*
2
3    Derby - Class org.apache.derby.diag.StatementDuration
4
5    Licensed to the Apache Software Foundation (ASF) under one or more
6    contributor license agreements. See the NOTICE file distributed with
7    this work for additional information regarding copyright ownership.
8    The ASF licenses this file to You under the Apache License, Version 2.0
9    (the "License"); you may not use this file except in compliance with
10    the License. You may obtain a copy of the License at
11
12       http://www.apache.org/licenses/LICENSE-2.0
13
14    Unless required by applicable law or agreed to in writing, software
15    distributed under the License is distributed on an "AS IS" BASIS,
16    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17    See the License for the specific language governing permissions and
18    limitations under the License.
19
20  */

21
22 package org.apache.derby.diag;
23
24 import java.io.BufferedReader JavaDoc;
25 import java.io.FileNotFoundException JavaDoc;
26 import java.io.InputStream JavaDoc;
27 import java.io.InputStreamReader JavaDoc;
28 import java.io.FileInputStream JavaDoc;
29
30 import java.util.Hashtable JavaDoc;
31 import java.util.Enumeration JavaDoc;
32 import java.util.Properties JavaDoc;
33 import java.sql.ResultSetMetaData JavaDoc;
34 import java.sql.SQLException JavaDoc;
35 import java.sql.Timestamp JavaDoc;
36 import java.sql.Types JavaDoc;
37 import org.apache.derby.vti.VTITemplate;
38 import org.apache.derby.iapi.sql.ResultColumnDescriptor;
39 import org.apache.derby.impl.jdbc.EmbedResultSetMetaData;
40 import org.apache.derby.iapi.reference.Limits;
41 import org.apache.derby.iapi.util.StringUtil;
42
43 /**
44     
45
46     StatementDuration is a virtual table which
47     can be used to analyze the execution duration of the statements
48     of "interest" in db2j.<!-- -->log or a specified file when
49     db2j.<!-- -->language.<!-- -->logStatementText=true.
50     
51
52     <P>A limitation is that, for each transaction ID,
53     a row will not be returned for the last statement with that
54     transaction id. (Transaction IDs change within a connection after
55     a commit or rollback, if the transaction that just ended modified data.)
56
57     <P>The execution duration is the time between the beginning of
58     execution of two successive statements. There are a number of reasons
59     why this time may not be accurate. The duration could include time
60     spent in the application waiting for user input, doing other work, etc.
61     It may also only include a portion of the actual execution time, if
62     the application executes a new statement before draining the previous
63     open ResultSet. StatementDuration can be used to get a rough sense of
64     where the bottlenecks in an application's JDBC code are.
65
66     <P>The StatementDuration virtual table has the following columns:
67     <UL><LI>TS varchar(26) - not nullable. The timestamp of the statement.</LI>
68     <LI>THREADID varchar(80) - not nullable. The thread name.</LI>
69     <LI>XID varchar(15) - not nullable. The transaction ID.</LI>
70     <LI>LOGTEXT long varchar - nullable. Text of the statement or commit or rollback.</LI>
71     <LI>DURATION varchar(10) - not nullable. Duration, in milliseconds, of the statement.</LI>
72     </UL>
73
74  */

75 public class StatementDuration extends VTITemplate
76 {
77     /*
78     ** private
79     */

80     private boolean gotFile;
81     private InputStreamReader JavaDoc inputFileStreamReader;
82     private InputStream JavaDoc inputStream;
83     private BufferedReader JavaDoc bufferedReader;
84     private String JavaDoc inputFileName;
85     private Hashtable JavaDoc hashTable;
86
87     // Variables for current row
88
private String JavaDoc line;
89     private int gmtIndex;
90     private int threadIndex;
91     private int xidIndex;
92     private int lccidIndex;
93     private String JavaDoc[] currentRow;
94
95     private static final String JavaDoc GMT_STRING = " GMT";
96     private static final String JavaDoc BEGIN_THREAD_STRING = "[";
97     private static final String JavaDoc END_THREAD_STRING = "]";
98     private static final String JavaDoc BEGIN_XID_STRING = "= ";
99     private static final String JavaDoc END_XID_STRING = ")";
100     private static final String JavaDoc BEGIN_EXECUTING_STRING = "Executing prepared";
101     private static final String JavaDoc END_EXECUTING_STRING = " :End prepared";
102
103
104     /**
105         StatementDuration() accesses the error log in
106         derby.system.home, if set, otherwise it looks in the current directory.
107         StatementDuration('filename') will access the specified
108         file name.
109      */

110     public StatementDuration()
111     {
112         String JavaDoc home = System.getProperty("derby.system.home");
113
114         inputFileName = "derby.log";
115
116         if (home != null)
117         {
118             inputFileName = home + "/" + inputFileName;
119         }
120     }
121
122     public StatementDuration(String JavaDoc inputFileName)
123     {
124         this.inputFileName = inputFileName;
125     }
126
127     /**
128         @see java.sql.ResultSet#getMetaData
129      */

130     public ResultSetMetaData JavaDoc getMetaData()
131     {
132         return metadata;
133     }
134
135     /**
136         @see java.sql.ResultSet#next
137         @exception SQLException If database access error occurs.
138      */

139     public boolean next() throws SQLException JavaDoc
140     {
141         if (! gotFile)
142         {
143             gotFile = true;
144             try
145             {
146                 inputFileStreamReader = new InputStreamReader JavaDoc(new FileInputStream JavaDoc(inputFileName));
147                 bufferedReader = new BufferedReader JavaDoc(inputFileStreamReader, 32*1024);
148             }
149             catch (FileNotFoundException JavaDoc ex)
150             {
151                 throw new SQLException JavaDoc(ex.getMessage());
152             }
153
154             hashTable = new Hashtable JavaDoc();
155         }
156
157         while (true)
158         {
159             try
160             {
161                 line = bufferedReader.readLine();
162             }
163             catch (java.io.IOException JavaDoc ioe)
164             {
165                 throw new SQLException JavaDoc(ioe.getMessage());
166             }
167
168             if (line == null)
169             {
170                 return false;
171             }
172
173             gmtIndex = line.indexOf(GMT_STRING);
174             threadIndex = line.indexOf(BEGIN_THREAD_STRING);
175             xidIndex = line.indexOf(BEGIN_XID_STRING);
176             lccidIndex = line.indexOf(BEGIN_XID_STRING, xidIndex + 1);
177
178             if (gmtIndex != -1 && threadIndex != -1)
179             {
180                 /* Build a row */
181                 String JavaDoc[] newRow = new String JavaDoc[6];
182                 for (int index = 1;
183                      index <= 5;
184                      index++)
185                 {
186                     newRow[index - 1] = setupColumn(index);
187                 }
188
189                 /* NOTE: We need to use the LCCID as the key
190                  */

191                 Object JavaDoc previousRow = hashTable.put(newRow[3],
192                                                    newRow);
193                 if (previousRow == null)
194                 {
195                     continue;
196                 }
197
198                 currentRow = (String JavaDoc[]) previousRow;
199                 
200                 /* Figure out the duration. */
201                 Timestamp JavaDoc endTs = Timestamp.valueOf(newRow[0]);
202                 long end = endTs.getTime() + endTs.getNanos() / 1000000;
203                 Timestamp JavaDoc startTs = Timestamp.valueOf(currentRow[0]);
204                 long start = startTs.getTime() + startTs.getNanos() / 1000000;
205                 currentRow[5] = Long.toString(end - start);
206
207                 return true;
208             }
209         }
210     }
211
212     /**
213         @see java.sql.ResultSet#close
214      */

215     public void close()
216     {
217         if (bufferedReader != null)
218         {
219             try
220             {
221                 bufferedReader.close();
222                 inputFileStreamReader.close();
223             }
224             catch (java.io.IOException JavaDoc ioe)
225             {
226                 // eat exceptions during close;
227
}
228             finally
229             {
230                 bufferedReader = null;
231                 inputFileStreamReader = null;
232             }
233         }
234     }
235
236     /**
237         All columns in StatementDuration VTI have String data types.
238         @see java.sql.ResultSet#getString
239         @exception SQLException If database access error occurs.
240      */

241     public String JavaDoc getString(int columnNumber)
242         throws SQLException JavaDoc
243     {
244         return currentRow[columnNumber - 1];
245     }
246
247     private String JavaDoc setupColumn(int columnNumber)
248         throws SQLException JavaDoc
249     {
250         switch (columnNumber)
251         {
252             case 1:
253                 return line.substring(0, gmtIndex);
254
255             case 2:
256                 return line.substring(threadIndex + 1, line.indexOf(END_THREAD_STRING));
257
258             case 3:
259                 return line.substring(xidIndex + 2, line.indexOf(END_XID_STRING, xidIndex));
260
261             case 4:
262                 return line.substring(lccidIndex + 2, line.indexOf(END_XID_STRING, lccidIndex));
263
264             case 5:
265                 /* Executing prepared statement is a special case as
266                  * it could span multiple lines
267                  */

268                 String JavaDoc output;
269                 if (line.indexOf(BEGIN_EXECUTING_STRING) == -1)
270                 {
271                     output = line.substring(line.indexOf(END_XID_STRING, lccidIndex) + 3);
272                 }
273                 else
274                 {
275
276                 /* We need to build string until we find the end of the text */
277                 int endIndex = line.indexOf(END_EXECUTING_STRING, lccidIndex);
278                 if (endIndex == -1)
279                 {
280                     output = line.substring(line.indexOf(END_XID_STRING, lccidIndex) + 3);
281                 }
282                 else
283                 {
284                     output = line.substring(line.indexOf(END_XID_STRING, lccidIndex) + 3,
285                                             endIndex);
286                 }
287
288                 while (endIndex == -1)
289                 {
290                     try
291                     {
292                         line = bufferedReader.readLine();
293                     }
294                     catch (java.io.IOException JavaDoc ioe)
295                     {
296                         throw new SQLException JavaDoc("Error reading file " + ioe);
297                     }
298                     endIndex = line.indexOf(END_EXECUTING_STRING);
299                     if (endIndex == -1)
300                     {
301                         output = output + line;
302                     }
303                     else
304                     {
305                         output = output + line.substring(0, endIndex);
306                     }
307                 }
308                 }
309
310                 output = StringUtil.truncate(output, Limits.DB2_VARCHAR_MAXWIDTH);
311
312
313                 return output;
314
315             default:
316                 return null;
317         }
318     }
319
320
321     /**
322         @see java.sql.ResultSet#wasNull
323      */

324     public boolean wasNull()
325     {
326         return false;
327     }
328
329     /*
330     ** Metadata
331     */

332     private static final ResultColumnDescriptor[] columnInfo = {
333
334         EmbedResultSetMetaData.getResultColumnDescriptor("TS", Types.VARCHAR, false, 26),
335         EmbedResultSetMetaData.getResultColumnDescriptor("THREADID", Types.VARCHAR, false, 80),
336         EmbedResultSetMetaData.getResultColumnDescriptor("XID", Types.VARCHAR, false, 15),
337         EmbedResultSetMetaData.getResultColumnDescriptor("LCCID", Types.VARCHAR, false, 10),
338         EmbedResultSetMetaData.getResultColumnDescriptor("LOGTEXT", Types.VARCHAR, true, Limits.DB2_VARCHAR_MAXWIDTH),
339         EmbedResultSetMetaData.getResultColumnDescriptor("DURATION", Types.VARCHAR, false, 10),
340     };
341     
342     private static final ResultSetMetaData JavaDoc metadata = new EmbedResultSetMetaData(columnInfo);
343 }
344
345
Popular Tags