Skip to content

Instantly share code, notes, and snippets.

@ngauthier
Last active November 1, 2018 15:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ngauthier/75c99fbd011d9e86eaa030321e65440e to your computer and use it in GitHub Desktop.
Save ngauthier/75c99fbd011d9e86eaa030321e65440e to your computer and use it in GitHub Desktop.

Honeycomb Beeline Golang - Field Sampler

Usage:

// Configure it with a default sample rate
hook, err := fieldsampler.NewFieldSamplerHook(1)
if err != nil {
	log.Fatal(err)
}
beeline.Init(beeline.Config{
	WriteKey:    honeycombWriteKey,
	Dataset:     "nomics",
	ServiceName: honeycombServiceName,
	SamplerHook: hook,
	STDOUT:      honeycombWriteKey == "",
})

// When creating a span, add a trace field to optionally override the sample rate on a per-trace basis
ctx, span := beeline.StartSpan(ctx, "HighVolumeSpan")
span.AddTraceField("CustomSampleRate", 5)		
package fieldsampler
import (
"github.com/honeycombio/beeline-go/sample"
)
const (
// CustomSampleRateFieldName is the field to use to override the default Sample Rate
CustomSampleRateFieldName = "CustomSampleRate"
// DeterministicSampleFieldName is the field used as a determinant for the sampler
DeterministicSampleFieldName = "trace.trace_id"
)
// NewFieldSamplerHook creates a new SamplerHook that respects CustomSampleRateFieldName if present,
// otherwise it uses the given defaultSampleRate. Then it delegates to the beeline deterministic sampler.
func NewFieldSamplerHook(defaultSampleRate uint) (func(map[string]interface{}) (bool, int), error) {
defaultSampler, err := sample.NewDeterministicSampler(defaultSampleRate)
if err != nil {
return nil, err
}
return func(fields map[string]interface{}) (bool, int) {
sampler := defaultSampler
rate := int(defaultSampleRate)
if custom, ok := fields[CustomSampleRateFieldName].(int); ok {
rate = custom
newSampler, err := sample.NewDeterministicSampler(uint(rate))
if err == nil && rate > 0 {
sampler = newSampler
}
}
determinant := ""
if traceID, ok := fields[DeterministicSampleFieldName].(string); ok {
determinant = traceID
}
shouldSample := sampler.Sample(determinant)
return shouldSample, rate
}, nil
}
package fieldsampler
import (
"context"
"testing"
beeline "github.com/honeycombio/beeline-go"
"github.com/honeycombio/beeline-go/trace"
libhoney "github.com/honeycombio/libhoney-go"
)
func TestOverrideSampleRate(t *testing.T) {
hook, err := NewFieldSamplerHook(5)
if err != nil {
t.Fatal(err)
}
mo := &libhoney.MockOutput{}
libhoney.Init(
libhoney.Config{
APIHost: "placeholder",
WriteKey: "placeholder",
Dataset: "placeholder",
Output: mo,
},
)
trace.GlobalConfig.SamplerHook = hook
_, span := beeline.StartSpan(context.Background(), "start")
span.AddTraceField("CustomSampleRate", 1)
span.Send()
events := mo.Events()
if len(events) != 1 {
t.Fatal(len(events))
}
ev := events[0]
if ev.SampleRate != 1 {
t.Fatal("Expected SampleRate to be 1:", ev.SampleRate)
}
if custom, ok := ev.Fields()["CustomSampleRate"]; !ok {
t.Fatal("Expected CustomSampleRate to be set", ev.Fields())
} else if custom != 1 {
t.Fatal("Expected CustomSampleRate to be 1:", custom)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment