Dokumen ini memberikan ringkasan tentang pencatatan log dan pemecahan masalah umum dengan Library Klien Cloud untuk Java.
Logging
Ada dua cara untuk mengaktifkan logging untuk library klien:
menggunakan java.util.logging, atau menggunakan Logging Debug Library Klien dengan
SLF4J.
Menggunakan java.util.logging
Cloud Client Libraries for Java menggunakan paket Java Logging API (java.util.logging). Mengonfigurasi level logging akan mengungkapkan informasi yang membantu Anda memecahkan masalah, termasuk:
- Waktu komunikasi klien-server yang mendasarinya.
- Header pesan permintaan dan respons.
- Pesan verbose di library dependensi pokok.
Untuk mengaktifkan logging verbose dengan cepat untuk Library Klien Cloud untuk Java, buat
file logging.properties dengan konten berikut:
# 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
# io.grpc is for gRPC + Netty layer
io.grpc.level=FINE
# com.google.auth is for authentication
com.google.auth.level=FINE
# Example when you specify the storage library's level. This works when
# the target Cloud library uses the logging API.
com.google.cloud.storage.level=INFO
Selanjutnya, jalankan aplikasi Anda dengan -Djava.util.logging.config.file=path/to/logging.properties
sebagai VM argument, bukan Program argument.
Jika menggunakan IntelliJ, Anda menentukan argumen VM di Run/Debug Configuration:

