#812
CLIENT-5630 Support metrics sampling and exporters
Summary
Implements the shared client metrics v3 collection/snapshot model for the Go client (CLIENT-5630), aligned with the collection + exporter tech specs.
- Flags / tiers: master (
metrics.enabled) with independent operational and usage;DefaultMetricsPolicy/ nil / zero-valueEnableMetrics→ master + operational (legacy); YAML v3enabledwithoutextended.operationalleaves operational off. - Sampler: one
metrics_onper user API call (range/threshold,math/rand/v2); gates command-path latency, bytes, error splits,command.count/retries. - Dual latency (Decision 15):
cluster.latency.{read,write,batch,query}(whole successful call);namespace.latency.*(successful node RPC/sub-batch);node.latency.conn(successful open, not sampler-gated). Newtypes/histogram/latency_buckets.gofor the shared columns+shift layout; existingSyncHistogramkept for Go fine-grained command/phase metrics. - CM-7 / Decision 14: client vs server timeouts via
fromServer; namespace error/timeout/key_busy/record_too_big/device_overload on each failed attempt; bytes on RPC success only. - CM-8: node
connection.{open,tls,auth}.failurevs clustervalidation.*; auth only on auth result codes (network/TLS during login → open/tls);open.failurerolls up TLS/auth. - Usage (CM-17 / CM-27):
feature.api.*plus shapes andfilter.ael|exp(including per-record batch filters); no object-mapping (N/A) and no CM-28. - Batch / query / scan: parent owns
command.count+ cluster latency; children record namespace latency only;batch.partial_failureonce per key on successful batch completion; one-key batches stay on the wire path when metrics are on. - Export:
NONE|FILE|CUSTOM; new snake_case file exporter (header(3));nodes_departedcap 256, cleared only after a fully successful periodic export; on-demand includes but does not drain. Dynconfig re-apply is idempotent (no export-ticker restart on unchanged policy). Separate on-demand vs export CPU sample windows. - Also: dynconfig static hydrate no longer wipes
ClientPolicycredentials;Connection.updateDeadlineno longer extends a sub-ms remainingTotalTimeoutpast the absolute deadline.