diff --git a/config.go b/config.go index 4ee979a..1eda12f 100644 --- a/config.go +++ b/config.go @@ -5,6 +5,9 @@ import ( "os" "github.com/google/uuid" + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/sdk/resource" + semconv "go.opentelemetry.io/otel/semconv/v1.26.0" "go.uber.org/zap" ) @@ -62,18 +65,12 @@ func (c *Config) InitDefault(log *zap.Logger) { c.Exporter = otlp } - if c.ServiceName == "" { - c.ServiceName = "RoadRunner" - } else { + if c.ServiceName != "" { log.Warn("service_name is deprecated, use resource.service_name instead") } - - if c.ServiceVersion == "" { - c.ServiceVersion = "1.0.0" - } else { + if c.ServiceVersion != "" { log.Warn("service_version is deprecated, use resource.service_version instead") } - if c.Exporter == jaegerExp { log.Warn("jaeger exporter is deprecated, use OTLP instead: https://github.com/roadrunner-server/roadrunner/issues/1699") } @@ -81,52 +78,59 @@ func (c *Config) InitDefault(log *zap.Logger) { switch c.Client { case grpcClient: case httpClient: + case "": + c.Client = httpClient + setClientFromEnv(&c.Client, log) default: + log.Warn("unknown exporter client", zap.String("client", string(c.Client))) c.Client = httpClient - // As per https://opentelemetry.io/docs/specs/otel/protocol/exporter/#specify-protocol - exporterEnv := "OTEL_EXPORTER_OTLP_TRACES_PROTOCOL" - exporterVal := os.Getenv(exporterEnv) - if exporterVal == "" { - exporterEnv = "OTEL_EXPORTER_OTLP_PROTOCOL" - exporterVal = os.Getenv(exporterEnv) - } - switch exporterVal { - case "": - // use default - case "grpc": - c.Client = grpcClient - case "http/protobuf": - c.Client = httpClient - default: - log.Warn("unknown exporter protocol", zap.String("env.name", exporterEnv), zap.String("env.value", exporterVal)) - } } if c.Resource == nil { - c.Resource = &Resource{ - // https://github.com/open-telemetry/opentelemetry-specification/blob/v1.25.0/specification/resource/semantic_conventions/README.md#service-experimental - ServiceNameKey: c.ServiceName, - ServiceVersionKey: c.ServiceVersion, - ServiceInstanceIDKey: uuid.NewString(), - ServiceNamespaceKey: fmt.Sprintf("RoadRunner-%s", uuid.NewString()), - } - - return + c.Resource = &Resource{} } - if c.Resource.ServiceNameKey == "" { - c.Resource.ServiceNameKey = c.ServiceName - } + envAttrs := resource.Environment() + fillValue(&c.Resource.ServiceNameKey, c.ServiceName, envAttrs, semconv.ServiceNameKey, "RoadRunner") + fillValue(&c.Resource.ServiceVersionKey, c.ServiceVersion, envAttrs, semconv.ServiceVersionKey, "1.0.0") + fillValue(&c.Resource.ServiceInstanceIDKey, "", envAttrs, semconv.ServiceInstanceIDKey, uuid.NewString()) + fillValue(&c.Resource.ServiceNamespaceKey, "", envAttrs, semconv.ServiceNamespaceKey, fmt.Sprintf("RoadRunner-%s", uuid.NewString())) +} - if c.Resource.ServiceVersionKey == "" { - c.Resource.ServiceVersionKey = c.ServiceVersion +func setClientFromEnv(client *Client, log *zap.Logger) { + // https://opentelemetry.io/docs/specs/otel/protocol/exporter/#specify-protocol + exporterEnv := "OTEL_EXPORTER_OTLP_TRACES_PROTOCOL" + exporterVal := os.Getenv(exporterEnv) + if exporterVal == "" { + exporterEnv = "OTEL_EXPORTER_OTLP_PROTOCOL" + exporterVal = os.Getenv(exporterEnv) } - - if c.Resource.ServiceInstanceIDKey == "" { - c.Resource.ServiceInstanceIDKey = uuid.NewString() + switch exporterVal { + case "": + case "grpc": + *client = grpcClient + case "http/protobuf": + *client = httpClient + case "http/json": + log.Warn("unsupported exporter protocol", zap.String("env.name", exporterEnv), zap.String("env.value", exporterVal)) + default: + log.Warn("unknown exporter protocol", zap.String("env.name", exporterEnv), zap.String("env.value", exporterVal)) } +} - if c.Resource.ServiceNamespaceKey == "" { - c.Resource.ServiceNamespaceKey = fmt.Sprintf("RoadRunner-%s", uuid.NewString()) +func fillValue(target *string, fromConf string, fromResource *resource.Resource, fromResourceKey attribute.Key, fromDefault string) { + if *target != "" { + return + } + if fromConf != "" { + *target = fromConf + return + } + if resValue, haveValue := fromResource.Set().Value(fromResourceKey); haveValue { + if resStr := resValue.AsString(); resStr != "" { + *target = resStr + return + } } + *target = fromDefault } diff --git a/plugin.go b/plugin.go index e29223b..6530a60 100644 --- a/plugin.go +++ b/plugin.go @@ -18,7 +18,7 @@ import ( "go.opentelemetry.io/otel/propagation" "go.opentelemetry.io/otel/sdk/resource" sdktrace "go.opentelemetry.io/otel/sdk/trace" - semconv "go.opentelemetry.io/otel/semconv/v1.10.0" + semconv "go.opentelemetry.io/otel/semconv/v1.26.0" "go.temporal.io/sdk/interceptor" "go.uber.org/zap" @@ -112,9 +112,13 @@ func (p *Plugin) Init(cfg Configurer, log Logger) error { //nolint:gocyclo return errors.Errorf("unknown exporter: %s", p.cfg.Exporter) } + resource, err := newResource(p.cfg.Resource, cfg.RRVersion()) + if err != nil { + return errors.E(op, err) + } p.tracer = sdktrace.NewTracerProvider( sdktrace.WithBatcher(exporter), - sdktrace.WithResource(newResource(p.cfg.Resource, cfg.RRVersion())), + sdktrace.WithResource(resource), ) p.propagators = propagation.NewCompositeTextMapPropagator(propagation.TraceContext{}, propagation.Baggage{}, jprop.Jaeger{}) @@ -161,20 +165,23 @@ func (p *Plugin) Name() string { return pluginName } -func newResource(res *Resource, rrVersion string) *resource.Resource { - return resource.NewWithAttributes( - semconv.SchemaURL, - semconv.OSNameKey.String(runtime.GOOS), - semconv.ServiceNameKey.String(res.ServiceNameKey), - semconv.ServiceVersionKey.String(res.ServiceVersionKey), - semconv.ServiceInstanceIDKey.String(res.ServiceInstanceIDKey), - semconv.ServiceNamespaceKey.String(res.ServiceNamespaceKey), - semconv.WebEngineNameKey.String("RoadRunner"), - semconv.WebEngineVersionKey.String(rrVersion), - semconv.HostArchKey.String(runtime.GOARCH), - semconv.TelemetrySDKNameKey.String("opentelemetry"), - semconv.TelemetrySDKLanguageKey.String("go"), - semconv.TelemetrySDKVersionKey.String(otel.Version()), +func newResource(res *Resource, rrVersion string) (*resource.Resource, error) { + return resource.New(context.Background(), + resource.WithSchemaURL(semconv.SchemaURL), + resource.WithAttributes( + semconv.OSNameKey.String(runtime.GOOS), + semconv.ServiceNameKey.String(res.ServiceNameKey), + semconv.ServiceVersionKey.String(res.ServiceVersionKey), + semconv.ServiceInstanceIDKey.String(res.ServiceInstanceIDKey), + semconv.ServiceNamespaceKey.String(res.ServiceNamespaceKey), + semconv.WebEngineNameKey.String("RoadRunner"), + semconv.WebEngineVersionKey.String(rrVersion), + semconv.HostArchKey.String(runtime.GOARCH), + semconv.TelemetrySDKNameKey.String("opentelemetry"), + semconv.TelemetrySDKLanguageKey.String("go"), + semconv.TelemetrySDKVersionKey.String(otel.Version()), + ), + resource.WithFromEnv(), ) }