diff options
Diffstat (limited to 'core/src')
12 files changed, 102 insertions, 75 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 0b2003d..9c66f82 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 @@ -6,17 +6,13 @@ package eu.mulk.quarkus.googlecloud.jsonlogging; import java.io.PrintWriter; import java.io.StringWriter; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.ServiceLoader; +import java.util.*; import java.util.ServiceLoader.Provider; import java.util.logging.Level; import java.util.stream.Collectors; import org.jboss.logmanager.ExtFormatter; import org.jboss.logmanager.ExtLogRecord; +import org.jspecify.annotations.Nullable; /** * Formats log records as JSON for consumption by Google Cloud Logging. @@ -42,7 +38,7 @@ public class Formatter extends ExtFormatter { private final List<StructuredParameterProvider> parameterProviders; private final List<LabelProvider> labelProviders; - private final ThreadLocal<StringBuilder> stringBuilder; + private final ThreadLocal<@Nullable StringBuilder> stringBuilder; /** * Constructs a {@link Formatter} with custom configuration. @@ -125,8 +121,9 @@ public class Formatter extends ExtFormatter { String insertId = null; - if (logRecord.getParameters() != null) { - for (var parameter : logRecord.getParameters()) { + var logRecordParameters = logRecord.getParameters(); + if (logRecordParameters != null) { + for (var parameter : logRecordParameters) { if (parameter instanceof StructuredParameter) { parameters.add((StructuredParameter) parameter); } else if (parameter instanceof Label) { @@ -158,7 +155,7 @@ public class Formatter extends ExtFormatter { logRecord.getLevel().intValue() >= 1000 ? ERROR_EVENT_TYPE : null, insertId); - var b = stringBuilder.get(); + var b = Objects.requireNonNull(stringBuilder.get()); b.delete(0, b.length()); b.append("{"); entry.json(b); @@ -166,7 +163,7 @@ public class Formatter extends ExtFormatter { return b.toString(); } - private static LogEntry.SourceLocation sourceLocationOf(ExtLogRecord logRecord) { + private static LogEntry.@Nullable SourceLocation sourceLocationOf(ExtLogRecord logRecord) { var sourceFileName = logRecord.getSourceFileName(); var sourceLineNumber = logRecord.getSourceLineNumber(); var sourceClassName = logRecord.getSourceClassName(); @@ -191,9 +188,10 @@ public class Formatter extends ExtFormatter { var messagePrintWriter = new PrintWriter(messageStringWriter); messagePrintWriter.append(this.formatMessage(logRecord)); - if (logRecord.getThrown() != null) { + var logRecordThrown = logRecord.getThrown(); + if (logRecordThrown != null) { messagePrintWriter.println(); - logRecord.getThrown().printStackTrace(messagePrintWriter); + logRecordThrown.printStackTrace(messagePrintWriter); } messagePrintWriter.close(); @@ -230,9 +228,9 @@ public class Formatter extends ExtFormatter { private static class ProviderContext implements LabelProvider.Context, StructuredParameterProvider.Context { - private final String loggerName; + private final @Nullable String loggerName; private final long sequenceNumber; - private final String threadName; + private final @Nullable String threadName; private ProviderContext(ExtLogRecord logRecord) { loggerName = logRecord.getLoggerName(); @@ -241,7 +239,7 @@ public class Formatter extends ExtFormatter { } @Override - public String loggerName() { + public @Nullable String loggerName() { return loggerName; } @@ -251,7 +249,7 @@ public class Formatter extends ExtFormatter { } @Override - public String threadName() { + public @Nullable String threadName() { return threadName; } } 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 index 9c2bb23..48b376c 100644 --- a/core/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/InsertId.java +++ b/core/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/InsertId.java @@ -1,21 +1,22 @@ -// SPDX-FileCopyrightText: © 2021 Matthias Andreas Benkard <code@mail.matthias.benkard.de> +// 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; +import org.jspecify.annotations.Nullable; /** * 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>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>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> * @@ -63,7 +64,7 @@ public final class InsertId { } @Override - public boolean equals(Object obj) { + public boolean equals(@Nullable Object obj) { if (obj == this) return true; if (obj == null || obj.getClass() != this.getClass()) return false; var that = (InsertId) obj; 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..9e16aab 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,12 +4,13 @@ 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; +import org.jspecify.annotations.Nullable; /** * A simple single key–value pair forming a {@link StructuredParameter}. @@ -40,6 +41,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 +61,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 +74,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 +87,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 +100,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 +113,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 +126,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 +144,7 @@ public final class KeyValueParameter implements StructuredParameter { @Override public JsonObjectBuilder json() { - return Json.createObjectBuilder().add(key, value); + return JSON.createObjectBuilder().add(key, value); } /** @@ -166,7 +169,7 @@ public final class KeyValueParameter implements StructuredParameter { } @Override - public boolean equals(Object obj) { + public boolean equals(@Nullable Object obj) { if (obj == this) return true; if (obj == null || obj.getClass() != this.getClass()) return false; var that = (KeyValueParameter) obj; diff --git a/core/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/Label.java b/core/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/Label.java index d5a9000..2696185 100644 --- a/core/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/Label.java +++ b/core/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/Label.java @@ -5,6 +5,7 @@ package eu.mulk.quarkus.googlecloud.jsonlogging; import java.util.Objects; +import org.jspecify.annotations.Nullable; /** * A label usable to tag a log message. @@ -78,7 +79,7 @@ public final class Label { } @Override - public boolean equals(Object obj) { + public boolean equals(@Nullable Object obj) { if (obj == this) return true; if (obj == null || obj.getClass() != this.getClass()) return false; var that = (Label) obj; diff --git a/core/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/LabelProvider.java b/core/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/LabelProvider.java index 0298042..2bc0349 100644 --- a/core/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/LabelProvider.java +++ b/core/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/LabelProvider.java @@ -5,6 +5,7 @@ package eu.mulk.quarkus.googlecloud.jsonlogging; import java.util.Collection; +import org.jspecify.annotations.Nullable; /** * A user-supplied provider for {@link Label}s. @@ -52,7 +53,7 @@ public interface LabelProvider { * @return a collection of {@link Label}s to add to each log entry that is logged. * @see #getLabels(Context) */ - default Collection<Label> getLabels() { + default @Nullable Collection<Label> getLabels() { return null; } @@ -63,7 +64,7 @@ public interface LabelProvider { * * @return a collection of {@link Label}s to add to each log entry that is logged. */ - default Collection<Label> getLabels(Context context) { + default @Nullable Collection<Label> getLabels(Context context) { return getLabels(); } 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 5d4d9cf..d335ee4 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 @@ -4,12 +4,12 @@ package eu.mulk.quarkus.googlecloud.jsonlogging; -import io.smallrye.common.constraint.Nullable; import jakarta.json.JsonString; import jakarta.json.JsonValue; import java.time.Instant; import java.util.List; import java.util.Map; +import org.jspecify.annotations.Nullable; /** * A JSON log entry compatible with Google Cloud Logging. @@ -27,15 +27,15 @@ final class LogEntry { private final String message; private final String severity; private final Timestamp timestamp; - @Nullable private final String trace; - @Nullable private final String spanId; - @Nullable private final SourceLocation sourceLocation; + private final @Nullable String trace; + private final @Nullable String spanId; + private final @Nullable SourceLocation sourceLocation; private final Map<String, String> labels; private final List<StructuredParameter> parameters; private final Map<String, String> mappedDiagnosticContext; - @Nullable private final String nestedDiagnosticContext; - @Nullable private final String type; - @Nullable private final String insertId; + private final @Nullable String nestedDiagnosticContext; + private final @Nullable String type; + private final @Nullable String insertId; LogEntry( String message, @@ -66,9 +66,9 @@ final class LogEntry { static final class SourceLocation { - @Nullable private final String file; - @Nullable private final String line; - @Nullable private final String function; + private final @Nullable String file; + private final @Nullable String line; + private final @Nullable String function; SourceLocation(@Nullable String file, @Nullable String line, @Nullable String function) { this.file = file; @@ -81,7 +81,7 @@ final class LogEntry { if (file != null) { b.append("\"file\":"); - appendEscapedString(b, file); + appendJsonString(b, file); commaNeeded = true; } @@ -90,7 +90,7 @@ final class LogEntry { b.append(","); } b.append("\"line\":"); - appendEscapedString(b, line); + appendJsonString(b, line); commaNeeded = true; } @@ -99,7 +99,7 @@ final class LogEntry { b.append(","); } b.append("\"function\":"); - appendEscapedString(b, function); + appendJsonString(b, function); } } } @@ -130,25 +130,25 @@ final class LogEntry { if (insertId != null) { b.append("\"logging.googleapis.com/insertId\":"); - appendEscapedString(b, 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(","); } @@ -163,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(","); } @@ -182,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(","); @@ -191,7 +191,7 @@ final class LogEntry { if (type != null) { b.append("\"@type\":"); - appendEscapedString(b, type); + appendJsonString(b, type); b.append(","); } @@ -202,10 +202,10 @@ 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); @@ -236,7 +236,7 @@ final class LogEntry { } else { first = false; } - appendEscapedString(b, entry.getKey()); + appendJsonString(b, entry.getKey()); b.append(":"); appendJsonObject(b, entry.getValue()); } @@ -244,7 +244,7 @@ final class LogEntry { break; case STRING: - appendEscapedString(b, ((JsonString) value).getString()); + appendJsonString(b, ((JsonString) value).getString()); break; case NUMBER: @@ -265,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/ProviderContext.java b/core/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/ProviderContext.java index 08b399a..93f7a7a 100644 --- a/core/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/ProviderContext.java +++ b/core/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/ProviderContext.java @@ -5,6 +5,7 @@ package eu.mulk.quarkus.googlecloud.jsonlogging; import org.jboss.logmanager.ExtLogRecord; +import org.jspecify.annotations.Nullable; /** * Contextual data available to {@link StructuredParameterProvider} and {@link LabelProvider}. @@ -19,7 +20,7 @@ public interface ProviderContext { * * @return {@link ExtLogRecord#getLoggerName()}. */ - String loggerName(); + @Nullable String loggerName(); /** * The {@link ExtLogRecord#getSequenceNumber()} property of the log record that is being @@ -34,5 +35,5 @@ public interface ProviderContext { * * @return {@link ExtLogRecord#getThreadName()}. */ - String threadName(); + @Nullable String threadName(); } diff --git a/core/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/StructuredParameterProvider.java b/core/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/StructuredParameterProvider.java index d78f0d8..c02516c 100644 --- a/core/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/StructuredParameterProvider.java +++ b/core/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/StructuredParameterProvider.java @@ -4,6 +4,8 @@ package eu.mulk.quarkus.googlecloud.jsonlogging; +import org.jspecify.annotations.Nullable; + /** * A user-supplied provider for {@link StructuredParameter}s. * @@ -58,7 +60,7 @@ public interface StructuredParameterProvider { * @return a {@link StructuredParameter} to add to each log entry that is logged. * @see #getParameter(Context) */ - default StructuredParameter getParameter() { + default @Nullable StructuredParameter getParameter() { return null; } @@ -73,7 +75,7 @@ public interface StructuredParameterProvider { * * @return a {@link StructuredParameter} to add to each log entry that is logged. */ - default StructuredParameter getParameter(Context context) { + default @Nullable StructuredParameter getParameter(Context context) { return getParameter(); } diff --git a/core/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/logmanager/package-info.java b/core/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/logmanager/package-info.java index 3b6f38c..d36dfc1 100644 --- a/core/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/logmanager/package-info.java +++ b/core/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/logmanager/package-info.java @@ -19,4 +19,7 @@ * when used in conjunction with frameworks other than Quarkus (such as Spring Boot). See the class * documentation for details. */ +@NullMarked package eu.mulk.quarkus.googlecloud.jsonlogging.logmanager; + +import org.jspecify.annotations.NullMarked; 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..17133c4 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.6.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.6.0") * * // ... * } @@ -198,4 +198,7 @@ * } * } */ +@NullMarked package eu.mulk.quarkus.googlecloud.jsonlogging; + +import org.jspecify.annotations.NullMarked; 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..7bbdac6 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,7 +1,14 @@ +// 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 java.util.logging.Level.FINEST; + import java.util.List; -import org.jboss.logmanager.ExtLogRecord; +import java.util.logging.LogRecord; +import org.jboss.logmanager.formatters.Formatters; import org.openjdk.jmh.annotations.*; import org.openjdk.jmh.infra.Blackhole; @@ -11,11 +18,14 @@ import org.openjdk.jmh.infra.Blackhole; @State(org.openjdk.jmh.annotations.Scope.Benchmark) public class FormatterBenchmark { - private ExtLogRecord simpleLogRecord; - private ExtLogRecord structuredLogRecord; - private ExtLogRecord massivelyStructuredLogRecord; - private ExtLogRecord nestedLogRecord; - private Formatter formatter; + private static final LogRecord NULL_LOG_RECORD = new LogRecord(FINEST, ""); + private static final java.util.logging.Formatter NULL_FORMATTER = Formatters.nullFormatter(); + + private LogRecord simpleLogRecord = NULL_LOG_RECORD; + private LogRecord structuredLogRecord = NULL_LOG_RECORD; + private LogRecord massivelyStructuredLogRecord = NULL_LOG_RECORD; + private LogRecord nestedLogRecord = NULL_LOG_RECORD; + private java.util.logging.Formatter formatter = NULL_FORMATTER; @Setup public void setup() { 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 d202fd9..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; |