forgejo/modules/opentelemetry/resource.go

91 lines
2.3 KiB
Go
Raw Normal View History

// Copyright 2024 TheFox0x7. All rights reserved.
// SPDX-License-Identifier: EUPL-1.2
package opentelemetry
import (
"context"
"net/url"
"strings"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/sdk/resource"
semconv "go.opentelemetry.io/otel/semconv/v1.25.0"
)
const (
decoderTelemetrySdk = "sdk"
decoderProcess = "process"
decoderOS = "os"
decoderHost = "host"
)
func newResource(ctx context.Context) (*resource.Resource, error) {
opts := []resource.Option{
resource.WithAttributes(parseSettingAttributes(setting.OpenTelemetry.ResourceAttributes)...),
}
opts = append(opts, parseDecoderOpts()...)
opts = append(opts, resource.WithAttributes(
semconv.ServiceName(setting.OpenTelemetry.ServiceName),
semconv.ServiceVersion(setting.ForgejoVersion),
))
return resource.New(ctx, opts...)
}
func parseDecoderOpts() []resource.Option {
var opts []resource.Option
for _, v := range strings.Split(setting.OpenTelemetry.ResourceDetectors, ",") {
switch v {
case decoderTelemetrySdk:
opts = append(opts, resource.WithTelemetrySDK())
case decoderProcess:
opts = append(opts, resource.WithProcess())
case decoderOS:
opts = append(opts, resource.WithOS())
case decoderHost:
opts = append(opts, resource.WithHost())
case "": // Don't warn on empty string
default:
log.Warn("Ignoring unknown resource decoder option: %s", v)
}
}
return opts
}
func parseSettingAttributes(s string) []attribute.KeyValue {
var attrs []attribute.KeyValue
rawAttrs := strings.TrimSpace(s)
if rawAttrs == "" {
return attrs
}
pairs := strings.Split(rawAttrs, ",")
var invalid []string
for _, p := range pairs {
k, v, found := strings.Cut(p, "=")
if !found {
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
log.Warn("Otel resource attribute decoding error, retaining unescaped value. key=%s, val=%s", key, val)
}
attrs = append(attrs, attribute.String(key, val))
}
if len(invalid) > 0 {
log.Warn("Partial resource, missing values: %v", invalid)
}
return attrs
}