-
Notifications
You must be signed in to change notification settings - Fork 61
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
feat: add client side logging with slf4j #3403
Conversation
…g needs more work.
gax-java/gax/src/main/java/com/google/api/gax/logging/LoggingUtils.java
Outdated
Show resolved
Hide resolved
gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/GrpcLoggingInterceptor.java
Outdated
Show resolved
Hide resolved
gax-java/gax/src/main/java/com/google/api/gax/logging/JsonContextMapHandler.java
Outdated
Show resolved
Hide resolved
gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/GrpcLoggingInterceptor.java
Outdated
Show resolved
Hide resolved
…g entries, add request id to track.
…ing interceptors.
gax-java/gax-httpjson/src/main/java/com/google/api/gax/httpjson/HttpJsonLoggingInterceptor.java
Outdated
Show resolved
Hide resolved
|
||
@InternalApi | ||
@AutoValue | ||
public abstract class LogData { |
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.
Do you think it would make sense to have something like LogRequestData (or RequestLogData or whatever name) that extends from LogData and the equivalent for Response? Request and Response classes would have fields specific them that aren't shared from LogData
Or is the request/ response data for an RPC supposed to be tied to a single LogData object?
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.
Currently both request and respond logging extracts data from this shared LogData. The main benefit is less overhead in object creation, and both request/respond logging can access shared info(rpc name, service name).
We can create separate structure for request/respond data potentially, but I don't see it necessary at this point as there is no conflict/overrides between request and response data. Considering that we also want to limit classes exposed as public.
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.
Ok, I think I'm fine with this now, but I am just curious how this is going to work with Streaming calls. We can figure that out as part of the follow up tasks.
gax-java/gax/src/main/java/com/google/api/gax/logging/Slf4jUtils.java
Outdated
Show resolved
Hide resolved
gax-java/gax/src/main/java/com/google/api/gax/logging/Slf4jUtils.java
Outdated
Show resolved
Hide resolved
import java.util.Map; | ||
|
||
@InternalApi | ||
public class LoggingUtils { |
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.
From offline discussion, need to improve readability on these logging classes.
Ideas for renaming:
LoggingUtils -> SdkLogger
Slf4jLoggingHelpers -> Slf4jLogger
refactor ideas: create a SDKLogger for public access methods, hide all others. Classes that needs logger should initialize a SDKLogger, and call methods within the SDKLogger. This should also avoid most of the static calls.
Added as a task to migration ticket
try { | ||
action.run(); | ||
} catch (Throwable t) { | ||
// let logging exceptions fail silently |
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 wonder if it would make since to log this error at the lowest levels (maybe TRACE?) about any logging exceptions?
It would be like using logging to debug logging errors... Which honestly doesn't sound like something people would be doing. Just some thoughts, probably doesn't make any sense.
} | ||
|
||
private static void addIfNotEmpty(Consumer<String> setter, String value) { | ||
if (value != null && !value.isEmpty()) { |
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.
nit: Guava's Strings.isEmptyorNull
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. I think we have a few follow up tasks and clean up that we can tackle in future PRs.
|
|
This Pr contains changes for adding client logging capability to auth. see [go/java-client-logging-design](http://goto.google.com/java-client-logging-design) Some logging setups are mirror of same setting in Gax ([pr 3403](googleapis/sdk-platform-java#3403)) Changes includes: - add slf4j as optional dependency, enable logging only when GOOGLE_SDK_JAVA_LOGGING=true - user app should add SLF4J + binding dependencies accordingly. For SLF4J 1x, we record extra info with MDC; for SLF4J2x, we record extra info with KeyValuePairs. More user guide to be added via README (see [draft](https://docs.google.com/document/d/1g8HJCstkEEZZc73gFlQO8uPGs07SkWKkr7NG-Yg4bvM/edit?tab=t.0#heading=h.9t58aw3up7to)). - If env var not true, or no binding present, default to no-op. - Add log for request and response made to auth endpoints for UserCredentials, ServiceAccountCredentials, ComputeEngineCredentials, ImpersonatedCredentials. For token values included, added hash in log. Note this PR mainly focuses on adding logging setups, logging statements can be added incrementally later if necessary. Here is an example logging output for access token request from UserCredentials when DEBUG level is allowed. (TO UPDATE) ``` {"@timestamp":"2024-12-04T21:10:48.596382834-05:00","@Version":"1","message":"Sending auth request to refresh access token.","logger_name":"com.google.auth.oauth2.UserCredentials","thread_name":"main","severity":"DEBUG","level_value":10000,"request.method":"POST","request.headers":{"x-goog-api-client":"gl-java/19.0.1 auth/1.32.2-SNAPSHOT cred-type/u","accept-encoding":["gzip"]},"request.url":"https://foo.com/bar","request.payload":{"refresh_token":"bae0258be92ea1d1e14f984507bee05ff4502a29104f4101d22a4a88706b0fc0","grant_type":"refresh_token","client_secret":"2d3c802ef65d75e88b098792e2268cd3f55a08bcbb8c8c4672f1195d1951d4b5","client_id":"ya29.1.AADtN_UtlxN3PuGAxrN2XQnZTVRvDyVWnYq4I6dws"}} {"@timestamp":"2024-12-04T21:10:48.624914522-05:00","@Version":"1","message":"Received auth respond for refresh access token.","logger_name":"com.google.auth.oauth2.UserCredentials","thread_name":"main","severity":"INFO","level_value":20000,"response.status":"200","response.headers":"{}"} {"@timestamp":"2024-12-04T21:10:48.627483862-05:00","@Version":"1","message":"Auth response payload.","logger_name":"com.google.auth.oauth2.UserCredentials","thread_name":"main","severity":"DEBUG","level_value":10000,"access_token":"1/MkS*****KPY2","refresh_token":"1/Tl6*****yGWY","token_type":"Bearer","expires_in":"3600"} ``` Testing setup - Currently added flavor of tests: - unit tests with no extra dependency - unit tests depending on either binding be present, or logback implementation to capture logging for test - test for log behaviors for various requests where logs are added. (see LoggingTest) Remaining issue with test scenarios: 1. when no binding present: this is tested via regular tests 2. when env var is T and binding present: tested via test-logging (profile with logback deps) 3. no SLF4J present: same logic as 1, it should be fine with coverage of 1. This is hard to setup this because SLF4J is needed at compile. 4. SLF4J 1x + binding: Hard to setup because SLF4J 2x is needed at compile
🤖 I have created a release *beep* *boop* --- <details><summary>2.54.0</summary> ## [2.54.0](v2.53.0...v2.54.0) (2025-02-25) ### Features * add client side logging with slf4j ([#3403](#3403)) ([fe002fa](fe002fa)) ### Bug Fixes * S2A gRPC flow creates ComputeEngineCredentials via newBuilder. ([#3651](#3651)) ([29c061e](29c061e)) ### Dependencies * update dependency ch.qos.logback:logback-core to v1.3.15 [security] ([#3654](#3654)) ([093d867](093d867)) * update google api dependencies ([#3631](#3631)) ([48db2a1](48db2a1)) * update google auth library dependencies to v1.33.1 ([#3656](#3656)) ([f7877a5](f7877a5)) * update google http client dependencies to v1.46.3 ([#3657](#3657)) ([9d5b3b5](9d5b3b5)) * update grpc to 1.70.0 ([#3641](#3641)) ([ad26cf9](ad26cf9)) * update grpc to 1.70.0 (missed update) ([#3658](#3658)) ([6ca0599](6ca0599)) * Update opentelemetry-semconv to v1.29.0-alpha ([#3635](#3635)) ([49ac09d](49ac09d)) ### Documentation * update showcase readme ([#3659](#3659)) ([0ddf073](0ddf073)) </details> --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com> Co-authored-by: Joe Wang <[email protected]>
| Package | Type | Package file | Manager | Update | Change | |---|---|---|---|---|---| | [com.google.api.grpc:proto-google-common-protos](https://github.com/googleapis/sdk-platform-java) | dependencies | misk/gradle/libs.versions.toml | gradle | minor | `2.53.0` -> `2.54.0` | | [com.google.cloud:google-cloud-core-http](https://github.com/googleapis/sdk-platform-java) | dependencies | misk/gradle/libs.versions.toml | gradle | minor | `2.52.0` -> `2.53.0` | | [com.google.cloud:google-cloud-core](https://github.com/googleapis/sdk-platform-java) | dependencies | misk/gradle/libs.versions.toml | gradle | minor | `2.52.0` -> `2.53.0` | | [com.google.api:gax](https://github.com/googleapis/sdk-platform-java) | dependencies | misk/gradle/libs.versions.toml | gradle | minor | `2.62.0` -> `2.63.0` | | [com.autonomousapps.dependency-analysis](https://github.com/autonomousapps/dependency-analysis-android-gradle-plugin) | plugin | misk/gradle/libs.versions.toml | gradle | minor | `2.10.1` -> `2.11.0` | | [software.amazon.awssdk:sdk-core](https://aws.amazon.com/sdkforjava) | dependencies | misk/gradle/libs.versions.toml | gradle | patch | `2.30.37` -> `2.30.38` | | [software.amazon.awssdk:sqs](https://aws.amazon.com/sdkforjava) | dependencies | misk/gradle/libs.versions.toml | gradle | patch | `2.30.37` -> `2.30.38` | | [software.amazon.awssdk:dynamodb-enhanced](https://aws.amazon.com/sdkforjava) | dependencies | misk/gradle/libs.versions.toml | gradle | patch | `2.30.37` -> `2.30.38` | | [software.amazon.awssdk:dynamodb](https://aws.amazon.com/sdkforjava) | dependencies | misk/gradle/libs.versions.toml | gradle | patch | `2.30.37` -> `2.30.38` | | [software.amazon.awssdk:aws-core](https://aws.amazon.com/sdkforjava) | dependencies | misk/gradle/libs.versions.toml | gradle | patch | `2.30.37` -> `2.30.38` | | [software.amazon.awssdk:bom](https://aws.amazon.com/sdkforjava) | dependencies | misk/gradle/libs.versions.toml | gradle | patch | `2.30.37` -> `2.30.38` | | [software.amazon.awssdk:auth](https://aws.amazon.com/sdkforjava) | dependencies | misk/gradle/libs.versions.toml | gradle | patch | `2.30.37` -> `2.30.38` | --- ### Release Notes <details> <summary>googleapis/sdk-platform-java (com.google.api.grpc:proto-google-common-protos)</summary> ### [`v2.54.0`](https://github.com/googleapis/sdk-platform-java/blob/HEAD/CHANGELOG.md#2540-2025-02-25) ##### Features - add client side logging with slf4j ([#​3403](googleapis/sdk-platform-java#3403)) ([fe002fa](googleapis/sdk-platform-java@fe002fa)) ##### Bug Fixes - S2A gRPC flow creates ComputeEngineCredentials via newBuilder. ([#​3651](googleapis/sdk-platform-java#3651)) ([29c061e](googleapis/sdk-platform-java@29c061e)) ##### Dependencies - update dependency ch.qos.logback:logback-core to v1.3.15 \[security] ([#​3654](googleapis/sdk-platform-java#3654)) ([093d867](googleapis/sdk-platform-java@093d867)) - update google api dependencies ([#​3631](googleapis/sdk-platform-java#3631)) ([48db2a1](googleapis/sdk-platform-java@48db2a1)) - update google auth library dependencies to v1.33.1 ([#​3656](googleapis/sdk-platform-java#3656)) ([f7877a5](googleapis/sdk-platform-java@f7877a5)) - update google http client dependencies to v1.46.3 ([#​3657](googleapis/sdk-platform-java#3657)) ([9d5b3b5](googleapis/sdk-platform-java@9d5b3b5)) - update grpc to 1.70.0 ([#​3641](googleapis/sdk-platform-java#3641)) ([ad26cf9](googleapis/sdk-platform-java@ad26cf9)) - update grpc to 1.70.0 (missed update) ([#​3658](googleapis/sdk-platform-java#3658)) ([6ca0599](googleapis/sdk-platform-java@6ca0599)) - Update opentelemetry-semconv to v1.29.0-alpha ([#​3635](googleapis/sdk-platform-java#3635)) ([49ac09d](googleapis/sdk-platform-java@49ac09d)) ##### Documentation - update showcase readme ([#​3659](googleapis/sdk-platform-java#3659)) ([0ddf073](googleapis/sdk-platform-java@0ddf073)) </details> <details> <summary>autonomousapps/dependency-analysis-android-gradle-plugin (com.autonomousapps.dependency-analysis)</summary> ### [`v2.11.0`](https://github.com/autonomousapps/dependency-analysis-android-gradle-plugin/blob/HEAD/CHANGELOG.md#Version-2110) - \[Feat]: new task (`:computeAllDependencies`) for producing a version catalog file containing all dependencies. - \[Fix]: kotlin-reflect must be on the compile classpath. - \[Test]: Update AGP 8.9.0 stable. - \[Test]: conditional signing. </details> --- ### Configuration 📅 **Schedule**: Branch creation - "after 6pm every weekday,before 2am every weekday" in timezone Australia/Melbourne, Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Never, or you tick the rebase/retry checkbox. 👻 **Immortal**: This PR will be recreated if closed unmerged. Get [config help](https://github.com/renovatebot/renovate/discussions) if that's undesired. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). GitOrigin-RevId: c7d38837c081de3bba13d5d7f2d42008ba98f440
Changes to introduce client logging debug feature to Gax. Guide on usage will be added separately to README file.
slf4j-api
as optional dependency to gax-javaLoggingUtils
,LogData
andLoggerProvider
are public because access are needed from gax-grpc and gax-httpjson packagesLoggingUtils
handles logic to enable/disable from env var, and contains shared utility methods for record data for logging and record logs (abstracting away any need for SLF4J classes).Slf4jUtils
any logic interacting with SLF4J classes.LoggerProvider
provides the SLF4J Logger. This is so that Logger interceptor classes do not declare Logger directly.Tests added:
envVarTest
profileThese tests may not compile depending on the logging dependency brought in. Set up profiles to control test compile and run:
it/logging
folder for compile by default, orenable-golden-tests
.native
is also excluded for now.Notable changes since last reviewed:
Context: go/java-client-logging-design
TODO: