|
@@ -5,6 +5,8 @@
|
|
|
|
|
|
package io.opentelemetry.instrumentation.log4j.appender.v2_17;
|
|
|
|
|
|
+import static java.util.Collections.emptyList;
|
|
|
+
|
|
|
import io.opentelemetry.instrumentation.api.appender.internal.LogBuilder;
|
|
|
import io.opentelemetry.instrumentation.api.appender.internal.LogEmitterProvider;
|
|
|
import io.opentelemetry.instrumentation.api.appender.internal.LogEmitterProviderHolder;
|
|
@@ -13,9 +15,13 @@ import io.opentelemetry.instrumentation.log4j.appender.v2_17.internal.LogEventMa
|
|
|
import io.opentelemetry.instrumentation.sdk.appender.internal.DelegatingLogEmitterProvider;
|
|
|
import io.opentelemetry.sdk.logs.SdkLogEmitterProvider;
|
|
|
import java.io.Serializable;
|
|
|
+import java.util.Arrays;
|
|
|
+import java.util.List;
|
|
|
import java.util.concurrent.TimeUnit;
|
|
|
import java.util.function.BiConsumer;
|
|
|
+import java.util.stream.Collectors;
|
|
|
import javax.annotation.Nullable;
|
|
|
+import org.apache.logging.log4j.ThreadContext;
|
|
|
import org.apache.logging.log4j.core.Appender;
|
|
|
import org.apache.logging.log4j.core.Core;
|
|
|
import org.apache.logging.log4j.core.Filter;
|
|
@@ -24,8 +30,10 @@ import org.apache.logging.log4j.core.LogEvent;
|
|
|
import org.apache.logging.log4j.core.appender.AbstractAppender;
|
|
|
import org.apache.logging.log4j.core.config.Property;
|
|
|
import org.apache.logging.log4j.core.config.plugins.Plugin;
|
|
|
+import org.apache.logging.log4j.core.config.plugins.PluginBuilderAttribute;
|
|
|
import org.apache.logging.log4j.core.config.plugins.PluginBuilderFactory;
|
|
|
import org.apache.logging.log4j.core.time.Instant;
|
|
|
+import org.apache.logging.log4j.message.MapMessage;
|
|
|
import org.apache.logging.log4j.util.ReadOnlyStringMap;
|
|
|
|
|
|
@Plugin(
|
|
@@ -39,8 +47,7 @@ public class OpenTelemetryAppender extends AbstractAppender {
|
|
|
private static final LogEmitterProviderHolder logEmitterProviderHolder =
|
|
|
new LogEmitterProviderHolder();
|
|
|
|
|
|
- private static final LogEventMapper<ReadOnlyStringMap> mapper =
|
|
|
- new LogEventMapper<>(ContextDataAccessorImpl.INSTANCE);
|
|
|
+ private final LogEventMapper<ReadOnlyStringMap> mapper;
|
|
|
|
|
|
@PluginBuilderFactory
|
|
|
public static <B extends Builder<B>> B builder() {
|
|
@@ -50,10 +57,43 @@ public class OpenTelemetryAppender extends AbstractAppender {
|
|
|
static class Builder<B extends Builder<B>> extends AbstractAppender.Builder<B>
|
|
|
implements org.apache.logging.log4j.core.util.Builder<OpenTelemetryAppender> {
|
|
|
|
|
|
+ @PluginBuilderAttribute private boolean captureExperimentalAttributes;
|
|
|
+ @PluginBuilderAttribute private boolean captureMapMessageAttributes;
|
|
|
+ @PluginBuilderAttribute private String captureContextDataAttributes;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Sets whether experimental attributes should be set to logs. These attributes may be changed
|
|
|
+ * or removed in the future, so only enable this if you know you do not require attributes
|
|
|
+ * filled by this instrumentation to be stable across versions.
|
|
|
+ */
|
|
|
+ public B setCaptureExperimentalAttributes(boolean captureExperimentalAttributes) {
|
|
|
+ this.captureExperimentalAttributes = captureExperimentalAttributes;
|
|
|
+ return asBuilder();
|
|
|
+ }
|
|
|
+
|
|
|
+ /** Sets whether log4j {@link MapMessage} attributes should be copied to logs. */
|
|
|
+ public B setCaptureMapMessageAttributes(boolean captureMapMessageAttributes) {
|
|
|
+ this.captureMapMessageAttributes = captureMapMessageAttributes;
|
|
|
+ return asBuilder();
|
|
|
+ }
|
|
|
+
|
|
|
+ /** Configures the {@link ThreadContext} attributes that will be copied to logs. */
|
|
|
+ public B setCaptureContextDataAttributes(String captureContextDataAttributes) {
|
|
|
+ this.captureContextDataAttributes = captureContextDataAttributes;
|
|
|
+ return asBuilder();
|
|
|
+ }
|
|
|
+
|
|
|
@Override
|
|
|
public OpenTelemetryAppender build() {
|
|
|
return new OpenTelemetryAppender(
|
|
|
- getName(), getLayout(), getFilter(), isIgnoreExceptions(), getPropertyArray());
|
|
|
+ getName(),
|
|
|
+ getLayout(),
|
|
|
+ getFilter(),
|
|
|
+ isIgnoreExceptions(),
|
|
|
+ getPropertyArray(),
|
|
|
+ captureExperimentalAttributes,
|
|
|
+ captureMapMessageAttributes,
|
|
|
+ captureContextDataAttributes);
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -62,8 +102,28 @@ public class OpenTelemetryAppender extends AbstractAppender {
|
|
|
Layout<? extends Serializable> layout,
|
|
|
Filter filter,
|
|
|
boolean ignoreExceptions,
|
|
|
- Property[] properties) {
|
|
|
+ Property[] properties,
|
|
|
+ boolean captureExperimentalAttributes,
|
|
|
+ boolean captureMapMessageAttributes,
|
|
|
+ String captureContextDataAttributes) {
|
|
|
+
|
|
|
super(name, filter, layout, ignoreExceptions, properties);
|
|
|
+ this.mapper =
|
|
|
+ new LogEventMapper<>(
|
|
|
+ ContextDataAccessorImpl.INSTANCE,
|
|
|
+ captureExperimentalAttributes,
|
|
|
+ captureMapMessageAttributes,
|
|
|
+ splitAndFilterBlanksAndNulls(captureContextDataAttributes));
|
|
|
+ }
|
|
|
+
|
|
|
+ private static List<String> splitAndFilterBlanksAndNulls(String value) {
|
|
|
+ if (value == null) {
|
|
|
+ return emptyList();
|
|
|
+ }
|
|
|
+ return Arrays.stream(value.split(","))
|
|
|
+ .map(String::trim)
|
|
|
+ .filter(s -> !s.isEmpty())
|
|
|
+ .collect(Collectors.toList());
|
|
|
}
|
|
|
|
|
|
@Override
|