feat: add commons pool2 instrumentation#19091
Conversation
There was a problem hiding this comment.
Pull request overview
This PR adds a new instrumentation family for Apache Commons Pool 2, enabling database connection pool metrics for GenericObjectPool and GenericKeyedObjectPool instances. It follows the established pattern of the existing database-pool instrumentations (Apache DBCP, c3p0, Alibaba Druid), providing a standalone library entrypoint (CommonsPool2Telemetry) plus a javaagent module that auto-registers metrics on pool construction and unregisters them on jmxUnregister.
Changes:
- Adds
library,javaagent, andtestingmodules underinstrumentation/apache-commons-pool2, wiring metrics throughDbConnectionPoolMetricsand using an identity-key map for pool lifecycle tracking. - Registers the new Gradle projects, supported-library docs, metadata, and latest-dependency version pin.
- Adds FOSSA targets for the new modules (with an incorrect project path).
Reviewed changes
Copilot reviewed 16 out of 16 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
settings.gradle.kts |
Registers the three new apache-commons-pool2 Gradle projects |
instrumentation/apache-commons-pool2/library/.../ConnectionPoolMetrics.java |
Core metric registration/callback logic for both pool MXBean types via identity-keyed map |
instrumentation/apache-commons-pool2/library/.../CommonsPool2Telemetry.java |
Public library entrypoint accepting an Object pool |
instrumentation/apache-commons-pool2/javaagent/.../BaseGenericObjectPoolInstrumentation.java |
Constructor + jmxUnregister advice; derives pool name from JMX ObjectName with fallbacks |
instrumentation/apache-commons-pool2/javaagent/.../CommonsPool2Singletons.java |
Holds the CommonsPool2Telemetry singleton |
instrumentation/apache-commons-pool2/javaagent/.../CommonsPool2InstrumentationModule.java |
Registers the type instrumentation |
instrumentation/apache-commons-pool2/testing/.../AbstractCommonsPool2InstrumentationTest.java |
Shared tests covering both pool types with JMX enabled/disabled |
instrumentation/apache-commons-pool2/{library,javaagent}/src/test/.../CommonsPool2InstrumentationTest.java |
Library/agent test subclasses |
instrumentation/apache-commons-pool2/*/build.gradle.kts |
Build config, muzzle range, and stable-semconv test tasks |
instrumentation/apache-commons-pool2/metadata.yaml |
Instrumentation metadata and semconv opt-in config |
docs/supported-libraries.md |
Documents the new supported library |
.github/config/latest-dep-versions.json |
Pins latest commons-pool2 version |
.fossa.yml |
Adds FOSSA targets (referencing a non-existent project path) |
| target: ':instrumentation:commons-pool2-2.0:javaagent' | ||
| - type: gradle | ||
| path: ./ | ||
| target: ':instrumentation:commons-pool2-2.0:library' |
|
This PR has review comments. Review suggestions, whether from maintainers or automated reviewers, aren't always correct or required. Please evaluate each comment on its merits, then make sure each thread has a clear outcome. For example, link to the commit if you applied a suggestion, explain why it wasn't applied, or ask a follow-up question. Automation flags a PR for human review once every review thread has a reply or is marked as resolved. Status across open PRs is visible on the pull request dashboard. |
| static void registerMetrics(OpenTelemetry openTelemetry, Object pool, String poolName) { | ||
| if (pool instanceof GenericObjectPoolMXBean) { | ||
| GenericObjectPoolMXBean objectPool = (GenericObjectPoolMXBean) pool; | ||
| registerMetrics( |
There was a problem hiding this comment.
how do you know that this pool is actually used for database connections?
There was a problem hiding this comment.
This connection pool has a wide range of use cases and is not limited to database connection scenarios. For example, it can serve as a socket connection pool in Lettuce, Jedis, or Thrift applications, and can also function as other types of object pools. Should we define a separate set of metrics without database-specific semantics, instead of reusing the existing metric names designed for databases?
There was a problem hiding this comment.
My understanding is that connection pool metrics can not be reused for other object pools.
|
|
||
| String name = objectName == null ? null : objectName.getKeyProperty("name"); | ||
| if (name == null) { | ||
| name = String.valueOf(System.identityHashCode(pool)); |
There was a problem hiding this comment.
metric attributes should have low cardinality
| .and(takesArgument(1, named("java.lang.String"))) | ||
| .and(takesArgument(2, named("java.lang.String"))), |
There was a problem hiding this comment.
named() does an exact type-name match and is mainly useful when you want to avoid classloading or reference a type that may not be on the compile classpath. For JDK core types like String, you can use the class literal instead
| .and(takesArgument(1, named("java.lang.String"))) | |
| .and(takesArgument(2, named("java.lang.String"))), | |
| .and(takesArgument(1, named(String.class))) | |
| .and(takesArgument(2, named(String.class))), |
| idleObjectsAttributes = attributes.toBuilder().put(OBJECT_STATE, STATE_IDLE).build(); | ||
| } | ||
|
|
||
| ObservableLongMeasurement objects() { |
There was a problem hiding this comment.
since these metrics don't follow the semantic conventions, i think we'd need put them behind a feature flag in the java agent instrumentation. Or maybe based on Lauri's comment these all need to be reworked to just focus on database
There was a problem hiding this comment.
@laurit @jaydeluca If we only focus on database scenarios such as Jedis and Lettuce, we will have to implement targeted handling for these two libraries. However, there are also non-database use cases. For instance, Thrift relies on commons-pool2 object pools to manage socket connections, where commons-pool2 is used as a standalone dependency instead of being built into Thrift. Such scenarios would not be covered under the database-only approach. Which of the two solutions do you recommend? Should we only instrument database-related components like Jedis and Lettuce, or instrument the entire commons-pool2 module with a feature toggle to enable or disable the capability?
| | [Apache CXF JAX-RS](https://cxf.apache.org/) | 3.2+ (not including 4.0+ yet) | N/A | Provides `http.route` [2], Controller Spans [3] | | ||
| | [Apache CXF JAX-WS](https://cxf.apache.org/) | 3.0+ (not including 4.0+ yet) | N/A | Provides `http.route` [2], Controller Spans [3] | | ||
| | [Apache DBCP](https://commons.apache.org/proper/commons-dbcp/) | 2.0+ | [opentelemetry-apache-dbcp-2.0](../instrumentation/apache-dbcp-2.0/library) | [Database Pool Metrics] | | ||
| | [Apache Commons Pool 2](https://commons.apache.org/proper/commons-pool/) | 2.0+ | [opentelemetry-apache-commons-pool2-2.0](../instrumentation/apache-commons-pool2-2.0/library) | none | |
There was a problem hiding this comment.
this should be put in alphabetical order
Add support for commons pool2