Skip to content

Add WithBlockedStats SinkOption to drop stats by exact name - #177

Closed
th0114nd wants to merge 2 commits into
masterfrom
tholland/blocked-stats-sink-option
Closed

Add WithBlockedStats SinkOption to drop stats by exact name#177
th0114nd wants to merge 2 commits into
masterfrom
tholland/blocked-stats-sink-option

Conversation

@th0114nd

@th0114nd th0114nd commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Adds a WithBlockedStats(map[string]struct{}) SinkOption to netSink.
  • FlushCounter/FlushGauge/FlushTimer do an O(1) map lookup against it and silently drop matching stats before they're buffered or written to the wire.

Important caveat: what "name" actually is

The lookup is against the name gostats itself resolves — the dot-joined scope path plus any serialized tags (e.g. service.subscope.stat_name or stat_name.__tag=value), exactly as passed into FlushCounter/FlushGauge/FlushTimer.

It does not include:

  • an environment prefix (e.g. production:, staging:) added by a downstream ingestion pipeline, or
  • an aggregation-type suffix (e.g. :count, :rate, :p99, :sum) added by a downstream aggregator/exporter.

Motivation

Test plan

  • go build ./...
  • go vet ./...
  • go test ./... (124 passed)
  • New tests: TestNetSink_BlockedStats, TestNetSink_BlockedStats_NilMap

🤖 Generated with Claude Code

th0114nd and others added 2 commits July 10, 2026 18:04
net_sink now accepts an optional map[string]struct{} of blocked stat
names via WithBlockedStats. FlushCounter/FlushGauge/FlushTimer do an
O(1) lookup against it and silently drop matching stats before they're
buffered or written to the wire.

The lookup is against the name gostats itself resolves (dot-joined
scope path plus serialized tags) — it does not see any environment
prefix or aggregation-type suffix (:count, :rate, :p99, ...) that a
downstream metrics pipeline appends after ingestion. Callers populating
the map from an externally sourced blocklist (e.g. a Grafana Cloud
metric-blocklist export) need to strip those before use.

Motivated by matchingconfigset wanting to drop known-noisy matchingv2
metrics before they leave the process, rather than relying entirely on
downstream blocklist rules.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
internal/tags always appends serialized tags after a stat's name via
".__key=value" (sorted by key, sourced from TagSet.Serialize /
SerializeTags) — never in the middle of it. So matching on the exact
full resolved name meant one blocklist entry only covered one specific
tag combination, which isn't viable for anything with per-instance or
otherwise variable tags. Truncate at the first ".__" before the map
lookup so a single entry matches a stat regardless of its tag values.

Also adds TestNetSink_BlockedStats_IgnoresTags and
BenchmarkFlushCounter_BlockedStats, which sweeps blocklist size from 0
to 100k entries for both the allowed and blocked paths. Confirms the
lookup is genuinely O(1) (~57ns/op flat across all sizes) and zero
allocations.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@th0114nd th0114nd closed this Jul 11, 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.

1 participant