This a Yammer|Codahale|Dropwizard Metrics extension to instrument JDBC resources and measure SQL execution times.
Wrap your existing DataSource using JdbcProxyFactory
or MetricsSql
builder class:
metricRegistry = new MetricRegistry();
dataSource = MetricsSql.forRegistry(metricRegistry)
.wrap("mysql", mysqlDataSource);
The String mysql is a datasource Id used in metric names.
Same as DataSource
metricRegistry = new MetricRegistry();
connection = MetricsSql.forRegistry(metricRegistry)
.wrap("mysql", mysqlConnection);
- Register Metrics SQL JDBC Driver: replace the original JDBC driver by
com.github.gquintana.metrics.sql.Driver
- Change JDBC URL prefix:
jdbc:xxx
becomesjdbc:metrics:xxx
Examples:
jdbc:metrics:mysql://localhost:3306/sakila?profileSQL=true&metrics_name=sakila
jdbc:metrics:postgresql://localhost/demo?metrics_driver=org.postgresql.Driver&ssl=true
jdbc:metrics:h2:~/test;AUTO_SERVER=TRUE;;AUTO_RECONNECT=TRUE;metrics_driver=org.h2.Driver;metrics_proxy_factory=caching
The driver supports several options:
metrics_driver
: the real driver class to wrapmetrics_name
: the database name used in metric names: defaults to xxx_drivermetrics_registry_holder
: the strategy used to locate the Metric registry: class name implementingMetricRegistryHolder
, defaults toStaticMetricRegistryHolder
metrics_naming_strategy
: the strategy used to generate what should be metered and the timer names: class name implementingMetricNamingStrategy
metrics_proxy_factory
: the strategy used to create proxies: eitherreflect
(the default),cglib
orcaching
,
- Naming strategy: implements
MetricNamingStrategy
, can configure:- Which operation should be timed (return null means not timed)
- How the metric is named
- Proxy factory: implements
ProxyFactory
, can configure how JDBC elements are wrapped (simplejava.lang.reflect.Proxy
or CGLib based proxies). - Registry holder: implements
MetricRegistryHolder
, can configure how the metric registry is resolved.
Beware of using unprepared statements and unbound parameters, it will generate a lot of metrics. For instance ...:
Statement statement = connection.createStatement();
statement.execute("insert into METRICS(ID, NAME) values(1, 'One')");
statement.execute("insert into METRICS(ID, NAME) values(2, 'Two')");
... will generate 2 metrics!
There are several options:
- Use prepared statements and bound parameters
- Tune the naming strategy to filter unprepared statements
- Tune the naming strategy to make both SQL statements generate the same metric name
The JmxReporter
doesn't play well with DefaultMetricNamingStrategy
, you'll have to change either the naming strategy or the object name factory. A SqlObjectNameFactory
is provided:
JmxReporter.forRegistry(metricRegistry)
.registerWith(mBeanServer)
.createsObjectNamesWith(new SqlObjectNameFactory())
.build();