Extensions for OpenTelemetry Go SDK — reusable filters and samplers for fine-grained telemetry control.
- Filter registry — global, thread-safe registry of attribute-based filters (
signal.Filterinterface) - FilterBasedSampler — trace sampler that drops spans based on registered filters
- CompositeSampler — combines multiple
sdktrace.Samplerinstances with a restrict-only strategy (any sampler can restrict the decision, but never upgrade it)
go get github.com/thumbrise/otelextRequires Go 1.25+ and OpenTelemetry SDK v1.42+.
package main
import (
"github.com/thumbrise/otelext/signal"
"github.com/thumbrise/otelext/signal/trace"
)
func main() {
// Register your custom filter (must implement signal.Filter)
signal.RegisterFilter(myFilter)
// Create a sampler that drops spans matched by registered filters
sampler := trace.NewFilterBasedSampler()
// Use sampler in your TracerProvider setup
// sdktrace.NewTracerProvider(sdktrace.WithSampler(sampler))
}sampler := trace.NewCompositeSampler(
trace.NewFilterBasedSampler(),
sdktrace.TraceIDRatioBased(0.5),
)
// The strictest decision wins: if any sampler returns Drop, the span is dropped.type Filter interface {
ShouldDrop(ctx context.Context, attrs attribute.Set) bool
Key(ctx context.Context) string
Description(ctx context.Context) string
}| Function | Description |
|---|---|
RegisterFilter(f) |
Add a filter to the global registry |
RegisteredFilters() |
Get a copy of all registered filters |
ClearFilters() |
Remove all registered filters |
| Type | Description |
|---|---|
FilterBasedSampler |
Sampler that drops spans when any registered filter matches |
CompositeSampler |
Combines samplers; strictest decision wins (restrict-only strategy) |
- Add package-level GoDoc comments (
signal/doc.go,signal/trace/doc.go) - Add
CONTRIBUTING.md(contribution guide, commit style, PR process) - Add
CHANGELOG.mdor set up auto-generation via semantic-release
- Add built-in
signal.Filterimplementations (by span name, by attributes, regex-based, etc.) - Support filters for metrics and logs (currently traces only)
- Add
Optionpattern forFilterBasedSampler(fallback decision, custom logger) - Add
Optionpattern forCompositeSampler(strategy: restrict-only / permissive / majority) - Consider
UnregisterFilter(key)for dynamic filter management - Rework registry. Replace global package level registry with a struct for multi callers possibility
- Add benchmarks for
CompositeSamplerwith a large number of samplers - Add concurrency tests (parallel filter registration/read)
- Add integration tests with a real
TracerProvider
- Add CI step for test coverage reporting (codecov / coveralls)
- Add coverage badge to README
- Set up automatic tag releases
- Add
CODEOWNERSfile - Add
SECURITY.md(responsible disclosure policy) - Publish on pkg.go.dev with examples (Example tests)
- Add
.goreleaser.ymlif binary releases are planned
- Go 1.25+
- Task (task runner)
- golangci-lint v2.4+
task lint # Run golangci-lint + license header checks
task test # Run tests + benchmarks
task license # Auto-fix missing license headersApache License 2.0 — Copyright 2026 thumbrise