feat(gax): Actionable Errors Logging API Tracer#12202
feat(gax): Actionable Errors Logging API Tracer#12202westarle merged 5 commits intogoogleapis:mainfrom
Conversation
Summary of ChangesHello, 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 enhances the GAX tracing mechanism by introducing a dedicated Highlights
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. Footnotes
|
There was a problem hiding this comment.
Code Review
This pull request introduces a new LoggingTracer and LoggingTracerFactory to provide actionable error logging for RPC failures, along with their corresponding unit tests. The LoggingTracer collects various context attributes and error details for logging. Feedback includes suggestions to use constants for log context keys in LoggingTracer for better maintainability, to ensure consistent context merging in one of the newTracer overloads in LoggingTracerFactory, and to improve the LoggingTracerTest to assert actual logged messages.
sdk-platform-java/gax-java/gax/src/main/java/com/google/api/gax/tracing/LoggingTracer.java
Outdated
Show resolved
Hide resolved
...latform-java/gax-java/gax/src/main/java/com/google/api/gax/tracing/LoggingTracerFactory.java
Outdated
Show resolved
Hide resolved
sdk-platform-java/gax-java/gax/src/test/java/com/google/api/gax/tracing/LoggingTracerTest.java
Outdated
Show resolved
Hide resolved
2de91cf to
d5cc997
Compare
sdk-platform-java/gax-java/gax/src/main/java/com/google/api/gax/tracing/LoggingTracer.java
Outdated
Show resolved
Hide resolved
sdk-platform-java/gax-java/gax/src/main/java/com/google/api/gax/tracing/LoggingTracer.java
Outdated
Show resolved
Hide resolved
sdk-platform-java/gax-java/gax/src/main/java/com/google/api/gax/tracing/LoggingTracer.java
Outdated
Show resolved
Hide resolved
sdk-platform-java/gax-java/gax/src/test/java/com/google/api/gax/tracing/LoggingTracerTest.java
Show resolved
Hide resolved
d5cc997 to
60569e8
Compare
60569e8 to
a73c78b
Compare
| */ | ||
| @BetaApi | ||
| @InternalApi | ||
| public class LoggingTracer extends BaseApiTracer { |
There was a problem hiding this comment.
Can we change the scope of this class and the constructor from public to package private?
|
|
||
| Map<String, Object> logContext = new HashMap<>(apiTracerContext.getAttemptAttributes()); | ||
|
|
||
| if (apiTracerContext.serviceName() != null) { |
There was a problem hiding this comment.
This is probably a miss. I think getAttemptAttributes should include serviceName as well, since it is listed as a common attribute in the requirement.
There was a problem hiding this comment.
added to getAttemptAttributes()
| } | ||
|
|
||
| @Override | ||
| public void attemptFailedRetriesExhausted(Throwable error) { |
There was a problem hiding this comment.
Can we add unit tests for this method attemptFailedRetriesExhausted and method below attemptPermanentFailure?
| } | ||
|
|
||
| @Test | ||
| void testAttemptFailed_LogsErrorAndAttributes() { |
There was a problem hiding this comment.
I see that most of the logics are in recordActionableError, we could test it directly by making it package private and @VisibleForTesting.
Then we can have a simple test for each method that calls it.
| void testAttemptFailed_LogsErrorAndAttributes() { | ||
| ApiTracerContext context = | ||
| ApiTracerContext.empty().toBuilder() | ||
| .setServiceName("test-service") |
There was a problem hiding this comment.
Since all these 5 attributes are all from getAttemptAttributes(), maybe we don't have to add all them, using one or two should be good enough? I think it also blurred the focus of the test which is extracting errors info.
| "test.service.v1.Method", | ||
| attributesMap.get(ObservabilityAttributes.GRPC_RPC_METHOD_ATTRIBUTE)); | ||
| assertEquals("grpc", attributesMap.get(ObservabilityAttributes.RPC_SYSTEM_NAME_ATTRIBUTE)); | ||
| assertEquals( |
There was a problem hiding this comment.
Can we try to test these attributes in its own test case? This is inline with the best practices. Maybe we can group all the error info ones together, but I feel status should be its own test case.
Same comment for testing the error message as well.
|
|
||
| /** Function to extract the ErrorInfo payload from the error, if available */ | ||
| @Nullable | ||
| static ErrorInfo extractErrorInfo(@Nullable Throwable error) { |
There was a problem hiding this comment.
I'm adding similar logic in #12189.
Let me know if you'd prefer a different surface for my util.
There was a problem hiding this comment.
happy to move to your logic when it's ready.
blakeli0
left a comment
There was a problem hiding this comment.
LGTM, thanks!
Do you mind adding some descriptions to the PR before merging?
This PR implements the "Actionable Errors" logging framework in the Java client libraries by hooking directly into the
ApiTracerframework. By capturing errors at the tracer level(specifically tied to T4 spans), we ensure that developers receive detailed, actionable context (like
google.rpc.ErrorInfopayloads including reason, domain, and metadata) directly intheir SLF4J logs.
Introduced
LoggingTracerandLoggingTracerFactory: Created a new tracer incom.google.api.gax.tracingextendingBaseApiTracer.If the thrown error is an
ApiExceptioncontainingErrorInfo, the tracer builds a context map (flattening themetadatamap and includingreason/domain) and emits a structured SLF4J log record viaLoggingUtils.logActionableErrorat theDEBUGlevel.Testing
TestServiceProviderto act as a properILoggerFactorythat caches and returns identicalTestLoggerinstances. This eliminates the needfor reflection to override
LOGGER_PROVIDERcaches, keeping tests clean and isolated.gax-java/gax/pom.xmlto excludeLoggingTracerTestfrom default surefire executions and explicitly bind it to theenvVarTestprofile,adhering to our environment-variable test constraints.