Add diagnostics_channel TracingChannel support

Draft
MI
12d ago
+557-11

This PR introduces tracing channels support to pg-pool and pg querying methods as discussed in #3619

I haven't yet run a benchmark, but without active tracing or subscribers the overhead is non-existent so existing users shouldn't be affected. The overhead would come from the consumers of the diag channels published here which is done anyways via monkey patching.

I added the following channels:

ChannelTypePackageDescription
pg:queryTracingChannelpgQuery lifecycle (start, end, error with async context)
pg:connectionTracingChannelpgClient connection lifecycle
pg:pool:connectTracingChannelpg-poolPool connection acquisition lifecycle
pg:pool:releaseChannelpg-poolClient released back to pool
pg:pool:removeChannelpg-poolClient removed from pool

I understand there may be hesitation given that AI tooling was used in the implementation. To be clear, this isn't a drive-by contribution. I designed the channel layout, wrote the proposal document, and iterated through multiple rounds to handle real edge cases (Node 18 compat, preserving custom Promise types, hasSubscribers guards). The AI assisted with the code, but the approach and decisions are mine.

Usage

Instrumentations will only need to subscribe to tracing channels to create traces, logs or metrics:

import { tracingChannel } from 'diagnostics_channel'

tracingChannel('pg:query').subscribe({
  start({ query, client }) {
    // start span
    // query: { text, name, rowMode }
    // client: { database, host, port, user, processID, ssl }
  },
  asyncEnd({ query, result }) {
    // end span
    // result: { rowCount, command }
  },
  error({ query, error }) {
    // record error on span
  },
})

This is part of a broader initiative to bring TracingChannel support to the most widely used Node.js database and cache libraries. The same pattern has already been merged and shipped in:

I have been directly involved in those prior implementations and I'm happy to own this through to release, address any feedback, and provide whatever support is needed. Would love to hear your thoughts.

Supersedes #3624.


Summary by cubic

Adds diagnostics_channel TracingChannel support to pg and pg-pool so instrumentation libraries can subscribe to structured query and pool events instead of monkey-patching. No behavior change for existing users: all tracing is gated behind subscriber checks, so there is no overhead when nothing is subscribed.

New channels

  • pg:query and pg:connection tracing channels on Client, carrying query text/name/rowMode and client connection details with async context.
  • pg:pool:connect tracing channel and pg:pool:release / pg:pool:remove plain channels on Pool, carrying pool statistics and client IDs.

Compatibility

  • Node 18 backported TracingChannel without the aggregated hasSubscribers getter, so the guard treats undefined as "may have subscribers" to keep tracing working there.
  • Promise-based connect preserves user-configured Promise types by tracing through the callback path instead of tracePromise.