-
Notifications
You must be signed in to change notification settings - Fork 103
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
OpenTelemetry for launcher #1215
OpenTelemetry for launcher #1215
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I love it, but I want to noodle on the function signatures
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { | ||
ctx, span := traces.New(r.Context()) | ||
defer span.End() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is an interesting question... I don't know if we should add spans to kryptoEcMiddleware.Wrap
vs wrapping with a span middleware. Thoughts?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought it was helpful this way because it gives us more specific timing info for the kryptoEcMiddleware
, which would've been helpful in the past. We do already effectively wrap the entire localhost handler with the span middleware -- we use otelhttp.NewHandler
to wrap all our other handlers. So we have an outer span for the initial request, a child span for the kryptoEcMiddleware, and then a final child span for the request handling (e.g. control server acceleration or whatever we're doing).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a good point -- maybe we don't usually want to instrument a span, but this one might be special.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure I get the original point -- with the exception of the otelhttp wrapper, I'm mostly manually instrumenting spans here. Is that something we don't want?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There were a couple aspects to the original comment, but I'm not sure they're germane.
Foremost, my point is about how if we want to instrument the entire span, we'd be better off doing it in middleware. Though you're correct that otelhttp.NewHandler
is already that middleware.
The secondary point is that if we're instrumenting the span with otelhttp.NewHandler
, then immediately starting a subspan isn't going to be meaningful. It should be the same timing period. If there are smaller parts we want to trace it makes sense, but this looks like:
trace1{
trace2{
stuff
}
}
So I don't see it adding much
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Though I see that you need the span
to add in the error. But I wonder if SpanFromContext
is a better fit.
Basically, why add the span? Does it help any?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In general I like more child spans because they help us narrow down causes of performance issues. E.g. here, if we have a localserver request that we see take a long time, we can use the multiple child spans to identify if it's the krypto middleware that's taking a while, or the inner request to e.g. accelerate the control server interval. Without the child spans, all we have is one span that tells us it takes a certain amount of time for the request to be processed and a response to be returned, which isn't really more info than what we've got in the browser dev console.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right. But only if there are those inner spans. So why wrap the whole function, vs just the blocks you want? There's an extra span here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suppose I find it a little easier to view? All the spans I care about for troubleshooting one particular code path, grouped into one trace. And I appreciate when tracing/logging is done in a consistent way.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we're talking past each other. But we can point at a screen with real data and iterate later
func (t *execTableV2) generate(ctx context.Context, queryContext table.QueryContext) ([]map[string]string, error) { | ||
ctx, span := traces.New(ctx, trace.WithAttributes(attribute.String(traces.AttributeName("dataflattentable", "table_name"), t.tableName))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I want to add spans to the generate, but I think we should be doing it at a different level.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where do you have in mind?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably the osquery-go SDK, or even thrift.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I imagine we'll come back to that idea a little later?
8dbc2f2
to
9727212
Compare
…en replace it later
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure I can follow the exporter, but this seems about right.
I think we can add some sugar around adding errors. trace.AddErrorToCtx(ctx, err)
and trace.AddErrorToSpan(span, err)`maybe? But we could kick that forward.
func buildAttributes(callerFile string, keyVals ...interface{}) []attribute.KeyValue { | ||
callerDir := defaultAttributeNamespace | ||
if callerFile != "" { | ||
callerDir = filepath.Base(filepath.Dir(callerFile)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know what this value is -- is the path separator going to vary by platform?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's the closest I got to getting the package name -- e.g. when the caller is ee/localserver/request-controlservice.go, this will be localserver
. I can document this better.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added a comment to make this clearer
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On windows, are the paths /
or \
? (I'm never sure, since it's oddly inconsistent. windows paths are, of course \
, but sometimes the internal go paths are /
)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh sorry, I didn't realize I'd missed that part of the question -- let me confirm.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Then it'll need path
not filepath
and a comment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd say fix the typecasts, and it's a solid base to iterate with
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems like a solid starting point! Great job!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
awesome work!
24288af
Adds traces to a couple locations in launcher, as well as an optional exporter using OTLP over HTTP. These changes work out-of-the-box with the Jaeger all-in-one container documented here. Adds a command-line flag to disable exporting traces.