analytics-go icon indicating copy to clipboard operation
analytics-go copied to clipboard

Add context in Callback

Open jtejido opened this issue 2 years ago • 2 comments

Is it possible to add context in OnSuccess and OnFailure callbacks for proper span tracing?

jtejido avatar Jun 10 '22 02:06 jtejido

You can at least inject a context.Context when creating the segment using an http.Transport. here's an example for datadog APM tracing:

import (
	"context"
	"net/http"
	httpTrace "gopkg.in/DataDog/dd-trace-go.v1/contrib/net/http"
	"gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer"
	analytics "gopkg.in/segmentio/analytics-go.v3"
    // sorry if I missed some
)

type tracedTransport struct {
    base http.RoundTripper
    ctx context.Context
}

func (r *ddTransport) RoundTrip(req *http.Request) (*http.Response, error) {
    // get datadog span from context
    ctx := r.withTracingMetadata(r.ctx, req.Context())
	req = req.WithContext(ctx)
	return r.base.RoundTrip(req)
}

// framework-specific
func (r *ddTransport) withTracingMetadata(traceCtx, reqCtx context.Context) context.Context {
	span, _ := tracer.SpanFromContext(traceCtx)
    return tracer.ContextWithSpan(reqCtx, span)
}


func SegmentClientConstructor(ctx context.Context, writeKey) analytics.SegmentClient {
    transport := http.DefaultTransport

    // if you need to use a transport that expects to find tracing metadata in `req.Context`,
    // here's where you'd put it
    transport = httpTrace.WrapRoundTripper(transport)

    transport = &tracedTransport{
        base: transport,
        ctx: ctx,
    }

    config := analytics.Config{
        // ...
        Transport: transport,
    }
    client, err := analytics.NewWithConfig(
        writeKey,
        config,
    )
    if err != nil {
        // ...
    }
    return client
}
    

zdufour-asp avatar Dec 13 '22 18:12 zdufour-asp

Typically, to trace requests I would

http.NewRequestWithContext(ctx, "POST", ...) after adding the appropriate OTEL transport.

The Go segment API allows me to set the transport but not pass the current request context at the request time. The above snippet relies on a datadog wrapper, I haven't seen an equivalent for OTEL... but... it would be the wrong context if it was right, the background / global context rather than the request context. Is there a way to get the request context in the track/identify/group etc method that would pass to the outbound http request?

treyhyde avatar Sep 26 '23 02:09 treyhyde