blob: 9b672a1d70d4cdf38a53e400aab7310f161f0746 [file] [log] [blame]
Abhay Kumara2ae5992025-11-10 14:02:24 +00001// Copyright The OpenTelemetry Authors
2// SPDX-License-Identifier: Apache-2.0
3
4package trace // import "go.opentelemetry.io/otel/sdk/trace"
5
6import (
7 "errors"
8 "os"
9 "strconv"
10 "strings"
11)
12
13const (
14 tracesSamplerKey = "OTEL_TRACES_SAMPLER"
15 tracesSamplerArgKey = "OTEL_TRACES_SAMPLER_ARG"
16
17 samplerAlwaysOn = "always_on"
18 samplerAlwaysOff = "always_off"
19 samplerTraceIDRatio = "traceidratio"
20 samplerParentBasedAlwaysOn = "parentbased_always_on"
21 samplerParsedBasedAlwaysOff = "parentbased_always_off"
22 samplerParentBasedTraceIDRatio = "parentbased_traceidratio"
23)
24
25type errUnsupportedSampler string
26
27func (e errUnsupportedSampler) Error() string {
28 return "unsupported sampler: " + string(e)
29}
30
31var (
32 errNegativeTraceIDRatio = errors.New("invalid trace ID ratio: less than 0.0")
33 errGreaterThanOneTraceIDRatio = errors.New("invalid trace ID ratio: greater than 1.0")
34)
35
36type samplerArgParseError struct {
37 parseErr error
38}
39
40func (e samplerArgParseError) Error() string {
41 return "parsing sampler argument: " + e.parseErr.Error()
42}
43
44func (e samplerArgParseError) Unwrap() error {
45 return e.parseErr
46}
47
48func samplerFromEnv() (Sampler, error) {
49 sampler, ok := os.LookupEnv(tracesSamplerKey)
50 if !ok {
51 return nil, nil
52 }
53
54 sampler = strings.ToLower(strings.TrimSpace(sampler))
55 samplerArg, hasSamplerArg := os.LookupEnv(tracesSamplerArgKey)
56 samplerArg = strings.TrimSpace(samplerArg)
57
58 switch sampler {
59 case samplerAlwaysOn:
60 return AlwaysSample(), nil
61 case samplerAlwaysOff:
62 return NeverSample(), nil
63 case samplerTraceIDRatio:
64 if !hasSamplerArg {
65 return TraceIDRatioBased(1.0), nil
66 }
67 return parseTraceIDRatio(samplerArg)
68 case samplerParentBasedAlwaysOn:
69 return ParentBased(AlwaysSample()), nil
70 case samplerParsedBasedAlwaysOff:
71 return ParentBased(NeverSample()), nil
72 case samplerParentBasedTraceIDRatio:
73 if !hasSamplerArg {
74 return ParentBased(TraceIDRatioBased(1.0)), nil
75 }
76 ratio, err := parseTraceIDRatio(samplerArg)
77 return ParentBased(ratio), err
78 default:
79 return nil, errUnsupportedSampler(sampler)
80 }
81}
82
83func parseTraceIDRatio(arg string) (Sampler, error) {
84 v, err := strconv.ParseFloat(arg, 64)
85 if err != nil {
86 return TraceIDRatioBased(1.0), samplerArgParseError{err}
87 }
88 if v < 0.0 {
89 return TraceIDRatioBased(1.0), errNegativeTraceIDRatio
90 }
91 if v > 1.0 {
92 return TraceIDRatioBased(1.0), errGreaterThanOneTraceIDRatio
93 }
94
95 return TraceIDRatioBased(v), nil
96}