Skip to content

Commit

Permalink
enhance: refactored attribute mapping
Browse files Browse the repository at this point in the history
  • Loading branch information
plyr4 committed Sep 11, 2024
1 parent 00e22c4 commit 7e5ac7e
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 75 deletions.
7 changes: 2 additions & 5 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,9 @@ services:
VELA_ENABLE_SECURE_COOKIE: 'false'
VELA_REPO_ALLOWLIST: '*'
VELA_SCHEDULE_ALLOWLIST: '*'
VELA_OTEL_EXPORTER_OTLP_ENDPOINT: http://jaeger:4318
VELA_OTEL_TRACING_ENDPOINT: jaeger:4318
VELA_OTEL_TRACING_ENABLE: true
VELA_OTEL_TRACING_SERVICE_NAME: vela-server
VELA_OTEL_TRACING_RESOURCE_ATTRIBUTES: "process.runtime.name=go"
VELA_OTEL_TRACING_RESOURCE_ENV_ATTRIBUTES: "deployment.environment=CLOUD_ENVIRONMENT"
OTEL_EXPORTER_OTLP_ENDPOINT: http://jaeger:4318
VELA_OTEL_TRACING_ENDPOINT: jaeger:4318
VELA_OTEL_TRACING_SAMPLER_RATELIMIT_PER_SECOND: 0.2
env_file:
- .env
Expand Down
100 changes: 55 additions & 45 deletions tracing/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
package tracing

