Skip to content

Commit

Permalink
Add support for setting span name
Browse files Browse the repository at this point in the history
Signed-off-by: Joseph Woodward <[email protected]>
  • Loading branch information
josephwoodward committed Nov 3, 2022
1 parent eef3104 commit 601824c
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 10 deletions.
41 changes: 32 additions & 9 deletions client/opentelemetry.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package client

import (
"fmt"
"net/http"
"strings"

"github.com/go-openapi/runtime"
"github.com/go-openapi/strfmt"
Expand All @@ -17,11 +19,11 @@ type config struct {
Tracer trace.Tracer
Propagators propagation.TextMapPropagator
SpanStartOptions []trace.SpanStartOption
SpanNameFormatter func(string, *http.Request) string
SpanNameFormatter func(*runtime.ClientOperation) string
TracerProvider trace.TracerProvider
}

type OpenTelemetryOption interface {
type OpenTelemetryOpt interface {
apply(*config)
}

Expand All @@ -33,7 +35,7 @@ func (o optionFunc) apply(c *config) {

// WithTracerProvider specifies a tracer provider to use for creating a tracer.
// If none is specified, the global provider is used.
func WithTracerProvider(provider trace.TracerProvider) OpenTelemetryOption {
func WithTracerProvider(provider trace.TracerProvider) OpenTelemetryOpt {
return optionFunc(func(c *config) {
if provider != nil {
c.TracerProvider = provider
Expand All @@ -43,7 +45,7 @@ func WithTracerProvider(provider trace.TracerProvider) OpenTelemetryOption {

// WithPropagators configures specific propagators. If this
// option isn't specified, then the global TextMapPropagator is used.
func WithPropagators(ps propagation.TextMapPropagator) OpenTelemetryOption {
func WithPropagators(ps propagation.TextMapPropagator) OpenTelemetryOpt {
return optionFunc(func(c *config) {
if ps != nil {
c.Propagators = ps
Expand All @@ -53,12 +55,28 @@ func WithPropagators(ps propagation.TextMapPropagator) OpenTelemetryOption {

// WithSpanOptions configures an additional set of
// trace.SpanOptions, which are applied to each new span.
func WithSpanOptions(opts ...trace.SpanStartOption) OpenTelemetryOption {
func WithSpanOptions(opts ...trace.SpanStartOption) OpenTelemetryOpt {
return optionFunc(func(c *config) {
c.SpanStartOptions = append(c.SpanStartOptions, opts...)
})
}

// WithSpanNameFormatter takes a function that will be called on every
// request and the returned string will become the Span Name.
func WithSpanNameFormatter(f func(op *runtime.ClientOperation) string) OpenTelemetryOpt {
return optionFunc(func(c *config) {
c.SpanNameFormatter = f
})
}

func defaultTransportFormatter(op *runtime.ClientOperation) string {
if op.ID != "" {
return op.ID
}

return fmt.Sprintf("%s_%s", strings.ToLower(op.Method), op.PathPattern)
}

type openTelemetryTransport struct {
transport runtime.ClientTransport
host string
Expand All @@ -70,7 +88,7 @@ type openTelemetryTransport struct {
}

// newConfig creates a new config struct and applies opts to it.
func newConfig(opts ...OpenTelemetryOption) *config {
func newConfig(opts ...OpenTelemetryOpt) *config {
c := &config{
Propagators: otel.GetTextMapPropagator(),
}
Expand All @@ -87,15 +105,20 @@ func newConfig(opts ...OpenTelemetryOption) *config {
return c
}

func newOpenTelemetryTransport(transport runtime.ClientTransport, host string, opts []OpenTelemetryOption) *openTelemetryTransport {
func newOpenTelemetryTransport(transport runtime.ClientTransport, host string, opts []OpenTelemetryOpt) *openTelemetryTransport {
t := &openTelemetryTransport{
transport: transport,
host: host,
provider: otel.GetTracerProvider(),
propagator: otel.GetTextMapPropagator(),
}

c := newConfig(opts...)
defaultOpts := []OpenTelemetryOpt{
WithSpanOptions(trace.WithSpanKind(trace.SpanKindClient)),
WithSpanNameFormatter(defaultTransportFormatter),
}

c := newConfig(append(defaultOpts, opts...)...)
t.config = c

return t
Expand Down Expand Up @@ -152,7 +175,7 @@ func (t *openTelemetryTransport) newOpenTelemetrySpan(op *runtime.ClientOperatio
}
}

ctx, span := tracer.Start(ctx, operationName(op), t.spanStartOptions...)
ctx, span := tracer.Start(ctx, t.config.SpanNameFormatter(op), t.spanStartOptions...)

// TODO: Can we get the underlying request so we can wire these bits up easily?
// span.SetAttributes(semconv.HTTPClientAttributesFromHTTPRequest()...)
Expand Down
2 changes: 1 addition & 1 deletion client/runtime.go
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@ func (r *Runtime) WithOpenTracing(opts ...opentracing.StartSpanOption) runtime.C
// A new client span is created for each request.
// If the context of the client operation does not contain an active span, no span is created.
// The provided opts are applied to each spans - for example to add global tags.
func (r *Runtime) WithOpenTelemetry(opts ...OpenTelemetryOption) runtime.ClientTransport {
func (r *Runtime) WithOpenTelemetry(opts ...OpenTelemetryOpt) runtime.ClientTransport {
return newOpenTelemetryTransport(r, r.Host, opts)
}

Expand Down

0 comments on commit 601824c

Please sign in to comment.