Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

trace not recording using WithTrustRemote #160

Closed
tylerbrewer2 opened this issue Jan 10, 2024 · 1 comment
Closed

trace not recording using WithTrustRemote #160

tylerbrewer2 opened this issue Jan 10, 2024 · 1 comment

Comments

@tylerbrewer2
Copy link

tylerbrewer2 commented Jan 10, 2024

I'm running into a weird issue setting up otelconnect. When I add the WithTrustRemote option to the interceptor, traces are not exported. When I remove the option, traces are exported and I can see the parent trace successfully marked as a trace.Link

My client is passing a traceparent header that looks like this:

newHeaders.set('traceparent', `00-${activeSpan.spanContext().traceId}-${activeSpan.spanContext().spanId}-00`)

And my server setup is almost identical to the docs:

otelInterceptor := connect_go.WithInterceptors(
    otelconnect.NewInterceptor(otelconnect.WithTrustRemote()),
)

// register rpc handlers
rpc.handle(prodRPC.NewProductionServiceHandler(productionService, otelInterceptor))

func setupOTelSDK(ctx context.Context, serviceName, serviceVersion string, logger *slog.Logger) (shutdown func(context.Context) error, err error) {
	var shutdownFuncs []func(context.Context) error

	// shutdown calls cleanup functions registered via shutdownFuncs.
	// The errors from the calls are joined.
	// Each registered cleanup will be invoked once.
	shutdown = func(ctx context.Context) error {
		var err error
		for _, fn := range shutdownFuncs {
			err = errors.Join(err, fn(ctx))
		}
		shutdownFuncs = nil
		return err
	}

	// handleErr calls shutdown for cleanup and makes sure that all errors are returned.
	handleErr := func(inErr error) {
		logger.Info(fmt.Sprintf("OTEL ERROR: %s", inErr.Error()))
		err = errors.Join(inErr, shutdown(ctx))
	}

	// Set up resource.
	res, err := newResource(serviceName, serviceVersion)
	if err != nil {
		handleErr(err)
		return
	}

	// Set up propagator.
	prop := newPropagator()
	otel.SetTextMapPropagator(prop)

	// Set up trace provider.
	tracerProvider, err := newTraceProvider(res)
	if err != nil {
		handleErr(err)
		return
	}
	shutdownFuncs = append(shutdownFuncs, tracerProvider.Shutdown)
	otel.SetTracerProvider(tracerProvider)

	return
}

func newResource(serviceName, serviceVersion string) (*resource.Resource, error) {
	return resource.Merge(resource.Default(),
		resource.NewWithAttributes(semconv.SchemaURL,
			semconv.ServiceName(serviceName),
			semconv.ServiceVersion(serviceVersion),
		))
}

func newPropagator() propagation.TextMapPropagator {
	return propagation.NewCompositeTextMapPropagator(
		propagation.TraceContext{},
		propagation.Baggage{},
	)
}

func newTraceProvider(res *resource.Resource) (*trace.TracerProvider, error) {
	traceExporter, err := otlptracegrpc.New(context.Background())
	if err != nil {
		return nil, err
	}

	traceProvider := trace.NewTracerProvider(
		trace.WithBatcher(traceExporter,
			// Default is 5s. Set to 1s for demonstrative purposes.
			trace.WithBatchTimeout(time.Second)),
		trace.WithResource(res),
	)
	return traceProvider, nil
}
@tylerbrewer2
Copy link
Author

This issue looks like it was a rubber duck for me. I configured my client code to use the propagation package instead of manually building the header, and it looks like that fixed it.

  const output = {};
  propagation.inject(context.active(), output);
  const { traceparent } = output;
  newHeaders.set('traceparent', traceparent)

Closing this because I don't think it's an issue with the library. Thanks!

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

No branches or pull requests

1 participant