Wire datastore query metrics per S03 catalog

Why

The S03 catalog defines per-query database metrics. The helper landed with S03-B as metrics.InstrumentQuery (internal/metrics/database.go), emitting:

  • database_queries_total{name}, a counter.
  • database_query_duration_seconds{name}, a histogram. No status label and no exemplars: the call form takes no context.

Call sites wrap a query with defer metrics.InstrumentQuery(name)(). internal/storage/queries.go already instruments the storage-owned repositories this way. No internal/datastore query is instrumented yet. The TODO(#54) markers in internal/datastore enumerate the call sites and prescribe a name for each, swept to a uniform grammar by chore(datastore): sweep stale TODO(#92-followup... (!1228 - merged) • Hayley Swimelar • 19.3.

Surfaced by @vespian_gl during the review of feat(datastore): add container datastore and OC... (!125 - closed) • Hayley Swimelar.

What

  • Wrap each internal/datastore query with defer metrics.InstrumentQuery(name)(), using the marker-prescribed names.
  • Define the name constants per call site: static, low-cardinality, package-level, following the Observability section of docs/dev/storage.md.
  • Names count against the existing 200-name budget enforced by AuditCardinality (internal/metrics/cardinality.go).
  • Update the database_query_duration_seconds / database_queries_total row of the Observability table in docs/dev/storage.md, which today names only the storage-owned repositories.

Dependencies

None. The S03 spec merged (docs(specs): narrow S03 to logging conventions (!56 - merged) • Hayley Swimelar), and the helper landed with S03-B (docs/specs/S03-b-metrics.md).

Out of scope

  • Storage operation metrics (storage_*) are owned separately.
  • HTTP client metrics (http_client_*) are owned separately.
Edited by Hayley Swimelar