Add LabelProvider, rename {=> Structured}ParameterProvider.

Change-Id: Ib4902a35e22d023fc7e8dda4ca73ec2aab50695d
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
index c6e177c..c8bb310 100644
--- a/runtime/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/Formatter.java
+++ b/runtime/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/Formatter.java
@@ -29,10 +29,14 @@
   private static final String ERROR_EVENT_TYPE =
       "type.googleapis.com/google.devtools.clouderrorreporting.v1beta1.ReportedErrorEvent";
 
-  private final List<ParameterProvider> parameterProviders;
+  private final List<StructuredParameterProvider> parameterProviders;
+  private final List<LabelProvider> labelProviders;
 
-  public Formatter(Collection<ParameterProvider> parameterProviders) {
+  public Formatter(
+      Collection<StructuredParameterProvider> parameterProviders,
+      Collection<LabelProvider> labelProviders) {
     this.parameterProviders = List.copyOf(parameterProviders);
+    this.labelProviders = List.copyOf(labelProviders);
   }
 
   @Override
@@ -43,12 +47,21 @@
     Map<String, String> labels = new HashMap<>();
 
     for (var parameterProvider : parameterProviders) {
-      var parameter = parameterProvider.get();
+      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) {
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
index ace4a28..a26f4da 100644
--- a/runtime/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/GoogleCloudJsonLoggingRecorder.java
+++ b/runtime/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/GoogleCloudJsonLoggingRecorder.java
@@ -6,11 +6,18 @@
 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 {
   public RuntimeValue<Optional<java.util.logging.Formatter>> initialize() {
+
     var parameterProviders =
-        Arc.container().select(ParameterProvider.class).stream().collect(Collectors.toList());
-    return new RuntimeValue<>(Optional.of(new Formatter(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
index ae2e7e0..173d9e2 100644
--- a/runtime/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/KeyValueParameter.java
+++ b/runtime/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/KeyValueParameter.java
@@ -7,6 +7,22 @@
 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>Example:
+ *
+ * <pre>{@code
+ * logger.infof("Application starting.", StructuredParameter.of("version", "1.0"));
+ * }</pre>
+ *
+ * @see Label
+ * @see StructuredParameter
+ */
 public final class KeyValueParameter implements StructuredParameter {
 
   private final String key;
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
index 7c5d14d..72929f1 100644
--- a/runtime/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/Label.java
+++ b/runtime/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/Label.java
@@ -2,6 +2,21 @@
 
 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>Example:
+ *
+ * <pre>{@code
+ * logger.logf("Request rejected: unauthorized.", Label.of("requestId", "123"));
+ * }</pre>
+ *
+ * @see KeyValueParameter
+ * @see StructuredParameter
+ */
 public final class Label {
 
   private final String key;
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
new file mode 100644
index 0000000..ef31bcc
--- /dev/null
+++ b/runtime/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/LabelProvider.java
@@ -0,0 +1,16 @@
+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.
+ *
+ * @see StructuredParameterProvider
+ */
+public interface LabelProvider {
+
+  /** Provides 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/StructuredParameter.java b/runtime/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/StructuredParameter.java
index 0b4a36e..fa326d5 100644
--- a/runtime/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/StructuredParameter.java
+++ b/runtime/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/StructuredParameter.java
@@ -2,6 +2,31 @@
 
 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 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 log entry.
+   */
   JsonObjectBuilder json();
 }
diff --git a/runtime/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/ParameterProvider.java b/runtime/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/StructuredParameterProvider.java
similarity index 73%
rename from runtime/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/ParameterProvider.java
rename to runtime/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/StructuredParameterProvider.java
index fb212a3..d8ab39b 100644
--- a/runtime/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/ParameterProvider.java
+++ b/runtime/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/StructuredParameterProvider.java
@@ -4,9 +4,11 @@
  * 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.
+ *
+ * @see LabelProvider
  */
-public interface ParameterProvider {
+public interface StructuredParameterProvider {
 
   /** Provides a {@link StructuredParameter} to add to each log entry that is logged. */
-  StructuredParameter get();
+  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
new file mode 100644
index 0000000..cbb6e16
--- /dev/null
+++ b/runtime/src/main/java/eu/mulk/quarkus/googlecloud/jsonlogging/package-info.java
@@ -0,0 +1,5 @@
+/**
+ * Provides structured logging to standard output according to the Google Cloud Logging
+ * specification.
+ */
+package eu.mulk.quarkus.googlecloud.jsonlogging;