feat(o11y): Introduce rpc.system.name and rpc.method in gRPC#4121
feat(o11y): Introduce rpc.system.name and rpc.method in gRPC#4121diegomarquezp wants to merge 18 commits intomainfrom
rpc.system.name and rpc.method in gRPC#4121Conversation
Summary of ChangesHello @diegomarquezp, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request introduces significant improvements to the observability framework by enriching tracing contexts with RPC system and method information. It refactors the tracing mechanism to be more flexible and less dependent on specific span naming conventions, allowing for better integration with standardized observability practices. The changes streamline how RPC details are captured and propagated through the tracing system, enhancing the clarity and utility of generated traces. Highlights
Changelog
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Code Review
This pull request introduces a significant and beneficial refactoring to the tracing infrastructure. By replacing the explicit SpanName with a more structured ApiTracerContext carried by ApiTracerFactory, the code becomes more maintainable and extensible. The introduction of rpc.system.name and rpc.method attributes aligns with modern observability practices.
However, there are a couple of points that need attention:
-
Missing Tests (Critical): The PR adds new logic (e.g., in
ApiTracerContext) and refactors existing components, but it lacks corresponding unit tests. The repository's contribution guidelines (line 148:Testing: All new logic should be accompanied by tests.) are not being met. Please add tests for the new functionality, especially for the parsing logic inApiTracerContext.fromGrpcMethodNameandApiTracerContext.fromHttpJsonMethodName, and ensure existing tests are updated to reflect the API changes. -
Robustness: There's a potential for a
NullPointerExceptioninSpanTracerFactorywhich can be addressed with a defensive check.
Overall, this is a good direction, but the lack of tests is a critical issue that must be addressed before merging.
gax-java/gax/src/main/java/com/google/api/gax/tracing/SpanTracerFactory.java
Outdated
Show resolved
Hide resolved
b32f09a to
e5b927a
Compare
gax-java/gax/src/main/java/com/google/api/gax/tracing/TracedUnaryCallable.java
Outdated
Show resolved
Hide resolved
gax-java/gax/src/main/java/com/google/api/gax/tracing/ApiTracerFactory.java
Outdated
Show resolved
Hide resolved
rpc.system.name and rpc.method in gRPC
|
|
We will need mock adjustments downstream. For example, SkipTrailersTest when(tracerFactory.newTracer(Mockito.any(), Mockito.any(), Mockito.any())).thenReturn(tracer);
|
|
|
||
| OperationCallable<RequestT, ResponseT, MetadataT> tracedOperationCallable = | ||
| new TracedOperationCallable<>( | ||
| operationCallable, clientContext.getTracerFactory(), operationSpanName); |
There was a problem hiding this comment.
Anything related to Operation is LRO, which is OOS for now. We can finalized the method name format for LRO in next quarter.
| baseCallable, | ||
| clientContext.getTracerFactory(), | ||
| getSpanName(grpcCallSettings.getMethodDescriptor()), | ||
| getApiTracerContext(grpcCallSettings.getMethodDescriptor()), |
There was a problem hiding this comment.
Batching is technically OOS also, but since this is a very low risk change, I think we can take it.
| if (transport() == null) { | ||
| return null; | ||
| } | ||
| return transport() == Transport.GRPC ? "grpc" : "http"; |
There was a problem hiding this comment.
Can we use Transport.GRPC.toString()? Or if we still prefer lowercase, we can put grpc/http as label in the enum.
| this.innerCallable = innerCallable; | ||
| this.tracerFactory = tracerFactory; | ||
| this.spanName = spanName; | ||
| this.apiTracerContext = null; |
There was a problem hiding this comment.
Can we create an apiTracerContext from the SpanName so we don't have to do null check below?
There was a problem hiding this comment.
Do we have to make changes in this file and BaseApiTracerFactory? I think the default methods in ApiTracerFactory should not require us to do so?
| */ | ||
| default ApiTracer newTracer( | ||
| ApiTracer parent, ApiTracerContext tracerContext, OperationType operationType) { | ||
| ApiTracerContext context = getApiTracerContext().merge(tracerContext); |
There was a problem hiding this comment.
The default implementation is for backward compatibility. I don't think we need to merge because the existing overridden classes don't have an existing ApiTracerContext?
| /** | ||
| * @return the client name part of the span name | ||
| */ | ||
| public String getClientName() { |
There was a problem hiding this comment.
Is clientName just serviceName which we should already have it in StubSettings?
| } | ||
|
|
||
| private String[] getParsedFullMethodNameParts() { | ||
| Preconditions.checkState(fullMethodName() != null, "rpcMethod must be set to get SpanName"); |
There was a problem hiding this comment.
to get SpanName does not apply anymore.
| } | ||
|
|
||
| /** | ||
| * @return the method name part of the span name |
There was a problem hiding this comment.
method name could be used for more than Span, can we use more generic terms instead of span name in the Java docs?
In addition, can we provide an example for each of the public attributes so its easier to understand?





This PR introduces the
rpc.system.nameandrpc.methodspan attributes in gRPC.To achieve this, all
Traced*Callableclasses were modified with a constructor overload that accepts anApiTracerContextinstance. Such an instance will be preferred overSpanNamewhen deciding which (also newly introduced) overload ofApiTracerFactory.newTracer()will be called.The new method in
ApiTracerFactory,newTracer(ApiTracer parent, ApiTracerContext tracerContext, OperationType operationType)will by default merge the existing factory's context with the new one and simply create a newSpanName.However, the logic in
SpanTracerFactorywill use the context to create the span name directly.The
rpc.system.nameandrpc.methodproperties are obtained fromGrpcCallableFactoryand stored inApiTracerContext, which now holds the regexes for parsing client and method names (used when buildingSpanNames).