8000 feat(metrics): wire BigQuery store config, readiness probe and runtime by AntonTyb · Pull Request #1406 · google/xmc · GitHub
[go: up one dir, main page]

Skip to content

feat(metrics): wire BigQuery store config, readiness probe and runtime - #1406

Merged
AntonTyb merged 4 commits into
feat/metrics-ingester-bigquery-writerfrom
feat/metrics-ingester-bigquery-config
Oct 27, 2026
Merged

AntonTyb merged 4 commits into
feat/metrics-ingester-bigquery-writerfrom
feat/metrics-ingester-bigquery-config

Conversation

@AntonTyb
@AntonTyb AntonTyb commented Oct 25, 2026 •
Copy link
Copy Markdown
Collaborator

Stack (2/6): main ← #1405 ← #1406 (this PR) ← #1407 ← #1408 ← #1409 ← #1410 — review and merge bottom-up.

Summary

Wires BigQuery as a selectable metrics storage backend (-metrics_store=bigquery / METRICS_STORE=bigquery) in cmd/metrics_ingester, adding flag/env validation, the Tier 2 RuntimeStore composition root, a zero-cost Table.Metadata startup and /readyz probe, and CLI entrypoint cleanup handling. Stacked on #1405 (feat/metrics-ingester-bigquery-writer).

Motivation & Context

With BigQueryWriter and NormalizeMetrics in place, cmd/metrics_ingester needs runtime configuration, Storage Write API stream lifecycle management, and Kubernetes readiness probing so operators can run Pub/Sub -> BigQuery without deploying ClickHouse. Following the repository's Two-Tier Composition Root architecture keeps Cloud SDK client construction (bigquery.Client, managedwriter.Client, ManagedStream) isolated in runtime.go with deterministic LIFO rollback on startup errors and idempotent Close().

For /readyz and startup verification, probing Table.Metadata(ctx) verifies dataset/table existence and IAM permissions via a zero-cost metadata RPC (rather than executing billable BigQuery SQL queries every few seconds). Passing the uncancelled root context to NewManagedStream while passing the SIGINT/SIGTERM context to Ingester.Run ensures the Storage Write stream stays open during Ingester's 10s shutdown flush before defer store.Close() runs.

Key Changes

  • cmd/metrics_ingester/metricsingester/{config.go, config_test.go}: Adds -metrics_store (clickhouse | bigquery, default clickhouse), -bigquery_project_id (BIGQUERY_PROJECT_ID, falling back to ProjectID), -bigquery_dataset (BIGQUERY_DATASET, default xmc_metrics), and -bigquery_table (BIGQUERY_TABLE, default xmc_metrics), rejecting unknown stores and slash-containing BigQuery resource IDs.
  • cmd/metrics_ingester/metricsingester/{runtime.go, runtime_test.go, health.go, BUILD.bazel}: Adds RuntimeStore, OpenRuntimeStore, and OpenBigQueryStream with LIFO error rollback, sync.Once Close() (filtering expected io.EOF on healthy ManagedStream.Close()), and tableMetadataPinger, tested hermetically against in-process fake BigQuery REST and gRPC Storage Write servers.
  • cmd/metrics_ingester/{main.go, BUILD.bazel, README.md}: Adopts os.Exit(mainExitCode()) so deferred cleanups always run, wires OpenRuntimeStore, and documents BigQuery configuration, roles/bigquery.dataEditor IAM requirements, and /readyz behavior.

Assumptions

  • -metrics_store / METRICS_STORE defaults to "clickhouse" when unset — chosen to preserve zero-configuration backward compatibility for existing ClickHouse deployments — deployments running BigQuery without ClickHouse must explicitly set METRICS_STORE=bigquery (or -metrics_store=bigquery), otherwise startup will attempt to dial ClickHouse.
  • Startup and /readyz probes verify BigQuery reachability via Table.Metadata(ctx) rather than SELECT 1 SQL queries — chosen because Table.Metadata checks dataset/table existence and IAM permissions via a zero-cost metadata RPC without incurring per-probe BigQuery slot/scan charges — if the BigQuery Storage Write gRPC endpoint experiences an isolated outage while the BigQuery REST metadata endpoint stays healthy, /readyz will remain green and surface errors on AppendRows retries instead.
  • OpenBigQueryStream binds the long-lived Storage Write default stream to context.Background() rather than the SIGINT/SIGTERM signal context — chosen so the write stream stays open while Ingester.Run flushes in-flight batches during its 10-second graceful shutdown window before defer store.Close() executes — startup readiness verification remains bounded by startupPingTimeout and the caller context.

Verification & Testing

  • Commands Executed:
    • bazel test --@io_bazel_rules_go//go/config:race --runs_per_test=10 //cmd/metrics_ingester/... //deploy/bigquery/... //deploy/clickhouse/...
    • bazel coverage --combined_report=lcov //cmd/metrics_ingester/metricsingester:metricsingester_test
    • ./.githooks/pre-commit
  • Coverage & Test Status: All repository unit tests in pre-commit and 30/30 race-enabled package test runs passed; 100.0% line coverage in config.go (70/70) and health.go (31/31), and 98.1% (103/105) in runtime.go.

