From 992aa956b609653babe761782c4035ef5ed24efb Mon Sep 17 00:00:00 2001 From: Matthias Andreas Benkard Date: Wed, 3 Jul 2024 20:13:27 +0200 Subject: feat: Add InsertId class. Change-Id: Id620972fea28922a453cbe95ad8467d84df8eca8 --- .../quarkus/googlecloud/jsonlogging/Formatter.java | 7 +- .../quarkus/googlecloud/jsonlogging/InsertId.java | 82 ++++++++++++++++++++++ .../quarkus/googlecloud/jsonlogging/LogEntry.java | 12 +++- .../googlecloud/jsonlogging/FormatterTest.java | 4 +- 4 files changed, 102 insertions(+), 3 deletions(-) create mode 100644 core/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/InsertId.java diff --git a/core/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/Formatter.java b/core/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/Formatter.java index 4aa8f9f..0b2003d 100644 --- a/core/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/Formatter.java +++ b/core/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/Formatter.java @@ -123,6 +123,8 @@ public class Formatter extends ExtFormatter { } } + String insertId = null; + if (logRecord.getParameters() != null) { for (var parameter : logRecord.getParameters()) { if (parameter instanceof StructuredParameter) { @@ -130,6 +132,8 @@ public class Formatter extends ExtFormatter { } else if (parameter instanceof Label) { var label = (Label) parameter; labels.put(label.key(), label.value()); + } else if (parameter instanceof InsertId) { + insertId = ((InsertId) parameter).value(); } } } @@ -151,7 +155,8 @@ public class Formatter extends ExtFormatter { parameters, mdc, ndc, - logRecord.getLevel().intValue() >= 1000 ? ERROR_EVENT_TYPE : null); + logRecord.getLevel().intValue() >= 1000 ? ERROR_EVENT_TYPE : null, + insertId); var b = stringBuilder.get(); b.delete(0, b.length()); diff --git a/core/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/InsertId.java b/core/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/InsertId.java new file mode 100644 index 0000000..9c2bb23 --- /dev/null +++ b/core/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/InsertId.java @@ -0,0 +1,82 @@ +// SPDX-FileCopyrightText: © 2021 Matthias Andreas Benkard +// +// SPDX-License-Identifier: LGPL-3.0-or-later + +package eu.mulk.quarkus.googlecloud.jsonlogging; + +import java.util.Objects; + +/** + * A unique identifier for a log entry. + * + *

Prevents the duplicate insertion of log entries. Also serves as a discriminator to order log entries that carry + * the same time stamp. + * + *

Will be generated by Google Cloud Logging if not provided. + * + *

Instances of {@link InsertId} can be passed as log parameters to the {@code *f} family of logging + * functions on {@link org.jboss.logging.Logger}. + * + *

Example: + * + * {@snippet : + * logger.logf("Request rejected: unauthorized.", InsertId.of("123")); + * } + * + *

Result: + * + * {@snippet lang="json" : + * { + * "textPayload": "Request rejected: unauthorized.", + * "logging.googleapis.com/insertId": "123" + * } + * } + * + * @see Label + * @see StructuredParameter + */ +public final class InsertId { + + private final String value; + + private InsertId(String value) { + this.value = value; + } + + /** + * Constructs an {@link InsertId} from a string. + * + * @param value the value of the insertion ID. + * @return the newly constructed {@link InsertId}, ready to be passed to a logging function. + */ + public static InsertId of(String value) { + return new InsertId(value); + } + + /** + * The value of the label. + * + * @return the value of the label. + */ + public String value() { + return value; + } + + @Override + public boolean equals(Object obj) { + if (obj == this) return true; + if (obj == null || obj.getClass() != this.getClass()) return false; + var that = (InsertId) obj; + return Objects.equals(this.value, that.value); + } + + @Override + public int hashCode() { + return Objects.hash(value); + } + + @Override + public String toString() { + return "InsertId[value=" + value + ']'; + } +} diff --git a/core/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/LogEntry.java b/core/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/LogEntry.java index 19e6a3f..8859cb6 100644 --- a/core/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/LogEntry.java +++ b/core/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/LogEntry.java @@ -35,6 +35,7 @@ final class LogEntry { private final Map mappedDiagnosticContext; @Nullable private final String nestedDiagnosticContext; @Nullable private final String type; + @Nullable private final String insertId; LogEntry( String message, @@ -47,7 +48,8 @@ final class LogEntry { List parameters, Map mappedDiagnosticContext, @Nullable String nestedDiagnosticContext, - @Nullable String type) { + @Nullable String type, + @Nullable String insertId) { this.message = message; this.severity = severity; this.timestamp = timestamp; @@ -59,6 +61,7 @@ final class LogEntry { this.mappedDiagnosticContext = mappedDiagnosticContext; this.nestedDiagnosticContext = nestedDiagnosticContext; this.type = type; + this.insertId = insertId; } static final class SourceLocation { @@ -124,6 +127,13 @@ final class LogEntry { } void json(StringBuilder b) { + + if (insertId != null) { + b.append("\"logging.googleapis.com/insertId\":"); + appendEscapedString(b, insertId); + b.append(","); + } + if (trace != null) { b.append("\"logging.googleapis.com/trace\":"); appendEscapedString(b, trace); diff --git a/core/src/test/java/eu/mulk/quarkus/googlecloud/jsonlogging/FormatterTest.java b/core/src/test/java/eu/mulk/quarkus/googlecloud/jsonlogging/FormatterTest.java index 16fc537..d202fd9 100644 --- a/core/src/test/java/eu/mulk/quarkus/googlecloud/jsonlogging/FormatterTest.java +++ b/core/src/test/java/eu/mulk/quarkus/googlecloud/jsonlogging/FormatterTest.java @@ -67,6 +67,7 @@ class FormatterTest { assertLinesMatch( List.of( "\\{" + + "\"logging.googleapis.com/insertId\":\"123-456-789\"," + "\"logging.googleapis.com/labels\":\\{\"a\":\"b\",\"requestId\":\"123\"\\}," + "\"traceId\":\"39f9a49a9567a8bd7087b708f8932550\"," + "\"spanId\":\"c7431b14630b633d\"," @@ -91,7 +92,8 @@ class FormatterTest { new Object[] { (StructuredParameter) () -> JSON.createObjectBuilder().add("one", 1).add("two", 2.0).add("yes", true), - Label.of("a", "b") + Label.of("a", "b"), + InsertId.of("123-456-789"), }); return logRecord; } -- cgit v1.2.3