1
0
mirror of https://github.com/open-telemetry/opentelemetry-go.git synced 2026-06-03 18:35:08 +02:00
Files
opentelemetry-go/sdk/resource/env.go
T

96 lines
2.5 KiB
Go
Raw Normal View History

2020-07-20 11:43:51 -04:00
// Copyright The OpenTelemetry Authors
2024-02-29 07:05:28 +01:00
// SPDX-License-Identifier: Apache-2.0
2020-07-20 11:43:51 -04:00
package resource // import "go.opentelemetry.io/otel/sdk/resource"
2020-07-20 11:43:51 -04:00
import (
"context"
"fmt"
"net/url"
2020-07-20 11:43:51 -04:00
"os"
"strings"
"go.opentelemetry.io/otel"
2021-02-18 12:59:37 -05:00
"go.opentelemetry.io/otel/attribute"
2024-01-11 12:56:07 +01:00
semconv "go.opentelemetry.io/otel/semconv/v1.24.0"
2020-07-20 11:43:51 -04:00
)
const (
// resourceAttrKey is the environment variable name OpenTelemetry Resource information will be read from.
2023-10-19 08:47:07 +02:00
resourceAttrKey = "OTEL_RESOURCE_ATTRIBUTES" //nolint:gosec // False positive G101: Potential hardcoded credentials
// svcNameKey is the environment variable name that Service Name information will be read from.
svcNameKey = "OTEL_SERVICE_NAME"
)
2020-07-20 11:43:51 -04:00
2023-10-16 10:02:21 -07:00
// errMissingValue is returned when a resource value is missing.
var errMissingValue = fmt.Errorf("%w: missing value", ErrPartialResource)
2020-07-20 11:43:51 -04:00
// fromEnv is a Detector that implements the Detector and collects
// resources from environment. This Detector is included as a
// builtin.
type fromEnv struct{}
2020-07-20 11:43:51 -04:00
2022-04-25 13:22:49 -07:00
// compile time assertion that FromEnv implements Detector interface.
var _ Detector = fromEnv{}
2020-07-20 11:43:51 -04:00
2022-04-25 13:22:49 -07:00
// Detect collects resources from environment.
func (fromEnv) Detect(context.Context) (*Resource, error) {
attrs := strings.TrimSpace(os.Getenv(resourceAttrKey))
svcName := strings.TrimSpace(os.Getenv(svcNameKey))
2020-07-20 11:43:51 -04:00
if attrs == "" && svcName == "" {
return Empty(), nil
2020-07-20 11:43:51 -04:00
}
var res *Resource
if svcName != "" {
2023-02-07 13:42:47 -08:00
res = NewSchemaless(semconv.ServiceName(svcName))
}
r2, err := constructOTResources(attrs)
// Ensure that the resource with the service name from OTEL_SERVICE_NAME
// takes precedence, if it was defined.
2021-06-08 12:46:42 -04:00
res, err2 := Merge(r2, res)
if err == nil {
err = err2
} else if err2 != nil {
err = fmt.Errorf("detecting resources: %s", []string{err.Error(), err2.Error()})
}
return res, err
2020-07-20 11:43:51 -04:00
}
func constructOTResources(s string) (*Resource, error) {
if s == "" {
return Empty(), nil
}
2020-07-20 11:43:51 -04:00
pairs := strings.Split(s, ",")
var attrs []attribute.KeyValue
2020-07-20 11:43:51 -04:00
var invalid []string
for _, p := range pairs {
k, v, found := strings.Cut(p, "=")
if !found {
2020-07-20 11:43:51 -04:00
invalid = append(invalid, p)
continue
}
key := strings.TrimSpace(k)
val, err := url.PathUnescape(strings.TrimSpace(v))
if err != nil {
// Retain original value if decoding fails, otherwise it will be
// an empty string.
val = v
otel.Handle(err)
}
attrs = append(attrs, attribute.String(key, val))
2020-07-20 11:43:51 -04:00
}
var err error
if len(invalid) > 0 {
err = fmt.Errorf("%w: %v", errMissingValue, invalid)
}
2021-06-08 12:46:42 -04:00
return NewSchemaless(attrs...), err
2020-07-20 11:43:51 -04:00
}