implementing UCP Observability Providers, JFR and Open telemetry providers to monitor UCP#246
Closed
elaaissaouiabdessamad wants to merge 10 commits intomainfrom
Closed
implementing UCP Observability Providers, JFR and Open telemetry providers to monitor UCP#246elaaissaouiabdessamad wants to merge 10 commits intomainfrom
elaaissaouiabdessamad wants to merge 10 commits intomainfrom
Conversation
Add the new module entry so Maven includes it in the multi-module build.
…endencies Sets up the Maven module with: - UCP 23.26.1.0.0 as the primary dependency - OpenTelemetry API 1.44.1 for metric instrumentation - JUnit 5 and Mockito for unit testing - Compiler source/target pinned to Java 11 (required for JFR API) - Surefire configured for sequential, alphabetical test execution
…CPEventFactory, JFRUCPEventListenerProvider) UCPBaseEvent — abstract JFR Event subclass that captures the common pool snapshot fields (pool name, sizes, borrowed/available counts, wait time) from UCPEventContext. All concrete JFR event types extend this class. UCPEventFactory — static factory that maps every UCPEventListener.EventType to its concrete JFR event class and calls event.commit(). Unknown event types are logged at FINE level and silently skipped. JFRUCPEventListenerProvider — UCPEventListenerProvider implementation registered under the name "jfr-ucp-listener". Holds a single stateless listener singleton (TRACE_EVENT_LISTENER) that delegates to UCPEventFactory.
Adds 11 concrete JFR event classes, each extending UCPBaseEvent: Connection lifecycle (4): ConnectionBorrowedEvent — ucp.ConnectionBorrowed ConnectionClosedEvent — ucp.ConnectionClosed ConnectionCreatedEvent — ucp.ConnectionCreated ConnectionReturnedEvent — ucp.ConnectionReturned Pool lifecycle (5): PoolCreatedEvent — ucp.PoolCreated PoolStartingEvent — ucp.PoolStarting PoolStartedEvent — ucp.PoolStarted PoolStoppedEvent — ucp.PoolStopped PoolDestroyedEvent — ucp.PoolDestroyed Maintenance operations (3): PoolPurgedEvent — ucp.PoolPurged PoolRecycledEvent — ucp.PoolRecycled PoolRefreshedEvent — ucp.PoolRefreshed Every class carries @name, @Label, @description, and @category JFR annotations to make events discoverable in JDK Mission Control.
OtelUCPEventListenerProvider registers as "otel-ucp-listener" and exposes
UCP connection pool state as OTel metrics following the semantic conventions
for database client connection pools.
Metrics published:
db.client.connection.usage (LongGauge, state=used|idle) — live snapshot
db.client.connection.max (LongGauge) — max pool size, on lifecycle events
db.client.connection.idle.min(LongGauge) — min pool size, on lifecycle events
db.client.connection.wait_time(DoubleHistogram, s) — avg borrow wait, on
CONNECTION_BORROWED when > 0
db.client.connection.established (LongGauge) — cumulative connections opened
db.client.connection.closed (LongGauge) — cumulative connections closed
Design decisions:
- OTel instruments are instance fields (not static) so they bind to whichever
SDK is registered at pool activation time, not at class-load time.
- Per-pool Attributes objects are cached in a ConcurrentHashMap (PoolState)
to avoid allocations on high-frequency connection events.
- POOL_DESTROYED removes the pool's PoolState entry before recording the
final snapshot, avoiding a computeIfAbsent + immediate remove pattern.
- Serialization is explicitly blocked: UCPEventListener extends Serializable
but OTel instruments are not — a clear NotSerializableException is thrown
rather than an opaque failure.
…oader Adds META-INF/services/oracle.ucp.events.core.UCPEventListenerProvider so UCP discovers both providers automatically at runtime without any explicit registration code: - jfr-ucp-listener (JFRUCPEventListenerProvider) - otel-ucp-listener (OtelUCPEventListenerProvider)
Tests cover:
- Provider name and non-null listener contract
- isDesiredEvent() returns true for all EventType values
- UCPEventFactory null-safety (NPE on null type or null context)
- recordEvent() does not throw for all known EventTypes
- recordEvent() handles zero/default values and null pool name gracefully
- onUCPEvent() reads every UCPEventContext field for pool lifecycle,
connection, and maintenance event categories
Tests cover:
- Provider name, non-null listener, null config tolerance, singleton contract
- isDesiredEvent() returns true for all EventType values
- Null safety: null eventType, null context, both null, null pool name
- robustness: all EventTypes, zero/default context values
- Context field access contract:
· poolName() read exactly once per event
· borrowedConnectionsCount() / availableConnectionsCount() read on all events
· maxPoolSize() / minPoolSize() read only on pool lifecycle events,
NOT on connection or maintenance events
· getAverageConnectionWaitTime() read only on CONNECTION_BORROWED,
and recording suppressed when value is 0
· totalConnections() never read (not used by the OTel provider)
- Pool state lifecycle: POOL_DESTROYED without prior registration, double
POOL_DESTROYED, events after destruction
- NotSerializableException on serialization attempt
- Multi-pool independence and 8-thread concurrency stress test
…Java 11 The root pom's javac-release profile forces --release 8 for all modules. This module uses jdk.jfr which requires Java 11+, so both plugins need an explicit override: - maven-compiler-plugin: <release>11</release> - maven-javadoc-plugin: <release>11</release> Without the javadoc override the plugin inherits --release 8 from the parent profile's @options file, causing javadoc generation to fail with "package jdk.jfr does not exist".
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Implementing JFR, OTEL Providers for monitoring UCP.