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

Add SpanProfiler #448

Merged
merged 3 commits into from
Dec 21, 2023
Merged

Add SpanProfiler #448

merged 3 commits into from
Dec 21, 2023

Conversation

kolesnikovae
Copy link
Contributor

@kolesnikovae kolesnikovae commented Dec 8, 2023

The PR introduces spanprofiler. Its purpose is to facilitate "request-scoped" profiles with minimal effort and impact on application performance. The use of OpenTracing and OpenTelemetry SDK interfaces appears to be the simplest solution to this problem. For a detailed description, please refer to the README note.

We've successfully integrated and tested this feature in our internal deployments over the past two months with no reported issues.

Checklist

  • Tests updated
  • CHANGELOG.md updated - the order of entries should be [CHANGE], [FEATURE], [ENHANCEMENT], [BUGFIX]

Comment on lines +83 to +109
// isRemoteSpan reports whether the span context represents a remote parent.
//
// NOTE(kolesnikovae): this is ugly, but the only reliable method I found.
// The opentracing-go package and Jaeger client are not meant to change as
// both are deprecated.
func isRemoteSpan(c jaeger.SpanContext) bool {
jaegerCtx := *(*jaegerSpanCtx)(unsafe.Pointer(&c))
return jaegerCtx.remote
}

// jaegerSpanCtx represents memory layout of the jaeger.SpanContext type.
type jaegerSpanCtx struct {
traceID [16]byte // TraceID
spanID [8]byte // SpanID
parentID [8]byte // SpanID
baggage uintptr // map[string]string
debugID [2]uintptr // string

// samplingState is a pointer to a struct that has "localRootSpan" member,
// which we could probably use: that would allow omitting quite expensive
// parentSpanContextFromRef call. However, interpreting the pointer and
// the complex struct memory layout is more complicated and dangerous.
samplingState uintptr

// remote indicates that span context represents a remote parent
remote bool
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is, perhaps, the most controversial part. If anyone knows of a way to avoid such unsafe access, I'll be happy to make the necessary changes.

Please note that wrapping jaeger.SpanContext is not easily achievable, as this concrete type is often expected by users and is utilized in assertions.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To me this seems fine, we could consider running our fork of open tracing while we transition off.

Comment on lines +75 to +85
// We create a span wrapper to ensure we remove the newly attached pprof
// labels when span finishes. The need of this wrapper is questioned:
// as we do not have the original context, we could leave the goroutine
// labels – normally, span is finished at the very end of the goroutine's
// lifetime, so no significant side effects should take place.
w := spanWrapper{
parentPprofCtx: parentCtx,
currentPprofCtx: ctx,
}
w.Span = span.SetTag(profileIDTagKey, spanID)
return &w
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's worth noting that we could likely avoid wrapping jaeger.Span and preserve the original type. On the other hand, pprof does not clarify the behavior in case goroutine labels are not cleared (AFAIK).

@kolesnikovae kolesnikovae requested review from cyriltovena and removed request for cyriltovena December 8, 2023 10:42
@kolesnikovae kolesnikovae marked this pull request as ready for review December 8, 2023 10:42
@kolesnikovae
Copy link
Contributor Author

/cc @cyriltovena

Copy link
Contributor

@cyriltovena cyriltovena left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@kolesnikovae kolesnikovae merged commit de83901 into main Dec 21, 2023
3 checks passed
@kolesnikovae kolesnikovae deleted the feat/add-spanprofiler branch December 21, 2023 01:59
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

Successfully merging this pull request may close these issues.

None yet

2 participants