Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add metrics for JDBC connection pool: Apache Commons DBCP2 #144

Merged
merged 4 commits into from
Mar 31, 2021

Conversation

mateuszrzeszutek
Copy link
Contributor

  • Micrometer-core actually contains a ready-made instrumentation for commons-pool2 - the object pool used by dbcp2. I tried using it, but unfortunately it turned out to be not so useful - it relies on BasicDataSource#jmxName being set (BasicDataSource adds itself to the mbean server when you set the JMX name), unfortunately Spring completely ignores that property and registers the data source MXBean by itself. This results in the underlying object pool (and PooledConnection) MXBeans not being registered, because they're not spring beans - just objects created inside BasicDataSource. Because of that I had to ignore the commons-pool2 instrumentation and implement metrics just for dbcp2.
  • I've decided to use dbcp types (like BasicDataSourceMXBean) in this instrumentation - using plain JMX without compileOnly dependency is possible, but it's considerably less readable - you can see the example in the micrometer CommonsObjectPool2Metrics class.

@mateuszrzeszutek mateuszrzeszutek requested a review from a team as a code owner March 29, 2021 11:06
() ->
assertThat(TestMetricsAccess.getMeterNames())
.containsExactlyInAnyOrder(
"db.pool.connections.active",
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Meter tags/units are not being verified yet, I'm planning to implement that in the next PR

Copy link
Contributor

@breedx-splk breedx-splk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good overall, but I had a question about the metric names and how they mapped over from the pool size info. 👍

@jkwatson
Copy link
Contributor

have we verified that these metrics make it to the splunk backends and are properly chartable, etc?

@mateuszrzeszutek
Copy link
Contributor Author

have we verified that these metrics make it to the splunk backends and are properly chartable, etc?

image

@mateuszrzeszutek mateuszrzeszutek merged commit cd42f18 into main Mar 31, 2021
@delete-merged-branch delete-merged-branch bot deleted the dbcp2-metrics branch March 31, 2021 10:09
public static void registerMetrics(BasicDataSourceMXBean dataSource, ObjectName objectName) {
List<Tag> tags = getTags(objectName);

gauge(CONNECTIONS_TOTAL, tags, new TotalConnectionsUsed(dataSource));
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are these unregistered somewhere? If not does it mean that when the application that added these metrics is undeployed we'll still hold a reference to them?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, that is a very good point -- I'll fix that in another PR. Thanks!

@Override
public Map<? extends ElementMatcher<? super MethodDescription>, String> transformers() {
return singletonMap(
isPublic().and(named("preRegister")).and(takesArguments(2)),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume this means that metrics are only collected when jmx bean is registered. I was just curious is registering the jmx bean a default behaviour? Any idea whether users actually register it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In a Spring application Spring does it automatically -- for manually created and managed connection pools you have to set the pool's JMX name for it to be registered (which is not set by default).
I think it was reasonable to hook on the preRegister method, since it provides us a unique object name - even if for some users (which I suspect won't be many) it won't ever execute.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants