1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.jmonit.support.jdbc;
17
18 import java.sql.SQLException;
19 import java.util.StringTokenizer;
20
21 import org.jmonit.Monitor;
22 import org.jmonit.Monitoring;
23
24
25
26
27 public class JdbcMonitor
28 {
29
30
31
32 private Monitor monitor;
33
34
35
36
37
38
39 public JdbcMonitor( Monitor monitor )
40 {
41 super();
42 this.monitor = monitor.tag( "jdbc" );
43 }
44
45 public Monitor getConnectionMonitor()
46 {
47 return this.monitor;
48 }
49
50
51
52
53
54 public Monitor getStatementMonitor( String sql )
55 {
56 return getSubMonitor( generalizeSql( sql ), "statement" );
57 }
58
59
60
61
62
63 public Monitor getPreparedStatementMonitor( String sql )
64 {
65 return getSubMonitor( sql, "preparedStatement" );
66 }
67
68
69
70
71
72 public Monitor getCallableStatementMonitor( String sql )
73 {
74 return getSubMonitor( sql, "callableStatement" );
75 }
76
77 public void monitorSQLException( SQLException sqle )
78 {
79 Monitoring.add( monitor.getName() + ".SQLException" + sqle.getErrorCode(), 1 );
80 }
81
82 private Monitor getSubMonitor( String sql, String type )
83 {
84 StringBuffer name = new StringBuffer( monitor.getName() );
85 name.append( "." ).append( type ).append( "~" ).append( sql );
86
87 return Monitoring.getMonitor( name.toString() ).tag( "jdbc" ).tag( type );
88 }
89
90
91
92
93
94
95
96
97 protected String generalizeSql( String sql )
98 {
99 StringBuffer stb = new StringBuffer();
100 StringTokenizer tokenizer = new StringTokenizer( sql, " \t\r\n,)=", true );
101 boolean ws = false;
102 while ( tokenizer.hasMoreTokens() )
103 {
104 String token = tokenizer.nextToken();
105 if ( token.length() == 1 && Character.isWhitespace( token.charAt( 0 ) ) )
106 {
107 if ( !ws )
108 {
109 stb.append( " " );
110 }
111 ws = true;
112 continue;
113 }
114 ws = false;
115 char first = token.charAt( 0 );
116 char last = token.charAt( token.length() - 1 );
117 if ( first == last && ( first == '\'' || first == '"' ) )
118 {
119
120 token = "?";
121 }
122 else
123 {
124 boolean numeric = true;
125 char[] chars = token.toCharArray();
126 boolean dot = false;
127 for ( int i = 0; i < chars.length; i++ )
128 {
129 if ( !Character.isDigit( chars[i] ) && !dot && chars[i] != '.' )
130 {
131 numeric = false;
132 break;
133 }
134 if ( chars[i] == '.' )
135 {
136 dot = true;
137 }
138 }
139 if ( numeric )
140 {
141
142 token = "?";
143 }
144 }
145 stb.append( token );
146 }
147 return stb.toString().toLowerCase();
148 }
149 }