-
Notifications
You must be signed in to change notification settings - Fork 4.5k
stats/opentelemetry: separate out interceptors for tracing and metrics #8063
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
stats/opentelemetry: separate out interceptors for tracing and metrics #8063
Conversation
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #8063 +/- ##
==========================================
+ Coverage 81.96% 82.18% +0.22%
==========================================
Files 412 419 +7
Lines 40491 41898 +1407
==========================================
+ Hits 33188 34435 +1247
- Misses 5915 5998 +83
- Partials 1388 1465 +77
🚀 New features to boost your workflow:
|
69df069
to
71804b4
Compare
@janardhanvissa its not clear what is the intention of this refactor. The follow up from opentelemetry tracing API PR was to create separate interceptors for metrics and traces. Right now, single interceptor is handling both trace and metrics options. Once we have separate unary and stream interceptor each for tracing and metrics, we don't have to check for options disabled/enabled everytime. |
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.
Please see this discussion https://github.com/grpc/grpc-go/pull/7852/files#r1909469701 and modify accordingly.
…tion of rpcInfo and attemptInfo
@@ -130,7 +130,7 @@ func (h *clientTracingHandler) HandleConn(context.Context, stats.ConnStats) {} | |||
func (h *clientTracingHandler) TagRPC(ctx context.Context, _ *stats.RPCTagInfo) context.Context { | |||
ri := getRPCInfo(ctx) | |||
var ai *attemptInfo | |||
if ri == nil { | |||
if ri.ai == nil { |
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 here also we can't assume ri is not nil if the order of stats handlers changes.
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.
done
stats/opentelemetry/opentelemetry.go
Outdated
metricsHandler := &clientMetricsHandler{options: o} | ||
metricsHandler.initializeMetrics() | ||
unaryInterceptors = append(unaryInterceptors, metricsHandler.unaryInterceptor) | ||
streamInterceptors = append(streamInterceptors, metricsHandler.streamInterceptor) |
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 changing the current order. Let's avoid that. Keep only 2 variables metricsInterceptors and tracesInterceptors and add metricsInterceptors before traces
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.
done
stats/opentelemetry/opentelemetry.go
Outdated
streamInterceptors = append(streamInterceptors, tracingHandler.streamInterceptor) | ||
do = append(do, grpc.WithStatsHandler(tracingHandler)) | ||
} | ||
if len(unaryInterceptors) > 0 { |
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.
these ifs will change to metrics and traces
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.
done
// TagRPC implements per RPC attempt context management for traces. | ||
func (h *serverTracingHandler) TagRPC(ctx context.Context, _ *stats.RPCTagInfo) context.Context { | ||
ri := getRPCInfo(ctx) | ||
var ai *attemptInfo | ||
if ri == nil { | ||
if ri.ai == nil { |
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.
same here. We can't assume ri to be not nil 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.
done
var ai *attemptInfo | ||
if ri.ai == nil { | ||
ai = &attemptInfo{} | ||
} else { | ||
ai = ri.ai |
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.
Go style:
var ai *attemptInfo | |
if ri.ai == nil { | |
ai = &attemptInfo{} | |
} else { | |
ai = ri.ai | |
ai := ri.ai | |
if ai == nil { | |
ai = &attemptInfo{} |
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.
done
ci := getCallInfo(ctx) | ||
if ci == nil { | ||
if logger.V(2) { | ||
logger.Info("Creating new CallInfo since its not present in context in clientStatsHandler unaryInterceptor") | ||
} | ||
ci = &callInfo{ | ||
target: cc.CanonicalTarget(), | ||
method: determineMethod(method, opts...), | ||
} | ||
ctx = setCallInfo(ctx, ci) | ||
} |
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 see, so we are sharing the same data between the two interceptors.
In that case, can we pull it out into one function and call it from all four places? getOrCreateCallInfo
or something? And a comment indicating that it may already be present if the other interceptor ran first.
var ai *attemptInfo | ||
if ri == nil { | ||
ai = &attemptInfo{} |
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.
So this is the same as the interceptor call info thing?
Then similar: can we have a single function that does this, and is called from both TagRPC
implementations?
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.
LGTM except for the changes mentioned.
if ri == nil { | ||
ri = &rpcInfo{} | ||
} | ||
ai := ri.ai | ||
if ai == nil { | ||
ai = &attemptInfo{} | ||
} |
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.
if ri == nil { | |
ri = &rpcInfo{} | |
} | |
ai := ri.ai | |
if ai == nil { | |
ai = &attemptInfo{} | |
} | |
if ri == nil { | |
ri = &rpcInfo{ai: &attemptInfo{}} | |
} |
Does this not work?
if ai == nil { | ||
ai = &attemptInfo{} | ||
} | ||
return setRPCInfo(ctx, &rpcInfo{ai: ai}), ai |
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 adding it into the context a second time if it's already in there.
I think you want something more like:
ri := getRPCInfo(ctx)
if ri != nil {
return ctx, ri.ai
}
ri := &rpcInfo{ai: &attemptInfo{}}
return setRPCInfo(ctx, ri), ri.ai
RELEASE NOTES: None