Skip to content

Commit

Permalink
Detect resources from environment variables when not set in config
Browse files Browse the repository at this point in the history
  • Loading branch information
devnev committed Aug 19, 2024
1 parent a582e8e commit 83dbe59
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 60 deletions.
92 changes: 48 additions & 44 deletions config.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
)

Expand Down Expand Up @@ -62,71 +65,72 @@ 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")
}

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
}
39 changes: 23 additions & 16 deletions plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand Down Expand Up @@ -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{})
Expand Down Expand Up @@ -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(),
)
}

Expand Down

0 comments on commit 83dbe59

Please sign in to comment.