Skip to content

feat(checkers): ClickHouse health checks over the native protocol - #203

Merged
fclairamb merged 2 commits into
fclairamb:mainfrom
WeshGuillaume:feat/clickhouse-checker
Aug 8, 2026
Merged

fclairamb merged 2 commits into
fclairamb:mainfrom
WeshGuillaume:feat/clickhouse-checker

Conversation

@WeshGuillaume

Copy link
Copy Markdown
Contributor

Adds a clickhouse check type, bringing the customer-facing tally from 38 to 39.

What

A native-protocol ClickHouse checker built on clickhouse-go/v2 — the binary protocol on 9000/9440, not the HTTP interface on 8123 — so the check exercises the same transport analytics clients actually use.

Config: host, port (9000, or 9440 when secure), username (defaults to ClickHouse's own default user), password (declared secret, encrypted at rest), database (defaults to default), secure, tls_verify, timeout (max 30s), query (must start with SELECT).

Execution: ping, then run the query and report its first cell. Output carries server_version, host, port, database, secure; metrics are connection_time_ms / query_time_ms / total_time_ms. Ping failure → down, deadline → timeout, client construction failure → error. Dials through an SSH bastion when the check carries a tunnelCheckUid (SupportsTunnel: true).

Why these choices

  • Typed scan. The native protocol is strictly typed: SELECT 1 arrives as a UInt8, not text, so scanning into a string fails. Destinations are allocated from each column's own ScanType() and rendered via reflection, rather than assuming a string like the database/sql-based siblings can.
  • username is optional. Postgres/MySQL require it; ClickHouse ships with a default user, so defaulting is more correct than forcing operators to type default.
  • secure moves the default port (9000 → 9440), matching ClickHouse Cloud, which is TLS-only. tls_verify requires secure and is rejected otherwise.
  • Its own dashboard module rather than joining sqlDatabaseModule: the TLS toggle shifts the default port, which the shared SQL fields have no notion of.
  • Failure results keep their diagnostic output (host/port/database/tunneled) instead of collapsing to an error string. For a tunneled check, knowing the probe crossed a bastion is exactly what makes a failure actionable.

Testing

Unit tests cover FromMap type errors, Validate bounds and the tls_verify/secure pairing, GetConfig round-trip and default omission, name/slug autofill, sample validity, and the down/timeout classification against a real listener. Tunnel tests assert the verbatim host:port crosses the bastion (an RFC 2606 .invalid host proves local resolution was skipped) and that secure reaches 9440 on the wire.

Verified against a live ClickHouse 26.1.3:

Query Result
SELECT 1 up, result 1, server_version=26.1.3
SELECT version() up, result 26.1.3.52
SELECT count() FROM system.parts up, result 577
bad credentials down, code: 516 … Authentication failed

Notes for reviewers

  • Style deviates from the sibling SQL checkers in three places, deliberately, and I'm happy to realign if the project prefers literal consistency: FromMap is a loop over field tables rather than the siblings' if v, ok := m["x"].(string) wall (which needs a //nolint:cyclop); resolution uses resolved*() methods on the config instead of an execParams struct; and one failure() helper replaces the duplicated handlePingError/handleQueryError pair.
  • Files are split (config.go / configmap.go, checker.go / scan.go / result.go) to stay under 200 lines each.
  • golangci-lint was not available on my machine, so make lint-back did not run — gofmt and go vet are clean. dash0 lint/typecheck baseline is unchanged (identical counts before and after).
  • Docs updated: check-types.md, intro.md, ssh-tunnels.md, README.md, wiki/conventions/checker-config.md, wiki/architecture.md.

🤖 Generated with Claude Code

Adds a `clickhouse` check type built on the native (binary) protocol via
clickhouse-go/v2, not the HTTP interface, so the check exercises the same
transport analytics clients use.

Config: host, port (9000, or 9440 when `secure`), username (defaults to
ClickHouse's own `default` user), password (encrypted at rest), database,
secure, tls_verify, timeout, query. Ping then query; the result renders the
first cell from the column's own scan type, since the native protocol is
strictly typed and `SELECT 1` arrives as a UInt8 rather than text. Reports
server_version plus connection/query/total timings, and dials through an SSH
bastion when the check carries a tunnelCheckUid.

Its own dashboard module rather than a member of sqlDatabaseModule: the TLS
toggle moves the default port, which the shared SQL fields have no notion of.

Docs and the check-type tally move from 38 to 39.
@fclairamb

Copy link
Copy Markdown
Owner

LGTM, thank you @WeshGuillaume for this contribution !

@fclairamb
fclairamb enabled auto-merge (squash) August 8, 2026 15:49
…e checker

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@fclairamb
fclairamb merged commit 57d6f67 into fclairamb:main Aug 8, 2026
11 checks passed
@fclairamb fclairamb mentioned this pull request Aug 8, 2026
fclairamb added a commit that referenced this pull request Aug 8, 2026
🤖 I have created a release *beep* *boop*
---


##
[0.10.0](v0.9.0...v0.10.0)
(2026-08-08)


### Features

* **checkers:** ClickHouse health checks over the native protocol
([#203](#203))
([57d6f67](57d6f67))


### Bug Fixes

* **deps:** update dependency motion to v13
([#202](#202))
([5425dcf](5425dcf))
* **deps:** update github.com/dop251/goja digest to 493f220
([#200](#200))
([d029a09](d029a09))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).
This was referenced Sep 8, 2026
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.

2 participants