gocontext.go 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. package opentracing
  2. import "context"
  3. type contextKey struct{}
  4. var activeSpanKey = contextKey{}
  5. // ContextWithSpan returns a new `context.Context` that holds a reference to
  6. // `span`'s SpanContext.
  7. func ContextWithSpan(ctx context.Context, span Span) context.Context {
  8. return context.WithValue(ctx, activeSpanKey, span)
  9. }
  10. // SpanFromContext returns the `Span` previously associated with `ctx`, or
  11. // `nil` if no such `Span` could be found.
  12. //
  13. // NOTE: context.Context != SpanContext: the former is Go's intra-process
  14. // context propagation mechanism, and the latter houses OpenTracing's per-Span
  15. // identity and baggage information.
  16. func SpanFromContext(ctx context.Context) Span {
  17. val := ctx.Value(activeSpanKey)
  18. if sp, ok := val.(Span); ok {
  19. return sp
  20. }
  21. return nil
  22. }
  23. // StartSpanFromContext starts and returns a Span with `operationName`, using
  24. // any Span found within `ctx` as a ChildOfRef. If no such parent could be
  25. // found, StartSpanFromContext creates a root (parentless) Span.
  26. //
  27. // The second return value is a context.Context object built around the
  28. // returned Span.
  29. //
  30. // Example usage:
  31. //
  32. // SomeFunction(ctx context.Context, ...) {
  33. // sp, ctx := opentracing.StartSpanFromContext(ctx, "SomeFunction")
  34. // defer sp.Finish()
  35. // ...
  36. // }
  37. func StartSpanFromContext(ctx context.Context, operationName string, opts ...StartSpanOption) (Span, context.Context) {
  38. return startSpanFromContextWithTracer(ctx, GlobalTracer(), operationName, opts...)
  39. }
  40. // startSpanFromContextWithTracer is factored out for testing purposes.
  41. func startSpanFromContextWithTracer(ctx context.Context, tracer Tracer, operationName string, opts ...StartSpanOption) (Span, context.Context) {
  42. if parentSpan := SpanFromContext(ctx); parentSpan != nil {
  43. opts = append(opts, ChildOf(parentSpan.Context()))
  44. }
  45. span := tracer.StartSpan(operationName, opts...)
  46. return span, ContextWithSpan(ctx, span)
  47. }