Related Issues / Bugs

N/A

TAG=agy
CONV=0fafd02b-f3b1-4563-a73d-49ec0845afbd

Wire BigQuery as a selectable metrics storage backend in `cmd/metrics_ingester`
alongside ClickHouse, completing the Pub/Sub -> BigQuery ingestion path.

Key additions:
- Extend `Config` / `RegisterFlags` / `LoadConfig` with `-metrics_store`
  (`METRICS_STORE`, defaulting to `clickhouse`), `-bigquery_project_id`
  (`BIGQUERY_PROJECT_ID`, falling back to `ProjectID`), `-bigquery_dataset`
  (`BIGQUERY_DATASET`, defaulting to `xmc_metrics`), and `-bigquery_table`
  (`BIGQUERY_TABLE`, defaulting to `xmc_metrics`), rejecting unknown store names
  and slash-containing resource identifiers at startup.
- Add the Tier 2 composition root (`RuntimeStore` / `OpenRuntimeStore` /
  `OpenBigQueryStream`) with LIFO error rollback, `sync.Once` idempotent
  `Close()` (ignoring normal `io.EOF` on healthy `ManagedStream.Close()`), and a
  zero-cost `Table.Metadata` startup check and `/readyz` `Pinger`.
- Refactor `cmd/metrics_ingester/main.go` onto `os.Exit(mainExitCode())` so all
  deferred store, Pub/Sub, and HTTP server cleanups execute before exit, keeping
  the root `ManagedStream` context alive across `Ingester`'s 10s `SIGTERM`
  shutdown flush.

TAG=agy
CONV=0fafd02b-f3b1-4563-a73d-49ec0845afbd

Change-Id: Ib647b2fa5bab569fa00e1f00d53a0d5c6dfbffb1
@gemini-code-assist gemini-code-assist Bot left a comment
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Review

This pull request introduces support for Google Cloud BigQuery as an alternative metrics storage backend alongside the existing ClickHouse implementation. The changes include refactoring the metrics ingester to use a configurable storage interface, updating the configuration and health checks to be store-agnostic, and adding the necessary dependencies and tests. A review comment suggests improving the readability of a function signature in runtime.go by replacing the blank identifier with a descriptive name for the return value.

…Options

Name the first return parameter `store` alongside `retErr` in
`openBigQueryStoreWithOptions` to avoid mixing a blank-identifier return
parameter with a named error return parameter.

Comment link: #1406 (comment)

TAG=agy
CONV=0fafd02b-f3b1-4563-a73d-49ec0845afbd

Change-Id: Ibc02e0c2d48b38762a76767acb0eafcb59613970
@AntonTyb
AntonTyb marked this pull request as ready for review October 25, 2026 12:29
@github-actions
github-actions Bot requested a review from VLukiantsev October 25, 2026 12:29
@VLukiantsev
VLukiantsev added this pull request to stack #1412 October 26, 2026 09:37
VLukiantsev
VLukiantsev previously approved these changes Oct 26, 2026
…/metrics-ingester-bigquery-config

Sync downstream stack branch with PR #1405 review fixes.

TAG=agy
CONV=0fafd02b-f3b1-4563-a73d-49ec0845afbd

Change-Id: I27c9fb9e4325e0f34ff68d219f66ce5cdcc4df5c
AntonTyb added a commit that referenced this pull request Oct 26, 2026
…at/dataengine-query-backend-abstraction

Sync downstream stack branch with PR #1405/#1406 ancestry.

TAG=agy
CONV=0fafd02b-f3b1-4563-a73d-49ec0845afbd

Change-Id: If1841fa3894b857f6480650ecad7292bc3eea1f1
github-actions[bot]
github-actions Bot previously approved these changes Oct 26, 2026
@github-actions github-actions Bot left a comment
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🤖 Incremental PR Approval

Clean rebase detected with zero semantic patch lines changed.

Preserving prior approval by @VLukiantsev on commit c3e17b1.

…t chunk duplicates

Enable `managedwriter.EnableWriteRetries(true)` in `OpenBigQueryStream` so
transient `UNAVAILABLE` / `RESOURCE_EXHAUSTED` `AppendRows` errors are retried
automatically within the write timeout before nacking a batch, and document
multi-chunk partial-commit duplicate semantics in `cmd/metrics_ingester/README.md`.

TAG=agy
CONV=0fafd02b-f3b1-4563-a73d-49ec0845afbd

Change-Id: I24c7bda6a023878b3d22c38e06f5fce9cd150dc6
@github-actions github-actions Bot left a comment
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🤖 Incremental PR Approval

PR author is a code owner and changes since last approval (3 lines, excluding 36 test file lines) are within the 50-line grace delta.

Preserving prior approval by @VLukiantsev on commit c3e17b1.

< 8000 svg aria-label="Loading..." style="box-sizing: content-box; color: var(--color-icon-primary);" width="32" height="32" viewBox="0 0 16 16" fill="none" role="img" data-view-component="true" class="anim-rotate">

@AntonTyb
AntonTyb added this pull request to the merge queue Oct 27, 2026
Merged via the queue into main with commit a5b4c7f Oct 27, 2026
14 checks passed
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

0