| = Quarkus Google Cloud JSON Logging |
| Matthias Andreas Benkard |
| // Meta |
| :experimental: |
| :data-uri: |
| :sectnums: |
| :toc: |
| :stem: |
| :toclevels: 2 |
| :description: Quarkus Google Cloud JSON Logging Manual |
| :keywords: mulk |
| // Settings |
| :icons: font |
| :source-highlighter: rouge |
| |
| |
| Structured logging to standard output according to the Google Cloud |
| Logging specification. |
| |
| |
| == Summary |
| |
| This package contains a log formatter for JBoss Logging in the form of |
| a Quarkus plugin that implements the |
| https://cloud.google.com/logging/docs/structured-logging[Google Cloud |
| Logging JSON format] on standard output. |
| |
| It is possible to log unstructured text, structured data, or a mixture |
| of both depending on the situation. |
| |
| |
| == Activation |
| |
| Add the runtime POM to your dependency list. As long as the JAR is on |
| the classpath at both build time and runtime, the log formatter |
| automatically registers itself on startup. |
| |
| |
| === Activation with Maven |
| |
| [source,xml] |
| ---- |
| <project> |
| ... |
| |
| <dependencies> |
| ... |
| |
| <dependency> |
| <groupId>eu.mulk.quarkus-googlecloud-jsonlogging</groupId> |
| <artifactId>quarkus-googlecloud-jsonlogging</artifactId> |
| <version>4.0.0</version> |
| </dependency> |
| |
| ... |
| </dependencies> |
| |
| ... |
| </project> |
| ---- |
| |
| |
| === Activation with Gradle |
| |
| [source,groovy] |
| ---- |
| dependencies { |
| ... |
| |
| implementation("eu.mulk.quarkus-googlecloud-jsonlogging:quarkus-googlecloud-jsonlogging:4.0.0") |
| |
| ... |
| } |
| ---- |
| |
| |
| == Usage |
| |
| Logging unstructured data requires no code changes. All logs are |
| automatically converted to Google-Cloud-Logging-compatible JSON. |
| |
| Structured data can be logged in one of 3 different ways: by passing |
| https://javadocs.dev/eu.mulk.quarkus-googlecloud-jsonlogging/quarkus-googlecloud-jsonlogging/3.1.0/eu.mulk.quarkus.googlecloud.jsonlogging/eu/mulk/quarkus/googlecloud/jsonlogging/Label.html[Label]s |
| and |
| https://javadocs.dev/eu.mulk.quarkus-googlecloud-jsonlogging/quarkus-googlecloud-jsonlogging/3.1.0/eu.mulk.quarkus.googlecloud.jsonlogging/eu/mulk/quarkus/googlecloud/jsonlogging/StructuredParameter.html[StructuredParameter]s |
| as parameters to individual log entries, by supplying |
| https://javadocs.dev/eu.mulk.quarkus-googlecloud-jsonlogging/quarkus-googlecloud-jsonlogging/3.1.0/eu.mulk.quarkus.googlecloud.jsonlogging/eu/mulk/quarkus/googlecloud/jsonlogging/LabelProvider.html[LabelProvider]s |
| and |
| https://javadocs.dev/eu.mulk.quarkus-googlecloud-jsonlogging/quarkus-googlecloud-jsonlogging/3.1.0/eu.mulk.quarkus.googlecloud.jsonlogging/eu/mulk/quarkus/googlecloud/jsonlogging/StructuredParameterProvider.html[StructuredParameterProvider]s, |
| or by using the Mapped Diagnostic Context. |
| |
| |
| === Using Label and StructuredParameter |
| |
| Instances of |
| https://javadocs.dev/eu.mulk.quarkus-googlecloud-jsonlogging/quarkus-googlecloud-jsonlogging/3.1.0/eu.mulk.quarkus.googlecloud.jsonlogging/eu/mulk/quarkus/googlecloud/jsonlogging/Label.html[Label] |
| and |
| https://javadocs.dev/eu.mulk.quarkus-googlecloud-jsonlogging/quarkus-googlecloud-jsonlogging/3.1.0/eu.mulk.quarkus.googlecloud.jsonlogging/eu/mulk/quarkus/googlecloud/jsonlogging/StructuredParameter.html[StructuredParameter] |
| can be passed as log parameters to the `*f` family of logging |
| functions on JBoss Logging's |
| https://docs.jboss.org/jbosslogging/latest/org/jboss/logging/Logger.html[Logger]. |
| |
| Simple key–value pairs are represented by |
| https://javadocs.dev/eu.mulk.quarkus-googlecloud-jsonlogging/quarkus-googlecloud-jsonlogging/3.1.0/eu.mulk.quarkus.googlecloud.jsonlogging/eu/mulk/quarkus/googlecloud/jsonlogging/KeyValueParameter.html[KeyValueParameter]. |
| |
| **Example:** |
| |
| [source,java] |
| ---- |
| logger.logf( |
| "Request rejected: unauthorized.", |
| Label.of("requestId", "123"), |
| KeyValueParameter.of("resource", "/users/mulk"), |
| KeyValueParameter.of("method", "PATCH"), |
| KeyValueParameter.of("reason", "invalid token")); |
| ---- |
| |
| Result: |
| |
| [source,json] |
| ---- |
| { |
| "jsonPayload": { |
| "message": "Request rejected: unauthorized.", |
| "resource": "/users/mulk", |
| "method": "PATCH", |
| "reason": "invalid token" |
| }, |
| "labels": { |
| "requestId": "123" |
| } |
| } |
| ---- |
| |
| |
| === Using LabelProvider and StructuredParameterProvider |
| |
| Any CDI beans that implement |
| https://javadocs.dev/eu.mulk.quarkus-googlecloud-jsonlogging/quarkus-googlecloud-jsonlogging/3.1.0/eu.mulk.quarkus.googlecloud.jsonlogging/eu/mulk/quarkus/googlecloud/jsonlogging/LabelProvider.html[LabelProvider] |
| and |
| https://javadocs.dev/eu.mulk.quarkus-googlecloud-jsonlogging/quarkus-googlecloud-jsonlogging/3.1.0/eu.mulk.quarkus.googlecloud.jsonlogging/eu/mulk/quarkus/googlecloud/jsonlogging/StructuredParameterProvider.html[StructuredParameterProvider] |
| are discovered at build time and consulted to provide labels and |
| parameters for each message that is logged. This can be used to |
| provide contextual information such as tracing and request IDs stored |
| in thread-local storage. |
| |
| Alternatively, you can also register providers through the Java |
| https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/ServiceLoader.html[ServiceLoader] |
| mechanism. |
| |
| **Example:** |
| |
| [source,java] |
| ---- |
| @Singleton |
| @Unremovable |
| public final class TraceLogParameterProvider implements StructuredParameterProvider, LabelProvider { |
| |
| @Override |
| public StructuredParameter getParameter() { |
| var b = Json.createObjectBuilder(); |
| b.add("traceId", Span.current().getSpanContext().getTraceId()); |
| b.add("spanId", Span.current().getSpanContext().getSpanId()); |
| return () -> b; |
| } |
| |
| @Override |
| public Collection<Label> getLabels() { |
| return List.of(Label.of("requestId", "123")); |
| } |
| } |
| ---- |
| |
| Result: |
| |
| [source,json] |
| ---- |
| { |
| "jsonPayload": { |
| "message": "Request rejected: unauthorized.", |
| "traceId": "39f9a49a9567a8bd7087b708f8932550", |
| "spanId": "c7431b14630b633d" |
| }, |
| "labels": { |
| "requestId": "123" |
| } |
| } |
| ---- |
| |
| |
| === Using the Mapped Diagnostic Context |
| |
| Any key–value pairs in JBoss Logging's thread-local |
| https://docs.jboss.org/jbosslogging/latest/org/jboss/logging/MDC.html[MDC] |
| are added to the resulting JSON. |
| |
| **Example:** |
| |
| [source,java] |
| ---- |
| MDC.put("resource", "/users/mulk"); |
| MDC.put("method", "PATCH"); |
| logger.logf("Request rejected: unauthorized."); |
| ---- |
| |
| Result: |
| |
| [source,json] |
| ---- |
| { |
| "jsonPayload": { |
| "message": "Request rejected: unauthorized.", |
| "resource": "/users/mulk", |
| "method": "PATCH" |
| } |
| } |
| ---- |