Jika JVM program Anda berjalan dengan konfigurasi yang benar, Anda akan melihat pencatatan aktivitas tingkat FINE di konsol.
Contoh 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)
...
Ini adalah salah satu cara untuk mengonfigurasi tingkat logging. Untuk mengetahui informasi selengkapnya tentang penggunaan Java Logging API, lihat Ringkasan Logging Java.
Logging Debug Library Klien (SLF4J)
Library Klien Cloud dilengkapi dengan Logging Debug yang bersifat keikutsertaan yang dapat membantu Anda memecahkan masalah integrasi aplikasi dengan API. Saat logging diaktifkan, peristiwa utama seperti permintaan dan respons, beserta payload dan metadata data, seperti header, dicatat ke aliran error standar.
PERINGATAN: Logging Debug Library Klien menyertakan payload data Anda dalam teks biasa, yang dapat mencakup data sensitif seperti PII untuk diri Anda atau pelanggan Anda, kunci pribadi, atau data keamanan lainnya yang dapat disusupi jika bocor. Selalu terapkan kebersihan data yang baik dengan log aplikasi Anda, dan ikuti prinsip akses paling sedikit. Google juga merekomendasikan agar logging debug library klien diaktifkan hanya untuk sementara selama proses debug aktif, dan tidak digunakan secara permanen dalam produksi.
Prasyarat
Library kami mendukung logging debug menggunakan antarmuka SLF4J.
Library klien dan BOM Library tidak menyertakan dependensi slf4j-api. Anda harus menyiapkan dependensi logging, termasuk SLF4J dan implementasi serta konfigurasi logging yang sesuai sebelum mengaktifkan logging debug library klien.
NOTE: Anda harus memiliki SLF4J dan penyedia logging yang sesuai, misalnya, logback, log4j2, dll., di classpath untuk menggunakan fitur logging debug library klien; jika tidak, tidak ada logging debug meskipun Anda mengaktifkannya menggunakan variabel lingkungan.
Mengaktifkan Logging dengan variabel lingkungan
Logging debug dinonaktifkan secara default. Logging debug tidak diaktifkan kecuali secara eksplisit meskipun prasyaratnya terpenuhi.
Anda dapat mengaktifkan logging debug library klien dengan menetapkan variabel lingkungan
GOOGLE_SDK_JAVA_LOGGING ke true, tidak peka huruf besar/kecil.
Jika tidak disetel atau nilai lainnya, logging debug library klien akan dinonaktifkan.
Contoh penyiapan logging
Dokumentasi memberikan contoh logging debug menggunakan Logback.
Tambahkan dependensi Logback ke aplikasi Anda. Tindakan ini akan membawa dependensi slf4j secara transitif. Pengguna harus melihat penyiapan Logback untuk versi terbaru. Anda dapat melewati langkah ini jika aplikasi Anda sudah memiliki dependensi logback di classpath.
Jika Anda menggunakan Maven:
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>LATEST_VERSION</version>
</dependency>
Tambahkan konten ke file konfigurasi logback jika Anda ingin melihat log tingkat DEBUG. Anda dapat melewati langkah ini jika hanya memerlukan log tingkat INFO. Lihat konfigurasi Logback untuk mengetahui informasi selengkapnya.
<!-- set Client Library log level to DEBUG -->
<logger name="com.google.api" level="DEBUG"/>
<!-- set Auth Library log level to DEBUG -->
<logger name="com.google.auth" level="DEBUG"/>
ALPN tidak dikonfigurasi dengan benar
Jika Anda melihat pengecualian terkait ALPN is not configured properly, seperti:
Caused by: java.lang.IllegalArgumentException: ALPN is not configured properly. See https://github.com/grpc/grpc-java/blob/master/SECURITY.md#troubleshooting for more information.
Gunakan pemeriksa kompatibilitas untuk melihat apakah lingkungan Anda kompatibel dengan klien berbasis gRPC.
Ketidakcocokan mungkin berarti salah satu dari hal berikut:
- Anda tidak menggunakan platform yang didukung.
- Ada konflik classpath dengan
netty. - Anda melihat salah satu konflik yang ditentukan dalam Panduan pemecahan masalah gRPC.
Memecahkan masalah ClassNotFoundException, NoSuchMethodError, dan NoClassDefFoundError
Error ini sering kali disebabkan oleh adanya beberapa versi atau versi yang bertentangan dari dependensi yang sama di classpath. Konflik
dependensi ini sering terjadi pada guava atau protobuf-java.
Beberapa sumber dapat menyebabkan konflik classpath:
- Beberapa versi dependensi transitif yang sama di pohon dependensi.
- Classpath runtime Anda memiliki versi dependensi yang berbeda dengan yang Anda tentukan dalam build.
Misalnya, jika Anda memiliki dependensi langsung atau transitif pada Guava versi 19.0, dan google-cloud-java menggunakan Guava versi 30.0, maka google-cloud-java mungkin menggunakan metode Guava yang tidak ada di Guava 19.0, dan menyebabkan NoSuchMethodError.
Demikian pula, jika classpath Anda memiliki protobuf-java versi lama,
tetapi google-cloud-java memerlukan versi yang lebih baru, Anda mungkin akan melihat
NoClassDefFoundError yang gagal menginisialisasi class google-cloud-java.
Contoh:
java.lang.NoClassDefFoundError: Could not initialize class com.google.pubsub.v1.PubsubMessage$AttributesDefaultEntryHolder
Memvalidasi konflik
Periksa hierarki dependensi untuk melihat apakah Anda memiliki beberapa versi dependensi yang sama:
$ mvn dependency:tree
Cari versi dependensi yang berpotensi menimbulkan konflik seperti guava atau
protobuf-java.
Jika Anda mengalami error hanya selama runtime, lingkungan runtime Anda mungkin memperkenalkan JAR yang bertentangan ke classpath runtime Anda. Kasus umum adalah Hadoop, Spark, atau software server lain yang dijalankan aplikasi Anda memiliki versi JAR netty, guava, atau protobuf-java yang bertentangan di classpath.
Mendeteksi konflik selama build
Untuk mendeteksi kesalahan penautan dependensi pada waktu kompilasi, tambahkan Aturan Penerapan Pemeriksa Penautan di pom.xml Anda:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>3.0.0-M3</version>
<dependencies>
<dependency>
<groupId>com.google.cloud.tools</groupId>
<artifactId>linkage-checker-enforcer-rules</artifactId>
<version>1.5.7</version>
</dependency>
</dependencies>
<executions>
<execution>
<id>enforce-linkage-checker</id>
<!-- Important! Should run after compile -->
<phase>verify</phase>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<rules>
<LinkageCheckerRule
implementation="com.google.cloud.tools.dependencies.enforcer.LinkageCheckerRule"/>
</rules>
</configuration>
</execution>
</executions>
</plugin>
Namun, tidak ada cara untuk mendeteksi konflik classpath runtime. Anda harus sepenuhnya mengetahui JAR/class mana yang disertakan dalam classpath runtime karena setiap lingkungan server berbeda.
Menyelesaikan konflik
Ada berbagai strategi untuk menyelesaikan konflik, tetapi Anda harus memahami akar penyebab konflik:
- Jika Anda mengontrol hierarki dependensi, upgrade dependensi yang bertentangan (misalnya, mengupgrade Guava). Pendekatan ini adalah yang paling andal, tetapi dapat memerlukan upaya yang signifikan dan beberapa rilis library untuk memastikan kompatibilitas.
- Jika Anda tidak dapat mengubah dan mengirim versi baru dependensi, impor
com.google.cloud:libraries-bom:25.1.0(atau versi yang lebih baru) untuk memilih versi dependensi yang konsisten. Pendekatan ini menyederhanakan pengelolaan dependensi. Misalnya, berikut cara Anda dapat bergantung pada versi Guava dancom.google.cloud:google-cloud-storageyang konsisten tanpa menetapkan versi salah satunya secara eksplisit:
...
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>libraries-bom</artifactId>
<version>25.1.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
...
<dependencies>
<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>google-cloud-storage</artifactId>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
...
</dependencies>
...
Catatan rilis libraries-bom menampilkan library dependensi yang kompatibel. Misalnya, https://github.com/googleapis/java-cloud-bom/releases/tag/v26.31.0 menampilkan:
These client libraries are built with the following Java libraries: - Guava: 32.1.3-jre - Protobuf Java: 3.25.2 - Google Auth Library: 1.22.0 - Google API Client: 2.2.0 - gRPC: 1.61.0 - GAX: 2.41.0 - Google Cloud Core: 2.31.0Dengan memeriksa grafik dependensi project Anda (
mvn dependency:tree -Dverbose,gradle dependencies, atausbt dependencyTree), Anda mungkin menemukan beberapa dependensi memiliki versi yang tidak terduga, yang dapat menyebabkan konflik dependensi.Jika perubahan versi dependensi menyebabkan kegagalan lain, pertimbangkan untuk menggabungkan dependensi yang berkonflik dengan library Java. Google Cloud
Misalnya, untuk memberi bayangan pada
guavadanprotobuf-java:<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>...</version> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> <configuration> <keepDependenciesWithProvidedScope>false</keepDependenciesWithProvidedScope> <relocations> <!-- move protobuf to a shaded package --> <relocation> <pattern>com.google.protobuf</pattern> <shadedPattern>myapp.shaded.com.google.protobuf</shadedPattern> </relocation> <!-- move Guava to a shaded package --> <relocation> <pattern>com.google.common</pattern> <shadedPattern>myapp.shaded.com.google.common</shadedPattern> </relocation> </relocations> </configuration> </execution> </executions> </plugin>