diff options
| author | Matthias Andreas Benkard <code@mail.matthias.benkard.de> | 2022-01-15 10:39:30 +0100 | 
|---|---|---|
| committer | Matthias Andreas Benkard <code@mail.matthias.benkard.de> | 2022-01-15 10:39:30 +0100 | 
| commit | 20210245e619658c2459c77223d9abe3c643a882 (patch) | |
| tree | 7b5dbdab7bdd5fb3422afbbe616feee6084127c9 /runtime/src/main | |
| parent | 85d5b06d724b36232349e1b2cefe100f2f9ac598 (diff) | |
Split off -core module.
Change-Id: I64d3c195db94e92da44c7e4971f5e85991ac30c8
Diffstat (limited to 'runtime/src/main')
10 files changed, 75 insertions, 891 deletions
| 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. - * - * <p>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<StructuredParameterProvider> parameterProviders; -  private final List<LabelProvider> 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<StructuredParameterProvider> parameterProviders, -      Collection<LabelProvider> labelProviders) { -    this.parameterProviders = List.copyOf(parameterProviders); -    this.labelProviders = List.copyOf(labelProviders); -  } - -  @Override -  public String format(ExtLogRecord logRecord) { -    var message = formatMessageWithStackTrace(logRecord); - -    List<StructuredParameter> parameters = new ArrayList<>(); -    Map<String, String> 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/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}. - * - * <p>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}. - * - * <p><strong>Example:</strong> - * - * <pre>{@code - * logger.infof("Application starting.", StructuredParameter.of("version", "1.0")); - * }</pre> - * - * Result: - * - * <pre>{@code - * { - *   "jsonPayload": { - *     "message": "Application starting.", - *     "version": "1.0" - *   } - * } - * }</pre> - * - * @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. -   * -   * <p>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. -   * -   * <p>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. -   * -   * <p>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. -   * -   * <p>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. -   * -   * <p>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. -   * -   * <p>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. -   * -   * <p>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. -   * -   * <p>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. - * - * <p>Instances of {@link Label} can be passed as log parameters to the {@code *f} family of logging - * functions on {@link org.jboss.logging.Logger}. - * - * <p><strong>Example:</strong> - * - * <pre>{@code - * logger.logf("Request rejected: unauthorized.", Label.of("requestId", "123")); - * }</pre> - * - * Result: - * - * <pre>{@code - * { - *   "textPayload": "Request rejected: unauthorized.", - *   "labels": { - *     "requestId": "123" - *   } - * } - * }</pre> - * - * @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. -   * -   * <p>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. -   * -   * <p>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. - * - * <p>Any CDI beans registered under this class are applied to each log entry that is logged. - * - * <p><strong>Example:</strong> - * - * <pre>{@code - * @Singleton - * @Unremovable - * public final class RequestIdLabelProvider implements LabelProvider { - * - *   @Override - *   public Collection<Label> getLabels() { - *     return List.of(Label.of("requestId", RequestContext.current().getRequestId())); - *   } - * } - * }</pre> - * - * Result: - * - * <pre>{@code - * { - *   "textPayload": "Request rejected: unauthorized.", - *   "labels": { - *     "requestId": "123" - *   } - * } - * }</pre> - * - * @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<Label> getLabels(); -} diff --git a/runtime/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/LogEntry.java b/runtime/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/LogEntry.java deleted file mode 100644 index d108c81..0000000 --- a/runtime/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/LogEntry.java +++ /dev/null @@ -1,157 +0,0 @@ -package eu.mulk.quarkus.googlecloud.jsonlogging; - -import io.smallrye.common.constraint.Nullable; -import java.time.Instant; -import java.util.List; -import java.util.Map; -import javax.json.Json; -import javax.json.JsonObject; -import javax.json.JsonObjectBuilder; - -/** - * A JSON log entry compatible with Google Cloud Logging. - * - * <p>Roughly (but not quite) corresponds to Google Cloud Logging's <a - * href="https://cloud.google.com/logging/docs/reference/v2/rest/v2/LogEntry">LogEntry</a> - * structure. - * - * <p>A few of the fields are <a href="https://cloud.google.com/logging/docs/structured-logging"> - * treated specially</a> by the fluentd instance running in Google Kubernetes Engine. All other - * fields end up in the jsonPayload field on the Google Cloud Logging side. - */ -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; -  private final 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; - -  LogEntry( -      String message, -      String severity, -      Timestamp timestamp, -      @Nullable String trace, -      @Nullable String spanId, -      SourceLocation sourceLocation, -      Map<String, String> labels, -      List<StructuredParameter> parameters, -      Map<String, String> mappedDiagnosticContext, -      @Nullable String nestedDiagnosticContext, -      @Nullable String type) { -    this.message = message; -    this.severity = severity; -    this.timestamp = timestamp; -    this.trace = trace; -    this.spanId = spanId; -    this.sourceLocation = sourceLocation; -    this.labels = labels; -    this.parameters = parameters; -    this.mappedDiagnosticContext = mappedDiagnosticContext; -    this.nestedDiagnosticContext = nestedDiagnosticContext; -    this.type = type; -  } - -  static final class SourceLocation { - -    @Nullable private final String file; -    @Nullable private final String line; -    @Nullable private final String function; - -    SourceLocation(@Nullable String file, @Nullable String line, @Nullable String function) { -      this.file = file; -      this.line = line; -      this.function = function; -    } - -    JsonObject json() { -      var b = Json.createObjectBuilder(); - -      if (file != null) { -        b.add("file", file); -      } - -      if (line != null) { -        b.add("line", line); -      } - -      if (function != null) { -        b.add("function", function); -      } - -      return b.build(); -    } -  } - -  static final class Timestamp { - -    private final long seconds; -    private final int nanos; - -    Timestamp(long seconds, int nanos) { -      this.seconds = seconds; -      this.nanos = nanos; -    } - -    Timestamp(Instant t) { -      this(t.getEpochSecond(), t.getNano()); -    } - -    JsonObject json() { -      return Json.createObjectBuilder().add("seconds", seconds).add("nanos", nanos).build(); -    } -  } - -  JsonObjectBuilder json() { -    var b = Json.createObjectBuilder(); - -    if (trace != null) { -      b.add("logging.googleapis.com/trace", trace); -    } - -    if (spanId != null) { -      b.add("logging.googleapis.com/spanId", spanId); -    } - -    if (nestedDiagnosticContext != null && !nestedDiagnosticContext.isEmpty()) { -      b.add("nestedDiagnosticContext", nestedDiagnosticContext); -    } - -    if (!labels.isEmpty()) { -      b.add("logging.googleapis.com/labels", jsonOfStringMap(labels)); -    } - -    if (type != null) { -      b.add("@type", type); -    } - -    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)); -  } - -  private static JsonObjectBuilder jsonOfStringMap(Map<String, String> stringMap) { -    return stringMap.entrySet().stream() -        .reduce( -            Json.createObjectBuilder(), -            (acc, x) -> acc.add(x.getKey(), x.getValue()), -            JsonObjectBuilder::addAll); -  } - -  private static JsonObjectBuilder jsonOfParameterMap(List<StructuredParameter> parameters) { -    return parameters.stream() -        .reduce( -            Json.createObjectBuilder(), -            (acc, p) -> acc.addAll(p.json()), -            JsonObjectBuilder::addAll); -  } -} diff --git a/runtime/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/StructuredParameter.java b/runtime/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/StructuredParameter.java deleted file mode 100644 index c718080..0000000 --- a/runtime/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/StructuredParameter.java +++ /dev/null @@ -1,34 +0,0 @@ -package eu.mulk.quarkus.googlecloud.jsonlogging; - -import javax.json.JsonObjectBuilder; - -/** - * A structured parameter usable as logging payload. - * - * <p>Any instance of {@link StructuredParameter} can be passed as a log parameter to the {@code *f} - * family of logging functions on {@link org.jboss.logging.Logger}. - * - * <p>Example: - * - * <pre>{@code - * StructuredParameter p1 = ...; - * StructuredParameter p2 = ...; - * - * logger.logf("Something interesting happened.", p1, p2); - * }</pre> - * - * @see KeyValueParameter - * @see Label - */ -public interface StructuredParameter { - -  /** -   * The JSON to be embedded in the payload of the log entry. -   * -   * <p>May contain multiple keys and values as well as nested objects. Each top-level entry of the -   * returned object is embedded as a top-level entry in the payload of the log entry. -   * -   * @return A {@link JsonObjectBuilder} holding a set of key–value pairs. -   */ -  JsonObjectBuilder json(); -} diff --git a/runtime/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/StructuredParameterProvider.java b/runtime/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/StructuredParameterProvider.java deleted file mode 100644 index cacfea6..0000000 --- a/runtime/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/StructuredParameterProvider.java +++ /dev/null @@ -1,51 +0,0 @@ -package eu.mulk.quarkus.googlecloud.jsonlogging; - -/** - * A user-supplied provider for {@link StructuredParameter}s. - * - * <p>Any CDI beans registered under this class are applied to each log entry that is logged. - * - * <p><strong>Example:</strong> - * - * <pre>{@code - * @Singleton - * @Unremovable - * public final class TraceLogParameterProvider implements StructuredParameterProvider { - * - *   @Override - *   public StructuredParameter getParameter() { - *     var b = Json.createObjectBuilder(); - *     b.add("traceId", Span.current().getSpanContext().getTraceId()); - *     b.add("spanId", Span.current().getSpanContext().getSpanId()); - *     return () -> b; - *   } - * } - * }</pre> - * - * Result: - * - * <pre>{@code - * { - *   "jsonPayload": { - *     "message": "Request rejected: unauthorized.", - *     "traceId": "39f9a49a9567a8bd7087b708f8932550", - *     "spanId": "c7431b14630b633d" - *   } - * } - * }</pre> - * - * @see LabelProvider - */ -public interface StructuredParameterProvider { - -  /** -   * Provides a {@link StructuredParameter} to add to each log entry that is logged. -   * -   * <p>It is often useful to return a custom {@link StructuredParameter} rather than a {@link -   * KeyValueParameter} from this method. This way multiple key–value pairs can be generated by a -   * single invocation. -   * -   * @return a {@link StructuredParameter} to add to each log entry that is logged. -   */ -  StructuredParameter getParameter(); -} diff --git a/runtime/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/package-info.java b/runtime/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/package-info.java deleted file mode 100644 index 110ab73..0000000 --- a/runtime/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/package-info.java +++ /dev/null @@ -1,188 +0,0 @@ -/** - * Provides structured logging to standard output according to the Google Cloud Logging - * specification. - * - * <ul> - *   <li><a href="#sect-summary">Summary</a> - *   <li><a href="#sect-activation">Activation</a> - *   <li><a href="#sect-usage">Usage</a> - * </ul> - * - * <h2 id="sect-summary">Summary</h2> - * - * <p>This package contains a log formatter for JBoss Logging in the form of a Quarkus plugin that - * implements the <a href="https://cloud.google.com/logging/docs/structured-logging">Google Cloud - * Logging JSON format</a> on standard output. - * - * <p>It is possible to log unstructured text, structured data, or a mixture of both depending on - * the situation. - * - * <h2 id="sect-activation">Activation</h2> - * - * <ul> - *   <li><a href="#sect-activation-maven">Activation with Maven</a> - *   <li><a href="#sect-activation-gradle">Activation with Gradle</a> - * </ul> - * - * <p>Add the runtime POM to your dependency list. As long as the JAR is on the classpath at both - * build time and runtime, the log formatter automatically registers itself on startup. - * - * <h3 id="sect-activation-maven">Activation with Maven</h3> - * - * <pre>{@code - * <project> - *   ... - * - *   <dependencies> - *     ... - * - *     <dependency> - *       <groupId>eu.mulk.quarkus-googlecloud-jsonlogging</groupId> - *       <artifactId>quarkus-googlecloud-jsonlogging</artifactId> - *       <version>3.1.0</version> - *     </dependency> - * - *     ... - *   </dependencies> - * - *   ... - * </project> - * }</pre> - * - * <h3 id="sect-activation-gradle">Activation with Gradle</h3> - * - * <pre>{@code - * dependencies { - *   ... - * - *   implementation("eu.mulk.quarkus-googlecloud-jsonlogging:quarkus-googlecloud-jsonlogging:3.1.0") - * - *   ... - * } - * }</pre> - * - * <h2 id="sect-usage">Usage</h2> - * - * <ul> - *   <li><a href="#sect-usage-parameter">Using Label and StructuredParameter</a> - *   <li><a href="#sect-usage-provider">Using LabelProvider and StructuredParameterProvider</a> - *   <li><a href="#sect-usage-mdc">Using the Mapped Diagnostic Context</a> - * </ul> - * - * <p>Logging unstructured data requires no code changes. All logs are automatically converted to - * Google-Cloud-Logging-compatible JSON. - * - * <p>Structured data can be logged in one of 3 different ways: by passing {@link - * eu.mulk.quarkus.googlecloud.jsonlogging.Label}s and {@link - * eu.mulk.quarkus.googlecloud.jsonlogging.StructuredParameter}s as parameters to individual log - * entries, by supplying {@link eu.mulk.quarkus.googlecloud.jsonlogging.LabelProvider}s and {@link - * eu.mulk.quarkus.googlecloud.jsonlogging.StructuredParameterProvider}s, or by using the Mapped - * Diagnostic Context. - * - * <h3 id="sect-usage-parameter">Using Label and StructuredParameter</h3> - * - * <p>Instances of {@link eu.mulk.quarkus.googlecloud.jsonlogging.Label} and {@link - * eu.mulk.quarkus.googlecloud.jsonlogging.StructuredParameter} can be passed as log parameters to - * the {@code *f} family of logging functions on JBoss Logging's {@link org.jboss.logging.Logger}. - * - * <p>Simple key–value pairs are represented by {@link - * eu.mulk.quarkus.googlecloud.jsonlogging.KeyValueParameter}. - * - * <p><strong>Example:</strong> - * - * <pre>{@code - * logger.logf( - *   "Request rejected: unauthorized.", - *   Label.of("requestId", "123"), - *   KeyValueParameter.of("resource", "/users/mulk"), - *   KeyValueParameter.of("method", "PATCH"), - *   KeyValueParameter.of("reason", "invalid token")); - * }</pre> - * - * Result: - * - * <pre>{@code - * { - *   "jsonPayload": { - *     "message": "Request rejected: unauthorized.", - *     "resource": "/users/mulk", - *     "method": "PATCH", - *     "reason": "invalid token" - *   }, - *   "labels": { - *     "requestId": "123" - *   } - * } - * }</pre> - * - * <h3 id="sect-usage-provider">Using LabelProvider and StructuredParameterProvider</h3> - * - * <p>Any CDI beans that implement {@link eu.mulk.quarkus.googlecloud.jsonlogging.LabelProvider}s - * and {@link eu.mulk.quarkus.googlecloud.jsonlogging.StructuredParameterProvider}s are discovered - * at build time and consulted to provide labels and parameters for each message that is logged. - * This can be used to provide contextual information such as tracing and request IDs stored in - * thread-local storage. - * - * <p><strong>Example:</strong> - * - * <pre>{@code - * @Singleton - * @Unremovable - * public final class TraceLogParameterProvider implements StructuredParameterProvider, LabelProvider { - * - *   @Override - *   public StructuredParameter getParameter() { - *     var b = Json.createObjectBuilder(); - *     b.add("traceId", Span.current().getSpanContext().getTraceId()); - *     b.add("spanId", Span.current().getSpanContext().getSpanId()); - *     return () -> b; - *   } - * - *   @Override - *   public Collection<Label> getLabels() { - *     return List.of(Label.of("requestId", "123")); - *   } - * } - * }</pre> - * - * Result: - * - * <pre>{@code - * { - *   "jsonPayload": { - *     "message": "Request rejected: unauthorized.", - *     "traceId": "39f9a49a9567a8bd7087b708f8932550", - *     "spanId": "c7431b14630b633d" - *   }, - *   "labels": { - *     "requestId": "123" - *   } - * } - * }</pre> - * - * <h3 id="sect-usage-mdc">Using the Mapped Diagnostic Context</h3> - * - * <p>Any key–value pairs in JBoss Logging's thread-local {@link org.jboss.logging.MDC} are added to - * the resulting JSON. - * - * <p><strong>Example:</strong> - * - * <pre>{@code - * MDC.put("resource", "/users/mulk"); - * MDC.put("method", "PATCH"); - * logger.logf("Request rejected: unauthorized."); - * }</pre> - * - * Result: - * - * <pre>{@code - * { - *   "jsonPayload": { - *     "message": "Request rejected: unauthorized.", - *     "resource": "/users/mulk", - *     "method": "PATCH" - *   } - * } - * }</pre> - */ -package eu.mulk.quarkus.googlecloud.jsonlogging; diff --git a/runtime/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/GoogleCloudJsonLoggingRecorder.java b/runtime/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/runtime/GoogleCloudJsonLoggingRecorder.java index 7234a71..661b69f 100644 --- a/runtime/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/GoogleCloudJsonLoggingRecorder.java +++ b/runtime/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/runtime/GoogleCloudJsonLoggingRecorder.java @@ -1,5 +1,8 @@ -package eu.mulk.quarkus.googlecloud.jsonlogging; +package eu.mulk.quarkus.googlecloud.jsonlogging.runtime; +import eu.mulk.quarkus.googlecloud.jsonlogging.Formatter; +import eu.mulk.quarkus.googlecloud.jsonlogging.LabelProvider; +import eu.mulk.quarkus.googlecloud.jsonlogging.StructuredParameterProvider;  import io.quarkus.arc.Arc;  import io.quarkus.runtime.RuntimeValue;  import io.quarkus.runtime.annotations.Recorder; diff --git a/runtime/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/runtime/package-info.java b/runtime/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/runtime/package-info.java new file mode 100644 index 0000000..2fa7499 --- /dev/null +++ b/runtime/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/runtime/package-info.java @@ -0,0 +1,71 @@ +/** + * Provides structured logging to standard output according to the Google Cloud Logging + * specification. + * + * <ul> + *   <li><a href="#sect-summary">Summary</a> + *   <li><a href="#sect-activation">Activation</a> + *   <li><a href="#sect-usage">Usage</a> + * </ul> + * + * <h2 id="sect-summary">Summary</h2> + * + * <p>This package contains a log formatter for JBoss Logging in the form of a Quarkus plugin that + * implements the <a href="https://cloud.google.com/logging/docs/structured-logging">Google Cloud + * Logging JSON format</a> on standard output. + * + * <p>It is possible to log unstructured text, structured data, or a mixture of both depending on + * the situation. + * + * <h2 id="sect-activation">Activation</h2> + * + * <ul> + *   <li><a href="#sect-activation-maven">Activation with Maven</a> + *   <li><a href="#sect-activation-gradle">Activation with Gradle</a> + * </ul> + * + * <p>Add the runtime POM to your dependency list. As long as the JAR is on the classpath at both + * build time and runtime, the log formatter automatically registers itself on startup. + * + * <h3 id="sect-activation-maven">Activation with Maven</h3> + * + * <pre>{@code + * <project> + *   ... + * + *   <dependencies> + *     ... + * + *     <dependency> + *       <groupId>eu.mulk.quarkus-googlecloud-jsonlogging</groupId> + *       <artifactId>quarkus-googlecloud-jsonlogging</artifactId> + *       <version>4.0.0</version> + *     </dependency> + * + *     ... + *   </dependencies> + * + *   ... + * </project> + * }</pre> + * + * <h3 id="sect-activation-gradle">Activation with Gradle</h3> + * + * <pre>{@code + * dependencies { + *   ... + * + *   implementation("eu.mulk.quarkus-googlecloud-jsonlogging:quarkus-googlecloud-jsonlogging:4.0.0") + * + *   ... + * } + * }</pre> + * + * <h2 id="sect-usage">Usage</h2> + * + * <p>See the documentation of the {@link eu.mulk.quarkus.googlecloud.jsonlogging} package for usage + * instructions. + * + * @see eu.mulk.quarkus.googlecloud.jsonlogging + */ +package eu.mulk.quarkus.googlecloud.jsonlogging.runtime; | 
