summaryrefslogtreecommitdiff
path: root/core/src
diff options
context:
space:
mode:
Diffstat (limited to 'core/src')
-rw-r--r--core/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/Formatter.java7
-rw-r--r--core/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/InsertId.java82
-rw-r--r--core/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/KeyValueParameter.java18
-rw-r--r--core/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/LogEntry.java48
-rw-r--r--core/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/package-info.java4
-rw-r--r--core/src/test/java/eu/mulk/quarkus/googlecloud/jsonlogging/FormatterBenchmark.java4
-rw-r--r--core/src/test/java/eu/mulk/quarkus/googlecloud/jsonlogging/FormatterTest.java8
7 files changed, 140 insertions, 31 deletions
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..b55cf78
--- /dev/null
+++ b/core/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/InsertId.java
@@ -0,0 +1,82 @@
+// SPDX-FileCopyrightText: © 2024 Matthias Andreas Benkard <code@mail.matthias.benkard.de>
+//
+// 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.
+ *
+ * <p>Prevents the duplicate insertion of log entries. Also serves as a discriminator to order log entries that carry
+ * the same time stamp.
+ *
+ * <p>Will be generated by Google Cloud Logging if not provided.
+ *
+ * <p>Instances of {@link InsertId} can be passed as log parameters to the {@code *f} family of logging
+ * functions on {@link org.jboss.logging.Logger}.
+ *
+ * <p><strong>Example:</strong>
+ *
+ * {@snippet :
+ * logger.logf("Request rejected: unauthorized.", InsertId.of("123"));
+ * }
+ *
+ * <p>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/KeyValueParameter.java b/core/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/KeyValueParameter.java
index 2ea4521..a2c468b 100644
--- a/core/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/KeyValueParameter.java
+++ b/core/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/KeyValueParameter.java
@@ -4,9 +4,9 @@
package eu.mulk.quarkus.googlecloud.jsonlogging;
-import jakarta.json.Json;
import jakarta.json.JsonObjectBuilder;
import jakarta.json.JsonValue;
+import jakarta.json.spi.JsonProvider;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Objects;
@@ -40,6 +40,8 @@ import java.util.Objects;
*/
public final class KeyValueParameter implements StructuredParameter {
+ private static final JsonProvider JSON = JsonProvider.provider();
+
private final String key;
private final JsonValue value;
@@ -58,7 +60,7 @@ public final class KeyValueParameter implements StructuredParameter {
* @return the newly constructed parameter, ready to be passed to a logging function.
*/
public static KeyValueParameter of(String key, String value) {
- return new KeyValueParameter(key, Json.createValue(value));
+ return new KeyValueParameter(key, JSON.createValue(value));
}
/**
@@ -71,7 +73,7 @@ public final class KeyValueParameter implements StructuredParameter {
* @return the newly constructed parameter, ready to be passed to a logging function.
*/
public static KeyValueParameter of(String key, int value) {
- return new KeyValueParameter(key, Json.createValue(value));
+ return new KeyValueParameter(key, JSON.createValue(value));
}
/**
@@ -84,7 +86,7 @@ public final class KeyValueParameter implements StructuredParameter {
* @return the newly constructed parameter, ready to be passed to a logging function.
*/
public static KeyValueParameter of(String key, long value) {
- return new KeyValueParameter(key, Json.createValue(value));
+ return new KeyValueParameter(key, JSON.createValue(value));
}
/**
@@ -97,7 +99,7 @@ public final class KeyValueParameter implements StructuredParameter {
* @return the newly constructed parameter, ready to be passed to a logging function.
*/
public static KeyValueParameter of(String key, double value) {
- return new KeyValueParameter(key, Json.createValue(value));
+ return new KeyValueParameter(key, JSON.createValue(value));
}
/**
@@ -110,7 +112,7 @@ public final class KeyValueParameter implements StructuredParameter {
* @return the newly constructed parameter, ready to be passed to a logging function.
*/
public static KeyValueParameter of(String key, BigDecimal value) {
- return new KeyValueParameter(key, Json.createValue(value));
+ return new KeyValueParameter(key, JSON.createValue(value));
}
/**
@@ -123,7 +125,7 @@ public final class KeyValueParameter implements StructuredParameter {
* @return the newly constructed parameter, ready to be passed to a logging function.
*/
public static KeyValueParameter of(String key, BigInteger value) {
- return new KeyValueParameter(key, Json.createValue(value));
+ return new KeyValueParameter(key, JSON.createValue(value));
}
/**
@@ -141,7 +143,7 @@ public final class KeyValueParameter implements StructuredParameter {
@Override
public JsonObjectBuilder json() {
- return Json.createObjectBuilder().add(key, value);
+ return JSON.createObjectBuilder().add(key, 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..2d08c29 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<String, String> 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<StructuredParameter> parameters,
Map<String, String> 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 {
@@ -78,7 +81,7 @@ final class LogEntry {
if (file != null) {
b.append("\"file\":");
- appendEscapedString(b, file);
+ appendJsonString(b, file);
commaNeeded = true;
}
@@ -87,7 +90,7 @@ final class LogEntry {
b.append(",");
}
b.append("\"line\":");
- appendEscapedString(b, line);
+ appendJsonString(b, line);
commaNeeded = true;
}
@@ -96,7 +99,7 @@ final class LogEntry {
b.append(",");
}
b.append("\"function\":");
- appendEscapedString(b, function);
+ appendJsonString(b, function);
}
}
}
@@ -124,21 +127,28 @@ final class LogEntry {
}
void json(StringBuilder b) {
+
+ if (insertId != null) {
+ b.append("\"logging.googleapis.com/insertId\":");
+ appendJsonString(b, insertId);
+ b.append(",");
+ }
+
if (trace != null) {
b.append("\"logging.googleapis.com/trace\":");
- appendEscapedString(b, trace);
+ appendJsonString(b, trace);
b.append(",");
}
if (spanId != null) {
b.append("\"logging.googleapis.com/spanId\":");
- appendEscapedString(b, spanId);
+ appendJsonString(b, spanId);
b.append(",");
}
if (nestedDiagnosticContext != null && !nestedDiagnosticContext.isEmpty()) {
b.append("\"nestedDiagnosticContext\":");
- appendEscapedString(b, nestedDiagnosticContext);
+ appendJsonString(b, nestedDiagnosticContext);
b.append(",");
}
@@ -153,18 +163,18 @@ final class LogEntry {
first = false;
}
- appendEscapedString(b, entry.getKey());
+ appendJsonString(b, entry.getKey());
b.append(":");
- appendEscapedString(b, entry.getValue());
+ appendJsonString(b, entry.getValue());
}
b.append("},");
}
for (var entry : mappedDiagnosticContext.entrySet()) {
- appendEscapedString(b, entry.getKey());
+ appendJsonString(b, entry.getKey());
b.append(":");
- appendEscapedString(b, entry.getValue());
+ appendJsonString(b, entry.getValue());
b.append(",");
}
@@ -172,7 +182,7 @@ final class LogEntry {
var jsonObject = parameter.json().build();
jsonObject.forEach(
(key, value) -> {
- appendEscapedString(b, key);
+ appendJsonString(b, key);
b.append(":");
appendJsonObject(b, value);
b.append(",");
@@ -181,7 +191,7 @@ final class LogEntry {
if (type != null) {
b.append("\"@type\":");
- appendEscapedString(b, type);
+ appendJsonString(b, type);
b.append(",");
}
@@ -192,17 +202,17 @@ final class LogEntry {
}
b.append("\"message\":");
- appendEscapedString(b, message);
+ appendJsonString(b, message);
b.append(",\"severity\":");
- appendEscapedString(b, severity);
+ appendJsonString(b, severity);
b.append(",\"timestamp\":{");
timestamp.json(b);
b.append("}");
}
- private void appendJsonObject(StringBuilder b, JsonValue value) {
+ private static void appendJsonObject(StringBuilder b, JsonValue value) {
switch (value.getValueType()) {
case ARRAY:
b.append("[");
@@ -226,7 +236,7 @@ final class LogEntry {
} else {
first = false;
}
- appendEscapedString(b, entry.getKey());
+ appendJsonString(b, entry.getKey());
b.append(":");
appendJsonObject(b, entry.getValue());
}
@@ -234,7 +244,7 @@ final class LogEntry {
break;
case STRING:
- appendEscapedString(b, ((JsonString) value).getString());
+ appendJsonString(b, ((JsonString) value).getString());
break;
case NUMBER:
@@ -255,7 +265,7 @@ final class LogEntry {
}
}
- private static void appendEscapedString(StringBuilder b, String s) {
+ private static void appendJsonString(StringBuilder b, String s) {
b.append('"');
for (var i = 0; i < s.length(); i++) {
diff --git a/core/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/package-info.java b/core/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/package-info.java
index 61967a0..a84f1fc 100644
--- a/core/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/package-info.java
+++ b/core/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/package-info.java
@@ -43,7 +43,7 @@
* <dependency>
* <groupId>eu.mulk.quarkus-googlecloud-jsonlogging</groupId>
* <artifactId>quarkus-googlecloud-jsonlogging-core</artifactId>
- * <version>6.4.0</version>
+ * <version>6.5.0</version>
* </dependency>
*
* ...
@@ -59,7 +59,7 @@
* dependencies {
* // ...
*
- * implementation("eu.mulk.quarkus-googlecloud-jsonlogging:quarkus-googlecloud-jsonlogging-core:6.4.0")
+ * implementation("eu.mulk.quarkus-googlecloud-jsonlogging:quarkus-googlecloud-jsonlogging-core:6.5.0")
*
* // ...
* }
diff --git a/core/src/test/java/eu/mulk/quarkus/googlecloud/jsonlogging/FormatterBenchmark.java b/core/src/test/java/eu/mulk/quarkus/googlecloud/jsonlogging/FormatterBenchmark.java
index 78291c1..c330dfe 100644
--- a/core/src/test/java/eu/mulk/quarkus/googlecloud/jsonlogging/FormatterBenchmark.java
+++ b/core/src/test/java/eu/mulk/quarkus/googlecloud/jsonlogging/FormatterBenchmark.java
@@ -1,3 +1,7 @@
+// SPDX-FileCopyrightText: © 2024 Matthias Andreas Benkard <code@mail.matthias.benkard.de>
+//
+// SPDX-License-Identifier: LGPL-3.0-or-later
+
package eu.mulk.quarkus.googlecloud.jsonlogging;
import java.util.List;
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..33df302 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
@@ -1,3 +1,7 @@
+// SPDX-FileCopyrightText: © 2024 Matthias Andreas Benkard <code@mail.matthias.benkard.de>
+//
+// SPDX-License-Identifier: LGPL-3.0-or-later
+
package eu.mulk.quarkus.googlecloud.jsonlogging;
import static org.junit.jupiter.api.Assertions.assertLinesMatch;
@@ -67,6 +71,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 +96,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;
}