Skip to content

Inline ClickHouseTracer hook calls; drop defensive wrappers#782

Open
Copilot wants to merge 7 commits into
mainfrom
copilot/add-telemetry
Open

Inline ClickHouseTracer hook calls; drop defensive wrappers#782
Copilot wants to merge 7 commits into
mainfrom
copilot/add-telemetry

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented May 29, 2026

Summary

Reworks the recently-added tracer hooks API to be a near zero-cost addition: removes the runWithTracer() / safeCallTracer() / logTracerError() wrappers and inlines bare hook calls into each client method. Tracer exceptions now propagate to the caller — users are expected to verify their tracer doesn't throw via a simple e2e test rather than the client carrying defensive plumbing on the hot path. Docs are updated to emphasize the zero-dependency design.

  • client-common/src/client.ts — Each of query/command/exec/insert/ping now opens the span inline, wraps the underlying connection.* call in a flat try / catch / finally, and calls this.tracer?.setAttributes/setStatus/recordException/endSpan directly. No helper, no per-hook try/catch.
  • client-common/src/tracing_internal.ts — Deleted.
  • client-common/src/tracing.ts, config.ts — JSDoc updated: hooks are inlined on the hot path with no defensive wrapper; implementations must be non-throwing.
  • docs/howto/tracing.md — Calls out zero-dependency / nothing-in-the-bundle / near-zero per-op cost up front; replaces the "broken tracer cannot break the client" guarantee with the new propagation contract.
  • __tests__/unit/tracing.test.ts — Replaced the swallow-exceptions tests with one asserting tracer exceptions propagate and one asserting endSpan still runs on success.

Shape on the hot path:

const span = this.tracer?.startSpan(name, attrs)
try {
  const result = await this.connection.query(...)
  this.tracer?.setAttributes(span, { 'clickhouse.query_id': result.query_id })
  this.tracer?.setStatus(span, { code: 'OK' })
  return result
} catch (err) {
  this.tracer?.recordException(span, err)
  this.tracer?.setStatus(span, { code: 'ERROR', message: ... })
  throw err
} finally {
  this.tracer?.endSpan(span)
}

Checklist

  • Unit and integration tests covering the common scenarios were added
  • A human-readable description of the changes was provided to include in CHANGELOG

CHANGELOG: Tracer hooks are now invoked inline with no defensive wrapper — exceptions thrown by a user-supplied ClickHouseTracer propagate to the caller instead of being swallowed and logged at WARN.

@CLAassistant
Copy link
Copy Markdown

CLAassistant commented May 29, 2026

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you all sign our Contributor License Agreement before we can accept your contribution.
1 out of 2 committers have signed the CLA.

✅ peter-leonov-ch
❌ Copilot
You have signed the CLA already but the status is still pending? Let us recheck it.

Copilot AI linked an issue May 29, 2026 that may be closed by this pull request
Copilot AI changed the title [WIP] Add telemetry for metrics, logs, and traces Add user-supplied tracer hooks called at client lifecycle events May 29, 2026
Copilot AI requested a review from peter-leonov-ch May 29, 2026 23:36
@codecov
Copy link
Copy Markdown

codecov Bot commented May 29, 2026

Codecov Report

❌ Patch coverage is 84.84848% with 10 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
packages/client-common/src/client.ts 84.37% 7 Missing and 3 partials ⚠️

📢 Thoughts on this report? Let us know!

@peter-leonov-ch peter-leonov-ch marked this pull request as ready for review May 30, 2026 00:20
@peter-leonov-ch peter-leonov-ch requested a review from mshustov as a code owner May 30, 2026 00:20
Copilot AI review requested due to automatic review settings May 30, 2026 00:20
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds an optional, dependency-free tracer hook family on the client config that mirrors the OpenTelemetry Span API and is invoked around query / command / exec / insert / ping, with all hook calls guarded so a broken tracer cannot break client operations.

Changes:

  • New public types/constants (ClickHouseTracer, ClickHouseTracerSpanAttributes, ClickHouseTracerSpanStatus, ClickHouseSpanNames) in client-common, re-exported by client and client-web; new tracer config field.
  • New runWithTracer helper that wraps each lifecycle operation, emits base attributes (db.system, db.namespace, server.address, clickhouse.application, op-specific), updates the server-assigned query_id, and translates outcomes to OK/ERROR status with recordException.
  • Documentation (docs/howto/tracing.md), CHANGELOG entry under 1.20.0, and unit tests covering all operations, the empty-insert short-circuit, error propagation, and broken-tracer resilience.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
packages/client-common/src/tracing.ts New public tracer interface, attribute/status types, and span-name constants.
packages/client-common/src/tracing_internal.ts runWithTracer and applyAttributes helpers with WARN-level error swallowing.
packages/client-common/src/config.ts Adds optional tracer config field.
packages/client-common/src/client.ts Wires runWithTracer into query/command/exec/insert/ping and adds baseSpanAttributes.
packages/client-common/src/index.ts Public re-exports of new tracing types/constants.
packages/client-node/src/index.ts Re-exports new tracing surface from @clickhouse/client.
packages/client-web/src/index.ts Re-exports new tracing surface from @clickhouse/client-web.
packages/client-common/tests/unit/tracing.test.ts Unit tests for hook flow, error path, no-tracer passthrough, and broken-tracer resilience.
docs/howto/tracing.md New tracing how-to with OTEL adapter and recording-only examples.
CHANGELOG.md 1.20.0 entry describing the new tracer-hooks API.

Comment thread packages/client-common/src/client.ts Outdated
Comment thread docs/howto/tracing.md Outdated
Copilot AI changed the title Add user-supplied tracer hooks called at client lifecycle events Inline ClickHouseTracer hook calls; drop defensive wrappers May 31, 2026
@polRk
Copy link
Copy Markdown

polRk commented May 31, 2026

Just a suggestion from the outside: you might want to avoid custom tracing boilerplate and refactor this using native Node.js diagnostics_channel. We implemented this exact pattern for telemetry in ydbjs. It allowed us to completely decouple the tracer from the main package and seamlessly inject telemetry via --import. It keeps the core clean and lightweight.

https://github.com/ydb-platform/ydb-js-sdk/tree/main/packages/telemetry

@peter-leonov-ch
Copy link
Copy Markdown
Collaborator

@copilot resolve the merge conflicts in this pull request

Copy link
Copy Markdown
Contributor Author

Copilot AI commented Jun 2, 2026

@copilot resolve the merge conflicts in this pull request

Conflicts are resolved in merge commit 885d296 (merged origin/main into this branch and resolved the packages/client-node/src/index.ts and packages/client-web/src/index.ts export conflicts).

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.

Add telemetry

5 participants