From 20210245e619658c2459c77223d9abe3c643a882 Mon Sep 17 00:00:00 2001 From: Matthias Andreas Benkard Date: Sat, 15 Jan 2022 10:39:30 +0100 Subject: Split off -core module. Change-Id: I64d3c195db94e92da44c7e4971f5e85991ac30c8 --- .../quarkus/googlecloud/jsonlogging/Formatter.java | 141 ---------------- .../GoogleCloudJsonLoggingRecorder.java | 33 ---- .../googlecloud/jsonlogging/KeyValueParameter.java | 181 -------------------- .../quarkus/googlecloud/jsonlogging/Label.java | 93 ---------- .../googlecloud/jsonlogging/LabelProvider.java | 45 ----- .../quarkus/googlecloud/jsonlogging/LogEntry.java | 157 ----------------- .../jsonlogging/StructuredParameter.java | 34 ---- .../jsonlogging/StructuredParameterProvider.java | 51 ------ .../googlecloud/jsonlogging/package-info.java | 188 --------------------- .../runtime/GoogleCloudJsonLoggingRecorder.java | 36 ++++ .../jsonlogging/runtime/package-info.java | 71 ++++++++ 11 files changed, 107 insertions(+), 923 deletions(-) delete mode 100644 runtime/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/Formatter.java delete mode 100644 runtime/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/GoogleCloudJsonLoggingRecorder.java delete mode 100644 runtime/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/KeyValueParameter.java delete mode 100644 runtime/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/Label.java delete mode 100644 runtime/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/LabelProvider.java delete mode 100644 runtime/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/LogEntry.java delete mode 100644 runtime/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/StructuredParameter.java delete mode 100644 runtime/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/StructuredParameterProvider.java delete mode 100644 runtime/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/package-info.java create mode 100644 runtime/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/runtime/GoogleCloudJsonLoggingRecorder.java create mode 100644 runtime/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/runtime/package-info.java (limited to 'runtime/src/main') diff --git a/runtime/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/Formatter.java b/runtime/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/Formatter.java deleted file mode 100644 index 066f709..0000000 --- a/runtime/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/Formatter.java +++ /dev/null @@ -1,141 +0,0 @@ -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.logging.Level; -import org.jboss.logmanager.ExtFormatter; -import org.jboss.logmanager.ExtLogRecord; - -/** - * Formats log records as JSON for consumption by Google Cloud Logging. - * - *

Meant to be used in containers running on Google Kubernetes Engine (GKE). - * - * @see LogEntry - */ -public class Formatter extends ExtFormatter { - - private static final String TRACE_LEVEL = "TRACE"; - private static final String DEBUG_LEVEL = "DEBUG"; - private static final String INFO_LEVEL = "INFO"; - private static final String WARNING_LEVEL = "WARNING"; - private static final String ERROR_LEVEL = "ERROR"; - - private static final String ERROR_EVENT_TYPE = - "type.googleapis.com/google.devtools.clouderrorreporting.v1beta1.ReportedErrorEvent"; - - private final List parameterProviders; - private final List labelProviders; - - /** - * Constructs a {@link Formatter}. - * - * @param parameterProviders the {@link StructuredParameterProvider}s to apply to each log entry. - * @param labelProviders the {@link LabelProvider}s to apply to each log entry. - */ - public Formatter( - Collection parameterProviders, - Collection labelProviders) { - this.parameterProviders = List.copyOf(parameterProviders); - this.labelProviders = List.copyOf(labelProviders); - } - - @Override - public String format(ExtLogRecord logRecord) { - var message = formatMessageWithStackTrace(logRecord); - - List parameters = new ArrayList<>(); - Map labels = new HashMap<>(); - - for (var parameterProvider : parameterProviders) { - var parameter = parameterProvider.getParameter(); - if (parameter != null) { - parameters.add(parameter); - } - } - - for (var labelProvider : labelProviders) { - var providedLabels = labelProvider.getLabels(); - if (providedLabels != null) { - for (var label : providedLabels) { - labels.put(label.key(), label.value()); - } - } - } - - if (logRecord.getParameters() != null) { - for (var parameter : logRecord.getParameters()) { - if (parameter instanceof StructuredParameter) { - parameters.add((StructuredParameter) parameter); - } else if (parameter instanceof Label) { - var label = (Label) parameter; - labels.put(label.key(), label.value()); - } - } - } - - var mdc = logRecord.getMdcCopy(); - var ndc = logRecord.getNdc(); - - var sourceLocation = - new LogEntry.SourceLocation( - logRecord.getSourceFileName(), - String.valueOf(logRecord.getSourceLineNumber()), - String.format( - "%s.%s", logRecord.getSourceClassName(), logRecord.getSourceMethodName())); - - var entry = - new LogEntry( - message, - severityOf(logRecord.getLevel()), - new LogEntry.Timestamp(logRecord.getInstant()), - null, - null, - sourceLocation, - labels, - parameters, - mdc, - ndc, - logRecord.getLevel().intValue() >= 1000 ? ERROR_EVENT_TYPE : null); - - return entry.json().build().toString() + "\n"; - } - - /** - * Formats the log message corresponding to {@code logRecord} including a stack trace of the - * {@link ExtLogRecord#getThrown()} exception if any. - */ - private String formatMessageWithStackTrace(ExtLogRecord logRecord) { - var messageStringWriter = new StringWriter(); - var messagePrintWriter = new PrintWriter(messageStringWriter); - messagePrintWriter.append(this.formatMessage(logRecord)); - - if (logRecord.getThrown() != null) { - messagePrintWriter.println(); - logRecord.getThrown().printStackTrace(messagePrintWriter); - } - - messagePrintWriter.close(); - return messageStringWriter.toString(); - } - - /** Computes the Google Cloud Logging severity corresponding to a given {@link Level}. */ - private static String severityOf(Level level) { - if (level.intValue() < 500) { - return TRACE_LEVEL; - } else if (level.intValue() < 700) { - return DEBUG_LEVEL; - } else if (level.intValue() < 900) { - return INFO_LEVEL; - } else if (level.intValue() < 1000) { - return WARNING_LEVEL; - } else { - return ERROR_LEVEL; - } - } -} diff --git a/runtime/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/GoogleCloudJsonLoggingRecorder.java b/runtime/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/GoogleCloudJsonLoggingRecorder.java deleted file mode 100644 index 7234a71..0000000 --- a/runtime/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/GoogleCloudJsonLoggingRecorder.java +++ /dev/null @@ -1,33 +0,0 @@ -package eu.mulk.quarkus.googlecloud.jsonlogging; - -import io.quarkus.arc.Arc; -import io.quarkus.runtime.RuntimeValue; -import io.quarkus.runtime.annotations.Recorder; -import java.util.Collection; -import java.util.Optional; -import java.util.stream.Collectors; - -/** A Quarkus recorder that registers {@link Formatter} as a log formatter for the application. */ -@Recorder -public class GoogleCloudJsonLoggingRecorder { - - /** - * Registers {@link Formatter} as a log formatter for the application. - * - *

Collects all discoverable {@link StructuredParameterProvider}s and {@link LabelProvider}s - * and passes them to {@link Formatter#Formatter(Collection, Collection)}. - * - * @return the registered {@link Formatter}. - */ - public RuntimeValue> initialize() { - - var parameterProviders = - Arc.container().select(StructuredParameterProvider.class).stream() - .collect(Collectors.toList()); - - var labelProviders = - Arc.container().select(LabelProvider.class).stream().collect(Collectors.toList()); - - return new RuntimeValue<>(Optional.of(new Formatter(parameterProviders, labelProviders))); - } -} diff --git a/runtime/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/KeyValueParameter.java b/runtime/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/KeyValueParameter.java deleted file mode 100644 index a5924b4..0000000 --- a/runtime/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/KeyValueParameter.java +++ /dev/null @@ -1,181 +0,0 @@ -package eu.mulk.quarkus.googlecloud.jsonlogging; - -import java.math.BigDecimal; -import java.math.BigInteger; -import java.util.Objects; -import javax.json.Json; -import javax.json.JsonObjectBuilder; -import javax.json.JsonValue; - -/** - * A simple single key–value pair forming a {@link StructuredParameter}. - * - *

This class is suitable for the common case of logging a key–value pair as parameter to the - * {@code *f} family of logging functions on {@link org.jboss.logging.Logger}. For advanced use - * cases, provide your own implementation of {@link StructuredParameter}. - * - *

Example: - * - *

{@code
- * logger.infof("Application starting.", StructuredParameter.of("version", "1.0"));
- * }
- * - * Result: - * - *
{@code
- * {
- *   "jsonPayload": {
- *     "message": "Application starting.",
- *     "version": "1.0"
- *   }
- * }
- * }
- * - * @see Label - * @see StructuredParameter - */ -public final class KeyValueParameter implements StructuredParameter { - - private final String key; - private final JsonValue value; - - private KeyValueParameter(String key, JsonValue value) { - this.key = key; - this.value = value; - } - - /** - * Creates a {@link KeyValueParameter} from a {@link String} value. - * - *

The resulting JSON value is of type {@code string}. - * - * @param key the key part of the key–value pair. - * @param value the value part of the key–value pair. - * @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)); - } - - /** - * Creates a {@link KeyValueParameter} from an {@code int} value. - * - *

The resulting JSON value is of type {@code number}. - * - * @param key the key part of the key–value pair. - * @param value the value part of the key–value pair. - * @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)); - } - - /** - * Creates a {@link KeyValueParameter} from a {@code long} value. - * - *

The resulting JSON value is of type {@code number}. - * - * @param key the key part of the key–value pair. - * @param value the value part of the key–value pair. - * @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)); - } - - /** - * Creates a {@link KeyValueParameter} from a {@code double} value. - * - *

The resulting JSON value is of type {@code number}. - * - * @param key the key part of the key–value pair. - * @param value the value part of the key–value pair. - * @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)); - } - - /** - * Creates a {@link KeyValueParameter} from a {@link BigDecimal} value. - * - *

The resulting JSON value is of type {@code number}. - * - * @param key the key part of the key–value pair. - * @param value the value part of the key–value pair. - * @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)); - } - - /** - * Creates a {@link KeyValueParameter} from a {@link BigInteger} value. - * - *

The resulting JSON value is of type {@code number}. - * - * @param key the key part of the key–value pair. - * @param value the value part of the key–value pair. - * @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)); - } - - /** - * Creates a {@link KeyValueParameter} from a {@code boolean} value. - * - *

The resulting JSON value is of type {@code boolean}. - * - * @param key the key part of the key–value pair. - * @param value the value part of the key–value pair. - * @return the newly constructed parameter, ready to be passed to a logging function. - */ - public static KeyValueParameter of(String key, boolean value) { - return new KeyValueParameter(key, value ? JsonValue.TRUE : JsonValue.FALSE); - } - - @Override - public JsonObjectBuilder json() { - return Json.createObjectBuilder().add(key, value); - } - - /** - * The key part of the key–value pair. - * - * @return the key part of the key–value pair. - */ - public String key() { - return key; - } - - /** - * The value part of the key–value pair. - * - *

Can be of any non-composite JSON type (i.e. {@code string}, {@code number}, or {@code - * boolean}). - * - * @return the value pairt of the key–value pair. - */ - public JsonValue 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 = (KeyValueParameter) obj; - return Objects.equals(this.key, that.key) && Objects.equals(this.value, that.value); - } - - @Override - public int hashCode() { - return Objects.hash(key, value); - } - - @Override - public String toString() { - return "KeyValueParameter[" + "key=" + key + ", " + "value=" + value + ']'; - } -} diff --git a/runtime/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/Label.java b/runtime/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/Label.java deleted file mode 100644 index 33664dd..0000000 --- a/runtime/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/Label.java +++ /dev/null @@ -1,93 +0,0 @@ -package eu.mulk.quarkus.googlecloud.jsonlogging; - -import java.util.Objects; - -/** - * A label usable to tag a log message. - * - *

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

Example: - * - *

{@code
- * logger.logf("Request rejected: unauthorized.", Label.of("requestId", "123"));
- * }
- * - * Result: - * - *
{@code
- * {
- *   "textPayload": "Request rejected: unauthorized.",
- *   "labels": {
- *     "requestId": "123"
- *   }
- * }
- * }
- * - * @see KeyValueParameter - * @see StructuredParameter - */ -public final class Label { - - private final String key; - private final String value; - - private Label(String key, String value) { - this.key = key; - this.value = value; - } - - /** - * Constructs a {@link Label} from a key (i.e. name) and a value. - * - *

It is often useful for the key to be a {@link String} constant that is shared by multiple - * parts of the program. - * - * @param key the key (name) of the label. - * @param value the value of the label. - * @return the newly constructed {@link Label}, ready to be passed to a logging function. - */ - public static Label of(String key, String value) { - return new Label(key, value); - } - - /** - * The name of the label. - * - *

It is often useful for this to be a {@link String} constant that is shared by multiple parts - * of the program. - * - * @return the name of the label. - */ - public String key() { - return key; - } - - /** - * 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 = (Label) obj; - return Objects.equals(this.key, that.key) && Objects.equals(this.value, that.value); - } - - @Override - public int hashCode() { - return Objects.hash(key, value); - } - - @Override - public String toString() { - return "Label[" + "key=" + key + ", " + "value=" + value + ']'; - } -} diff --git a/runtime/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/LabelProvider.java b/runtime/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/LabelProvider.java deleted file mode 100644 index dbd035c..0000000 --- a/runtime/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/LabelProvider.java +++ /dev/null @@ -1,45 +0,0 @@ -package eu.mulk.quarkus.googlecloud.jsonlogging; - -import java.util.Collection; - -/** - * A user-supplied provider for {@link Label}s. - * - *

Any CDI beans registered under this class are applied to each log entry that is logged. - * - *

Example: - * - *

{@code
- * @Singleton
- * @Unremovable
- * public final class RequestIdLabelProvider implements LabelProvider {
- *
- *   @Override
- *   public Collection
- * - * Result: - * - *
{@code
- * {
- *   "textPayload": "Request rejected: unauthorized.",
- *   "labels": {
- *     "requestId": "123"
- *   }
- * }
- * }
- * - * @see StructuredParameterProvider - */ -public interface LabelProvider { - - /** - * Provides a collection of {@link Label}s to add to each log entry that is logged. - * - * @return a collection of {@link Label}s to add to each log entry that is logged. - */ - Collection