1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.commons.monitoring.jdbc;
19
20 import org.apache.commons.monitoring.Role;
21 import org.apache.commons.monitoring.counters.Counter;
22 import org.apache.commons.monitoring.repositories.Repository;
23 import org.apache.commons.monitoring.stopwatches.StopWatch;
24
25 import java.lang.reflect.InvocationHandler;
26 import java.lang.reflect.InvocationTargetException;
27 import java.lang.reflect.Method;
28 import java.sql.SQLException;
29 import java.sql.Statement;
30
31 public class MonitoredStatement implements InvocationHandler {
32 private final Statement statement;
33
34 public MonitoredStatement(final Statement statement) {
35 this.statement = statement;
36 }
37
38 protected SQLException monitor(final SQLException sqle) {
39 final String name = "SQLException:" + sqle.getSQLState() + ":" + sqle.getErrorCode();
40 Repository.INSTANCE.getCounter(new Counter.Key(Role.FAILURES, name)).add(1);
41 return sqle;
42 }
43
44 @Override
45 public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable {
46 final String name = method.getName();
47 if (name.startsWith("execute")) {
48 final StopWatch stopWatch;
49 if (name.endsWith("Batch") && (args == null || args.length == 0)) {
50 stopWatch = Repository.INSTANCE.start(Repository.INSTANCE.getCounter(new Counter.Key(Role.JDBC, "batch")));
51 } else {
52 stopWatch = Repository.INSTANCE.start(Repository.INSTANCE.getCounter(new Counter.Key(Role.JDBC, (String) args[0])));
53 }
54
55 try {
56 return doInvoke(method, args);
57 } catch (final InvocationTargetException e) {
58 throw extractSQLException(e);
59 } finally {
60 stopWatch.stop();
61 }
62 }
63 return doInvoke(method, args);
64 }
65
66 private Object doInvoke(final Method method, final Object[] args) throws IllegalAccessException, InvocationTargetException {
67 return method.invoke(statement, args);
68 }
69
70 protected Throwable extractSQLException(final InvocationTargetException e) throws Throwable {
71 final Throwable th = e.getCause();
72 if (SQLException.class.isInstance(th)) {
73 return monitor(SQLException.class.cast(th));
74 }
75 return th;
76 }
77 }