From d2280ad9e239fb686bcc1df74fa465dba50b235c Mon Sep 17 00:00:00 2001 From: Matthias Andreas Benkard Date: Sun, 23 Jun 2024 17:08:58 +0200 Subject: perf: Reuse a single JsonProvider. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This speeds up the formatter significantly. Before: Benchmark Mode Cnt Score Error Units FormatterBenchmark.massivelyStructuredLogRecord thrpt 10 6552.727 ± 2169.572 ops/s FormatterBenchmark.simpleLogRecord thrpt 10 8126.699 ± 2259.912 ops/s FormatterBenchmark.structuredLogRecord thrpt 10 5594.849 ± 1129.151 ops/s After: Benchmark Mode Cnt Score Error Units FormatterBenchmark.massivelyStructuredLogRecord thrpt 10 137879.001 ± 30467.644 ops/s FormatterBenchmark.simpleLogRecord thrpt 10 896085.217 ± 249890.421 ops/s FormatterBenchmark.structuredLogRecord thrpt 10 553428.807 ± 194787.754 ops/s Change-Id: If184327a4ff0de0d92b769493dbf6270ba3a8c8e --- .../quarkus/googlecloud/jsonlogging/Formatter.java | 5 +++- .../quarkus/googlecloud/jsonlogging/LogEntry.java | 33 +++++++++++----------- .../googlecloud/jsonlogging/FormatterTest.java | 10 ++++--- 3 files changed, 27 insertions(+), 21 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 c4e36de..72b0b50 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 @@ -4,6 +4,7 @@ package eu.mulk.quarkus.googlecloud.jsonlogging; +import jakarta.json.spi.JsonProvider; import java.io.PrintWriter; import java.io.StringWriter; import java.util.ArrayList; @@ -38,6 +39,7 @@ public class Formatter extends ExtFormatter { private final List parameterProviders; private final List labelProviders; + private final JsonProvider json; /** * Constructs a {@link Formatter} with custom configuration. @@ -53,6 +55,7 @@ public class Formatter extends ExtFormatter { Collection labelProviders) { this.parameterProviders = List.copyOf(parameterProviders); this.labelProviders = List.copyOf(labelProviders); + this.json = JsonProvider.provider(); } /** @@ -152,7 +155,7 @@ public class Formatter extends ExtFormatter { ndc, logRecord.getLevel().intValue() >= 1000 ? ERROR_EVENT_TYPE : null); - return entry.json().build().toString() + "\n"; + return entry.json(json).build().toString() + "\n"; } /** 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 5655373..8517bde 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 @@ -5,9 +5,9 @@ package eu.mulk.quarkus.googlecloud.jsonlogging; import io.smallrye.common.constraint.Nullable; -import jakarta.json.Json; import jakarta.json.JsonObject; import jakarta.json.JsonObjectBuilder; +import jakarta.json.spi.JsonProvider; import java.time.Instant; import java.util.List; import java.util.Map; @@ -74,8 +74,8 @@ final class LogEntry { this.function = function; } - JsonObject json() { - var b = Json.createObjectBuilder(); + JsonObject json(JsonProvider json) { + var b = json.createObjectBuilder(); if (file != null) { b.add("file", file); @@ -107,13 +107,13 @@ final class LogEntry { this(t.getEpochSecond(), t.getNano()); } - JsonObject json() { - return Json.createObjectBuilder().add("seconds", seconds).add("nanos", nanos).build(); + JsonObject json(JsonProvider json) { + return json.createObjectBuilder().add("seconds", seconds).add("nanos", nanos).build(); } } - JsonObjectBuilder json() { - var b = Json.createObjectBuilder(); + JsonObjectBuilder json(JsonProvider json) { + var b = json.createObjectBuilder(); if (trace != null) { b.add("logging.googleapis.com/trace", trace); @@ -128,7 +128,7 @@ final class LogEntry { } if (!labels.isEmpty()) { - b.add("logging.googleapis.com/labels", jsonOfStringMap(labels)); + b.add("logging.googleapis.com/labels", jsonOfStringMap(json, labels)); } if (type != null) { @@ -137,24 +137,25 @@ final class LogEntry { return b.add("message", message) .add("severity", severity) - .add("timestamp", timestamp.json()) - .add("logging.googleapis.com/sourceLocation", sourceLocation.json()) - .addAll(jsonOfStringMap(mappedDiagnosticContext)) - .addAll(jsonOfParameterMap(parameters)); + .add("timestamp", timestamp.json(json)) + .add("logging.googleapis.com/sourceLocation", sourceLocation.json(json)) + .addAll(jsonOfStringMap(json, mappedDiagnosticContext)) + .addAll(jsonOfParameterMap(json, parameters)); } - private static JsonObjectBuilder jsonOfStringMap(Map stringMap) { + private JsonObjectBuilder jsonOfStringMap(JsonProvider json, Map stringMap) { return stringMap.entrySet().stream() .reduce( - Json.createObjectBuilder(), + json.createObjectBuilder(), (acc, x) -> acc.add(x.getKey(), x.getValue()), JsonObjectBuilder::addAll); } - private static JsonObjectBuilder jsonOfParameterMap(List parameters) { + private JsonObjectBuilder jsonOfParameterMap( + JsonProvider json, List parameters) { return parameters.stream() .reduce( - Json.createObjectBuilder(), + json.createObjectBuilder(), (acc, p) -> acc.addAll(p.json()), JsonObjectBuilder::addAll); } 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 b755230..6d40b15 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 @@ -2,7 +2,7 @@ package eu.mulk.quarkus.googlecloud.jsonlogging; import static org.junit.jupiter.api.Assertions.assertLinesMatch; -import jakarta.json.Json; +import jakarta.json.spi.JsonProvider; import java.util.Collection; import java.util.List; import org.jboss.logmanager.ExtLogRecord; @@ -11,6 +11,8 @@ import org.junit.jupiter.api.Test; class FormatterTest { + private static final JsonProvider JSON = JsonProvider.provider(); + @Test void simpleRecord() { var logRecord = makeSimpleRecord(); @@ -43,7 +45,7 @@ class FormatterTest { new StructuredParameterProvider() { @Override public StructuredParameter getParameter() { - var b = Json.createObjectBuilder(); + var b = JSON.createObjectBuilder(); b.add("traceId", "39f9a49a9567a8bd7087b708f8932550"); b.add("spanId", "c7431b14630b633d"); return () -> b; @@ -88,7 +90,7 @@ class FormatterTest { logRecord.setParameters( new Object[] { (StructuredParameter) - () -> Json.createObjectBuilder().add("one", 1).add("two", 2.0).add("yes", true), + () -> JSON.createObjectBuilder().add("one", 1).add("two", 2.0).add("yes", true), Label.of("a", "b") }); return logRecord; @@ -128,7 +130,7 @@ class FormatterTest { new Object[] { (StructuredParameter) () -> { - var b = Json.createObjectBuilder(); + var b = JSON.createObjectBuilder(); for (int i = 0; i < 10; i++) { b.add("int-" + i, i); } -- cgit v1.2.3