-
Notifications
You must be signed in to change notification settings - Fork 311
Add a span when waiting for an available database connection from a pool #9251
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
base: master
Are you sure you want to change the base?
Conversation
df910b9
to
fec7eac
Compare
Also: see support case 2199108 |
Thanks for the contribution @deejgregor! |
…o detect blocking
I've done a little bit more experimenting and I've found a few things along the way, so I wanted to provide an update and ask a few questions. First, my update: I simplified (I think) My questions:
Configuration options and tracingTodayjdbc-datasource not enabled (default)Database pool and database driver connection operations are not visible: no jdbc-datasource enabled
FutureI wanted to propose an option or two of how to configure this, but I haven't been terribly happy with anything I came up with. Here are my main thoughts:
That combination gets me three things:
One option could be to just enable the |
What Does This Do
This adds a
pool.waiting
span when waiting for an available database connection from a Hikari (>= 2.4.0) or DBCP2 (>= 2.10.0) connection pool.Motivation
Additional Notes
Is this a contribution you would be interested in?
It would definitely be helpful to us at $WORK if this could be in the tracer, as we use connection pools heavily and delays due to exhausted connection pools tend to be not be quick to identify.
Concerns
For modern versions of HIkari, the instrumentation to determine blocking in
HikariBlockedTrackingSynchronousQueue
replaces theSynchronousQueue
created byConcurrentBag.<init>
, and assumes thattrue
is always passed when creating theSynchronousQueue
. This sets the fairness policy and it has been set this way since 2017, so the likelihood of it changing in future versions of HIkari is very low.Instrumented Code
Hikari
There is a common method,
ConcurrentBag.borrow
, that is used for both blocking and non-blocking paths. This method is instrumented along with deeper methods that indicate when the blocking path was taken. Depending on the Hikari version, there are two different downstream methods that are instrumented. AThreadLocal
is used with the help ofHikariBlockedTracker
to communicate between the various instrumentations when the blocking path was taken. Apool.waiting
span is created whenConcurrentBag.borrow
returns, but only if blocking occurred.Apache DBCP2
In commons-pool >= 2.10.0 and later, this is straightforward, as
LinkedBlockingDeque.pollFirst(Duration)
is called only in blocking cases byGenericObjectPool.borrowObject
from a number of places in dbcp2.Additional work needs to be done to ensure that a span is only created whenThis is done.LinkedBlockingDeque.pollFirst
is called from dbcp2.This code can be extended to work with earlier versions of commons-pool, however determining the blocking signature of
poolFirst
will require a little bit more work and might require differentiating between versions of commons-pool to make sure only the appropriate signature is instrumented (or looking for another way to determine blocking).Test cases
A test class was added in https://github.com/deejgregor/dd-trace-java/blob/hikaricp-blocked-tracking/dd-java-agent/instrumentation/jdbc/src/test/groovy/SaturatedPoolBlockingTest.groovy.
Additional work
Although this seems to work functionally in with the included test, there are a few items still being worked on:
Other considerations
getConnection()
calls to database drivers be traced from connection pools to indicate when a request delay is caused by new connection is being opened? This might be particularly helpful for forking database backends like PostgreSQL that have longer connection times.Contributor Checklist
type:
and (comp:
orinst:
) labels in addition to any usefull labelsclose
,fix
or any linking keywords when referencing an issue.Use
solves
instead, and assign the PR milestone to the issueJira ticket: [PROJ-IDENT]