mirror of
https://github.com/imgproxy/imgproxy.git
synced 2025-01-23 11:14:48 +02:00
119 lines
2.6 KiB
Go
119 lines
2.6 KiB
Go
package otel
|
|
|
|
import (
|
|
"encoding/binary"
|
|
"errors"
|
|
"fmt"
|
|
"os"
|
|
"strconv"
|
|
"strings"
|
|
|
|
sdktrace "go.opentelemetry.io/otel/sdk/trace"
|
|
"go.opentelemetry.io/otel/trace"
|
|
)
|
|
|
|
const (
|
|
tracesSamplerKey = "OTEL_TRACES_SAMPLER"
|
|
tracesSamplerArgKey = "OTEL_TRACES_SAMPLER_ARG"
|
|
|
|
samplerTraceIDRatio = "traceidratio"
|
|
)
|
|
|
|
var (
|
|
errNegativeTraceIDRatio = errors.New("invalid trace ID ratio: less than 0.0")
|
|
errGreaterThanOneTraceIDRatio = errors.New("invalid trace ID ratio: greater than 1.0")
|
|
)
|
|
|
|
type samplerArgParseError struct {
|
|
parseErr error
|
|
}
|
|
|
|
func (e samplerArgParseError) Error() string {
|
|
return fmt.Sprintf("parsing sampler argument: %s", e.parseErr.Error())
|
|
}
|
|
|
|
func (e samplerArgParseError) Unwrap() error {
|
|
return e.parseErr
|
|
}
|
|
|
|
type traceIDRatioSampler struct {
|
|
traceIDUpperBound uint64
|
|
description string
|
|
}
|
|
|
|
func (ts traceIDRatioSampler) ShouldSample(p sdktrace.SamplingParameters) sdktrace.SamplingResult {
|
|
psc := trace.SpanContextFromContext(p.ParentContext)
|
|
x := binary.BigEndian.Uint64(p.TraceID[len(p.TraceID)-8:]) >> 1
|
|
if x < ts.traceIDUpperBound {
|
|
return sdktrace.SamplingResult{
|
|
Decision: sdktrace.RecordAndSample,
|
|
Tracestate: psc.TraceState(),
|
|
}
|
|
}
|
|
return sdktrace.SamplingResult{
|
|
Decision: sdktrace.Drop,
|
|
Tracestate: psc.TraceState(),
|
|
}
|
|
}
|
|
|
|
func (ts traceIDRatioSampler) Description() string {
|
|
return ts.description
|
|
}
|
|
|
|
func traceIDRatioBased(fraction float64) sdktrace.Sampler {
|
|
if fraction >= 1 {
|
|
return sdktrace.AlwaysSample()
|
|
}
|
|
|
|
if fraction <= 0 {
|
|
fraction = 0
|
|
}
|
|
|
|
return &traceIDRatioSampler{
|
|
traceIDUpperBound: uint64(fraction * (1 << 63)),
|
|
description: fmt.Sprintf("traceIDRatioBased{%g}", fraction),
|
|
}
|
|
}
|
|
|
|
func parseTraceIDRatio(arg string) (sdktrace.Sampler, error) {
|
|
v, err := strconv.ParseFloat(arg, 64)
|
|
if err != nil {
|
|
return traceIDRatioBased(1.0), samplerArgParseError{err}
|
|
}
|
|
if v < 0.0 {
|
|
return traceIDRatioBased(0.0), errNegativeTraceIDRatio
|
|
}
|
|
if v > 1.0 {
|
|
return traceIDRatioBased(1.0), errGreaterThanOneTraceIDRatio
|
|
}
|
|
|
|
return traceIDRatioBased(v), nil
|
|
}
|
|
|
|
func addTraceIDRatioSampler(opts []sdktrace.TracerProviderOption) ([]sdktrace.TracerProviderOption, error) {
|
|
samplerName, ok := os.LookupEnv(tracesSamplerKey)
|
|
if !ok {
|
|
return opts, nil
|
|
}
|
|
|
|
if strings.ToLower(strings.TrimSpace(samplerName)) != samplerTraceIDRatio {
|
|
return opts, nil
|
|
}
|
|
|
|
samplerArg, hasSamplerArg := os.LookupEnv(tracesSamplerArgKey)
|
|
samplerArg = strings.TrimSpace(samplerArg)
|
|
|
|
var (
|
|
sampler sdktrace.Sampler
|
|
err error
|
|
)
|
|
|
|
if !hasSamplerArg {
|
|
sampler = traceIDRatioBased(1.0)
|
|
} else {
|
|
sampler, err = parseTraceIDRatio(samplerArg)
|
|
}
|
|
|
|
return append(opts, sdktrace.WithSampler(sampler)), err
|
|
}
|