Skip to content

Commit 5baebce

Browse files
authored
Merge pull request #796 from XSAM/feature/jaeger-exporter-env
Add environment variables for Jaeger exporter
2 parents d9eb17f + 0842556 commit 5baebce

File tree

7 files changed

+1081
-5
lines changed

7 files changed

+1081
-5
lines changed

exporters/trace/jaeger/env.go

+163
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
// Copyright The OpenTelemetry Authors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package jaeger
16+
17+
import (
18+
"errors"
19+
"os"
20+
"strconv"
21+
"strings"
22+
23+
"go.opentelemetry.io/otel/api/global"
24+
"go.opentelemetry.io/otel/api/kv"
25+
"go.opentelemetry.io/otel/api/kv/value"
26+
)
27+
28+
// Environment variable names
29+
const (
30+
// The service name.
31+
envServiceName = "JAEGER_SERVICE_NAME"
32+
// Whether the exporter is disabled or not. (default false).
33+
envDisabled = "JAEGER_DISABLED"
34+
// A comma separated list of name=value tracer-level tags, which get added to all reported spans.
35+
// The value can also refer to an environment variable using the format ${envVarName:defaultValue}.
36+
envTags = "JAEGER_TAGS"
37+
// The HTTP endpoint for sending spans directly to a collector,
38+
// i.e. http://jaeger-collector:14268/api/traces.
39+
envEndpoint = "JAEGER_ENDPOINT"
40+
// Username to send as part of "Basic" authentication to the collector endpoint.
41+
envUser = "JAEGER_USER"
42+
// Password to send as part of "Basic" authentication to the collector endpoint.
43+
envPassword = "JAEGER_PASSWORD"
44+
)
45+
46+
// CollectorEndpointFromEnv return environment variable value of JAEGER_ENDPOINT
47+
func CollectorEndpointFromEnv() string {
48+
return os.Getenv(envEndpoint)
49+
}
50+
51+
// WithCollectorEndpointOptionFromEnv uses environment variables to set the username and password
52+
// if basic auth is required.
53+
func WithCollectorEndpointOptionFromEnv() CollectorEndpointOption {
54+
return func(o *CollectorEndpointOptions) {
55+
if e := os.Getenv(envUser); e != "" {
56+
o.username = e
57+
}
58+
if e := os.Getenv(envPassword); e != "" {
59+
o.password = os.Getenv(envPassword)
60+
}
61+
}
62+
}
63+
64+
// WithDisabledFromEnv uses environment variables and overrides disabled field.
65+
func WithDisabledFromEnv() Option {
66+
return func(o *options) {
67+
if e := os.Getenv(envDisabled); e != "" {
68+
if v, err := strconv.ParseBool(e); err == nil {
69+
o.Disabled = v
70+
}
71+
}
72+
}
73+
}
74+
75+
// ProcessFromEnv parse environment variables into jaeger exporter's Process.
76+
// It will return a nil tag slice if the environment variable JAEGER_TAGS is malformed.
77+
func ProcessFromEnv() Process {
78+
var p Process
79+
if e := os.Getenv(envServiceName); e != "" {
80+
p.ServiceName = e
81+
}
82+
if e := os.Getenv(envTags); e != "" {
83+
tags, err := parseTags(e)
84+
if err != nil {
85+
global.Handle(err)
86+
} else {
87+
p.Tags = tags
88+
}
89+
}
90+
91+
return p
92+
}
93+
94+
// WithProcessFromEnv uses environment variables and overrides jaeger exporter's Process.
95+
func WithProcessFromEnv() Option {
96+
return func(o *options) {
97+
p := ProcessFromEnv()
98+
if p.ServiceName != "" {
99+
o.Process.ServiceName = p.ServiceName
100+
}
101+
if len(p.Tags) != 0 {
102+
o.Process.Tags = p.Tags
103+
}
104+
}
105+
}
106+
107+
var errTagValueNotFound = errors.New("missing tag value")
108+
var errTagEnvironmentDefaultValueNotFound = errors.New("missing default value for tag environment value")
109+
110+
// parseTags parses the given string into a collection of Tags.
111+
// Spec for this value:
112+
// - comma separated list of key=value
113+
// - value can be specified using the notation ${envVar:defaultValue}, where `envVar`
114+
// is an environment variable and `defaultValue` is the value to use in case the env var is not set
115+
func parseTags(sTags string) ([]kv.KeyValue, error) {
116+
pairs := strings.Split(sTags, ",")
117+
tags := make([]kv.KeyValue, len(pairs))
118+
for i, p := range pairs {
119+
field := strings.SplitN(p, "=", 2)
120+
if len(field) != 2 {
121+
return nil, errTagValueNotFound
122+
}
123+
k, v := strings.TrimSpace(field[0]), strings.TrimSpace(field[1])
124+
125+
if strings.HasPrefix(v, "${") && strings.HasSuffix(v, "}") {
126+
ed := strings.SplitN(v[2:len(v)-1], ":", 2)
127+
if len(ed) != 2 {
128+
return nil, errTagEnvironmentDefaultValueNotFound
129+
}
130+
e, d := ed[0], ed[1]
131+
v = os.Getenv(e)
132+
if v == "" && d != "" {
133+
v = d
134+
}
135+
}
136+
137+
tags[i] = parseKeyValue(k, v)
138+
}
139+
140+
return tags, nil
141+
}
142+
143+
func parseKeyValue(k, v string) kv.KeyValue {
144+
return kv.KeyValue{
145+
Key: kv.Key(k),
146+
Value: parseValue(v),
147+
}
148+
}
149+
150+
func parseValue(str string) value.Value {
151+
if v, err := strconv.ParseInt(str, 10, 64); err == nil {
152+
return value.Int64(v)
153+
}
154+
if v, err := strconv.ParseFloat(str, 64); err == nil {
155+
return value.Float64(v)
156+
}
157+
if v, err := strconv.ParseBool(str); err == nil {
158+
return value.Bool(v)
159+
}
160+
161+
// Fallback
162+
return value.String(str)
163+
}

0 commit comments

Comments
 (0)