${project.groupId}
apm-lettuce-plugin
diff --git a/apm-agent-core/src/main/java/co/elastic/apm/agent/bci/IndyBootstrap.java b/apm-agent-core/src/main/java/co/elastic/apm/agent/bci/IndyBootstrap.java
index a1dbe47967..69dc2899e3 100644
--- a/apm-agent-core/src/main/java/co/elastic/apm/agent/bci/IndyBootstrap.java
+++ b/apm-agent-core/src/main/java/co/elastic/apm/agent/bci/IndyBootstrap.java
@@ -22,13 +22,14 @@
import co.elastic.apm.agent.bci.classloading.IndyPluginClassLoader;
import co.elastic.apm.agent.bci.classloading.LookupExposer;
import co.elastic.apm.agent.common.JvmRuntimeInfo;
+import co.elastic.apm.agent.sdk.logging.Logger;
+import co.elastic.apm.agent.sdk.logging.LoggerFactory;
+import co.elastic.apm.agent.sdk.state.CallDepth;
import co.elastic.apm.agent.sdk.state.GlobalState;
import co.elastic.apm.agent.util.PackageScanner;
import net.bytebuddy.asm.Advice;
import net.bytebuddy.dynamic.ClassFileLocator;
import net.bytebuddy.dynamic.loading.ClassInjector;
-import co.elastic.apm.agent.sdk.logging.Logger;
-import co.elastic.apm.agent.sdk.logging.LoggerFactory;
import org.stagemonitor.configuration.ConfigurationOptionProvider;
import org.stagemonitor.util.IOUtils;
@@ -211,6 +212,8 @@ public class IndyBootstrap {
@Nullable
static Method indyBootstrapMethod;
+ private static final CallDepth callDepth = CallDepth.get(IndyBootstrap.class);
+
public static Method getIndyBootstrapMethod(final Logger logger) {
if (indyBootstrapMethod != null) {
return indyBootstrapMethod;
@@ -356,6 +359,14 @@ public static ConstantCallSite bootstrap(MethodHandles.Lookup lookup,
MethodType adviceMethodType,
Object... args) {
try {
+ if (callDepth.isNestedCallAndIncrement()) {
+ // avoid re-entrancy and stack overflow errors
+ // may happen when bootstrapping an instrumentation that also gets triggered during the bootstrap
+ // for example, adding correlation ids to the thread context when executing logger.debug.
+ // We cannot use a static logger field as it would initialize logging before it's ready
+ LoggerFactory.getLogger(IndyBootstrap.class).warn("Nested instrumented invokedynamic instruction linkage detected", new Throwable());
+ return null;
+ }
String adviceClassName = (String) args[0];
int enter = (Integer) args[1];
Class> instrumentedType = (Class>) args[2];
@@ -411,6 +422,8 @@ public static ConstantCallSite bootstrap(MethodHandles.Lookup lookup,
// must not be a static field as it would initialize logging before it's ready
LoggerFactory.getLogger(IndyBootstrap.class).error(e.getMessage(), e);
return null;
+ } finally {
+ callDepth.decrement();
}
}
diff --git a/apm-agent-core/src/main/java/co/elastic/apm/agent/impl/ActivationListener.java b/apm-agent-core/src/main/java/co/elastic/apm/agent/impl/ActivationListener.java
index 8ba358454e..4461a537e9 100644
--- a/apm-agent-core/src/main/java/co/elastic/apm/agent/impl/ActivationListener.java
+++ b/apm-agent-core/src/main/java/co/elastic/apm/agent/impl/ActivationListener.java
@@ -18,11 +18,10 @@
*/
package co.elastic.apm.agent.impl;
-import co.elastic.apm.agent.impl.error.ErrorCapture;
import co.elastic.apm.agent.impl.transaction.AbstractSpan;
/**
- * A callback for {@link AbstractSpan} and {@link ErrorCapture} activation and deactivation events
+ * A callback for {@link AbstractSpan} activation and deactivation events
*
* The constructor can optionally have a {@link ElasticApmTracer} parameter.
*
@@ -37,14 +36,6 @@ public interface ActivationListener {
*/
void beforeActivate(AbstractSpan> span) throws Throwable;
- /**
- * A callback for {@link ErrorCapture#activate()}
- *
- * @param error the {@link ErrorCapture} that is being activated
- * @throws Throwable if there was an error while calling this method
- */
- void beforeActivate(ErrorCapture error) throws Throwable;
-
/**
* A callback for {@link AbstractSpan#deactivate()}
*
@@ -56,12 +47,4 @@ public interface ActivationListener {
* @throws Throwable if there was an error while calling this method
*/
void afterDeactivate(AbstractSpan> deactivatedSpan) throws Throwable;
-
- /**
- * A callback for {@link ErrorCapture#deactivate()}
- *
- * @param deactivatedError the error that has just been deactivated
- * @throws Throwable if there was an error while calling this method
- */
- void afterDeactivate(ErrorCapture deactivatedError) throws Throwable;
}
diff --git a/apm-agent-core/src/main/java/co/elastic/apm/agent/impl/ElasticApmTracer.java b/apm-agent-core/src/main/java/co/elastic/apm/agent/impl/ElasticApmTracer.java
index 43abf0fc49..9be39a785b 100644
--- a/apm-agent-core/src/main/java/co/elastic/apm/agent/impl/ElasticApmTracer.java
+++ b/apm-agent-core/src/main/java/co/elastic/apm/agent/impl/ElasticApmTracer.java
@@ -176,7 +176,7 @@ public Transaction startRootTransaction(@Nullable ClassLoader initiatingClassLoa
public Transaction startRootTransaction(Sampler sampler, long epochMicros, @Nullable ClassLoader initiatingClassLoader) {
Transaction transaction = null;
if (isRunning()) {
- transaction = createTransaction().start(TraceContext.asRoot(), null, epochMicros, sampler, initiatingClassLoader);
+ transaction = createTransaction().start(TraceContext.asRoot(), null, epochMicros, sampler);
afterTransactionStart(initiatingClassLoader, transaction);
}
return transaction;
@@ -201,7 +201,7 @@ public Transaction startChildTransaction(@Nullable C headerCarrier, TextHead
Transaction transaction = null;
if (isRunning()) {
transaction = createTransaction().start(TraceContext.getFromTraceContextTextHeaders(), headerCarrier,
- textHeadersGetter, epochMicros, sampler, initiatingClassLoader);
+ textHeadersGetter, epochMicros, sampler);
afterTransactionStart(initiatingClassLoader, transaction);
}
return transaction;
@@ -220,7 +220,7 @@ public Transaction startChildTransaction(@Nullable C headerCarrier, BinaryHe
Transaction transaction = null;
if (isRunning()) {
transaction = createTransaction().start(TraceContext.getFromTraceContextBinaryHeaders(), headerCarrier,
- binaryHeadersGetter, epochMicros, sampler, initiatingClassLoader);
+ binaryHeadersGetter, epochMicros, sampler);
afterTransactionStart(initiatingClassLoader, transaction);
}
return transaction;
diff --git a/apm-agent-core/src/main/java/co/elastic/apm/agent/impl/error/ErrorCapture.java b/apm-agent-core/src/main/java/co/elastic/apm/agent/impl/error/ErrorCapture.java
index 5632f397ce..406123f209 100644
--- a/apm-agent-core/src/main/java/co/elastic/apm/agent/impl/error/ErrorCapture.java
+++ b/apm-agent-core/src/main/java/co/elastic/apm/agent/impl/error/ErrorCapture.java
@@ -44,6 +44,8 @@ public class ErrorCapture implements Recyclable {
private static final Logger logger = LoggerFactory.getLogger(ErrorCapture.class);
+ private static final ThreadLocal activeError = new ThreadLocal<>();
+
private final TraceContext traceContext;
/**
@@ -205,34 +207,20 @@ private void setCulprit(StackTraceElement stackTraceElement) {
}
public ErrorCapture activate() {
- List activationListeners = tracer.getActivationListeners();
- for (int i = 0; i < activationListeners.size(); i++) {
- try {
- activationListeners.get(i).beforeActivate(this);
- } catch (Error e) {
- throw e;
- } catch (Throwable t) {
- logger.warn("Exception while calling {}#beforeActivate", activationListeners.get(i).getClass().getSimpleName(), t);
- }
- }
+ activeError.set(this);
return this;
}
public ErrorCapture deactivate() {
- List activationListeners = tracer.getActivationListeners();
- for (int i = 0; i < activationListeners.size(); i++) {
- try {
- // `this` is guaranteed to not be recycled yet as the reference count is only decremented after this method has executed
- activationListeners.get(i).afterDeactivate(this);
- } catch (Error e) {
- throw e;
- } catch (Throwable t) {
- logger.warn("Exception while calling {}#afterDeactivate", activationListeners.get(i).getClass().getSimpleName(), t);
- }
- }
+ activeError.remove();
return this;
}
+ @Nullable
+ public static ErrorCapture getActive() {
+ return activeError.get();
+ }
+
public static class TransactionInfo implements Recyclable {
/**
* A hint for UI to be able to show whether a recorded trace for the corresponding transaction is expected
diff --git a/apm-agent-core/src/main/java/co/elastic/apm/agent/impl/transaction/TraceContext.java b/apm-agent-core/src/main/java/co/elastic/apm/agent/impl/transaction/TraceContext.java
index 6f2393936f..9bfdb30e68 100644
--- a/apm-agent-core/src/main/java/co/elastic/apm/agent/impl/transaction/TraceContext.java
+++ b/apm-agent-core/src/main/java/co/elastic/apm/agent/impl/transaction/TraceContext.java
@@ -23,16 +23,12 @@
import co.elastic.apm.agent.impl.Tracer;
import co.elastic.apm.agent.impl.sampling.Sampler;
import co.elastic.apm.agent.objectpool.Recyclable;
-import co.elastic.apm.agent.sdk.weakconcurrent.WeakConcurrent;
-import co.elastic.apm.agent.sdk.weakconcurrent.WeakMap;
import co.elastic.apm.agent.util.ByteUtils;
-import co.elastic.apm.agent.util.ClassLoaderUtils;
import co.elastic.apm.agent.util.HexUtils;
import co.elastic.apm.agent.sdk.logging.Logger;
import co.elastic.apm.agent.sdk.logging.LoggerFactory;
import javax.annotation.Nullable;
-import java.lang.ref.WeakReference;
import java.nio.charset.StandardCharsets;
import java.util.Objects;
@@ -97,10 +93,6 @@ public class TraceContext implements Recyclable {
private static final Double SAMPLE_RATE_ZERO = 0d;
- /**
- * Helps to reduce allocations by caching {@link WeakReference}s to {@link ClassLoader}s
- */
- private static final WeakMap> classLoaderWeakReferenceCache = WeakConcurrent.buildMap();
private static final ChildContextCreator FROM_PARENT_CONTEXT = new ChildContextCreator() {
@Override
public boolean asChildOf(TraceContext child, TraceContext parent) {
@@ -224,9 +216,7 @@ public static void copyTraceContextTextHeaders(S source, TextHeaderGetter
private final StringBuilder outgoingTextHeader = new StringBuilder(TEXT_HEADER_EXPECTED_LENGTH);
private byte flags;
private boolean discardable = true;
- // weakly referencing to avoid CL leaks in case of leaked spans
- @Nullable
- private WeakReference applicationClassLoader;
+
private final TraceState traceState;
final CoreConfiguration coreConfiguration;
@@ -440,7 +430,6 @@ public void asChildOf(TraceContext parent) {
clock.init(parent.clock);
serviceName = parent.serviceName;
serviceVersion = parent.serviceVersion;
- applicationClassLoader = parent.applicationClassLoader;
traceState.copyFrom(parent.traceState);
onMutation();
}
@@ -457,7 +446,6 @@ public void resetState() {
clock.resetState();
serviceName = null;
serviceVersion = null;
- applicationClassLoader = null;
traceState.resetState();
traceState.setSizeLimit(coreConfiguration.getTracestateSizeLimit());
}
@@ -658,7 +646,6 @@ public void copyFrom(TraceContext other) {
clock.init(other.clock);
serviceName = other.serviceName;
serviceVersion = other.serviceVersion;
- applicationClassLoader = other.applicationClassLoader;
traceState.copyFrom(other.traceState);
onMutation();
}
@@ -728,27 +715,6 @@ public int hashCode() {
return Objects.hash(traceId, id, parentId, flags);
}
- void setApplicationClassLoader(@Nullable ClassLoader classLoader) {
- if (ClassLoaderUtils.isBootstrapClassLoader(classLoader) || ClassLoaderUtils.isAgentClassLoader(classLoader)) {
- return;
- }
- WeakReference local = classLoaderWeakReferenceCache.get(classLoader);
- if (local == null) {
- local = new WeakReference<>(classLoader);
- classLoaderWeakReferenceCache.putIfAbsent(classLoader, local);
- }
- applicationClassLoader = local;
- }
-
- @Nullable
- public ClassLoader getApplicationClassLoader() {
- if (applicationClassLoader != null) {
- return applicationClassLoader.get();
- } else {
- return null;
- }
- }
-
public TraceState getTraceState() {
return traceState;
}
diff --git a/apm-agent-core/src/main/java/co/elastic/apm/agent/impl/transaction/Transaction.java b/apm-agent-core/src/main/java/co/elastic/apm/agent/impl/transaction/Transaction.java
index 4e470be1d0..e7c1b77585 100644
--- a/apm-agent-core/src/main/java/co/elastic/apm/agent/impl/transaction/Transaction.java
+++ b/apm-agent-core/src/main/java/co/elastic/apm/agent/impl/transaction/Transaction.java
@@ -119,17 +119,13 @@ public Transaction(ElasticApmTracer tracer) {
super(tracer);
}
- public Transaction start(TraceContext.ChildContextCreator childContextCreator, @Nullable T parent, long epochMicros,
- Sampler sampler, @Nullable ClassLoader initiatingClassLoader) {
- traceContext.setApplicationClassLoader(initiatingClassLoader);
+ public Transaction start(TraceContext.ChildContextCreator childContextCreator, @Nullable T parent, long epochMicros, Sampler sampler) {
boolean startedAsChild = parent != null && childContextCreator.asChildOf(traceContext, parent);
onTransactionStart(startedAsChild, epochMicros, sampler);
return this;
}
- public Transaction start(TraceContext.ChildContextCreatorTwoArg childContextCreator, @Nullable T parent, A arg,
- long epochMicros, Sampler sampler, @Nullable ClassLoader initiatingClassLoader) {
- traceContext.setApplicationClassLoader(initiatingClassLoader);
+ public Transaction start(TraceContext.ChildContextCreatorTwoArg childContextCreator, @Nullable T parent, A arg, long epochMicros, Sampler sampler) {
boolean startedAsChild = childContextCreator.asChildOf(traceContext, parent, arg);
onTransactionStart(startedAsChild, epochMicros, sampler);
return this;
diff --git a/apm-agent-core/src/main/java/co/elastic/apm/agent/logging/LoggingConfiguration.java b/apm-agent-core/src/main/java/co/elastic/apm/agent/logging/LoggingConfiguration.java
index 0138ab1a8d..dcfd2ccc99 100644
--- a/apm-agent-core/src/main/java/co/elastic/apm/agent/logging/LoggingConfiguration.java
+++ b/apm-agent-core/src/main/java/co/elastic/apm/agent/logging/LoggingConfiguration.java
@@ -149,27 +149,6 @@ static LogLevel mapLogLevel(LogLevel original) {
.dynamic(false)
.buildWithDefault(DEFAULT_LOG_FILE);
- private final ConfigurationOption logCorrelationEnabled = ConfigurationOption.booleanOption()
- .key("enable_log_correlation")
- .configurationCategory(LOGGING_CATEGORY)
- .description("A boolean specifying if the agent should integrate into SLF4J's https://www.slf4j.org/api/org/slf4j/MDC.html[MDC] to enable trace-log correlation.\n" +
- "If set to `true`, the agent will set the `trace.id` and `transaction.id` for the currently active spans and transactions to the MDC.\n" +
- "Since version 1.16.0, the agent also adds `error.id` of captured error to the MDC just before the error message is logged.\n" +
- "See <> for more details.\n" +
- "\n" +
- "NOTE: While it's allowed to enable this setting at runtime, you can't disable it without a restart.")
- .dynamic(true)
- .addValidator(new ConfigurationOption.Validator() {
- @Override
- public void assertValid(Boolean value) {
- if (logCorrelationEnabled != null && logCorrelationEnabled.get() && Boolean.FALSE.equals(value)) {
- // the reason is that otherwise the MDC will not be cleared when disabling while a span is currently active
- throw new IllegalArgumentException("Disabling the log correlation at runtime is not possible.");
- }
- }
- })
- .buildWithDefault(false);
-
private final ConfigurationOption logEcsReformatting = ConfigurationOption.enumOption(LogEcsReformatting.class)
.key("log_ecs_reformatting")
.configurationCategory(LOGGING_CATEGORY)
@@ -177,8 +156,7 @@ public void assertValid(Boolean value) {
.description("Specifying whether and how the agent should automatically reformat application logs \n" +
"into {ecs-logging-ref}/index.html[ECS-compatible JSON], suitable for ingestion into Elasticsearch for \n" +
"further Log analysis. This functionality is available for log4j1, log4j2 and Logback. \n" +
- "Once this option is enabled with any valid option, log correlation will be activated as well, " +
- "regardless of the <> configuration. \n" +
+ "The ECS log lines will include active trace/transaction/error IDs, if there are such. \n" +
"\n" +
"Available options:\n" +
"\n" +
@@ -379,11 +357,6 @@ private static void setLogLevel(@Nullable LogLevel level) {
Configurator.setLevel("com.networknt.schema", org.apache.logging.log4j.Level.WARN);
}
- public boolean isLogCorrelationEnabled() {
- // Enabling automatic ECS-reformatting implicitly enables log correlation
- return logCorrelationEnabled.get() || getLogEcsReformatting() != LogEcsReformatting.OFF;
- }
-
public LogEcsReformatting getLogEcsReformatting() {
return logEcsReformatting.get();
}
@@ -398,8 +371,8 @@ public List getLogEcsFormatterAllowList() {
@Nullable
public String getLogEcsFormattingDestinationDir() {
- String logShadingDestDir = logEcsFormattingDestinationDir.get().trim();
- return (logShadingDestDir.isEmpty()) ? null : logShadingDestDir;
+ String logReformattingDestDir = logEcsFormattingDestinationDir.get().trim();
+ return (logReformattingDestDir.isEmpty()) ? null : logReformattingDestDir;
}
public long getLogFileSize() {
diff --git a/apm-agent-core/src/main/java/co/elastic/apm/agent/util/ClassLoaderUtils.java b/apm-agent-core/src/main/java/co/elastic/apm/agent/util/ClassLoaderUtils.java
index e79e820c3b..d21902ac98 100644
--- a/apm-agent-core/src/main/java/co/elastic/apm/agent/util/ClassLoaderUtils.java
+++ b/apm-agent-core/src/main/java/co/elastic/apm/agent/util/ClassLoaderUtils.java
@@ -44,7 +44,9 @@ public static boolean isPersistentClassLoader(@Nullable ClassLoader classLoader)
}
public static boolean isAgentClassLoader(@Nullable ClassLoader classLoader) {
- return classLoader != null && classLoader.getClass().getName().startsWith("co.elastic.apm");
+ return (classLoader != null && classLoader.getClass().getName().startsWith("co.elastic.apm")) ||
+ // This one also covers unit tests, where the app class loader loads the agent
+ ClassLoaderUtils.class.getClassLoader().equals(classLoader);
}
public static boolean isBootstrapClassLoader(@Nullable ClassLoader classLoader) {
diff --git a/apm-agent-core/src/test/java/co/elastic/apm/agent/MockReporter.java b/apm-agent-core/src/test/java/co/elastic/apm/agent/MockReporter.java
index ad783686bf..0a1c69ba91 100644
--- a/apm-agent-core/src/test/java/co/elastic/apm/agent/MockReporter.java
+++ b/apm-agent-core/src/test/java/co/elastic/apm/agent/MockReporter.java
@@ -420,6 +420,12 @@ public void awaitSpanCount(int count) {
.isEqualTo(count));
}
+ public void awaitErrorCount(int count) {
+ awaitUntilAsserted(() -> assertThat(getNumReportedErrors())
+ .describedAs("expecting %d errors", count)
+ .isEqualTo(count));
+ }
+
@Override
public synchronized void report(ErrorCapture error) {
if (closed) {
@@ -470,6 +476,10 @@ public synchronized List getErrors() {
return Collections.unmodifiableList(errors);
}
+ public synchronized int getNumReportedErrors() {
+ return errors.size();
+ }
+
public synchronized ErrorCapture getFirstError() {
assertThat(errors)
.describedAs("at least one error expected, none have been reported")
diff --git a/apm-agent-core/src/test/java/co/elastic/apm/agent/TransactionUtils.java b/apm-agent-core/src/test/java/co/elastic/apm/agent/TransactionUtils.java
index 7be44399f6..5f0aae242c 100644
--- a/apm-agent-core/src/test/java/co/elastic/apm/agent/TransactionUtils.java
+++ b/apm-agent-core/src/test/java/co/elastic/apm/agent/TransactionUtils.java
@@ -32,7 +32,7 @@
public class TransactionUtils {
public static void fillTransaction(Transaction t) {
- t.start(TraceContext.asRoot(), null, (long) 0, ConstantSampler.of(true), TransactionUtils.class.getClassLoader())
+ t.start(TraceContext.asRoot(), null, (long) 0, ConstantSampler.of(true))
.withName("GET /api/types")
.withType("request")
.withResult("success")
diff --git a/apm-agent-core/src/test/java/co/elastic/apm/agent/report/serialize/DslJsonSerializerTest.java b/apm-agent-core/src/test/java/co/elastic/apm/agent/report/serialize/DslJsonSerializerTest.java
index 40852fd464..10a0b4b764 100644
--- a/apm-agent-core/src/test/java/co/elastic/apm/agent/report/serialize/DslJsonSerializerTest.java
+++ b/apm-agent-core/src/test/java/co/elastic/apm/agent/report/serialize/DslJsonSerializerTest.java
@@ -157,7 +157,7 @@ void testSerializeUrlPort(boolean useNumericPort) {
void testErrorSerialization() {
ElasticApmTracer tracer = MockTracer.create();
Transaction transaction = new Transaction(tracer);
- transaction.start(TraceContext.asRoot(), null, -1, ConstantSampler.of(true), null);
+ transaction.start(TraceContext.asRoot(), null, -1, ConstantSampler.of(true));
ErrorCapture error = new ErrorCapture(tracer).asChildOf(transaction).withTimestamp(5000);
error.setTransactionSampled(true);
error.setTransactionType("test-type");
@@ -206,7 +206,7 @@ void testErrorSerializationAllFrames() {
void testErrorSerializationWithEmptyTraceId() {
ElasticApmTracer tracer = MockTracer.create();
Transaction transaction = new Transaction(tracer);
- transaction.start(TraceContext.asRoot(), null, -1, ConstantSampler.of(true), null);
+ transaction.start(TraceContext.asRoot(), null, -1, ConstantSampler.of(true));
transaction.getTraceContext().getTraceId().resetState();
ErrorCapture error = new ErrorCapture(tracer).asChildOf(transaction).withTimestamp(5000);
@@ -1213,7 +1213,7 @@ private FaaSMetaDataExtension createFaaSMetaDataExtension() {
private Transaction createRootTransaction(Sampler sampler) {
Transaction t = new Transaction(MockTracer.create());
- t.start(TraceContext.asRoot(), null, 0, sampler, getClass().getClassLoader());
+ t.start(TraceContext.asRoot(), null, 0, sampler);
t.withType("type");
t.getContext().getRequest().withMethod("GET");
t.getContext().getRequest().getUrl().withFull("http://localhost:8080/foo/bar");
diff --git a/apm-agent-core/src/test/java/org/example/stacktrace/ErrorCaptureTest.java b/apm-agent-core/src/test/java/org/example/stacktrace/ErrorCaptureTest.java
index 9420dc3af7..df9e168a07 100644
--- a/apm-agent-core/src/test/java/org/example/stacktrace/ErrorCaptureTest.java
+++ b/apm-agent-core/src/test/java/org/example/stacktrace/ErrorCaptureTest.java
@@ -109,4 +109,13 @@ void testTransactionContextTransferNonFinishedBody() {
.describedAs("Body buffer should be null when copying from a transaction where capturing was not finished yet")
.isNull();
}
+
+ @Test
+ void testActiveError() {
+ assertThat(ErrorCapture.getActive()).isNull();
+ ErrorCapture errorCapture = new ErrorCapture(tracer).activate();
+ assertThat(ErrorCapture.getActive()).isNotNull();
+ errorCapture.deactivate().end();
+ assertThat(ErrorCapture.getActive()).isNull();
+ }
}
diff --git a/apm-agent-plugins/apm-ecs-logging-plugin/pom.xml b/apm-agent-plugins/apm-ecs-logging-plugin/pom.xml
index 0bd3c0f80e..b753b44c03 100644
--- a/apm-agent-plugins/apm-ecs-logging-plugin/pom.xml
+++ b/apm-agent-plugins/apm-ecs-logging-plugin/pom.xml
@@ -34,6 +34,11 @@
2.14.1
provided
+