Skip to content
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

docs: troubleshooting guide for logging #9315

Merged
merged 2 commits into from
Apr 5, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 67 additions & 0 deletions TROUBLESHOOTING.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,72 @@
# Troubleshooting

## Logging

Our libraries use the Java logging API via `java.util.logging` package.
Configuring logging level reveals various facts that help your troubleshooting,
including:

- The timing of underlying client-server communication
- Request and response message headers
- Verbose messages in underlying dependency libraries

While there are various ways to configure the logging,
to quickly enable verbose logging for the Google Cloud Java libraries, create
a file `logging.properties` with the following content:

```
# run java program pointing to this properties file with the java arg
# -Djava.util.logging.config.file=path/to/logging.properties
handlers=java.util.logging.ConsoleHandler
java.util.logging.SimpleFormatter.format=%1$tF %1$tT,%1$tL %4$-8s %3$-50s - %5$s %6$s%n

# --- ConsoleHandler ---
java.util.logging.ConsoleHandler.level=ALL
java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter
.level=INFO

# --- Specify logging level for certain packages ---
# com.google.api is for HTTP 1.1 layer
com.google.api.level=ALL
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we add notes to indicate that this is only needed for REST APIs and io.groc.level below is only needed for gRPC APIs?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added comments.

Note that even when you use gRPC library, some authentication happens in HTTP 1.1.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that even when you use gRPC library, some authentication happens in HTTP 1.1.

Thanks, that's good to know. I guess it would be mostly covered by the com.google.auth.level=FINE below?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That does not show HTTP headers.

# io.grpc is for gRPC + Netty layer
io.grpc.level=FINE
# com.google.auth is for authentication
com.google.auth.level=FINE

# Example when we want to specify storge library's level. This works when
# the target Cloud library uses the logging API.
com.google.cloud.storage.level=INFO
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm afraid this is only useful for handwritten libraries, for pure generated ones, we have very little logs, which is something we are planning to improve as part of the observability project. Can we add something to indicate it as well or maybe remove this section?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added that.

```

and run your application with `-Djava.util.logging.config.file=path/to/logging.properties`
as the "VM argument" (not "Program argument").

If you use IntelliJ, you specify the VM argument in "Run/Debug Configuration":

![Screenshot of IntelliJ configuration](docs/logging_vm_options.png)

If the JVM of your program is running with the configuration correctly, you see
the FINE-level logging in your console. Example output:

```
2023-04-05 13:03:01,761 FINE com.google.auth.oauth2.DefaultCredentialsProvider - Attempting to load credentials from well known file: /usr/local/google/home/suztomo/.config/gcloud/application_default_credentials.json
2023-04-05 13:03:01,847 FINE io.grpc.ManagedChannelRegistry - Unable to find OkHttpChannelProvider
java.lang.ClassNotFoundException: io.grpc.okhttp.OkHttpChannelProvider
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:581)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522)
at java.base/java.lang.Class.forName0(Native Method)
at java.base/java.lang.Class.forName(Class.java:315)
...
```

Note that you may see many stacktraces printed there.
As long as it's "FINE" level, they are not errors.

This is just one way to configure logging level.
For more details about Java logging API usage, see [Java Logging Overview](
https://docs.oracle.com/javase/8/docs/technotes/guides/logging/overview.html).

## ALPN is not configured properly

If you see exceptions related to `ALPN is not configured properly`, such as:
Binary file added docs/logging_vm_options.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.