import (
"fmt"
"maps"
"os"
"strings"

Expand All @@ -19,70 +19,58 @@ type Client struct {

// Config represents the configurations for otel tracing.
type Config struct {
EnableTracing bool
ServiceName string
ExporterURL string
CertPath string
TLSMinVersion string
ResourceAttributes map[string]string
EnableTracing bool
ServiceName string
ExporterURL string
CertPath string
TLSMinVersion string
ResourceAttributes map[string]string
TraceStateAttributes map[string]string
SpanAttributes map[string]string
Sampler
}

// Sampler represents the configurations for the otel sampler.
// Used to determine if a trace should be sampled.
type Sampler struct {
TraceStateAttributes map[string]string
SpanAttributes map[string]string
Ratio float64
PerSecond float64
PerSecond float64
}

// FromCLIContext takes cli context and returns a tracing config to supply to traceable services.
func FromCLIContext(c *cli.Context) (*Client, error) {
cfg := Config{
EnableTracing: c.Bool("tracing.enable"),
ServiceName: c.String("tracing.service.name"),
ExporterURL: c.String("tracing.exporter.endpoint"),
CertPath: c.String("tracing.exporter.cert_path"),
TLSMinVersion: c.String("tracing.tls-min-version"),
ResourceAttributes: map[string]string{},
EnableTracing: c.Bool("tracing.enable"),
ServiceName: c.String("tracing.service.name"),
ExporterURL: c.String("tracing.exporter.endpoint"),
CertPath: c.String("tracing.exporter.cert_path"),
TLSMinVersion: c.String("tracing.tls-min-version"),
ResourceAttributes: map[string]string{},
TraceStateAttributes: map[string]string{},
SpanAttributes: map[string]string{},
Sampler: Sampler{
TraceStateAttributes: map[string]string{
"sampler": c.String("tracing.sampler.tracestate"),
},
SpanAttributes: map[string]string{
"w3c.tracestate": fmt.Sprintf("sampler=%s", c.String("tracing.sampler.tracestate")),
"sampler.parent": c.String("tracing.sampler.parent"),
"sampler.type": c.String("tracing.sampler.type"),
},
Ratio: c.Float64("tracing.sampler.ratio"),
PerSecond: c.Float64("tracing.sampler.persecond"),
},
}

// add resource attributes
for _, attr := range c.StringSlice("tracing.resource.attributes") {
kv := strings.Split(attr, "=")
if len(kv) != 2 {
continue
}

cfg.ResourceAttributes[kv[0]] = kv[1]
// identity func used to map a string back to itself
identityFn := func(s string) string {
return s
}

// add resource attributes from environment
for _, attr := range c.StringSlice("tracing.resource.env_attributes") {
kv := strings.Split(attr, "=")
if len(kv) != 2 {
continue
}
// static span attributes
cfg.SpanAttributes = keyValueSliceToMap(c.StringSlice("tracing.span.attributes"), identityFn)

v, found := os.LookupEnv(kv[1])
if found {
cfg.ResourceAttributes[kv[0]] = v
}
}
// static tracestate attributes
cfg.TraceStateAttributes = keyValueSliceToMap(c.StringSlice("tracing.tracestate.attributes"), identityFn)

// static resource attributes
cfg.ResourceAttributes = keyValueSliceToMap(c.StringSlice("tracing.resource.attributes"), identityFn)

// merge static resource attributes with those fetched from the environment
m := keyValueSliceToMap(c.StringSlice("tracing.resource.env_attributes"), os.Getenv)
maps.Copy(cfg.ResourceAttributes, m)

// initialize the tracer provider and assign it to the client
tracer, err := initTracer(c.Context, cfg)
if err != nil {
return nil, err
Expand All @@ -93,3 +81,25 @@ func FromCLIContext(c *cli.Context) (*Client, error) {
TracerProvider: tracer,
}, nil
}

// keyValueSliceToMap converts a slice of key=value strings to a map of key to value using the supplied map function.
func keyValueSliceToMap(kv []string, fn func(string) string) map[string]string {
m := map[string]string{}
for _, attr := range kv {
parts := strings.SplitN(attr, "=", 2)

if len(parts) != 2 || len(parts[1]) == 0 {
continue
}

v := fn(parts[1])

if len(v) == 0 {
continue
}

m[parts[0]] = v
}

return m
}
41 changes: 16 additions & 25 deletions tracing/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ var Flags = []cli.Flag{
Usage: "set otel tracing service name",
Value: "vela-server",
},
&cli.StringFlag{
EnvVars: []string{"VELA_OTEL_TRACING_ENDPOINT"},
Name: "tracing.exporter.endpoint",
Usage: "set the otel exporter endpoint",
},
&cli.StringFlag{
EnvVars: []string{"VELA_OTEL_TRACING_EXPORTER_SSL_CERT_PATH"},
Name: "tracing.exporter.cert_path",
Expand All @@ -35,47 +40,33 @@ var Flags = []cli.Flag{
Usage: "optional TLS minimum version requirement to set when communicating with the otel exporter",
Value: "1.2",
},
&cli.StringFlag{
EnvVars: []string{"VELA_OTEL_TRACING_ENDPOINT"},
Name: "tracing.exporter.endpoint",
Usage: "set the otel exporter endpoint",
Value: "127.0.0.1:4318",
},

// Resource Flags

&cli.StringSliceFlag{
EnvVars: []string{"VELA_OTEL_TRACING_RESOURCE_ATTRIBUTES"},
Name: "tracing.resource.attributes",
Usage: "set otel resource attributes as a list of key=value pairs. each one will be attached to each span as an attribute",
Usage: "set otel resource attributes as a list of key=value pairs. each one will be attached to each span as a resource attribute",
Value: cli.NewStringSlice("process.runtime.name=go"),
},
&cli.StringSliceFlag{
EnvVars: []string{"VELA_OTEL_TRACING_RESOURCE_ENV_ATTRIBUTES"},
Name: "tracing.resource.env_attributes",
Usage: "set otel resource attributes as a list of key=env_variable_key pairs. each one will be attached to each span as an attribute where the value is retrieved from the environment using the pair value",
},
&cli.StringSliceFlag{
EnvVars: []string{"VELA_OTEL_TRACING_SPAN_ATTRIBUTES"},
Name: "tracing.span.attributes",
Usage: "set otel span attributes as a list of key=value pairs. each one will be attached to each span as a sampler attribute",
},
&cli.StringSliceFlag{
EnvVars: []string{"VELA_OTEL_TRACING_TRACESTATE_ATTRIBUTES"},
Name: "tracing.tracestate.attributes",
Usage: "set otel tracestate attributes as a list of key=value pairs. each one will be inserted into the tracestate for each sampled span",
},

// Sampler Flags

&cli.StringFlag{
EnvVars: []string{"VELA_OTEL_TRACING_SAMPLER_TRACESTATE"},
Name: "tracing.sampler.tracestate",
Usage: "set otel sampler trace state attached to each span as an attribute.",
Value: "sampler.tracestate",
},
&cli.StringFlag{
EnvVars: []string{"VELA_OTEL_TRACING_SAMPLER_PARENT"},
Name: "tracing.sampler.parent",
Usage: "set otel sampler parent attribute attached to each span.",
Value: "sampler.parent",
},
&cli.StringFlag{
EnvVars: []string{"VELA_OTEL_TRACING_SAMPLER_TYPE"},
Name: "tracing.sampler.type",
Usage: "set otel sampler type attribute attached to each span.",
Value: "sampler.type",
},
&cli.Float64Flag{
EnvVars: []string{"VELA_OTEL_TRACING_SAMPLER_RATELIMIT_PER_SECOND"},
Name: "tracing.sampler.persecond",
Expand Down

0 comments on commit 7e5ac7e

Please sign in to comment.