Factor the resource detector list into internal/otlpresource so the logger's OTLP provider and the trace provider describe the same process with the same attributes. OTLP log records now carry the full resource (process.pid, service.name, service.version, host.*, os.*, etc.) instead of no resource attributes at all.
53 lines
1.8 KiB
Go
53 lines
1.8 KiB
Go
// Package otlpresource builds the OpenTelemetry resource shared between the
|
|
// tracing and logger packages so spans, metrics, and logs describe the same
|
|
// process with the same attributes (service.name, process.pid, host.*, etc.).
|
|
// Keep the detector list in sync across signals.
|
|
package otlpresource
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"log/slog"
|
|
|
|
"go.opentelemetry.io/otel/attribute"
|
|
"go.opentelemetry.io/otel/sdk/resource"
|
|
semconv "go.opentelemetry.io/otel/semconv/v1.26.0"
|
|
)
|
|
|
|
// Options carries optional attributes that only some callers supply.
|
|
// Zero values are skipped.
|
|
type Options struct {
|
|
ServiceVersion string // added as semconv.ServiceVersionKey
|
|
Environment string // added as attribute "environment"
|
|
}
|
|
|
|
// New builds the shared OTel resource. Non-fatal partial/schema errors are
|
|
// logged via the provided slog logger and a usable resource is still returned.
|
|
func New(ctx context.Context, log *slog.Logger, opts Options) (*resource.Resource, error) {
|
|
detectors := []resource.Option{
|
|
resource.WithFromEnv(), // OTEL_SERVICE_NAME / OTEL_RESOURCE_ATTRIBUTES
|
|
resource.WithTelemetrySDK(), // telemetry.sdk.*
|
|
resource.WithProcess(), // process.pid + process.executable.* + process.runtime.*
|
|
resource.WithOS(),
|
|
resource.WithContainer(),
|
|
resource.WithHost(),
|
|
}
|
|
if opts.ServiceVersion != "" {
|
|
detectors = append(detectors,
|
|
resource.WithAttributes(semconv.ServiceVersionKey.String(opts.ServiceVersion)))
|
|
}
|
|
if opts.Environment != "" {
|
|
detectors = append(detectors,
|
|
resource.WithAttributes(attribute.String("environment", opts.Environment)))
|
|
}
|
|
|
|
res, err := resource.New(ctx, detectors...)
|
|
if errors.Is(err, resource.ErrPartialResource) || errors.Is(err, resource.ErrSchemaURLConflict) {
|
|
if log != nil {
|
|
log.Warn("otel resource setup", "err", err)
|
|
}
|
|
return res, nil
|
|
}
|
|
return res, err
|
|
}
|