Skip to content
This repository has been archived by the owner on Oct 23, 2023. It is now read-only.

Support "follows from" relationships between spans #54

Open
btubbs opened this issue Jan 25, 2021 · 0 comments
Open

Support "follows from" relationships between spans #54

btubbs opened this issue Jan 25, 2021 · 0 comments

Comments

@btubbs
Copy link

btubbs commented Jan 25, 2021

I want to connect spans across an event publishing backend, as opposed to synchronous API calls. opentracing-go has support for this, but signalfx-go-tracing drops these relationships when starting a span. See ddtrace/opentracer/tracer.go. The StartSpan method there has handling for opentracing.ChildOfRef, but will completely ignore any references of type opentracing.FollowsFromRef. Even if it wanted to handle the "follows from" references, there's no place to stick them on a ddtrace.StartSpanConfig (which has a "Parent" span context, but no "FollowsFrom" span context).

Are "follows from" relationships completely unsupported by SignalFX's tracing implementation, or is this just a case of implementation lag in the Go library? I could submit a PR to add the span options and necessary field in StartSpanConfig, but if there's no support for them in SignalFX's backend or UI, there wouldn't be a point. Does that support exist?

Here is a snippet to illustrate the problem in code:

package main

import (
	"context"
	"fmt"

	"github.com/opentracing/opentracing-go"
	"github.com/signalfx/signalfx-go-tracing/ddtrace/opentracer"
	"github.com/signalfx/signalfx-go-tracing/ddtrace/tracer"
	"github.com/signalfx/signalfx-go-tracing/tracing"
)

func main() {
	// start up the tracer
	tracing.Start(tracing.WithServiceName("carrier_test"))

	// start a trace+span for a "foo" operation
	ctx := context.Background()
	span, ctx := tracer.StartSpanFromContext(ctx, "foo_sender")
	//fmt.Println(span)
	//fmt.Println(ctx)

	// inject the span context into a text map
	carrier := tracer.TextMapCarrier{}
	err := span.Tracer().Inject(span.Context(), opentracing.TextMap, carrier)
	fmt.Println("err", err)
	fmt.Println("carrier", carrier)
	// printed carrier should look like this: map[x-b3-sampled:1 x-b3-spanid:d287d348039d504 x-b3-traceid:d287d348039d504]

	// now imagine that we're including the text map copy of the span context in a protobuf message
	// that just has a map<string, string> field in it, and publishing that over something like
	// RabbitMQ, Kafka, etc.
	wireData := map[string]string(carrier)
	fmt.Println("wireData", wireData)

	// and now imagine that some code on the other end picks up that message from Rabbit/Kafka, and wants
	// to start a followsfrom span that refers to the one passed on the wire.
	otracer := opentracer.New() // get opentracing-compatible wrapped instance of ddtrace global tracer
	spanCtx, err := otracer.Extract(opentracing.TextMap, opentracing.TextMapCarrier(wireData))
	fmt.Println("spanCtx", spanCtx)

	// start a new span that "follows from" the one that sent the message.
	newSpan := otracer.StartSpan("process_foo", opentracing.FollowsFrom(spanCtx))
	fmt.Println("newSpan", newSpan)

	// NOTE that printed span has no information about the one that it is supposed to follow from.
	// This is because the StartSpan method silently ignores the opentracing.FollowsFrom option that
	// was passed in.  Only references of the "child of" type are honored by that method.
}

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant