From 28c6b61d0e660e3d8c256288f6b77da25842970c Mon Sep 17 00:00:00 2001 From: Rafael Winterhalter Date: Mon, 5 Feb 2024 22:51:09 +0100 Subject: [PATCH 1/9] Remove logging API. --- .../apm/agent/impl/ElasticApmTracer.java | 22 +++++++++ .../elastic/apm/agent/impl/metadata/Node.java | 3 +- .../apm/agent/impl/metadata/Service.java | 19 ++----- .../apm-ecs-logging-plugin/pom.xml | 7 --- ...ulLoggerErrorCapturingInstrumentation.java | 1 - .../AbstractJulEcsReformattingHelper.java | 6 +-- .../jul/sending/JulLogSenderHandler.java | 10 ++-- .../Log4J1EcsReformattingHelper.java | 6 +-- .../log4j1/sending/LogSenderAppender.java | 10 ++-- .../Log4j2_7PlusLogCorrelationHelper.java | 1 - .../Log4J2EcsReformattingHelper.java | 6 +-- .../sending/Log4j2LogSenderAppender.java | 10 ++-- .../LogbackEcsReformattingHelper.java | 6 +-- .../sending/LogbackLogSenderAppender.java | 10 ++-- .../AbstractEcsReformattingHelper.java | 40 +++++++-------- apm-agent-plugins/apm-logging-plugin/pom.xml | 9 ---- .../apm/agent/tracer/GlobalTracer.java | 17 +++++++ .../elastic/apm/agent/tracer/NoopTracer.java | 15 ++++++ .../co/elastic/apm/agent/tracer/Tracer.java | 8 +++ .../apm/agent/tracer/service/Node.java | 27 ++++++++++ .../apm/agent/tracer/service/Service.java | 49 +++++++++++++++++++ 21 files changed, 197 insertions(+), 85 deletions(-) create mode 100644 apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/service/Node.java create mode 100644 apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/service/Service.java 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 25e26f2bf4..6639e57be2 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 @@ -26,6 +26,8 @@ import co.elastic.apm.agent.configuration.CoreConfiguration; import co.elastic.apm.agent.configuration.MetricsConfiguration; import co.elastic.apm.agent.configuration.ServerlessConfiguration; +import co.elastic.apm.agent.impl.metadata.ServiceFactory; +import co.elastic.apm.agent.tracer.service.Service; import co.elastic.apm.agent.tracer.service.ServiceInfo; import co.elastic.apm.agent.configuration.SpanConfiguration; import co.elastic.apm.agent.context.ClosableLifecycleListenerAdapter; @@ -973,4 +975,24 @@ public Set getTraceHeaderNames() { public ServiceInfo autoDetectedServiceInfo() { return AutoDetectedServiceInfo.autoDetected(); } + + @Override + public void reportLog(String log) { + reporter.reportLog(log); + } + + @Override + public void reportLog(byte[] log) { + reporter.reportLog(log); + } + + @Nullable + @Override + public Service createService(String ephemeralId) { + return new ServiceFactory().createService( + coreConfiguration, + ephemeralId, + configurationRegistry.getConfig(ServerlessConfiguration.class).runsOnAwsLambda() + ); + } } diff --git a/apm-agent-core/src/main/java/co/elastic/apm/agent/impl/metadata/Node.java b/apm-agent-core/src/main/java/co/elastic/apm/agent/impl/metadata/Node.java index c56f58bb0c..11717c4e1a 100644 --- a/apm-agent-core/src/main/java/co/elastic/apm/agent/impl/metadata/Node.java +++ b/apm-agent-core/src/main/java/co/elastic/apm/agent/impl/metadata/Node.java @@ -23,7 +23,7 @@ /** * A representation of a service node, ie JVM */ -public class Node { +public class Node implements co.elastic.apm.agent.tracer.service.Node { /** * (Optional) @@ -37,6 +37,7 @@ public Node(@Nullable String name) { } @Nullable + @Override public String getName() { return name; } diff --git a/apm-agent-core/src/main/java/co/elastic/apm/agent/impl/metadata/Service.java b/apm-agent-core/src/main/java/co/elastic/apm/agent/impl/metadata/Service.java index ac666749a0..6c44db9159 100644 --- a/apm-agent-core/src/main/java/co/elastic/apm/agent/impl/metadata/Service.java +++ b/apm-agent-core/src/main/java/co/elastic/apm/agent/impl/metadata/Service.java @@ -25,7 +25,7 @@ /** * Information about the instrumented Service */ -public class Service { +public class Service implements co.elastic.apm.agent.tracer.service.Service { /** * Name and version of the Elastic APM agent @@ -127,10 +127,8 @@ public Service withLanguage(Language language) { return this; } - /** - * Representation of a service node - */ @Nullable + @Override public Node getNode() { return node; } @@ -143,11 +141,8 @@ public Service withNode(Node node) { return this; } - /** - * Immutable name of the service emitting this event - * (Required) - */ @Nullable + @Override public String getName() { return name; } @@ -161,10 +156,8 @@ public Service withName(String name) { return this; } - /** - * Environment name of the service, e.g. "production" or "staging" - */ @Nullable + @Override public String getEnvironment() { return environment; } @@ -193,10 +186,8 @@ public Service withRuntime(RuntimeInfo runtime) { return this; } - /** - * Version of the service emitting this event - */ @Nullable + @Override public String getVersion() { return version; } diff --git a/apm-agent-plugins/apm-ecs-logging-plugin/pom.xml b/apm-agent-plugins/apm-ecs-logging-plugin/pom.xml index e002528b8a..1127e9427d 100644 --- a/apm-agent-plugins/apm-ecs-logging-plugin/pom.xml +++ b/apm-agent-plugins/apm-ecs-logging-plugin/pom.xml @@ -16,13 +16,6 @@ - - - ${project.groupId} - apm-agent-core - ${project.version} - - co.elastic.logging diff --git a/apm-agent-plugins/apm-logging-plugin/apm-jul-plugin/src/main/java/co/elastic/apm/agent/jul/error/JulLoggerErrorCapturingInstrumentation.java b/apm-agent-plugins/apm-logging-plugin/apm-jul-plugin/src/main/java/co/elastic/apm/agent/jul/error/JulLoggerErrorCapturingInstrumentation.java index 744956f7c4..7357599636 100644 --- a/apm-agent-plugins/apm-logging-plugin/apm-jul-plugin/src/main/java/co/elastic/apm/agent/jul/error/JulLoggerErrorCapturingInstrumentation.java +++ b/apm-agent-plugins/apm-logging-plugin/apm-jul-plugin/src/main/java/co/elastic/apm/agent/jul/error/JulLoggerErrorCapturingInstrumentation.java @@ -18,7 +18,6 @@ */ package co.elastic.apm.agent.jul.error; -import co.elastic.apm.agent.impl.Tracer; import co.elastic.apm.agent.loginstr.error.AbstractLoggerErrorCapturingInstrumentation; import co.elastic.apm.agent.loginstr.error.LoggerErrorHelper; import net.bytebuddy.asm.Advice; diff --git a/apm-agent-plugins/apm-logging-plugin/apm-jul-plugin/src/main/java/co/elastic/apm/agent/jul/reformatting/AbstractJulEcsReformattingHelper.java b/apm-agent-plugins/apm-logging-plugin/apm-jul-plugin/src/main/java/co/elastic/apm/agent/jul/reformatting/AbstractJulEcsReformattingHelper.java index 7e0eb6fd25..b5284b4981 100644 --- a/apm-agent-plugins/apm-logging-plugin/apm-jul-plugin/src/main/java/co/elastic/apm/agent/jul/reformatting/AbstractJulEcsReformattingHelper.java +++ b/apm-agent-plugins/apm-logging-plugin/apm-jul-plugin/src/main/java/co/elastic/apm/agent/jul/reformatting/AbstractJulEcsReformattingHelper.java @@ -21,10 +21,10 @@ import co.elastic.apm.agent.jul.sending.JulLogSenderHandler; import co.elastic.apm.agent.loginstr.correlation.CorrelationIdMapAdapter; import co.elastic.apm.agent.loginstr.reformatting.AbstractEcsReformattingHelper; -import co.elastic.apm.agent.report.Reporter; import co.elastic.apm.agent.sdk.logging.Logger; import co.elastic.apm.agent.sdk.logging.LoggerFactory; import co.elastic.apm.agent.sdk.internal.util.LoggerUtils; +import co.elastic.apm.agent.tracer.Tracer; import co.elastic.logging.AdditionalField; import co.elastic.logging.jul.EcsFormatter; @@ -151,8 +151,8 @@ private static FileHandler doCreateFileHandler(String pattern, int maxLogFileSiz protected abstract boolean isFileHandler(Handler originalHandler); @Override - protected T createAndStartLogSendingAppender(Reporter reporter, Formatter formatter) { - return (T) new JulLogSenderHandler(reporter, formatter); + protected T createAndStartLogSendingAppender(Tracer tracer, Formatter formatter) { + return (T) new JulLogSenderHandler(tracer, formatter); } @Override diff --git a/apm-agent-plugins/apm-logging-plugin/apm-jul-plugin/src/main/java/co/elastic/apm/agent/jul/sending/JulLogSenderHandler.java b/apm-agent-plugins/apm-logging-plugin/apm-jul-plugin/src/main/java/co/elastic/apm/agent/jul/sending/JulLogSenderHandler.java index 58fcf82b81..975f5f0b91 100644 --- a/apm-agent-plugins/apm-logging-plugin/apm-jul-plugin/src/main/java/co/elastic/apm/agent/jul/sending/JulLogSenderHandler.java +++ b/apm-agent-plugins/apm-logging-plugin/apm-jul-plugin/src/main/java/co/elastic/apm/agent/jul/sending/JulLogSenderHandler.java @@ -18,24 +18,24 @@ */ package co.elastic.apm.agent.jul.sending; -import co.elastic.apm.agent.report.Reporter; +import co.elastic.apm.agent.tracer.Tracer; import java.util.logging.Formatter; import java.util.logging.Handler; import java.util.logging.LogRecord; public class JulLogSenderHandler extends Handler { - private final Reporter reporter; + private final Tracer tracer; private final Formatter formatter; - public JulLogSenderHandler(Reporter reporter, Formatter formatter) { - this.reporter = reporter; + public JulLogSenderHandler(Tracer tracer, Formatter formatter) { + this.tracer = tracer; this.formatter = formatter; } @Override public void publish(LogRecord record) { - reporter.reportLog(formatter.format(record)); + tracer.reportLog(formatter.format(record)); } @Override diff --git a/apm-agent-plugins/apm-logging-plugin/apm-log4j1-plugin/src/main/java/co/elastic/apm/agent/log4j1/reformatting/Log4J1EcsReformattingHelper.java b/apm-agent-plugins/apm-logging-plugin/apm-log4j1-plugin/src/main/java/co/elastic/apm/agent/log4j1/reformatting/Log4J1EcsReformattingHelper.java index f70bbd550b..2d6f88910d 100644 --- a/apm-agent-plugins/apm-logging-plugin/apm-log4j1-plugin/src/main/java/co/elastic/apm/agent/log4j1/reformatting/Log4J1EcsReformattingHelper.java +++ b/apm-agent-plugins/apm-logging-plugin/apm-log4j1-plugin/src/main/java/co/elastic/apm/agent/log4j1/reformatting/Log4J1EcsReformattingHelper.java @@ -22,9 +22,9 @@ import co.elastic.apm.agent.loginstr.reformatting.AbstractEcsReformattingHelper; import co.elastic.apm.agent.loginstr.reformatting.Utils; -import co.elastic.apm.agent.report.Reporter; import co.elastic.apm.agent.sdk.logging.Logger; import co.elastic.apm.agent.sdk.logging.LoggerFactory; +import co.elastic.apm.agent.tracer.Tracer; import co.elastic.logging.log4j.EcsLayout; import org.apache.log4j.Appender; import org.apache.log4j.FileAppender; @@ -112,8 +112,8 @@ protected void closeShadeAppender(WriterAppender shadeAppender) { } @Override - protected Appender createAndStartLogSendingAppender(Reporter reporter, Layout formatter) { - return new LogSenderAppender(reporter, formatter); + protected Appender createAndStartLogSendingAppender(Tracer tracer, Layout formatter) { + return new LogSenderAppender(tracer, formatter); } @Override diff --git a/apm-agent-plugins/apm-logging-plugin/apm-log4j1-plugin/src/main/java/co/elastic/apm/agent/log4j1/sending/LogSenderAppender.java b/apm-agent-plugins/apm-logging-plugin/apm-log4j1-plugin/src/main/java/co/elastic/apm/agent/log4j1/sending/LogSenderAppender.java index ae1c66987f..80fc697bbf 100644 --- a/apm-agent-plugins/apm-logging-plugin/apm-log4j1-plugin/src/main/java/co/elastic/apm/agent/log4j1/sending/LogSenderAppender.java +++ b/apm-agent-plugins/apm-logging-plugin/apm-log4j1-plugin/src/main/java/co/elastic/apm/agent/log4j1/sending/LogSenderAppender.java @@ -18,17 +18,17 @@ */ package co.elastic.apm.agent.log4j1.sending; -import co.elastic.apm.agent.report.Reporter; +import co.elastic.apm.agent.tracer.Tracer; import org.apache.log4j.AppenderSkeleton; import org.apache.log4j.Layout; import org.apache.log4j.spi.LoggingEvent; public class LogSenderAppender extends AppenderSkeleton { - private final Reporter reporter; + private final Tracer tracer; private final Layout formatter; - public LogSenderAppender(Reporter reporter, Layout formatter) { - this.reporter = reporter; + public LogSenderAppender(Tracer tracer, Layout formatter) { + this.tracer = tracer; this.formatter = formatter; } @@ -39,7 +39,7 @@ public synchronized void doAppend(LoggingEvent event) { @Override protected void append(LoggingEvent event) { - reporter.reportLog(formatter.format(event)); + tracer.reportLog(formatter.format(event)); } @Override diff --git a/apm-agent-plugins/apm-logging-plugin/apm-log4j2-plugin/src/main/java/co/elastic/apm/agent/log4j2/correlation/Log4j2_7PlusLogCorrelationHelper.java b/apm-agent-plugins/apm-logging-plugin/apm-log4j2-plugin/src/main/java/co/elastic/apm/agent/log4j2/correlation/Log4j2_7PlusLogCorrelationHelper.java index 0551af209a..fd0b2ac813 100644 --- a/apm-agent-plugins/apm-logging-plugin/apm-log4j2-plugin/src/main/java/co/elastic/apm/agent/log4j2/correlation/Log4j2_7PlusLogCorrelationHelper.java +++ b/apm-agent-plugins/apm-logging-plugin/apm-log4j2-plugin/src/main/java/co/elastic/apm/agent/log4j2/correlation/Log4j2_7PlusLogCorrelationHelper.java @@ -19,7 +19,6 @@ package co.elastic.apm.agent.log4j2.correlation; import co.elastic.apm.agent.tracer.GlobalTracer; -import co.elastic.apm.agent.impl.error.ErrorCapture; import co.elastic.apm.agent.loginstr.correlation.AbstractLogCorrelationHelper; import co.elastic.apm.agent.loginstr.correlation.CorrelationIdMapAdapter; import co.elastic.apm.agent.tracer.Tracer; diff --git a/apm-agent-plugins/apm-logging-plugin/apm-log4j2-plugin/src/main/java/co/elastic/apm/agent/log4j2/reformatting/Log4J2EcsReformattingHelper.java b/apm-agent-plugins/apm-logging-plugin/apm-log4j2-plugin/src/main/java/co/elastic/apm/agent/log4j2/reformatting/Log4J2EcsReformattingHelper.java index a9c7f519bc..399f8b77e4 100644 --- a/apm-agent-plugins/apm-logging-plugin/apm-log4j2-plugin/src/main/java/co/elastic/apm/agent/log4j2/reformatting/Log4J2EcsReformattingHelper.java +++ b/apm-agent-plugins/apm-logging-plugin/apm-log4j2-plugin/src/main/java/co/elastic/apm/agent/log4j2/reformatting/Log4J2EcsReformattingHelper.java @@ -21,9 +21,9 @@ import co.elastic.apm.agent.log4j2.sending.Log4j2LogSenderAppender; import co.elastic.apm.agent.loginstr.reformatting.AbstractEcsReformattingHelper; import co.elastic.apm.agent.loginstr.reformatting.Utils; -import co.elastic.apm.agent.report.Reporter; import co.elastic.apm.agent.sdk.logging.Logger; import co.elastic.apm.agent.sdk.logging.LoggerFactory; +import co.elastic.apm.agent.tracer.Tracer; import co.elastic.logging.log4j2.EcsLayout; import org.apache.logging.log4j.core.Appender; import org.apache.logging.log4j.core.Layout; @@ -155,8 +155,8 @@ protected void closeShadeAppender(Appender shadeAppender) { } @Override - protected Appender createAndStartLogSendingAppender(Reporter reporter, Layout ecsLayout) { - Log4j2LogSenderAppender appender = new Log4j2LogSenderAppender(reporter, (StringLayout) ecsLayout); + protected Appender createAndStartLogSendingAppender(Tracer tracer, Layout ecsLayout) { + Log4j2LogSenderAppender appender = new Log4j2LogSenderAppender(tracer, (StringLayout) ecsLayout); appender.start(); return appender; } diff --git a/apm-agent-plugins/apm-logging-plugin/apm-log4j2-plugin/src/main/java/co/elastic/apm/agent/log4j2/sending/Log4j2LogSenderAppender.java b/apm-agent-plugins/apm-logging-plugin/apm-log4j2-plugin/src/main/java/co/elastic/apm/agent/log4j2/sending/Log4j2LogSenderAppender.java index 652d30de3a..b48cb99aa4 100644 --- a/apm-agent-plugins/apm-logging-plugin/apm-log4j2-plugin/src/main/java/co/elastic/apm/agent/log4j2/sending/Log4j2LogSenderAppender.java +++ b/apm-agent-plugins/apm-logging-plugin/apm-log4j2-plugin/src/main/java/co/elastic/apm/agent/log4j2/sending/Log4j2LogSenderAppender.java @@ -18,25 +18,25 @@ */ package co.elastic.apm.agent.log4j2.sending; -import co.elastic.apm.agent.report.Reporter; +import co.elastic.apm.agent.tracer.Tracer; import org.apache.logging.log4j.core.LogEvent; import org.apache.logging.log4j.core.StringLayout; import org.apache.logging.log4j.core.appender.AbstractAppender; public class Log4j2LogSenderAppender extends AbstractAppender { - private final Reporter reporter; + private final Tracer tracer; private final StringLayout ecsLayout; - public Log4j2LogSenderAppender(Reporter reporter, StringLayout ecsLayout) { + public Log4j2LogSenderAppender(Tracer tracer, StringLayout ecsLayout) { super("ElasticApmAppender", null, ecsLayout, true, null); - this.reporter = reporter; + this.tracer = tracer; this.ecsLayout = ecsLayout; } @Override public void append(LogEvent event) { - reporter.reportLog(ecsLayout.toSerializable(event)); + tracer.reportLog(ecsLayout.toSerializable(event)); } } diff --git a/apm-agent-plugins/apm-logging-plugin/apm-logback-plugin/apm-logback-plugin-impl/src/main/java/co/elastic/apm/agent/logback/reformatting/LogbackEcsReformattingHelper.java b/apm-agent-plugins/apm-logging-plugin/apm-logback-plugin/apm-logback-plugin-impl/src/main/java/co/elastic/apm/agent/logback/reformatting/LogbackEcsReformattingHelper.java index 6ebb056352..6a64591cd5 100644 --- a/apm-agent-plugins/apm-logging-plugin/apm-logback-plugin/apm-logback-plugin-impl/src/main/java/co/elastic/apm/agent/logback/reformatting/LogbackEcsReformattingHelper.java +++ b/apm-agent-plugins/apm-logging-plugin/apm-logback-plugin/apm-logback-plugin-impl/src/main/java/co/elastic/apm/agent/logback/reformatting/LogbackEcsReformattingHelper.java @@ -32,9 +32,9 @@ import co.elastic.apm.agent.loginstr.reformatting.AbstractEcsReformattingHelper; import co.elastic.apm.agent.loginstr.reformatting.Utils; import co.elastic.apm.agent.common.util.WildcardMatcher; -import co.elastic.apm.agent.report.Reporter; import co.elastic.apm.agent.sdk.logging.Logger; import co.elastic.apm.agent.sdk.logging.LoggerFactory; +import co.elastic.apm.agent.tracer.Tracer; import co.elastic.logging.AdditionalField; import co.elastic.logging.logback.EcsEncoder; @@ -158,8 +158,8 @@ protected void closeShadeAppender(OutputStreamAppender shadeAppen } @Override - protected Appender createAndStartLogSendingAppender(Reporter reporter, Encoder formatter) { - LogbackLogSenderAppender appender = new LogbackLogSenderAppender(reporter, formatter); + protected Appender createAndStartLogSendingAppender(Tracer tracer, Encoder formatter) { + LogbackLogSenderAppender appender = new LogbackLogSenderAppender(tracer, formatter); appender.start(); return appender; } diff --git a/apm-agent-plugins/apm-logging-plugin/apm-logback-plugin/apm-logback-plugin-impl/src/main/java/co/elastic/apm/agent/logback/sending/LogbackLogSenderAppender.java b/apm-agent-plugins/apm-logging-plugin/apm-logback-plugin/apm-logback-plugin-impl/src/main/java/co/elastic/apm/agent/logback/sending/LogbackLogSenderAppender.java index 3e2e3fea2f..539bd6211d 100644 --- a/apm-agent-plugins/apm-logging-plugin/apm-logback-plugin/apm-logback-plugin-impl/src/main/java/co/elastic/apm/agent/logback/sending/LogbackLogSenderAppender.java +++ b/apm-agent-plugins/apm-logging-plugin/apm-logback-plugin/apm-logback-plugin-impl/src/main/java/co/elastic/apm/agent/logback/sending/LogbackLogSenderAppender.java @@ -21,15 +21,15 @@ import ch.qos.logback.classic.spi.ILoggingEvent; import ch.qos.logback.core.UnsynchronizedAppenderBase; import ch.qos.logback.core.encoder.Encoder; -import co.elastic.apm.agent.report.Reporter; +import co.elastic.apm.agent.tracer.Tracer; import co.elastic.logging.logback.EcsEncoder; public class LogbackLogSenderAppender extends UnsynchronizedAppenderBase { - private final Reporter reporter; + private final Tracer tracer; private final EcsEncoder formatter; - public LogbackLogSenderAppender(Reporter reporter, Encoder formatter) { - this.reporter = reporter; + public LogbackLogSenderAppender(Tracer tracer, Encoder formatter) { + this.tracer = tracer; // Due to API compatibility (see below in 'append'), we have to use our own formatter type rather than the // base/interface class from logback. if (!(formatter instanceof EcsEncoder)) { @@ -42,6 +42,6 @@ public LogbackLogSenderAppender(Reporter reporter, Encoder format protected void append(ILoggingEvent eventObject) { // the Formatter interface was changed in logback 1.x, but our ECS implementation is compatible with both // older and newer versions of the API so we can rely on the more recent version of the API - reporter.reportLog(formatter.encode(eventObject)); + tracer.reportLog(formatter.encode(eventObject)); } } diff --git a/apm-agent-plugins/apm-logging-plugin/apm-logging-plugin-common/src/main/java/co/elastic/apm/agent/loginstr/reformatting/AbstractEcsReformattingHelper.java b/apm-agent-plugins/apm-logging-plugin/apm-logging-plugin-common/src/main/java/co/elastic/apm/agent/loginstr/reformatting/AbstractEcsReformattingHelper.java index 75af126a95..623c854314 100644 --- a/apm-agent-plugins/apm-logging-plugin/apm-logging-plugin-common/src/main/java/co/elastic/apm/agent/loginstr/reformatting/AbstractEcsReformattingHelper.java +++ b/apm-agent-plugins/apm-logging-plugin/apm-logging-plugin-common/src/main/java/co/elastic/apm/agent/loginstr/reformatting/AbstractEcsReformattingHelper.java @@ -18,13 +18,9 @@ */ package co.elastic.apm.agent.loginstr.reformatting; -import co.elastic.apm.agent.impl.ElasticApmTracer; import co.elastic.apm.agent.tracer.GlobalTracer; -import co.elastic.apm.agent.impl.metadata.Service; -import co.elastic.apm.agent.impl.metadata.ServiceFactory; import co.elastic.apm.agent.tracer.configuration.LogEcsReformatting; import co.elastic.apm.agent.common.util.WildcardMatcher; -import co.elastic.apm.agent.report.Reporter; import co.elastic.apm.agent.sdk.logging.Logger; import co.elastic.apm.agent.sdk.logging.LoggerFactory; import co.elastic.apm.agent.sdk.state.CallDepth; @@ -35,6 +31,8 @@ import co.elastic.apm.agent.tracer.configuration.CoreConfiguration; import co.elastic.apm.agent.tracer.configuration.LoggingConfiguration; import co.elastic.apm.agent.tracer.configuration.ServerlessConfiguration; +import co.elastic.apm.agent.tracer.service.Service; +import co.elastic.apm.agent.tracer.service.ServiceAwareTracer; import javax.annotation.Nullable; import java.util.List; @@ -168,26 +166,28 @@ public abstract class AbstractEcsReformattingHelper { @Nullable private final Map additionalFields; - private final Reporter reporter; + private final Tracer tracer; public AbstractEcsReformattingHelper() { - Tracer tracer = GlobalTracer.get(); + tracer = GlobalTracer.get(); loggingConfiguration = tracer.getConfig(LoggingConfiguration.class); additionalFields = loggingConfiguration.getLogEcsReformattingAdditionalFields(); - Service service = new ServiceFactory().createService( - tracer.getConfig(CoreConfiguration.class), - "", - tracer.getConfig(ServerlessConfiguration.class).runsOnAwsLambda() - ); - globalServiceName = service.getName(); - globalServiceVersion = service.getVersion(); - if (service.getNode() != null) { - configuredServiceNodeName = service.getNode().getName(); - } else { + Service service = tracer.createService(""); + if (service == null) { + globalServiceName = null; + globalServiceVersion = null; configuredServiceNodeName = null; + environment = null; + } else { + globalServiceName = service.getName(); + globalServiceVersion = service.getVersion(); + if (service.getNode() != null) { + configuredServiceNodeName = service.getNode().getName(); + } else { + configuredServiceNodeName = null; + } + environment = service.getEnvironment(); } - environment = service.getEnvironment(); - reporter = tracer.require(ElasticApmTracer.class).getReporter(); } /** @@ -330,7 +330,7 @@ private Object createAndMapSendingAppenderFor(final A originalAppender) { } sendingAppender = NULL_APPENDER; try { - sendingAppender = createAndStartLogSendingAppender(reporter, createEcsFormatter(originalAppender)); + sendingAppender = createAndStartLogSendingAppender(tracer, createEcsFormatter(originalAppender)); originalAppender2sendingAppender.put(originalAppender, sendingAppender); } catch (Throwable throwable) { logger.warn(String.format("Failed to create ECS shipper appender for log appender %s.%s. " + @@ -538,7 +538,7 @@ protected long getDefaultMaxLogFileSize() { protected abstract void closeShadeAppender(A shadeAppender); - protected abstract B createAndStartLogSendingAppender(Reporter reporter, F formatter); + protected abstract B createAndStartLogSendingAppender(Tracer tracer, F formatter); protected abstract void append(L logEvent, B appender); } diff --git a/apm-agent-plugins/apm-logging-plugin/pom.xml b/apm-agent-plugins/apm-logging-plugin/pom.xml index 4e26c9a0ef..333dce4ac2 100644 --- a/apm-agent-plugins/apm-logging-plugin/pom.xml +++ b/apm-agent-plugins/apm-logging-plugin/pom.xml @@ -27,13 +27,4 @@ apm-jul-plugin - - - - ${project.groupId} - apm-agent-core - ${project.version} - - - diff --git a/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/GlobalTracer.java b/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/GlobalTracer.java index 031f927381..1ad88cd129 100644 --- a/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/GlobalTracer.java +++ b/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/GlobalTracer.java @@ -22,6 +22,7 @@ import co.elastic.apm.agent.tracer.pooling.ObjectPoolFactory; import co.elastic.apm.agent.tracer.reference.ReferenceCounted; import co.elastic.apm.agent.tracer.reference.ReferenceCountedMap; +import co.elastic.apm.agent.tracer.service.Service; import javax.annotation.Nullable; import java.util.Set; @@ -133,4 +134,20 @@ public Transaction startChildTransaction(@Nullable C headerCarrier, He public ErrorCapture captureException(@Nullable Throwable e, @Nullable ClassLoader initiatingClassLoader) { return tracer.captureException(e, initiatingClassLoader); } + + @Override + public void reportLog(String log) { + tracer.reportLog(log); + } + + @Override + public void reportLog(byte[] log) { + tracer.reportLog(log); + } + + @Nullable + @Override + public Service createService(String ephemeralId) { + return tracer.createService(ephemeralId); + } } diff --git a/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/NoopTracer.java b/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/NoopTracer.java index 6088e75683..2c2727152d 100644 --- a/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/NoopTracer.java +++ b/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/NoopTracer.java @@ -22,6 +22,7 @@ import co.elastic.apm.agent.tracer.pooling.ObjectPoolFactory; import co.elastic.apm.agent.tracer.reference.ReferenceCounted; import co.elastic.apm.agent.tracer.reference.ReferenceCountedMap; +import co.elastic.apm.agent.tracer.service.Service; import javax.annotation.Nullable; import java.util.Collections; @@ -110,4 +111,18 @@ public Transaction startChildTransaction(@Nullable C headerCarrier, He public ErrorCapture captureException(@Nullable Throwable e, @Nullable ClassLoader initiatingClassLoader) { return null; } + + @Override + public void reportLog(String log) { + } + + @Override + public void reportLog(byte[] log) { + } + + @Override + @Nullable + public Service createService(String ephemeralId) { + return null; + } } diff --git a/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/Tracer.java b/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/Tracer.java index 97f8e8bb87..b7f9042142 100644 --- a/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/Tracer.java +++ b/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/Tracer.java @@ -22,6 +22,7 @@ import co.elastic.apm.agent.tracer.pooling.ObjectPoolFactory; import co.elastic.apm.agent.tracer.reference.ReferenceCounted; import co.elastic.apm.agent.tracer.reference.ReferenceCountedMap; +import co.elastic.apm.agent.tracer.service.Service; import javax.annotation.Nullable; import java.util.Set; @@ -80,4 +81,11 @@ public interface Tracer { @Nullable ErrorCapture captureException(@Nullable Throwable e, @Nullable ClassLoader initiatingClassLoader); + + void reportLog(String log); + + void reportLog(byte[] log); + + @Nullable + Service createService(String ephemeralId); } diff --git a/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/service/Node.java b/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/service/Node.java new file mode 100644 index 0000000000..6eb3a9c1e9 --- /dev/null +++ b/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/service/Node.java @@ -0,0 +1,27 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package co.elastic.apm.agent.tracer.service; + +import javax.annotation.Nullable; + +public interface Node { + + @Nullable + String getName(); +} diff --git a/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/service/Service.java b/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/service/Service.java new file mode 100644 index 0000000000..18b95dcba8 --- /dev/null +++ b/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/service/Service.java @@ -0,0 +1,49 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package co.elastic.apm.agent.tracer.service; + +import javax.annotation.Nullable; + +public interface Service { + + /** + * Immutable name of the service emitting this event + * (Required) + */ + @Nullable + String getName(); + + /** + * Version of the service emitting this event + */ + @Nullable + String getVersion(); + + /** + * Representation of a service node + */ + @Nullable + Node getNode(); + + /** + * Environment name of the service, e.g. "production" or "staging" + */ + @Nullable + String getEnvironment(); +} From fa603470bb655d02eeb83d8b7a2d8bea2ee8015f Mon Sep 17 00:00:00 2001 From: Rafael Winterhalter Date: Mon, 5 Feb 2024 22:55:20 +0100 Subject: [PATCH 2/9] Clean up core dependencies from POMs that do not need it. --- apm-agent-plugins/apm-servlet-plugin/pom.xml | 6 ------ .../apm-spring-webmvc/apm-spring-webmvc-spring5/pom.xml | 6 ------ integration-tests/spring-boot-1-5/pom.xml | 6 ++++++ 3 files changed, 6 insertions(+), 12 deletions(-) diff --git a/apm-agent-plugins/apm-servlet-plugin/pom.xml b/apm-agent-plugins/apm-servlet-plugin/pom.xml index 7e9d59e5f5..6c55c37d9e 100644 --- a/apm-agent-plugins/apm-servlet-plugin/pom.xml +++ b/apm-agent-plugins/apm-servlet-plugin/pom.xml @@ -16,12 +16,6 @@ - - - ${project.groupId} - apm-agent-core - ${project.version} - ${project.groupId} apm-java-concurrent-plugin diff --git a/apm-agent-plugins/apm-spring-webmvc/apm-spring-webmvc-spring5/pom.xml b/apm-agent-plugins/apm-spring-webmvc/apm-spring-webmvc-spring5/pom.xml index 2cf09ff875..d3547ad591 100644 --- a/apm-agent-plugins/apm-spring-webmvc/apm-spring-webmvc-spring5/pom.xml +++ b/apm-agent-plugins/apm-spring-webmvc/apm-spring-webmvc-spring5/pom.xml @@ -33,12 +33,6 @@ - - - ${project.groupId} - apm-agent-core - ${project.version} - javax.servlet javax.servlet-api diff --git a/integration-tests/spring-boot-1-5/pom.xml b/integration-tests/spring-boot-1-5/pom.xml index bb6482860b..ac2d91b9b3 100644 --- a/integration-tests/spring-boot-1-5/pom.xml +++ b/integration-tests/spring-boot-1-5/pom.xml @@ -28,6 +28,12 @@ apm-servlet-plugin ${project.version} + + ${project.groupId} + apm-agent-core + ${project.version} + test + ${project.groupId} apm-agent-core From 432aa881220e0d5ae72e65fd34884ba20bc826c5 Mon Sep 17 00:00:00 2001 From: Rafael Winterhalter Date: Mon, 5 Feb 2024 23:44:12 +0100 Subject: [PATCH 3/9] Add API for handling lambda instrumentation and apply to the AWS plugin. --- .../apm/agent/impl/ElasticApmTracer.java | 41 +++++++++++--- .../apm/agent/impl/context/Request.java | 8 +-- .../apm/agent/impl/context/Response.java | 7 ++- .../apm/agent/impl/context/ServiceOrigin.java | 5 +- .../impl/context/TransactionContext.java | 1 + .../apm/agent/impl/transaction/Faas.java | 7 ++- .../agent/impl/transaction/FaasTrigger.java | 4 +- .../apm-awslambda-plugin/pom.xml | 6 --- ...stractAwsLambdaHandlerInstrumentation.java | 4 +- .../RequestHandlerInstrumentation.java | 10 ++-- .../RequestStreamHandlerInstrumentation.java | 10 ++-- .../APIGatewayProxyV1TransactionHelper.java | 16 +++--- .../APIGatewayProxyV2TransactionHelper.java | 16 +++--- .../awslambda/helper/AWSEventsHelper.java | 6 +-- .../AbstractAPIGatewayTransactionHelper.java | 36 ++++++------- .../AbstractLambdaTransactionHelper.java | 54 +++++-------------- ...AbstractMessageBasedTransactionHelper.java | 20 +++---- .../helper/PlainTransactionHelper.java | 14 ++--- .../awslambda/helper/S3TransactionHelper.java | 24 ++++----- .../helper/SNSTransactionHelper.java | 10 ++-- .../helper/SQSTransactionHelper.java | 10 ++-- .../co/elastic/apm/agent/tracer/Faas.java | 36 +++++++++++++ .../elastic/apm/agent/tracer/FaasTrigger.java | 28 ++++++++++ .../apm/agent/tracer/GlobalTracer.java | 10 ++++ .../elastic/apm/agent/tracer/NoopTracer.java | 9 ++++ .../apm/agent/tracer/ServiceOrigin.java | 30 +++++++++++ .../co/elastic/apm/agent/tracer/Tracer.java | 9 +++- .../elastic/apm/agent/tracer/Transaction.java | 2 + .../apm/agent/tracer/TransactionContext.java | 2 + .../apm/agent/tracer/metadata/Request.java | 9 ++++ .../apm/agent/tracer/metadata/Response.java | 2 + 31 files changed, 289 insertions(+), 157 deletions(-) create mode 100644 apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/Faas.java create mode 100644 apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/FaasTrigger.java create mode 100644 apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/ServiceOrigin.java 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 6639e57be2..a376a19fc8 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 @@ -18,7 +18,9 @@ */ package co.elastic.apm.agent.impl; +import co.elastic.apm.agent.bci.ElasticApmAgent; import co.elastic.apm.agent.bci.IndyBootstrap; +import co.elastic.apm.agent.bci.InstrumentationStats; import co.elastic.apm.agent.collections.WeakReferenceCountedMap; import co.elastic.apm.agent.common.JvmRuntimeInfo; import co.elastic.apm.agent.common.util.WildcardMatcher; @@ -26,7 +28,8 @@ import co.elastic.apm.agent.configuration.CoreConfiguration; import co.elastic.apm.agent.configuration.MetricsConfiguration; import co.elastic.apm.agent.configuration.ServerlessConfiguration; -import co.elastic.apm.agent.impl.metadata.ServiceFactory; +import co.elastic.apm.agent.impl.metadata.*; +import co.elastic.apm.agent.sdk.internal.util.LoggerUtils; import co.elastic.apm.agent.tracer.service.Service; import co.elastic.apm.agent.tracer.service.ServiceInfo; import co.elastic.apm.agent.configuration.SpanConfiguration; @@ -35,7 +38,6 @@ import co.elastic.apm.agent.impl.baggage.Baggage; import co.elastic.apm.agent.impl.baggage.W3CBaggagePropagation; import co.elastic.apm.agent.impl.error.ErrorCapture; -import co.elastic.apm.agent.impl.metadata.MetaDataFuture; import co.elastic.apm.agent.impl.sampling.ProbabilitySampler; import co.elastic.apm.agent.impl.sampling.Sampler; import co.elastic.apm.agent.impl.stacktrace.StacktraceConfiguration; @@ -78,10 +80,7 @@ import java.util.List; import java.util.Map; import java.util.Set; -import java.util.concurrent.Callable; -import java.util.concurrent.CopyOnWriteArrayList; -import java.util.concurrent.ScheduledThreadPoolExecutor; -import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.*; /** @@ -92,6 +91,7 @@ */ public class ElasticApmTracer implements Tracer { private static final Logger logger = LoggerFactory.getLogger(ElasticApmTracer.class); + private static final Logger enabledInstrumentationsLogger = LoggerUtils.logOnce(logger); private static final WeakMap serviceInfoByClassLoader = WeakConcurrent.buildMap(); @@ -995,4 +995,33 @@ public Service createService(String ephemeralId) { configurationRegistry.getConfig(ServerlessConfiguration.class).runsOnAwsLambda() ); } + + @Override + public void flush() { + long flushTimeout = configurationRegistry.getConfig(ServerlessConfiguration.class).getDataFlushTimeout(); + try { + if (!reporter.flush(flushTimeout, TimeUnit.MILLISECONDS, true)) { + logger.error("APM data flush haven't completed within {} milliseconds.", flushTimeout); + } + } catch (Exception e) { + logger.error("An error occurred on flushing APM data.", e); + } + logEnabledInstrumentations(); + } + + private void logEnabledInstrumentations() { + if (enabledInstrumentationsLogger.isInfoEnabled()) { + InstrumentationStats instrumentationStats = ElasticApmAgent.getInstrumentationStats(); + enabledInstrumentationsLogger.info("Used instrumentation groups: {}", instrumentationStats.getUsedInstrumentationGroups()); + } + } + + @Override + public void completeMetaData(String name, String version, String id, String region) { + metaDataFuture.getFaaSMetaDataExtensionFuture().complete(new FaaSMetaDataExtension( + new Framework(name, version), + new NameAndIdField(null, id), + region + )); + } } diff --git a/apm-agent-core/src/main/java/co/elastic/apm/agent/impl/context/Request.java b/apm-agent-core/src/main/java/co/elastic/apm/agent/impl/context/Request.java index 028882f4e6..a6d2694b4e 100644 --- a/apm-agent-core/src/main/java/co/elastic/apm/agent/impl/context/Request.java +++ b/apm-agent-core/src/main/java/co/elastic/apm/agent/impl/context/Request.java @@ -175,13 +175,7 @@ public PotentiallyMultiValuedMap getFormUrlEncodedParameters() { return postParams; } - /** - * Adds a request header. - * - * @param headerName The name of the header. - * @param headerValue The value of the header. - * @return {@code this}, for fluent method chaining - */ + @Override public Request addHeader(String headerName, @Nullable String headerValue) { if (headerValue != null) { headers.add(headerName, headerValue); diff --git a/apm-agent-core/src/main/java/co/elastic/apm/agent/impl/context/Response.java b/apm-agent-core/src/main/java/co/elastic/apm/agent/impl/context/Response.java index 811f89293a..4a6ef90b99 100644 --- a/apm-agent-core/src/main/java/co/elastic/apm/agent/impl/context/Response.java +++ b/apm-agent-core/src/main/java/co/elastic/apm/agent/impl/context/Response.java @@ -60,8 +60,11 @@ public Response withFinished(boolean finished) { * @param headerValue The value of the header. * @return {@code this}, for fluent method chaining */ - public Response addHeader(String headerName, String headerValue) { - headers.add(headerName, headerValue); + @Override + public Response addHeader(String headerName, @Nullable String headerValue) { + if (headerValue != null) { + headers.add(headerName, headerValue); + } return this; } diff --git a/apm-agent-core/src/main/java/co/elastic/apm/agent/impl/context/ServiceOrigin.java b/apm-agent-core/src/main/java/co/elastic/apm/agent/impl/context/ServiceOrigin.java index 9927f7b66e..5cdf69b407 100644 --- a/apm-agent-core/src/main/java/co/elastic/apm/agent/impl/context/ServiceOrigin.java +++ b/apm-agent-core/src/main/java/co/elastic/apm/agent/impl/context/ServiceOrigin.java @@ -28,7 +28,7 @@ * If a request originated from another service, * the service origin interface can be used to collect information about the origin service. */ -public class ServiceOrigin implements Recyclable { +public class ServiceOrigin implements co.elastic.apm.agent.tracer.ServiceOrigin, Recyclable { @Nullable private String id; @@ -43,6 +43,7 @@ public String getId() { return id; } + @Override public ServiceOrigin withId(@Nullable String id) { this.id = id; return this; @@ -52,6 +53,7 @@ public StringBuilder getName() { return name; } + @Override public ServiceOrigin withName(@Nullable CharSequence name) { this.name.setLength(0); if (name != null) { @@ -72,6 +74,7 @@ public String getVersion() { return version; } + @Override public ServiceOrigin withVersion(@Nullable String version) { this.version = version; return this; diff --git a/apm-agent-core/src/main/java/co/elastic/apm/agent/impl/context/TransactionContext.java b/apm-agent-core/src/main/java/co/elastic/apm/agent/impl/context/TransactionContext.java index c4c9ea756b..05df0e1015 100644 --- a/apm-agent-core/src/main/java/co/elastic/apm/agent/impl/context/TransactionContext.java +++ b/apm-agent-core/src/main/java/co/elastic/apm/agent/impl/context/TransactionContext.java @@ -118,6 +118,7 @@ public CloudOrigin getCloudOrigin() { return cloudOrigin; } + @Override public ServiceOrigin getServiceOrigin() { return serviceOrigin; } diff --git a/apm-agent-core/src/main/java/co/elastic/apm/agent/impl/transaction/Faas.java b/apm-agent-core/src/main/java/co/elastic/apm/agent/impl/transaction/Faas.java index 9d7e73b5f8..1299184003 100644 --- a/apm-agent-core/src/main/java/co/elastic/apm/agent/impl/transaction/Faas.java +++ b/apm-agent-core/src/main/java/co/elastic/apm/agent/impl/transaction/Faas.java @@ -22,7 +22,7 @@ import javax.annotation.Nullable; -public class Faas implements Recyclable { +public class Faas implements co.elastic.apm.agent.tracer.Faas, Recyclable { @Nullable private String execution; @@ -68,26 +68,31 @@ public String getVersion() { return version; } + @Override public Faas withExecution(@Nullable String execution) { this.execution = execution; return this; } + @Override public Faas withColdStart(boolean coldStart) { this.coldStart = coldStart; return this; } + @Override public Faas withId(@Nullable String id) { this.id = id; return this; } + @Override public Faas withName(@Nullable String name) { this.name = name; return this; } + @Override public Faas withVersion(@Nullable String version) { this.version = version; return this; diff --git a/apm-agent-core/src/main/java/co/elastic/apm/agent/impl/transaction/FaasTrigger.java b/apm-agent-core/src/main/java/co/elastic/apm/agent/impl/transaction/FaasTrigger.java index 6d80601634..d3d3fb3775 100644 --- a/apm-agent-core/src/main/java/co/elastic/apm/agent/impl/transaction/FaasTrigger.java +++ b/apm-agent-core/src/main/java/co/elastic/apm/agent/impl/transaction/FaasTrigger.java @@ -22,7 +22,7 @@ import javax.annotation.Nullable; -public class FaasTrigger implements Recyclable { +public class FaasTrigger implements co.elastic.apm.agent.tracer.FaasTrigger, Recyclable { @Nullable private String type; @@ -40,11 +40,13 @@ public String getRequestId() { return requestId; } + @Override public FaasTrigger withType(@Nullable String type) { this.type = type; return this; } + @Override public FaasTrigger withRequestId(@Nullable String requestId) { this.requestId = requestId; return this; diff --git a/apm-agent-plugins/apm-awslambda-plugin/pom.xml b/apm-agent-plugins/apm-awslambda-plugin/pom.xml index 922bbab4be..b9e16a4ab1 100644 --- a/apm-agent-plugins/apm-awslambda-plugin/pom.xml +++ b/apm-agent-plugins/apm-awslambda-plugin/pom.xml @@ -17,12 +17,6 @@ - - - ${project.groupId} - apm-agent-core - ${project.version} - com.amazonaws aws-lambda-java-core diff --git a/apm-agent-plugins/apm-awslambda-plugin/src/main/java/co/elastic/apm/agent/awslambda/AbstractAwsLambdaHandlerInstrumentation.java b/apm-agent-plugins/apm-awslambda-plugin/src/main/java/co/elastic/apm/agent/awslambda/AbstractAwsLambdaHandlerInstrumentation.java index d447a53d40..a79ee7c37c 100644 --- a/apm-agent-plugins/apm-awslambda-plugin/src/main/java/co/elastic/apm/agent/awslambda/AbstractAwsLambdaHandlerInstrumentation.java +++ b/apm-agent-plugins/apm-awslambda-plugin/src/main/java/co/elastic/apm/agent/awslambda/AbstractAwsLambdaHandlerInstrumentation.java @@ -18,8 +18,8 @@ */ package co.elastic.apm.agent.awslambda; -import co.elastic.apm.agent.impl.ElasticApmTracer; import co.elastic.apm.agent.sdk.ElasticApmInstrumentation; +import co.elastic.apm.agent.tracer.Tracer; import co.elastic.apm.agent.tracer.configuration.ServerlessConfiguration; import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.matcher.ElementMatcher; @@ -41,7 +41,7 @@ public abstract class AbstractAwsLambdaHandlerInstrumentation extends ElasticApm @Nullable protected String handlerMethodName; - public AbstractAwsLambdaHandlerInstrumentation(ElasticApmTracer tracer) { + public AbstractAwsLambdaHandlerInstrumentation(Tracer tracer) { serverlessConfiguration = tracer.getConfig(ServerlessConfiguration.class); String awsLambdaHandler = serverlessConfiguration.getAwsLambdaHandler(); //noinspection ConstantConditions diff --git a/apm-agent-plugins/apm-awslambda-plugin/src/main/java/co/elastic/apm/agent/awslambda/RequestHandlerInstrumentation.java b/apm-agent-plugins/apm-awslambda-plugin/src/main/java/co/elastic/apm/agent/awslambda/RequestHandlerInstrumentation.java index 0d443b1316..a709840e7e 100644 --- a/apm-agent-plugins/apm-awslambda-plugin/src/main/java/co/elastic/apm/agent/awslambda/RequestHandlerInstrumentation.java +++ b/apm-agent-plugins/apm-awslambda-plugin/src/main/java/co/elastic/apm/agent/awslambda/RequestHandlerInstrumentation.java @@ -20,8 +20,8 @@ import co.elastic.apm.agent.awslambda.helper.AWSEventsHelper; import co.elastic.apm.agent.awslambda.helper.PlainTransactionHelper; -import co.elastic.apm.agent.impl.ElasticApmTracer; -import co.elastic.apm.agent.impl.transaction.Transaction; +import co.elastic.apm.agent.tracer.Tracer; +import co.elastic.apm.agent.tracer.Transaction; import com.amazonaws.services.lambda.runtime.Context; import net.bytebuddy.asm.Advice; import net.bytebuddy.description.method.MethodDescription; @@ -35,7 +35,7 @@ public class RequestHandlerInstrumentation extends AbstractAwsLambdaHandlerInstrumentation { - public RequestHandlerInstrumentation(ElasticApmTracer tracer) { + public RequestHandlerInstrumentation(Tracer tracer) { super(tracer); } @@ -70,8 +70,8 @@ public static Object handlerEnter(@Nullable @Advice.Argument(value = 0) Object i public static void handlerExit(@Nullable @Advice.Enter Object transactionObj, @Nullable @Advice.Thrown Throwable thrown, @Nullable @Advice.Return Object output) { - if (transactionObj instanceof Transaction) { - Transaction transaction = (Transaction) transactionObj; + if (transactionObj instanceof Transaction) { + Transaction transaction = (Transaction) transactionObj; if (output != null && output.getClass().getName().startsWith("com.amazonaws.services.lambda.runtime.events")) { // handler uses aws events, it's safe to assume that the AWS events classes are available diff --git a/apm-agent-plugins/apm-awslambda-plugin/src/main/java/co/elastic/apm/agent/awslambda/RequestStreamHandlerInstrumentation.java b/apm-agent-plugins/apm-awslambda-plugin/src/main/java/co/elastic/apm/agent/awslambda/RequestStreamHandlerInstrumentation.java index a32e9a5246..e97fe84d19 100644 --- a/apm-agent-plugins/apm-awslambda-plugin/src/main/java/co/elastic/apm/agent/awslambda/RequestStreamHandlerInstrumentation.java +++ b/apm-agent-plugins/apm-awslambda-plugin/src/main/java/co/elastic/apm/agent/awslambda/RequestStreamHandlerInstrumentation.java @@ -19,8 +19,8 @@ package co.elastic.apm.agent.awslambda; import co.elastic.apm.agent.awslambda.helper.PlainTransactionHelper; -import co.elastic.apm.agent.impl.ElasticApmTracer; -import co.elastic.apm.agent.impl.transaction.Transaction; +import co.elastic.apm.agent.tracer.Tracer; +import co.elastic.apm.agent.tracer.Transaction; import com.amazonaws.services.lambda.runtime.Context; import net.bytebuddy.asm.Advice; import net.bytebuddy.description.method.MethodDescription; @@ -35,7 +35,7 @@ public class RequestStreamHandlerInstrumentation extends AbstractAwsLambdaHandlerInstrumentation { - public RequestStreamHandlerInstrumentation(ElasticApmTracer tracer) { + public RequestStreamHandlerInstrumentation(Tracer tracer) { super(tracer); } @@ -65,8 +65,8 @@ public static Object handlerEnter(@Advice.Argument(value = 0) InputStream inputS @Advice.OnMethodExit(suppress = Throwable.class, inline = false, onThrowable = Throwable.class) public static void handlerExit(@Nullable @Advice.Enter Object transactionObj, @Nullable @Advice.Thrown Throwable thrown) { - if (transactionObj instanceof Transaction) { - Transaction transaction = (Transaction) transactionObj; + if (transactionObj instanceof Transaction) { + Transaction transaction = (Transaction) transactionObj; PlainTransactionHelper.getInstance().finalizeTransaction(transaction, null, thrown); } } diff --git a/apm-agent-plugins/apm-awslambda-plugin/src/main/java/co/elastic/apm/agent/awslambda/helper/APIGatewayProxyV1TransactionHelper.java b/apm-agent-plugins/apm-awslambda-plugin/src/main/java/co/elastic/apm/agent/awslambda/helper/APIGatewayProxyV1TransactionHelper.java index d2d4589d9c..20cbe4c828 100644 --- a/apm-agent-plugins/apm-awslambda-plugin/src/main/java/co/elastic/apm/agent/awslambda/helper/APIGatewayProxyV1TransactionHelper.java +++ b/apm-agent-plugins/apm-awslambda-plugin/src/main/java/co/elastic/apm/agent/awslambda/helper/APIGatewayProxyV1TransactionHelper.java @@ -19,10 +19,10 @@ package co.elastic.apm.agent.awslambda.helper; import co.elastic.apm.agent.awslambda.MapTextHeaderGetter; -import co.elastic.apm.agent.impl.ElasticApmTracer; import co.elastic.apm.agent.tracer.GlobalTracer; -import co.elastic.apm.agent.impl.transaction.Transaction; import co.elastic.apm.agent.sdk.internal.util.PrivilegedActionUtils; +import co.elastic.apm.agent.tracer.Tracer; +import co.elastic.apm.agent.tracer.Transaction; import com.amazonaws.services.lambda.runtime.Context; import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent; import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent; @@ -35,20 +35,20 @@ public class APIGatewayProxyV1TransactionHelper extends AbstractAPIGatewayTransa @Nullable private static APIGatewayProxyV1TransactionHelper INSTANCE; - private APIGatewayProxyV1TransactionHelper(ElasticApmTracer tracer) { + private APIGatewayProxyV1TransactionHelper(Tracer tracer) { super(tracer); } public static APIGatewayProxyV1TransactionHelper getInstance() { if (INSTANCE == null) { - INSTANCE = new APIGatewayProxyV1TransactionHelper(GlobalTracer.get().require(ElasticApmTracer.class)); + INSTANCE = new APIGatewayProxyV1TransactionHelper(GlobalTracer.get()); } return INSTANCE; } @Override - protected Transaction doStartTransaction(APIGatewayProxyRequestEvent apiGatewayEvent, Context lambdaContext) { - Transaction transaction = tracer.startChildTransaction(apiGatewayEvent.getHeaders(), MapTextHeaderGetter.INSTANCE, PrivilegedActionUtils.getClassLoader(apiGatewayEvent.getClass())); + protected Transaction doStartTransaction(APIGatewayProxyRequestEvent apiGatewayEvent, Context lambdaContext) { + Transaction transaction = tracer.startChildTransaction(apiGatewayEvent.getHeaders(), MapTextHeaderGetter.INSTANCE, PrivilegedActionUtils.getClassLoader(apiGatewayEvent.getClass())); String host = getHost(apiGatewayEvent); if (null != transaction) { @@ -92,7 +92,7 @@ private String getQueryString(APIGatewayProxyRequestEvent apiGatewayEvent) { } @Override - public void captureOutputForTransaction(Transaction transaction, APIGatewayProxyResponseEvent responseEvent) { + public void captureOutputForTransaction(Transaction transaction, APIGatewayProxyResponseEvent responseEvent) { Integer statusCode = responseEvent.getStatusCode(); if (statusCode == null) { statusCode = 0; @@ -101,7 +101,7 @@ public void captureOutputForTransaction(Transaction transaction, APIGatewayProxy } @Override - protected void setTransactionTriggerData(Transaction transaction, APIGatewayProxyRequestEvent apiGatewayRequest) { + protected void setTransactionTriggerData(Transaction transaction, APIGatewayProxyRequestEvent apiGatewayRequest) { super.setTransactionTriggerData(transaction, apiGatewayRequest); APIGatewayProxyRequestEvent.ProxyRequestContext rContext = apiGatewayRequest.getRequestContext(); diff --git a/apm-agent-plugins/apm-awslambda-plugin/src/main/java/co/elastic/apm/agent/awslambda/helper/APIGatewayProxyV2TransactionHelper.java b/apm-agent-plugins/apm-awslambda-plugin/src/main/java/co/elastic/apm/agent/awslambda/helper/APIGatewayProxyV2TransactionHelper.java index ec7ed0db69..db3edf620b 100644 --- a/apm-agent-plugins/apm-awslambda-plugin/src/main/java/co/elastic/apm/agent/awslambda/helper/APIGatewayProxyV2TransactionHelper.java +++ b/apm-agent-plugins/apm-awslambda-plugin/src/main/java/co/elastic/apm/agent/awslambda/helper/APIGatewayProxyV2TransactionHelper.java @@ -19,10 +19,10 @@ package co.elastic.apm.agent.awslambda.helper; import co.elastic.apm.agent.awslambda.MapTextHeaderGetter; -import co.elastic.apm.agent.impl.ElasticApmTracer; import co.elastic.apm.agent.tracer.GlobalTracer; -import co.elastic.apm.agent.impl.transaction.Transaction; import co.elastic.apm.agent.sdk.internal.util.PrivilegedActionUtils; +import co.elastic.apm.agent.tracer.Tracer; +import co.elastic.apm.agent.tracer.Transaction; import com.amazonaws.services.lambda.runtime.Context; import com.amazonaws.services.lambda.runtime.events.APIGatewayV2HTTPEvent; import com.amazonaws.services.lambda.runtime.events.APIGatewayV2HTTPResponse; @@ -33,20 +33,20 @@ public class APIGatewayProxyV2TransactionHelper extends AbstractAPIGatewayTransa @Nullable private static APIGatewayProxyV2TransactionHelper INSTANCE; - private APIGatewayProxyV2TransactionHelper(ElasticApmTracer tracer) { + private APIGatewayProxyV2TransactionHelper(Tracer tracer) { super(tracer); } public static APIGatewayProxyV2TransactionHelper getInstance() { if (INSTANCE == null) { - INSTANCE = new APIGatewayProxyV2TransactionHelper(GlobalTracer.get().require(ElasticApmTracer.class)); + INSTANCE = new APIGatewayProxyV2TransactionHelper(GlobalTracer.get()); } return INSTANCE; } @Override - protected Transaction doStartTransaction(APIGatewayV2HTTPEvent apiGatewayEvent, Context lambdaContext) { - Transaction transaction = tracer.startChildTransaction(apiGatewayEvent.getHeaders(), MapTextHeaderGetter.INSTANCE, PrivilegedActionUtils.getClassLoader(apiGatewayEvent.getClass())); + protected Transaction doStartTransaction(APIGatewayV2HTTPEvent apiGatewayEvent, Context lambdaContext) { + Transaction transaction = tracer.startChildTransaction(apiGatewayEvent.getHeaders(), MapTextHeaderGetter.INSTANCE, PrivilegedActionUtils.getClassLoader(apiGatewayEvent.getClass())); APIGatewayV2HTTPEvent.RequestContext requestContext = apiGatewayEvent.getRequestContext(); if (transaction != null) { @@ -60,12 +60,12 @@ protected Transaction doStartTransaction(APIGatewayV2HTTPEvent apiGatewayEvent, } @Override - public void captureOutputForTransaction(Transaction transaction, APIGatewayV2HTTPResponse responseEvent) { + public void captureOutputForTransaction(Transaction transaction, APIGatewayV2HTTPResponse responseEvent) { fillHttpResponseData(transaction, responseEvent.getHeaders(), responseEvent.getStatusCode()); } @Override - protected void setTransactionTriggerData(Transaction transaction, APIGatewayV2HTTPEvent apiGatewayRequest) { + protected void setTransactionTriggerData(Transaction transaction, APIGatewayV2HTTPEvent apiGatewayRequest) { super.setTransactionTriggerData(transaction, apiGatewayRequest); APIGatewayV2HTTPEvent.RequestContext rContext = apiGatewayRequest.getRequestContext(); setApiGatewayContextData(transaction, rContext.getRequestId(), rContext.getApiId(), diff --git a/apm-agent-plugins/apm-awslambda-plugin/src/main/java/co/elastic/apm/agent/awslambda/helper/AWSEventsHelper.java b/apm-agent-plugins/apm-awslambda-plugin/src/main/java/co/elastic/apm/agent/awslambda/helper/AWSEventsHelper.java index 9ec285ad99..b72c423c79 100644 --- a/apm-agent-plugins/apm-awslambda-plugin/src/main/java/co/elastic/apm/agent/awslambda/helper/AWSEventsHelper.java +++ b/apm-agent-plugins/apm-awslambda-plugin/src/main/java/co/elastic/apm/agent/awslambda/helper/AWSEventsHelper.java @@ -18,7 +18,7 @@ */ package co.elastic.apm.agent.awslambda.helper; -import co.elastic.apm.agent.impl.transaction.Transaction; +import co.elastic.apm.agent.tracer.Transaction; import com.amazonaws.services.lambda.runtime.Context; import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent; import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent; @@ -33,7 +33,7 @@ public class AWSEventsHelper { @Nullable - public static Transaction startTransaction(Object input, Context lambdaContext) { + public static Transaction startTransaction(Object input, Context lambdaContext) { if (input instanceof APIGatewayV2HTTPEvent && ((APIGatewayV2HTTPEvent) input).getRequestContext() != null && ((APIGatewayV2HTTPEvent) input).getRequestContext().getHttp() != null) { // API Gateway V2 trigger @@ -54,7 +54,7 @@ public static Transaction startTransaction(Object input, Context lambdaContext) return PlainTransactionHelper.getInstance().startTransaction(input, lambdaContext); } - public static void finalizeTransaction(Transaction transaction, Object output, @Nullable Throwable thrown) { + public static void finalizeTransaction(Transaction transaction, Object output, @Nullable Throwable thrown) { if (output instanceof APIGatewayV2HTTPResponse) { APIGatewayProxyV2TransactionHelper.getInstance().finalizeTransaction(transaction, (APIGatewayV2HTTPResponse) output, thrown); } else if (output instanceof APIGatewayProxyResponseEvent) { diff --git a/apm-agent-plugins/apm-awslambda-plugin/src/main/java/co/elastic/apm/agent/awslambda/helper/AbstractAPIGatewayTransactionHelper.java b/apm-agent-plugins/apm-awslambda-plugin/src/main/java/co/elastic/apm/agent/awslambda/helper/AbstractAPIGatewayTransactionHelper.java index 72c1d0eecb..b30ba86151 100644 --- a/apm-agent-plugins/apm-awslambda-plugin/src/main/java/co/elastic/apm/agent/awslambda/helper/AbstractAPIGatewayTransactionHelper.java +++ b/apm-agent-plugins/apm-awslambda-plugin/src/main/java/co/elastic/apm/agent/awslambda/helper/AbstractAPIGatewayTransactionHelper.java @@ -18,13 +18,13 @@ */ package co.elastic.apm.agent.awslambda.helper; -import co.elastic.apm.agent.impl.ElasticApmTracer; -import co.elastic.apm.agent.impl.context.CloudOrigin; -import co.elastic.apm.agent.impl.context.Request; -import co.elastic.apm.agent.impl.context.Response; -import co.elastic.apm.agent.impl.context.ServiceOrigin; +import co.elastic.apm.agent.tracer.ServiceOrigin; +import co.elastic.apm.agent.tracer.Tracer; +import co.elastic.apm.agent.tracer.Transaction; +import co.elastic.apm.agent.tracer.metadata.CloudOrigin; +import co.elastic.apm.agent.tracer.metadata.Request; +import co.elastic.apm.agent.tracer.metadata.Response; import co.elastic.apm.agent.tracer.util.ResultUtil; -import co.elastic.apm.agent.impl.transaction.Transaction; import co.elastic.apm.agent.common.util.WildcardMatcher; import co.elastic.apm.agent.sdk.logging.Logger; import co.elastic.apm.agent.sdk.logging.LoggerFactory; @@ -47,13 +47,13 @@ public abstract class AbstractAPIGatewayTransactionHelper extends Abstract private static final Set METHODS_WITH_BODY = new HashSet<>(Arrays.asList("POST", "PUT", "PATCH", "DELETE")); private static final String CONTENT_TYPE_FROM_URLENCODED = "application/x-www-form-urlencoded"; - protected AbstractAPIGatewayTransactionHelper(ElasticApmTracer tracer) { + protected AbstractAPIGatewayTransactionHelper(Tracer tracer) { super(tracer); } protected abstract String getApiGatewayVersion(); - protected void fillHttpRequestData(Transaction transaction, @Nullable String httpMethod, @Nullable Map headers, @Nullable String serverName, @Nullable String path, @Nullable String queryString, @Nullable String body) { + protected void fillHttpRequestData(Transaction transaction, @Nullable String httpMethod, @Nullable Map headers, @Nullable String serverName, @Nullable String path, @Nullable String queryString, @Nullable String body) { Request request = transaction.getContext().getRequest(); request.withMethod(httpMethod); fillUrlRelatedFields(request, serverName, path, queryString); @@ -67,7 +67,7 @@ protected void fillHttpRequestData(Transaction transaction, @Nullable String htt } } - protected void fillHttpResponseData(Transaction transaction, @Nullable Map headers, int statusCode) { + protected void fillHttpResponseData(Transaction transaction, @Nullable Map headers, int statusCode) { Response response = transaction.getContext().getResponse(); response.withFinished(true); if (transaction.isSampled() && null != headers && isCaptureHeaders()) { @@ -82,17 +82,11 @@ protected void fillHttpResponseData(Transaction transaction, @Nullable Map transaction, @Nullable String method, @Nullable String contentTypeHeader) { Request request = transaction.getContext().getRequest(); if (hasBody(contentTypeHeader, method)) { if (coreConfiguration.getCaptureBody() != OFF @@ -127,7 +121,7 @@ private boolean hasBody(@Nullable String contentTypeHeader, @Nullable String met } @Override - protected void setTransactionTriggerData(Transaction transaction, I apiGatewayRequest) { + protected void setTransactionTriggerData(Transaction transaction, I apiGatewayRequest) { transaction.withType(TRANSACTION_TYPE); CloudOrigin cloudOrigin = transaction.getContext().getCloudOrigin(); cloudOrigin.withServiceName("api gateway"); @@ -136,7 +130,7 @@ protected void setTransactionTriggerData(Transaction transaction, I apiGatewayRe transaction.getContext().getServiceOrigin().withVersion(getApiGatewayVersion()); } - protected void setApiGatewayContextData(Transaction transaction, @Nullable String requestId, @Nullable String apiId, + protected void setApiGatewayContextData(Transaction transaction, @Nullable String requestId, @Nullable String apiId, @Nullable String domainName, @Nullable String accountId) { transaction.getFaas().getTrigger().withRequestId(requestId); ServiceOrigin serviceOrigin = transaction.getContext().getServiceOrigin(); @@ -146,7 +140,7 @@ protected void setApiGatewayContextData(Transaction transaction, @Nullable Strin transaction.getContext().getCloudOrigin().withAccountId(accountId); } - private void setRequestHeaders(Transaction transaction, Map headers) { + private void setRequestHeaders(Transaction transaction, Map headers) { final Request req = transaction.getContext().getRequest(); if (transaction.isSampled() && isCaptureHeaders()) { for (Map.Entry headerEntry : headers.entrySet()) { @@ -156,7 +150,7 @@ private void setRequestHeaders(Transaction transaction, Map head } @Override - protected void setTransactionName(Transaction transaction, I event, Context lambdaContext) { + protected void setTransactionName(Transaction transaction, I event, Context lambdaContext) { StringBuilder transactionName = transaction.getAndOverrideName(AbstractSpan.PRIORITY_HIGH_LEVEL_FRAMEWORK); if (transactionName != null) { String httpMethod = getHttpMethod(event); diff --git a/apm-agent-plugins/apm-awslambda-plugin/src/main/java/co/elastic/apm/agent/awslambda/helper/AbstractLambdaTransactionHelper.java b/apm-agent-plugins/apm-awslambda-plugin/src/main/java/co/elastic/apm/agent/awslambda/helper/AbstractLambdaTransactionHelper.java index 8c61317ce1..2763e7423b 100644 --- a/apm-agent-plugins/apm-awslambda-plugin/src/main/java/co/elastic/apm/agent/awslambda/helper/AbstractLambdaTransactionHelper.java +++ b/apm-agent-plugins/apm-awslambda-plugin/src/main/java/co/elastic/apm/agent/awslambda/helper/AbstractLambdaTransactionHelper.java @@ -18,50 +18,42 @@ */ package co.elastic.apm.agent.awslambda.helper; -import co.elastic.apm.agent.bci.ElasticApmAgent; -import co.elastic.apm.agent.bci.InstrumentationStats; -import co.elastic.apm.agent.impl.ElasticApmTracer; +import co.elastic.apm.agent.tracer.Tracer; +import co.elastic.apm.agent.tracer.Transaction; import co.elastic.apm.agent.tracer.configuration.CoreConfiguration; import co.elastic.apm.agent.tracer.configuration.ServerlessConfiguration; import co.elastic.apm.agent.tracer.configuration.WebConfiguration; -import co.elastic.apm.agent.impl.metadata.FaaSMetaDataExtension; -import co.elastic.apm.agent.impl.metadata.Framework; -import co.elastic.apm.agent.impl.metadata.NameAndIdField; -import co.elastic.apm.agent.impl.transaction.Transaction; import co.elastic.apm.agent.sdk.logging.Logger; import co.elastic.apm.agent.sdk.logging.LoggerFactory; import co.elastic.apm.agent.tracer.AbstractSpan; -import co.elastic.apm.agent.sdk.internal.util.LoggerUtils; import co.elastic.apm.agent.sdk.internal.util.VersionUtils; import com.amazonaws.services.lambda.runtime.Context; import com.amazonaws.services.lambda.runtime.RequestHandler; import javax.annotation.Nullable; -import java.util.concurrent.TimeUnit; public abstract class AbstractLambdaTransactionHelper { private static final Logger logger = LoggerFactory.getLogger(AbstractLambdaTransactionHelper.class); - private static final Logger enabledInstrumentationsLogger = LoggerUtils.logOnce(logger); - protected final ElasticApmTracer tracer; + protected final Tracer tracer; protected final ServerlessConfiguration serverlessConfiguration; protected final CoreConfiguration coreConfiguration; protected final WebConfiguration webConfiguration; - protected AbstractLambdaTransactionHelper(ElasticApmTracer tracer) { + protected AbstractLambdaTransactionHelper(Tracer tracer) { this.tracer = tracer; this.coreConfiguration = tracer.getConfig(CoreConfiguration.class); this.webConfiguration = tracer.getConfig(WebConfiguration.class); this.serverlessConfiguration = tracer.getConfig(ServerlessConfiguration.class); } - protected abstract void setTransactionTriggerData(Transaction transaction, I input); + protected abstract void setTransactionTriggerData(Transaction transaction, I input); @Nullable - protected abstract Transaction doStartTransaction(I input, Context lambdaContext); + protected abstract Transaction doStartTransaction(I input, Context lambdaContext); - protected abstract void captureOutputForTransaction(Transaction transaction, O output); + protected abstract void captureOutputForTransaction(Transaction transaction, O output); private static boolean coldStart = true; @@ -69,13 +61,13 @@ protected AbstractLambdaTransactionHelper(ElasticApmTracer tracer) { private String functionArn; @Nullable - public Transaction startTransaction(I input, Context lambdaContext) { + public Transaction startTransaction(I input, Context lambdaContext) { boolean isColdStart = coldStart; if (isColdStart) { completeMetaData(lambdaContext); coldStart = false; } - Transaction transaction = doStartTransaction(input, lambdaContext); + Transaction transaction = doStartTransaction(input, lambdaContext); if (null != transaction) { transaction.getFaas() .withId(getFaasId(lambdaContext)) @@ -104,7 +96,7 @@ private String getFaasId(Context lambdaContext) { return functionArn; } - public void finalizeTransaction(Transaction transaction, @Nullable O output, @Nullable Throwable thrown) { + public void finalizeTransaction(Transaction transaction, @Nullable O output, @Nullable Throwable thrown) { try { if (null != output) { captureOutputForTransaction(transaction, output); @@ -118,23 +110,7 @@ public void finalizeTransaction(Transaction transaction, @Nullable O output, @Nu } finally { transaction.deactivate().end(); } - long flushTimeout = serverlessConfiguration.getDataFlushTimeout(); - try { - if (!tracer.getReporter().flush(flushTimeout, TimeUnit.MILLISECONDS, true)) { - logger.error("APM data flush haven't completed within {} milliseconds.", flushTimeout); - } - } catch (Exception e) { - logger.error("An error occurred on flushing APM data.", e); - } - - logEnabledInstrumentations(); - } - - private void logEnabledInstrumentations() { - if (enabledInstrumentationsLogger.isInfoEnabled()) { - InstrumentationStats instrumentationStats = ElasticApmAgent.getInstrumentationStats(); - enabledInstrumentationsLogger.info("Used instrumentation groups: {}", instrumentationStats.getUsedInstrumentationGroups()); - } + tracer.flush(); } private void completeMetaData(Context lambdaContext) { @@ -149,17 +125,13 @@ private void completeMetaData(Context lambdaContext) { lambdaLibVersion = "unknown"; } - tracer.getMetaDataFuture().getFaaSMetaDataExtensionFuture().complete(new FaaSMetaDataExtension( - new Framework("AWS Lambda", lambdaLibVersion), - new NameAndIdField(null, accountId), - region - )); + tracer.completeMetaData("AWS Lambda", lambdaLibVersion, accountId, region); } catch (Exception e) { logger.error("Failed updating metadata for first lambda execution!", e); } } - protected void setTransactionName(Transaction transaction, I event, Context lambdaContext) { + protected void setTransactionName(Transaction transaction, I event, Context lambdaContext) { StringBuilder transactionName = transaction.getAndOverrideName(AbstractSpan.PRIORITY_HIGH_LEVEL_FRAMEWORK); if (transactionName != null) { transactionName.append(lambdaContext.getFunctionName()); diff --git a/apm-agent-plugins/apm-awslambda-plugin/src/main/java/co/elastic/apm/agent/awslambda/helper/AbstractMessageBasedTransactionHelper.java b/apm-agent-plugins/apm-awslambda-plugin/src/main/java/co/elastic/apm/agent/awslambda/helper/AbstractMessageBasedTransactionHelper.java index 328d88febf..68071da7bc 100644 --- a/apm-agent-plugins/apm-awslambda-plugin/src/main/java/co/elastic/apm/agent/awslambda/helper/AbstractMessageBasedTransactionHelper.java +++ b/apm-agent-plugins/apm-awslambda-plugin/src/main/java/co/elastic/apm/agent/awslambda/helper/AbstractMessageBasedTransactionHelper.java @@ -18,12 +18,12 @@ */ package co.elastic.apm.agent.awslambda.helper; -import co.elastic.apm.agent.impl.ElasticApmTracer; -import co.elastic.apm.agent.impl.context.CloudOrigin; -import co.elastic.apm.agent.impl.context.ServiceOrigin; -import co.elastic.apm.agent.impl.transaction.Transaction; import co.elastic.apm.agent.tracer.AbstractSpan; import co.elastic.apm.agent.sdk.internal.util.PrivilegedActionUtils; +import co.elastic.apm.agent.tracer.ServiceOrigin; +import co.elastic.apm.agent.tracer.Tracer; +import co.elastic.apm.agent.tracer.Transaction; +import co.elastic.apm.agent.tracer.metadata.CloudOrigin; import com.amazonaws.services.lambda.runtime.Context; import javax.annotation.Nullable; @@ -31,7 +31,7 @@ public abstract class AbstractMessageBasedTransactionHelper extends AbstractLambdaTransactionHelper { protected static final String TRANSACTION_TYPE = "messaging"; - protected AbstractMessageBasedTransactionHelper(ElasticApmTracer tracer) { + protected AbstractMessageBasedTransactionHelper(Tracer tracer) { super(tracer); } @@ -50,23 +50,23 @@ protected AbstractMessageBasedTransactionHelper(ElasticApmTracer tracer) { @Nullable @Override - protected Transaction doStartTransaction(I event, Context lambdaContext) { - Transaction transaction = tracer.startRootTransaction(PrivilegedActionUtils.getClassLoader(lambdaContext.getClass())); + protected Transaction doStartTransaction(I event, Context lambdaContext) { + Transaction transaction = tracer.startRootTransaction(PrivilegedActionUtils.getClassLoader(lambdaContext.getClass())); if (null != transaction) { addSpanLinks(transaction, event); } return transaction; } - protected abstract void addSpanLinks(Transaction transaction, I event); + protected abstract void addSpanLinks(Transaction transaction, I event); @Override - public void captureOutputForTransaction(Transaction transaction, O output) { + public void captureOutputForTransaction(Transaction transaction, O output) { // Nothing to do here } @Override - protected void setTransactionTriggerData(Transaction transaction, I event) { + protected void setTransactionTriggerData(Transaction transaction, I event) { R record = getFirstRecord(event); transaction.withType(TRANSACTION_TYPE); diff --git a/apm-agent-plugins/apm-awslambda-plugin/src/main/java/co/elastic/apm/agent/awslambda/helper/PlainTransactionHelper.java b/apm-agent-plugins/apm-awslambda-plugin/src/main/java/co/elastic/apm/agent/awslambda/helper/PlainTransactionHelper.java index d86880d0f4..a0453ad866 100644 --- a/apm-agent-plugins/apm-awslambda-plugin/src/main/java/co/elastic/apm/agent/awslambda/helper/PlainTransactionHelper.java +++ b/apm-agent-plugins/apm-awslambda-plugin/src/main/java/co/elastic/apm/agent/awslambda/helper/PlainTransactionHelper.java @@ -18,10 +18,10 @@ */ package co.elastic.apm.agent.awslambda.helper; -import co.elastic.apm.agent.impl.ElasticApmTracer; import co.elastic.apm.agent.tracer.GlobalTracer; -import co.elastic.apm.agent.impl.transaction.Transaction; import co.elastic.apm.agent.sdk.internal.util.PrivilegedActionUtils; +import co.elastic.apm.agent.tracer.Tracer; +import co.elastic.apm.agent.tracer.Transaction; import com.amazonaws.services.lambda.runtime.Context; import javax.annotation.Nullable; @@ -33,29 +33,29 @@ public class PlainTransactionHelper extends AbstractLambdaTransactionHelper doStartTransaction(Object input, Context lambdaContext) { return tracer.startRootTransaction(PrivilegedActionUtils.getClassLoader(lambdaContext.getClass())); } @Override - public void captureOutputForTransaction(Transaction transaction, Object output) { + public void captureOutputForTransaction(Transaction transaction, Object output) { // Nothing to do here } @Override - protected void setTransactionTriggerData(Transaction transaction, Object input) { + protected void setTransactionTriggerData(Transaction transaction, Object input) { transaction.getFaas().getTrigger().withType("other"); transaction.withType(TRANSACTION_TYPE); } diff --git a/apm-agent-plugins/apm-awslambda-plugin/src/main/java/co/elastic/apm/agent/awslambda/helper/S3TransactionHelper.java b/apm-agent-plugins/apm-awslambda-plugin/src/main/java/co/elastic/apm/agent/awslambda/helper/S3TransactionHelper.java index e2203a665d..ac00d9ef54 100644 --- a/apm-agent-plugins/apm-awslambda-plugin/src/main/java/co/elastic/apm/agent/awslambda/helper/S3TransactionHelper.java +++ b/apm-agent-plugins/apm-awslambda-plugin/src/main/java/co/elastic/apm/agent/awslambda/helper/S3TransactionHelper.java @@ -18,14 +18,14 @@ */ package co.elastic.apm.agent.awslambda.helper; -import co.elastic.apm.agent.impl.ElasticApmTracer; +import co.elastic.apm.agent.sdk.internal.util.PrivilegedActionUtils; import co.elastic.apm.agent.tracer.AbstractSpan; +import co.elastic.apm.agent.tracer.FaasTrigger; import co.elastic.apm.agent.tracer.GlobalTracer; -import co.elastic.apm.agent.impl.context.CloudOrigin; -import co.elastic.apm.agent.impl.context.ServiceOrigin; -import co.elastic.apm.agent.impl.transaction.FaasTrigger; -import co.elastic.apm.agent.impl.transaction.Transaction; -import co.elastic.apm.agent.sdk.internal.util.PrivilegedActionUtils; +import co.elastic.apm.agent.tracer.ServiceOrigin; +import co.elastic.apm.agent.tracer.Tracer; +import co.elastic.apm.agent.tracer.Transaction; +import co.elastic.apm.agent.tracer.metadata.CloudOrigin; import com.amazonaws.services.lambda.runtime.Context; import com.amazonaws.services.lambda.runtime.events.S3Event; import com.amazonaws.services.lambda.runtime.events.models.s3.S3EventNotification; @@ -38,13 +38,13 @@ public class S3TransactionHelper extends AbstractLambdaTransactionHelper doStartTransaction(S3Event s3Event, Context lambdaContext) { return tracer.startRootTransaction(PrivilegedActionUtils.getClassLoader(lambdaContext.getClass())); } @Override - public void captureOutputForTransaction(Transaction transaction, Void output) { + public void captureOutputForTransaction(Transaction transaction, Void output) { // Nothing to do here } @Override - protected void setTransactionTriggerData(Transaction transaction, S3Event s3Event) { + protected void setTransactionTriggerData(Transaction transaction, S3Event s3Event) { transaction.withType(TRANSACTION_TYPE); FaasTrigger faasTrigger = transaction.getFaas().getTrigger(); @@ -97,7 +97,7 @@ protected void setTransactionTriggerData(Transaction transaction, S3Event s3Even } @Override - protected void setTransactionName(Transaction transaction, S3Event s3Event, Context lambdaContext) { + protected void setTransactionName(Transaction transaction, S3Event s3Event, Context lambdaContext) { S3EventNotification.S3EventNotificationRecord s3NotificationRecord = getS3NotificationRecord(s3Event); StringBuilder transactionName = transaction.getAndOverrideName(AbstractSpan.PRIORITY_HIGH_LEVEL_FRAMEWORK); if (transactionName != null && null != s3NotificationRecord && null != s3NotificationRecord.getS3() && null != s3NotificationRecord.getS3().getBucket()) { diff --git a/apm-agent-plugins/apm-awslambda-plugin/src/main/java/co/elastic/apm/agent/awslambda/helper/SNSTransactionHelper.java b/apm-agent-plugins/apm-awslambda-plugin/src/main/java/co/elastic/apm/agent/awslambda/helper/SNSTransactionHelper.java index ed635f00e4..9e3425837b 100644 --- a/apm-agent-plugins/apm-awslambda-plugin/src/main/java/co/elastic/apm/agent/awslambda/helper/SNSTransactionHelper.java +++ b/apm-agent-plugins/apm-awslambda-plugin/src/main/java/co/elastic/apm/agent/awslambda/helper/SNSTransactionHelper.java @@ -19,9 +19,9 @@ package co.elastic.apm.agent.awslambda.helper; import co.elastic.apm.agent.awslambda.SNSMessageAttributesGetter; -import co.elastic.apm.agent.impl.ElasticApmTracer; import co.elastic.apm.agent.tracer.GlobalTracer; -import co.elastic.apm.agent.impl.transaction.Transaction; +import co.elastic.apm.agent.tracer.Tracer; +import co.elastic.apm.agent.tracer.Transaction; import com.amazonaws.services.lambda.runtime.events.SNSEvent; import javax.annotation.Nullable; @@ -33,13 +33,13 @@ public class SNSTransactionHelper extends AbstractMessageBasedTransactionHelper< private final SNSEvent.SNSRecord placeholderRecord = new SNSEvent.SNSRecord(); - private SNSTransactionHelper(ElasticApmTracer tracer) { + private SNSTransactionHelper(Tracer tracer) { super(tracer); } public static SNSTransactionHelper getInstance() { if (INSTANCE == null) { - INSTANCE = new SNSTransactionHelper(GlobalTracer.get().require(ElasticApmTracer.class)); + INSTANCE = new SNSTransactionHelper(GlobalTracer.get()); } return INSTANCE; } @@ -78,7 +78,7 @@ record = event.getRecords().get(0); } @Override - protected void addSpanLinks(Transaction transaction, SNSEvent event) { + protected void addSpanLinks(Transaction transaction, SNSEvent event) { List records = event.getRecords(); if (records != null && !records.isEmpty()) { for (SNSEvent.SNSRecord record : records) { diff --git a/apm-agent-plugins/apm-awslambda-plugin/src/main/java/co/elastic/apm/agent/awslambda/helper/SQSTransactionHelper.java b/apm-agent-plugins/apm-awslambda-plugin/src/main/java/co/elastic/apm/agent/awslambda/helper/SQSTransactionHelper.java index 218506a463..6f6ba9e807 100644 --- a/apm-agent-plugins/apm-awslambda-plugin/src/main/java/co/elastic/apm/agent/awslambda/helper/SQSTransactionHelper.java +++ b/apm-agent-plugins/apm-awslambda-plugin/src/main/java/co/elastic/apm/agent/awslambda/helper/SQSTransactionHelper.java @@ -19,9 +19,9 @@ package co.elastic.apm.agent.awslambda.helper; import co.elastic.apm.agent.awslambda.SQSMessageAttributesGetter; -import co.elastic.apm.agent.impl.ElasticApmTracer; import co.elastic.apm.agent.tracer.GlobalTracer; -import co.elastic.apm.agent.impl.transaction.Transaction; +import co.elastic.apm.agent.tracer.Tracer; +import co.elastic.apm.agent.tracer.Transaction; import com.amazonaws.services.lambda.runtime.events.SQSEvent; import javax.annotation.Nullable; @@ -34,13 +34,13 @@ public class SQSTransactionHelper extends AbstractMessageBasedTransactionHelper< private final SQSEvent.SQSMessage placeholderMessage = new SQSEvent.SQSMessage(); - private SQSTransactionHelper(ElasticApmTracer tracer) { + private SQSTransactionHelper(Tracer tracer) { super(tracer); } public static SQSTransactionHelper getInstance() { if (INSTANCE == null) { - INSTANCE = new SQSTransactionHelper(GlobalTracer.get().require(ElasticApmTracer.class)); + INSTANCE = new SQSTransactionHelper(GlobalTracer.get()); } return INSTANCE; } @@ -76,7 +76,7 @@ record = event.getRecords().get(0); } @Override - protected void addSpanLinks(Transaction transaction, SQSEvent event) { + protected void addSpanLinks(Transaction transaction, SQSEvent event) { List records = event.getRecords(); if (records != null && !records.isEmpty()) { for (SQSEvent.SQSMessage record : records) { diff --git a/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/Faas.java b/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/Faas.java new file mode 100644 index 0000000000..678c02b6ea --- /dev/null +++ b/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/Faas.java @@ -0,0 +1,36 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package co.elastic.apm.agent.tracer; + +import javax.annotation.Nullable; + +public interface Faas { + + FaasTrigger getTrigger(); + + Faas withId(@Nullable String id); + + Faas withName(@Nullable String name); + + Faas withVersion(@Nullable String version); + + Faas withExecution(@Nullable String execution); + + Faas withColdStart(boolean coldStart); +} diff --git a/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/FaasTrigger.java b/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/FaasTrigger.java new file mode 100644 index 0000000000..72fd88913e --- /dev/null +++ b/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/FaasTrigger.java @@ -0,0 +1,28 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package co.elastic.apm.agent.tracer; + +import javax.annotation.Nullable; + +public interface FaasTrigger { + + FaasTrigger withType(@Nullable String type); + + FaasTrigger withRequestId(@Nullable String requestId); +} diff --git a/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/GlobalTracer.java b/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/GlobalTracer.java index 1ad88cd129..fa843ed2cc 100644 --- a/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/GlobalTracer.java +++ b/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/GlobalTracer.java @@ -150,4 +150,14 @@ public void reportLog(byte[] log) { public Service createService(String ephemeralId) { return tracer.createService(ephemeralId); } + + @Override + public void flush() { + tracer.flush(); + } + + @Override + public void completeMetaData(String name, String version, String id, String region) { + tracer.completeMetaData(name, version, id, region); + } } diff --git a/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/NoopTracer.java b/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/NoopTracer.java index 2c2727152d..e668c247e4 100644 --- a/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/NoopTracer.java +++ b/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/NoopTracer.java @@ -25,6 +25,7 @@ import co.elastic.apm.agent.tracer.service.Service; import javax.annotation.Nullable; +import java.io.IOException; import java.util.Collections; import java.util.Set; @@ -125,4 +126,12 @@ public void reportLog(byte[] log) { public Service createService(String ephemeralId) { return null; } + + @Override + public void flush() { + } + + @Override + public void completeMetaData(String name, String version, String id, String region) { + } } diff --git a/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/ServiceOrigin.java b/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/ServiceOrigin.java new file mode 100644 index 0000000000..9159bb29b5 --- /dev/null +++ b/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/ServiceOrigin.java @@ -0,0 +1,30 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package co.elastic.apm.agent.tracer; + +import javax.annotation.Nullable; + +public interface ServiceOrigin { + + ServiceOrigin withVersion(@Nullable String version); + + ServiceOrigin withName(@Nullable CharSequence name); + + ServiceOrigin withId(@Nullable String id); +} diff --git a/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/Tracer.java b/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/Tracer.java index b7f9042142..da0ddbbf30 100644 --- a/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/Tracer.java +++ b/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/Tracer.java @@ -25,9 +25,11 @@ import co.elastic.apm.agent.tracer.service.Service; import javax.annotation.Nullable; +import java.io.Flushable; +import java.io.IOException; import java.util.Set; -public interface Tracer { +public interface Tracer extends Flushable { boolean isRunning(); @@ -88,4 +90,9 @@ public interface Tracer { @Nullable Service createService(String ephemeralId); + + @Override + void flush(); + + void completeMetaData(String name, String version, String id, String region); } diff --git a/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/Transaction.java b/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/Transaction.java index 1424da3766..a8ce3a7648 100644 --- a/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/Transaction.java +++ b/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/Transaction.java @@ -56,4 +56,6 @@ public interface Transaction> extends AbstractSpan { void setFrameworkName(@Nullable String frameworkName); void setFrameworkVersion(@Nullable String frameworkVersion); + + Faas getFaas(); } diff --git a/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/TransactionContext.java b/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/TransactionContext.java index baafaacb96..d1800dd91c 100644 --- a/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/TransactionContext.java +++ b/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/TransactionContext.java @@ -43,4 +43,6 @@ public interface TransactionContext extends AbstractContext { User getUser(); CloudOrigin getCloudOrigin(); + + ServiceOrigin getServiceOrigin(); } diff --git a/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/metadata/Request.java b/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/metadata/Request.java index fe8afd2f5f..46ac03f623 100644 --- a/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/metadata/Request.java +++ b/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/metadata/Request.java @@ -75,6 +75,15 @@ public interface Request { Request addFormUrlEncodedParameters(String key, String[] values); + /** + * Adds a request header. + * + * @param headerName The name of the header. + * @param headerValue The value of the header. + * @return {@code this}, for fluent method chaining + */ + Request addHeader(String headerName, @Nullable String headerValue); + Request addHeader(String headerName, @Nullable Enumeration headerValues); Request addCookie(String cookieName, String cookieValue); diff --git a/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/metadata/Response.java b/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/metadata/Response.java index e87a517a8a..43a4457dab 100644 --- a/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/metadata/Response.java +++ b/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/metadata/Response.java @@ -40,5 +40,7 @@ public interface Response { Response withHeadersSent(boolean headersSent); + Response addHeader(String headerName, @Nullable String headerValue); + Response addHeader(String headerName, @Nullable Collection headerValues); } From 90a41e396712ed7187730a0948fb8a28684e49b4 Mon Sep 17 00:00:00 2001 From: Rafael Winterhalter Date: Tue, 6 Feb 2024 19:14:13 +0100 Subject: [PATCH 4/9] Move metrics API to tracer. --- ...InstrumentationStatsLifecycleListener.java | 6 ++-- .../apm/agent/collections/WeakMapCleaner.java | 6 ++-- .../ApmServerConfigurationSource.java | 9 ++--- .../apm/agent/configuration/StartupInfo.java | 7 ++-- .../ClosableLifecycleListenerAdapter.java | 9 ++--- .../apm/agent/impl/ElasticApmTracer.java | 27 +++++++++++++-- .../agent/impl/ElasticApmTracerBuilder.java | 2 +- .../impl/circuitbreaker/CircuitBreaker.java | 9 ++--- .../impl/circuitbreaker/GCStressMonitor.java | 3 +- .../impl/circuitbreaker/StressMonitor.java | 4 +-- .../SystemCpuStressMonitor.java | 4 +-- .../agent/impl/transaction/Transaction.java | 2 +- .../agent/logging/ApmServerLogAppender.java | 9 ++--- .../apm/agent/metrics/MetricCollector.java | 2 ++ .../apm/agent/metrics/MetricRegistry.java | 2 ++ .../elastic/apm/agent/metrics/MetricSet.java | 2 ++ .../metrics/builtin/AgentOverheadMetrics.java | 9 ++--- .../metrics/builtin/AgentReporterMetrics.java | 2 +- .../agent/metrics/builtin/CGroupMetrics.java | 11 ++++--- .../agent/metrics/builtin/JvmFdMetrics.java | 11 ++++--- .../agent/metrics/builtin/JvmGcMetrics.java | 11 ++++--- .../metrics/builtin/JvmMemoryMetrics.java | 11 ++++--- .../agent/metrics/builtin/SystemMetrics.java | 11 ++++--- .../agent/metrics/builtin/ThreadMetrics.java | 11 ++++--- .../report/serialize/DslJsonSerializer.java | 2 +- .../serialize/MetricRegistryReporter.java | 11 ++++--- .../serialize/MetricRegistrySerializer.java | 2 +- ...lastic.apm.agent.tracer.LifecycleListener} | 0 .../apm/agent/impl/ElasticApmTracerTest.java | 2 +- .../elastic/apm/agent/impl/LifecycleTest.java | 10 +++--- .../apm/agent/impl/SpanTypeBreakdownTest.java | 2 +- .../elastic/apm/agent/metrics/LabelsTest.java | 1 + .../apm/agent/metrics/MetricRegistryTest.java | 2 ++ .../builtin/AgentOverheadMetricsTest.java | 2 +- .../builtin/AgentReporterMetricsTest.java | 2 +- .../metrics/builtin/CGroupMetricsTest.java | 2 +- .../metrics/builtin/JvmFdMetricsTest.java | 2 +- .../metrics/builtin/JvmMemoryMetricsTest.java | 2 +- .../metrics/builtin/SystemMetricsTest.java | 2 +- .../metrics/builtin/ThreadMetricsTest.java | 2 +- .../serialize/MetricSetSerializationTest.java | 2 +- ...lastic.apm.agent.tracer.LifecycleListener} | 0 apm-agent-plugins/apm-jmx-plugin/pom.xml | 9 ----- .../co/elastic/apm/agent/jmx/JmxMetric.java | 3 +- .../apm/agent/jmx/JmxMetricTracker.java | 33 +++++++++---------- ...lastic.apm.agent.tracer.LifecycleListener} | 0 .../apm/agent/jmx/JmxMetricTrackerTest.java | 2 +- .../apm-micrometer-plugin/pom.xml | 6 ---- .../AbstractMicrometerInstrumentation.java | 3 +- .../micrometer/MicrometerMetricsReporter.java | 19 ++++------- .../embeddedotel/EmbeddedSdkManager.java | 8 ++--- ...lastic.apm.agent.tracer.LifecycleListener} | 0 .../apm/agent/profiler/ProfilingFactory.java | 8 +++-- .../apm/agent/profiler/SamplingProfiler.java | 5 +-- ...lastic.apm.agent.tracer.LifecycleListener} | 0 .../tracer}/AbstractLifecycleListener.java | 8 ++--- .../apm/agent/tracer/GlobalTracer.java | 23 +++++++++++++ .../apm/agent/tracer}/LifecycleListener.java | 13 +++----- .../elastic/apm/agent/tracer/NoopTracer.java | 19 +++++++++++ .../co/elastic/apm/agent/tracer/Tracer.java | 13 ++++++++ .../agent/tracer}/metrics/DoubleSupplier.java | 2 +- .../apm/agent/tracer}/metrics/Labels.java | 6 +--- 62 files changed, 241 insertions(+), 167 deletions(-) rename apm-agent-core/src/main/resources/META-INF/services/{co.elastic.apm.agent.context.LifecycleListener => co.elastic.apm.agent.tracer.LifecycleListener} (100%) rename apm-agent-core/src/test/resources/META-INF/services/{co.elastic.apm.agent.context.LifecycleListener => co.elastic.apm.agent.tracer.LifecycleListener} (100%) rename apm-agent-plugins/apm-jmx-plugin/src/main/resources/META-INF/services/{co.elastic.apm.agent.context.LifecycleListener => co.elastic.apm.agent.tracer.LifecycleListener} (100%) rename apm-agent-plugins/apm-opentelemetry/apm-opentelemetry-embedded-metrics-sdk/src/main/resources/META-INF/services/{co.elastic.apm.agent.context.LifecycleListener => co.elastic.apm.agent.tracer.LifecycleListener} (100%) rename apm-agent-plugins/apm-profiling-plugin/src/main/resources/META-INF/services/{co.elastic.apm.agent.context.LifecycleListener => co.elastic.apm.agent.tracer.LifecycleListener} (100%) rename {apm-agent-core/src/main/java/co/elastic/apm/agent/context => apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer}/AbstractLifecycleListener.java (83%) rename {apm-agent-core/src/main/java/co/elastic/apm/agent/context => apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer}/LifecycleListener.java (93%) rename {apm-agent-core/src/main/java/co/elastic/apm/agent => apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer}/metrics/DoubleSupplier.java (94%) rename {apm-agent-core/src/main/java/co/elastic/apm/agent => apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer}/metrics/Labels.java (98%) diff --git a/apm-agent-core/src/main/java/co/elastic/apm/agent/bci/InstrumentationStatsLifecycleListener.java b/apm-agent-core/src/main/java/co/elastic/apm/agent/bci/InstrumentationStatsLifecycleListener.java index a7f096ad59..c16d18c80d 100644 --- a/apm-agent-core/src/main/java/co/elastic/apm/agent/bci/InstrumentationStatsLifecycleListener.java +++ b/apm-agent-core/src/main/java/co/elastic/apm/agent/bci/InstrumentationStatsLifecycleListener.java @@ -19,10 +19,10 @@ package co.elastic.apm.agent.bci; import co.elastic.apm.agent.bci.bytebuddy.MatcherTimer; -import co.elastic.apm.agent.context.AbstractLifecycleListener; -import co.elastic.apm.agent.impl.ElasticApmTracer; +import co.elastic.apm.agent.tracer.AbstractLifecycleListener; import co.elastic.apm.agent.sdk.logging.Logger; import co.elastic.apm.agent.sdk.logging.LoggerFactory; +import co.elastic.apm.agent.tracer.Tracer; import java.util.ArrayList; import java.util.Collections; @@ -31,7 +31,7 @@ public class InstrumentationStatsLifecycleListener extends AbstractLifecycleList private static final Logger logger = LoggerFactory.getLogger(InstrumentationStatsLifecycleListener.class); @Override - public void init(ElasticApmTracer tracer) { + public void init(Tracer tracer) { InstrumentationStats instrumentationStats = ElasticApmAgent.getInstrumentationStats(); instrumentationStats.reset(); instrumentationStats.setMeasureMatching(logger.isDebugEnabled()); diff --git a/apm-agent-core/src/main/java/co/elastic/apm/agent/collections/WeakMapCleaner.java b/apm-agent-core/src/main/java/co/elastic/apm/agent/collections/WeakMapCleaner.java index 3755d8b26b..be6ea5fd98 100644 --- a/apm-agent-core/src/main/java/co/elastic/apm/agent/collections/WeakMapCleaner.java +++ b/apm-agent-core/src/main/java/co/elastic/apm/agent/collections/WeakMapCleaner.java @@ -18,8 +18,8 @@ */ package co.elastic.apm.agent.collections; -import co.elastic.apm.agent.context.AbstractLifecycleListener; -import co.elastic.apm.agent.impl.ElasticApmTracer; +import co.elastic.apm.agent.tracer.AbstractLifecycleListener; +import co.elastic.apm.agent.tracer.Tracer; import co.elastic.apm.agent.util.ExecutorUtils; import co.elastic.apm.agent.sdk.logging.Logger; import co.elastic.apm.agent.sdk.logging.LoggerFactory; @@ -41,7 +41,7 @@ public WeakMapCleaner() { } @Override - public void start(ElasticApmTracer tracer) { + public void start(Tracer tracer) { scheduler.scheduleWithFixedDelay(this, 1, 1, TimeUnit.SECONDS); } diff --git a/apm-agent-core/src/main/java/co/elastic/apm/agent/configuration/ApmServerConfigurationSource.java b/apm-agent-core/src/main/java/co/elastic/apm/agent/configuration/ApmServerConfigurationSource.java index 662810e4b7..0f63ac2d0c 100644 --- a/apm-agent-core/src/main/java/co/elastic/apm/agent/configuration/ApmServerConfigurationSource.java +++ b/apm-agent-core/src/main/java/co/elastic/apm/agent/configuration/ApmServerConfigurationSource.java @@ -18,12 +18,13 @@ */ package co.elastic.apm.agent.configuration; -import co.elastic.apm.agent.context.LifecycleListener; +import co.elastic.apm.agent.tracer.LifecycleListener; import co.elastic.apm.agent.impl.ElasticApmTracer; import co.elastic.apm.agent.report.ApmServerClient; import co.elastic.apm.agent.report.serialize.DslJsonSerializer; import co.elastic.apm.agent.sdk.logging.Logger; import co.elastic.apm.agent.sdk.logging.LoggerFactory; +import co.elastic.apm.agent.tracer.Tracer; import co.elastic.apm.agent.util.ExecutorUtils; import com.dslplatform.json.DslJson; import com.dslplatform.json.JsonReader; @@ -111,17 +112,17 @@ public void reload() { } @Override - public void init(ElasticApmTracer tracer) throws Exception { + public void init(Tracer tracer) throws Exception { // noop } @Override - public void start(final ElasticApmTracer tracer) { + public void start(final Tracer tracer) { threadPool = ExecutorUtils.createSingleThreadDaemonPool("remote-config-poller", 1); threadPool.execute(new Runnable() { @Override public void run() { - pollConfig(tracer.getConfigurationRegistry()); + pollConfig(tracer.require(ElasticApmTracer.class).getConfigurationRegistry()); } }); } diff --git a/apm-agent-core/src/main/java/co/elastic/apm/agent/configuration/StartupInfo.java b/apm-agent-core/src/main/java/co/elastic/apm/agent/configuration/StartupInfo.java index f75d4807ab..4de8761af2 100644 --- a/apm-agent-core/src/main/java/co/elastic/apm/agent/configuration/StartupInfo.java +++ b/apm-agent-core/src/main/java/co/elastic/apm/agent/configuration/StartupInfo.java @@ -18,8 +18,9 @@ */ package co.elastic.apm.agent.configuration; +import co.elastic.apm.agent.tracer.Tracer; import co.elastic.apm.agent.tracer.configuration.TimeDuration; -import co.elastic.apm.agent.context.AbstractLifecycleListener; +import co.elastic.apm.agent.tracer.AbstractLifecycleListener; import co.elastic.apm.agent.impl.ElasticApmTracer; import co.elastic.apm.agent.impl.stacktrace.StacktraceConfiguration; import co.elastic.apm.agent.util.VersionUtils; @@ -56,8 +57,8 @@ private static String getJvmAndOsVersionString() { } @Override - public void init(ElasticApmTracer tracer) { - ConfigurationRegistry configurationRegistry = tracer.getConfigurationRegistry(); + public void init(Tracer tracer) { + ConfigurationRegistry configurationRegistry = tracer.require(ElasticApmTracer.class).getConfigurationRegistry(); logConfiguration(configurationRegistry, logger); } diff --git a/apm-agent-core/src/main/java/co/elastic/apm/agent/context/ClosableLifecycleListenerAdapter.java b/apm-agent-core/src/main/java/co/elastic/apm/agent/context/ClosableLifecycleListenerAdapter.java index 10ba08a7ed..d784743219 100644 --- a/apm-agent-core/src/main/java/co/elastic/apm/agent/context/ClosableLifecycleListenerAdapter.java +++ b/apm-agent-core/src/main/java/co/elastic/apm/agent/context/ClosableLifecycleListenerAdapter.java @@ -18,17 +18,18 @@ */ package co.elastic.apm.agent.context; -import java.io.Closeable; +import co.elastic.apm.agent.tracer.AbstractLifecycleListener; +import co.elastic.apm.agent.tracer.LifecycleListener; public class ClosableLifecycleListenerAdapter extends AbstractLifecycleListener { - private final Closeable closeable; + private final AutoCloseable closeable; - public static LifecycleListener of(Closeable closeable) { + public static LifecycleListener of(AutoCloseable closeable) { return new ClosableLifecycleListenerAdapter(closeable); } - private ClosableLifecycleListenerAdapter(Closeable closeable) { + private ClosableLifecycleListenerAdapter(AutoCloseable closeable) { this.closeable = closeable; } 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 a376a19fc8..35cf1f416c 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 @@ -30,11 +30,13 @@ import co.elastic.apm.agent.configuration.ServerlessConfiguration; import co.elastic.apm.agent.impl.metadata.*; import co.elastic.apm.agent.sdk.internal.util.LoggerUtils; +import co.elastic.apm.agent.tracer.metrics.DoubleSupplier; +import co.elastic.apm.agent.tracer.metrics.Labels; import co.elastic.apm.agent.tracer.service.Service; import co.elastic.apm.agent.tracer.service.ServiceInfo; import co.elastic.apm.agent.configuration.SpanConfiguration; import co.elastic.apm.agent.context.ClosableLifecycleListenerAdapter; -import co.elastic.apm.agent.context.LifecycleListener; +import co.elastic.apm.agent.tracer.LifecycleListener; import co.elastic.apm.agent.impl.baggage.Baggage; import co.elastic.apm.agent.impl.baggage.W3CBaggagePropagation; import co.elastic.apm.agent.impl.error.ErrorCapture; @@ -943,7 +945,8 @@ public ScheduledThreadPoolExecutor getSharedSingleThreadedPool() { return sharedPool; } - public void addShutdownHook(Closeable closeable) { + @Override + public void addShutdownHook(AutoCloseable closeable) { lifecycleListeners.add(ClosableLifecycleListenerAdapter.of(closeable)); } @@ -1024,4 +1027,24 @@ public void completeMetaData(String name, String version, String id, String regi region )); } + + @Override + public void removeGauge(String name, Labels.Immutable labels) { + metricRegistry.removeGauge(name, labels); + } + + @Override + public void addGauge(String name, Labels.Immutable labels, DoubleSupplier supplier) { + metricRegistry.add(name, labels, supplier); + } + + @Override + public void submit(Runnable job) { + sharedPool.submit(job); + } + + @Override + public void schedule(Runnable job, long interval, TimeUnit timeUnit) { + sharedPool.scheduleAtFixedRate(job, 0, interval, timeUnit); + } } diff --git a/apm-agent-core/src/main/java/co/elastic/apm/agent/impl/ElasticApmTracerBuilder.java b/apm-agent-core/src/main/java/co/elastic/apm/agent/impl/ElasticApmTracerBuilder.java index 86c93a3353..b68faae5dd 100644 --- a/apm-agent-core/src/main/java/co/elastic/apm/agent/impl/ElasticApmTracerBuilder.java +++ b/apm-agent-core/src/main/java/co/elastic/apm/agent/impl/ElasticApmTracerBuilder.java @@ -26,7 +26,7 @@ import co.elastic.apm.agent.configuration.source.ConfigSources; import co.elastic.apm.agent.configuration.source.SystemPropertyConfigurationSource; import co.elastic.apm.agent.context.ClosableLifecycleListenerAdapter; -import co.elastic.apm.agent.context.LifecycleListener; +import co.elastic.apm.agent.tracer.LifecycleListener; import co.elastic.apm.agent.impl.metadata.MetaData; import co.elastic.apm.agent.impl.metadata.MetaDataFuture; import co.elastic.apm.agent.impl.stacktrace.StacktraceConfiguration; diff --git a/apm-agent-core/src/main/java/co/elastic/apm/agent/impl/circuitbreaker/CircuitBreaker.java b/apm-agent-core/src/main/java/co/elastic/apm/agent/impl/circuitbreaker/CircuitBreaker.java index f17e20876c..b90c539011 100644 --- a/apm-agent-core/src/main/java/co/elastic/apm/agent/impl/circuitbreaker/CircuitBreaker.java +++ b/apm-agent-core/src/main/java/co/elastic/apm/agent/impl/circuitbreaker/CircuitBreaker.java @@ -18,8 +18,9 @@ */ package co.elastic.apm.agent.impl.circuitbreaker; -import co.elastic.apm.agent.context.AbstractLifecycleListener; +import co.elastic.apm.agent.tracer.AbstractLifecycleListener; import co.elastic.apm.agent.impl.ElasticApmTracer; +import co.elastic.apm.agent.tracer.Tracer; import co.elastic.apm.agent.util.ExecutorUtils; import co.elastic.apm.agent.sdk.logging.Logger; import co.elastic.apm.agent.sdk.logging.LoggerFactory; @@ -50,7 +51,7 @@ public CircuitBreaker(ElasticApmTracer tracer) { } @Override - public void start(ElasticApmTracer tracer) { + public void start(Tracer tracer) { // failsafe loading of stress monitors in isolation loadGCStressMonitor(tracer); loadSystemCpuStressMonitor(tracer); @@ -63,7 +64,7 @@ public void run() { }); } - private void loadGCStressMonitor(ElasticApmTracer tracer) { + private void loadGCStressMonitor(Tracer tracer) { try { stressMonitors.add(new GCStressMonitor(tracer)); } catch (Throwable throwable) { @@ -71,7 +72,7 @@ private void loadGCStressMonitor(ElasticApmTracer tracer) { } } - private void loadSystemCpuStressMonitor(ElasticApmTracer tracer) { + private void loadSystemCpuStressMonitor(Tracer tracer) { try { stressMonitors.add(new SystemCpuStressMonitor(tracer)); } catch (Throwable throwable) { diff --git a/apm-agent-core/src/main/java/co/elastic/apm/agent/impl/circuitbreaker/GCStressMonitor.java b/apm-agent-core/src/main/java/co/elastic/apm/agent/impl/circuitbreaker/GCStressMonitor.java index 62405dadd6..a325e2632b 100644 --- a/apm-agent-core/src/main/java/co/elastic/apm/agent/impl/circuitbreaker/GCStressMonitor.java +++ b/apm-agent-core/src/main/java/co/elastic/apm/agent/impl/circuitbreaker/GCStressMonitor.java @@ -21,6 +21,7 @@ import co.elastic.apm.agent.impl.ElasticApmTracer; import co.elastic.apm.agent.sdk.logging.Logger; import co.elastic.apm.agent.sdk.logging.LoggerFactory; +import co.elastic.apm.agent.tracer.Tracer; import java.lang.management.ManagementFactory; import java.lang.management.MemoryPoolMXBean; @@ -35,7 +36,7 @@ class GCStressMonitor extends StressMonitor { private final List heapMBeans = new ArrayList<>(); private final StringBuilder latestStressDetectionInfo = new StringBuilder("No stress has been detected so far."); - GCStressMonitor(ElasticApmTracer tracer) { + GCStressMonitor(Tracer tracer) { super(tracer); discoverMBeans(); } diff --git a/apm-agent-core/src/main/java/co/elastic/apm/agent/impl/circuitbreaker/StressMonitor.java b/apm-agent-core/src/main/java/co/elastic/apm/agent/impl/circuitbreaker/StressMonitor.java index 992bb89344..a6db804364 100644 --- a/apm-agent-core/src/main/java/co/elastic/apm/agent/impl/circuitbreaker/StressMonitor.java +++ b/apm-agent-core/src/main/java/co/elastic/apm/agent/impl/circuitbreaker/StressMonitor.java @@ -18,13 +18,13 @@ */ package co.elastic.apm.agent.impl.circuitbreaker; -import co.elastic.apm.agent.impl.ElasticApmTracer; +import co.elastic.apm.agent.tracer.Tracer; abstract class StressMonitor { protected final CircuitBreakerConfiguration circuitBreakerConfiguration; - public StressMonitor(ElasticApmTracer tracer) { + public StressMonitor(Tracer tracer) { circuitBreakerConfiguration = tracer.getConfig(CircuitBreakerConfiguration.class); } diff --git a/apm-agent-core/src/main/java/co/elastic/apm/agent/impl/circuitbreaker/SystemCpuStressMonitor.java b/apm-agent-core/src/main/java/co/elastic/apm/agent/impl/circuitbreaker/SystemCpuStressMonitor.java index cb0b6536aa..fd0d5e8fe6 100644 --- a/apm-agent-core/src/main/java/co/elastic/apm/agent/impl/circuitbreaker/SystemCpuStressMonitor.java +++ b/apm-agent-core/src/main/java/co/elastic/apm/agent/impl/circuitbreaker/SystemCpuStressMonitor.java @@ -18,7 +18,7 @@ */ package co.elastic.apm.agent.impl.circuitbreaker; -import co.elastic.apm.agent.impl.ElasticApmTracer; +import co.elastic.apm.agent.tracer.Tracer; import co.elastic.apm.agent.util.JmxUtils; import co.elastic.apm.agent.sdk.logging.Logger; import co.elastic.apm.agent.sdk.logging.LoggerFactory; @@ -45,7 +45,7 @@ public class SystemCpuStressMonitor extends StressMonitor { @Nullable private final Method systemCpuUsageMethod; - SystemCpuStressMonitor(ElasticApmTracer tracer) { + SystemCpuStressMonitor(Tracer tracer) { super(tracer); operatingSystemBean = ManagementFactory.getOperatingSystemMXBean(); systemCpuUsageMethod = JmxUtils.getOperatingSystemMBeanMethod(operatingSystemBean, "getSystemCpuLoad"); 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 aabac69aed..78385a5795 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 @@ -27,7 +27,7 @@ import co.elastic.apm.agent.impl.context.Response; import co.elastic.apm.agent.impl.context.TransactionContext; import co.elastic.apm.agent.impl.sampling.Sampler; -import co.elastic.apm.agent.metrics.Labels; +import co.elastic.apm.agent.tracer.metrics.Labels; import co.elastic.apm.agent.metrics.MetricRegistry; import co.elastic.apm.agent.metrics.Timer; import co.elastic.apm.agent.tracer.Outcome; diff --git a/apm-agent-core/src/main/java/co/elastic/apm/agent/logging/ApmServerLogAppender.java b/apm-agent-core/src/main/java/co/elastic/apm/agent/logging/ApmServerLogAppender.java index 59328be609..97074fe210 100644 --- a/apm-agent-core/src/main/java/co/elastic/apm/agent/logging/ApmServerLogAppender.java +++ b/apm-agent-core/src/main/java/co/elastic/apm/agent/logging/ApmServerLogAppender.java @@ -18,10 +18,11 @@ */ package co.elastic.apm.agent.logging; -import co.elastic.apm.agent.context.AbstractLifecycleListener; -import co.elastic.apm.agent.context.LifecycleListener; +import co.elastic.apm.agent.tracer.AbstractLifecycleListener; +import co.elastic.apm.agent.tracer.LifecycleListener; import co.elastic.apm.agent.impl.ElasticApmTracer; import co.elastic.apm.agent.report.Reporter; +import co.elastic.apm.agent.tracer.Tracer; import co.elastic.logging.log4j2.EcsLayout; import org.apache.logging.log4j.core.Appender; import org.apache.logging.log4j.core.Core; @@ -103,8 +104,8 @@ public void append(LogEvent event) { public LifecycleListener getInitListener() { return new AbstractLifecycleListener() { @Override - public void init(ElasticApmTracer tracer) throws Exception { - initStreaming(tracer.getConfig(LoggingConfiguration.class), tracer.getReporter()); + public void init(Tracer tracer) throws Exception { + initStreaming(tracer.getConfig(LoggingConfiguration.class), tracer.require(ElasticApmTracer.class).getReporter()); } }; } diff --git a/apm-agent-core/src/main/java/co/elastic/apm/agent/metrics/MetricCollector.java b/apm-agent-core/src/main/java/co/elastic/apm/agent/metrics/MetricCollector.java index b8ccd561f4..199899b787 100644 --- a/apm-agent-core/src/main/java/co/elastic/apm/agent/metrics/MetricCollector.java +++ b/apm-agent-core/src/main/java/co/elastic/apm/agent/metrics/MetricCollector.java @@ -18,6 +18,8 @@ */ package co.elastic.apm.agent.metrics; +import co.elastic.apm.agent.tracer.metrics.Labels; + public interface MetricCollector { void addMetricValue(String metric, Labels labels, double value); diff --git a/apm-agent-core/src/main/java/co/elastic/apm/agent/metrics/MetricRegistry.java b/apm-agent-core/src/main/java/co/elastic/apm/agent/metrics/MetricRegistry.java index 2df93faa7f..9c1cdeb285 100644 --- a/apm-agent-core/src/main/java/co/elastic/apm/agent/metrics/MetricRegistry.java +++ b/apm-agent-core/src/main/java/co/elastic/apm/agent/metrics/MetricRegistry.java @@ -23,6 +23,8 @@ import co.elastic.apm.agent.report.ReporterConfiguration; import co.elastic.apm.agent.sdk.logging.Logger; import co.elastic.apm.agent.sdk.logging.LoggerFactory; +import co.elastic.apm.agent.tracer.metrics.DoubleSupplier; +import co.elastic.apm.agent.tracer.metrics.Labels; import org.HdrHistogram.WriterReaderPhaser; import javax.annotation.Nonnull; diff --git a/apm-agent-core/src/main/java/co/elastic/apm/agent/metrics/MetricSet.java b/apm-agent-core/src/main/java/co/elastic/apm/agent/metrics/MetricSet.java index 474a3827be..8bb1bc6f85 100644 --- a/apm-agent-core/src/main/java/co/elastic/apm/agent/metrics/MetricSet.java +++ b/apm-agent-core/src/main/java/co/elastic/apm/agent/metrics/MetricSet.java @@ -18,6 +18,8 @@ */ package co.elastic.apm.agent.metrics; +import co.elastic.apm.agent.tracer.metrics.DoubleSupplier; +import co.elastic.apm.agent.tracer.metrics.Labels; import co.elastic.apm.agent.tracer.pooling.Recyclable; import javax.annotation.Nullable; diff --git a/apm-agent-core/src/main/java/co/elastic/apm/agent/metrics/builtin/AgentOverheadMetrics.java b/apm-agent-core/src/main/java/co/elastic/apm/agent/metrics/builtin/AgentOverheadMetrics.java index c0a06ab921..3413f95f8a 100644 --- a/apm-agent-core/src/main/java/co/elastic/apm/agent/metrics/builtin/AgentOverheadMetrics.java +++ b/apm-agent-core/src/main/java/co/elastic/apm/agent/metrics/builtin/AgentOverheadMetrics.java @@ -19,9 +19,10 @@ package co.elastic.apm.agent.metrics.builtin; import co.elastic.apm.agent.configuration.MetricsConfiguration; -import co.elastic.apm.agent.context.AbstractLifecycleListener; +import co.elastic.apm.agent.tracer.AbstractLifecycleListener; import co.elastic.apm.agent.impl.ElasticApmTracer; -import co.elastic.apm.agent.metrics.Labels; +import co.elastic.apm.agent.tracer.Tracer; +import co.elastic.apm.agent.tracer.metrics.Labels; import co.elastic.apm.agent.metrics.MetricCollector; import co.elastic.apm.agent.metrics.MetricRegistry; import co.elastic.apm.agent.metrics.MetricsProvider; @@ -113,8 +114,8 @@ public AgentOverheadMetrics() { } @Override - public void start(ElasticApmTracer tracer) throws Exception { - MetricRegistry metricRegistry = tracer.getMetricRegistry(); + public void start(Tracer tracer) throws Exception { + MetricRegistry metricRegistry = tracer.require(ElasticApmTracer.class).getMetricRegistry(); MetricsConfiguration config = tracer.getConfig(MetricsConfiguration.class); bindTo(metricRegistry, config); } diff --git a/apm-agent-core/src/main/java/co/elastic/apm/agent/metrics/builtin/AgentReporterMetrics.java b/apm-agent-core/src/main/java/co/elastic/apm/agent/metrics/builtin/AgentReporterMetrics.java index 6970d114ae..e946bb90e1 100644 --- a/apm-agent-core/src/main/java/co/elastic/apm/agent/metrics/builtin/AgentReporterMetrics.java +++ b/apm-agent-core/src/main/java/co/elastic/apm/agent/metrics/builtin/AgentReporterMetrics.java @@ -19,7 +19,7 @@ package co.elastic.apm.agent.metrics.builtin; import co.elastic.apm.agent.configuration.MetricsConfiguration; -import co.elastic.apm.agent.metrics.Labels; +import co.elastic.apm.agent.tracer.metrics.Labels; import co.elastic.apm.agent.metrics.MetricCollector; import co.elastic.apm.agent.metrics.MetricRegistry; import co.elastic.apm.agent.metrics.MetricsProvider; diff --git a/apm-agent-core/src/main/java/co/elastic/apm/agent/metrics/builtin/CGroupMetrics.java b/apm-agent-core/src/main/java/co/elastic/apm/agent/metrics/builtin/CGroupMetrics.java index 9f64ed14cc..e89ee39ef5 100644 --- a/apm-agent-core/src/main/java/co/elastic/apm/agent/metrics/builtin/CGroupMetrics.java +++ b/apm-agent-core/src/main/java/co/elastic/apm/agent/metrics/builtin/CGroupMetrics.java @@ -18,10 +18,11 @@ */ package co.elastic.apm.agent.metrics.builtin; -import co.elastic.apm.agent.context.AbstractLifecycleListener; +import co.elastic.apm.agent.tracer.AbstractLifecycleListener; import co.elastic.apm.agent.impl.ElasticApmTracer; -import co.elastic.apm.agent.metrics.DoubleSupplier; -import co.elastic.apm.agent.metrics.Labels; +import co.elastic.apm.agent.tracer.metrics.DoubleSupplier; +import co.elastic.apm.agent.tracer.Tracer; +import co.elastic.apm.agent.tracer.metrics.Labels; import co.elastic.apm.agent.metrics.MetricRegistry; import co.elastic.apm.agent.sdk.logging.Logger; import co.elastic.apm.agent.sdk.logging.LoggerFactory; @@ -213,8 +214,8 @@ private File getMaxMemoryFile(File maxMemoryFile, String cgroupUnlimitedConstant } @Override - public void start(ElasticApmTracer tracer) { - bindTo(tracer.getMetricRegistry()); + public void start(Tracer tracer) { + bindTo(tracer.require(ElasticApmTracer.class).getMetricRegistry()); } void bindTo(MetricRegistry metricRegistry) { diff --git a/apm-agent-core/src/main/java/co/elastic/apm/agent/metrics/builtin/JvmFdMetrics.java b/apm-agent-core/src/main/java/co/elastic/apm/agent/metrics/builtin/JvmFdMetrics.java index 4a0764fe35..08d95586bf 100644 --- a/apm-agent-core/src/main/java/co/elastic/apm/agent/metrics/builtin/JvmFdMetrics.java +++ b/apm-agent-core/src/main/java/co/elastic/apm/agent/metrics/builtin/JvmFdMetrics.java @@ -18,10 +18,11 @@ */ package co.elastic.apm.agent.metrics.builtin; -import co.elastic.apm.agent.context.AbstractLifecycleListener; +import co.elastic.apm.agent.tracer.AbstractLifecycleListener; import co.elastic.apm.agent.impl.ElasticApmTracer; -import co.elastic.apm.agent.metrics.DoubleSupplier; -import co.elastic.apm.agent.metrics.Labels; +import co.elastic.apm.agent.tracer.metrics.DoubleSupplier; +import co.elastic.apm.agent.tracer.Tracer; +import co.elastic.apm.agent.tracer.metrics.Labels; import co.elastic.apm.agent.metrics.MetricRegistry; import javax.annotation.Nullable; @@ -40,8 +41,8 @@ public class JvmFdMetrics extends AbstractLifecycleListener { private static final MethodHandle getMaxFileDescriptorCount = getMethodHandle("getMaxFileDescriptorCount"); @Override - public void start(ElasticApmTracer tracer) { - bindTo(tracer.getMetricRegistry()); + public void start(Tracer tracer) { + bindTo(tracer.require(ElasticApmTracer.class).getMetricRegistry()); } void bindTo(final MetricRegistry registry) { diff --git a/apm-agent-core/src/main/java/co/elastic/apm/agent/metrics/builtin/JvmGcMetrics.java b/apm-agent-core/src/main/java/co/elastic/apm/agent/metrics/builtin/JvmGcMetrics.java index 4cd140aced..089c2df2d0 100644 --- a/apm-agent-core/src/main/java/co/elastic/apm/agent/metrics/builtin/JvmGcMetrics.java +++ b/apm-agent-core/src/main/java/co/elastic/apm/agent/metrics/builtin/JvmGcMetrics.java @@ -18,10 +18,11 @@ */ package co.elastic.apm.agent.metrics.builtin; -import co.elastic.apm.agent.context.AbstractLifecycleListener; +import co.elastic.apm.agent.tracer.AbstractLifecycleListener; import co.elastic.apm.agent.impl.ElasticApmTracer; -import co.elastic.apm.agent.metrics.DoubleSupplier; -import co.elastic.apm.agent.metrics.Labels; +import co.elastic.apm.agent.tracer.metrics.DoubleSupplier; +import co.elastic.apm.agent.tracer.Tracer; +import co.elastic.apm.agent.tracer.metrics.Labels; import co.elastic.apm.agent.metrics.MetricRegistry; import com.sun.management.ThreadMXBean; import org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement; @@ -35,8 +36,8 @@ public class JvmGcMetrics extends AbstractLifecycleListener { private final List garbageCollectorMXBeans = ManagementFactory.getGarbageCollectorMXBeans(); @Override - public void start(ElasticApmTracer tracer) { - bindTo(tracer.getMetricRegistry()); + public void start(Tracer tracer) { + bindTo(tracer.require(ElasticApmTracer.class).getMetricRegistry()); } void bindTo(final MetricRegistry registry) { diff --git a/apm-agent-core/src/main/java/co/elastic/apm/agent/metrics/builtin/JvmMemoryMetrics.java b/apm-agent-core/src/main/java/co/elastic/apm/agent/metrics/builtin/JvmMemoryMetrics.java index b83fbf2eff..272c1e7a31 100644 --- a/apm-agent-core/src/main/java/co/elastic/apm/agent/metrics/builtin/JvmMemoryMetrics.java +++ b/apm-agent-core/src/main/java/co/elastic/apm/agent/metrics/builtin/JvmMemoryMetrics.java @@ -18,10 +18,11 @@ */ package co.elastic.apm.agent.metrics.builtin; -import co.elastic.apm.agent.context.AbstractLifecycleListener; +import co.elastic.apm.agent.tracer.AbstractLifecycleListener; import co.elastic.apm.agent.impl.ElasticApmTracer; -import co.elastic.apm.agent.metrics.DoubleSupplier; -import co.elastic.apm.agent.metrics.Labels; +import co.elastic.apm.agent.tracer.metrics.DoubleSupplier; +import co.elastic.apm.agent.tracer.Tracer; +import co.elastic.apm.agent.tracer.metrics.Labels; import co.elastic.apm.agent.metrics.MetricRegistry; import co.elastic.apm.agent.sdk.logging.Logger; import co.elastic.apm.agent.sdk.logging.LoggerFactory; @@ -36,8 +37,8 @@ public class JvmMemoryMetrics extends AbstractLifecycleListener { private static final Logger logger = LoggerFactory.getLogger(JvmMemoryMetrics.class); @Override - public void start(ElasticApmTracer tracer) { - bindTo(tracer.getMetricRegistry()); + public void start(Tracer tracer) { + bindTo(tracer.require(ElasticApmTracer.class).getMetricRegistry()); } void bindTo(final MetricRegistry registry) { diff --git a/apm-agent-core/src/main/java/co/elastic/apm/agent/metrics/builtin/SystemMetrics.java b/apm-agent-core/src/main/java/co/elastic/apm/agent/metrics/builtin/SystemMetrics.java index 3659938a5f..a6e79439d8 100644 --- a/apm-agent-core/src/main/java/co/elastic/apm/agent/metrics/builtin/SystemMetrics.java +++ b/apm-agent-core/src/main/java/co/elastic/apm/agent/metrics/builtin/SystemMetrics.java @@ -18,11 +18,12 @@ */ package co.elastic.apm.agent.metrics.builtin; -import co.elastic.apm.agent.context.AbstractLifecycleListener; +import co.elastic.apm.agent.tracer.AbstractLifecycleListener; import co.elastic.apm.agent.impl.ElasticApmTracer; import co.elastic.apm.agent.common.util.WildcardMatcher; -import co.elastic.apm.agent.metrics.DoubleSupplier; -import co.elastic.apm.agent.metrics.Labels; +import co.elastic.apm.agent.tracer.metrics.DoubleSupplier; +import co.elastic.apm.agent.tracer.Tracer; +import co.elastic.apm.agent.tracer.metrics.Labels; import co.elastic.apm.agent.metrics.MetricRegistry; import co.elastic.apm.agent.util.JmxUtils; import org.stagemonitor.util.StringUtils; @@ -88,8 +89,8 @@ public SystemMetrics() { } @Override - public void start(ElasticApmTracer tracer) { - bindTo(tracer.getMetricRegistry()); + public void start(Tracer tracer) { + bindTo(tracer.require(ElasticApmTracer.class).getMetricRegistry()); } void bindTo(MetricRegistry metricRegistry) { diff --git a/apm-agent-core/src/main/java/co/elastic/apm/agent/metrics/builtin/ThreadMetrics.java b/apm-agent-core/src/main/java/co/elastic/apm/agent/metrics/builtin/ThreadMetrics.java index 52c5203555..cf3314c0ea 100644 --- a/apm-agent-core/src/main/java/co/elastic/apm/agent/metrics/builtin/ThreadMetrics.java +++ b/apm-agent-core/src/main/java/co/elastic/apm/agent/metrics/builtin/ThreadMetrics.java @@ -18,10 +18,11 @@ */ package co.elastic.apm.agent.metrics.builtin; -import co.elastic.apm.agent.context.AbstractLifecycleListener; +import co.elastic.apm.agent.tracer.AbstractLifecycleListener; import co.elastic.apm.agent.impl.ElasticApmTracer; -import co.elastic.apm.agent.metrics.DoubleSupplier; -import co.elastic.apm.agent.metrics.Labels; +import co.elastic.apm.agent.tracer.metrics.DoubleSupplier; +import co.elastic.apm.agent.tracer.Tracer; +import co.elastic.apm.agent.tracer.metrics.Labels; import co.elastic.apm.agent.metrics.MetricRegistry; import java.lang.management.ManagementFactory; @@ -30,8 +31,8 @@ public class ThreadMetrics extends AbstractLifecycleListener { @Override - public void start(ElasticApmTracer tracer) { - bindTo(tracer.getMetricRegistry()); + public void start(Tracer tracer) { + bindTo(tracer.require(ElasticApmTracer.class).getMetricRegistry()); } void bindTo(final MetricRegistry registry) { diff --git a/apm-agent-core/src/main/java/co/elastic/apm/agent/report/serialize/DslJsonSerializer.java b/apm-agent-core/src/main/java/co/elastic/apm/agent/report/serialize/DslJsonSerializer.java index 6ec3676c4b..2549fea0b2 100644 --- a/apm-agent-core/src/main/java/co/elastic/apm/agent/report/serialize/DslJsonSerializer.java +++ b/apm-agent-core/src/main/java/co/elastic/apm/agent/report/serialize/DslJsonSerializer.java @@ -59,7 +59,7 @@ import co.elastic.apm.agent.impl.transaction.StackFrame; import co.elastic.apm.agent.impl.transaction.TraceContext; import co.elastic.apm.agent.impl.transaction.Transaction; -import co.elastic.apm.agent.metrics.Labels; +import co.elastic.apm.agent.tracer.metrics.Labels; import co.elastic.apm.agent.report.ApmServerClient; import co.elastic.apm.agent.sdk.internal.collections.LongList; import co.elastic.apm.agent.sdk.logging.Logger; diff --git a/apm-agent-core/src/main/java/co/elastic/apm/agent/report/serialize/MetricRegistryReporter.java b/apm-agent-core/src/main/java/co/elastic/apm/agent/report/serialize/MetricRegistryReporter.java index aa1a9347a9..04327f4f0f 100644 --- a/apm-agent-core/src/main/java/co/elastic/apm/agent/report/serialize/MetricRegistryReporter.java +++ b/apm-agent-core/src/main/java/co/elastic/apm/agent/report/serialize/MetricRegistryReporter.java @@ -18,10 +18,11 @@ */ package co.elastic.apm.agent.report.serialize; +import co.elastic.apm.agent.tracer.Tracer; import co.elastic.apm.agent.tracer.service.ServiceInfo; -import co.elastic.apm.agent.context.AbstractLifecycleListener; +import co.elastic.apm.agent.tracer.AbstractLifecycleListener; import co.elastic.apm.agent.impl.ElasticApmTracer; -import co.elastic.apm.agent.metrics.Labels; +import co.elastic.apm.agent.tracer.metrics.Labels; import co.elastic.apm.agent.metrics.MetricRegistry; import co.elastic.apm.agent.metrics.MetricSet; import co.elastic.apm.agent.report.Reporter; @@ -47,10 +48,12 @@ public MetricRegistryReporter(ElasticApmTracer tracer) { } @Override - public void start(ElasticApmTracer tracer) { + public void start(Tracer tracer) { long intervalMs = tracer.getConfig(ReporterConfiguration.class).getMetricsIntervalMs(); if (intervalMs > 0) { - tracer.getSharedSingleThreadedPool().scheduleAtFixedRate(this, intervalMs, intervalMs, TimeUnit.MILLISECONDS); + tracer.require(ElasticApmTracer.class) + .getSharedSingleThreadedPool() + .scheduleAtFixedRate(this, intervalMs, intervalMs, TimeUnit.MILLISECONDS); } } diff --git a/apm-agent-core/src/main/java/co/elastic/apm/agent/report/serialize/MetricRegistrySerializer.java b/apm-agent-core/src/main/java/co/elastic/apm/agent/report/serialize/MetricRegistrySerializer.java index e5b3700f39..690f02bb7c 100644 --- a/apm-agent-core/src/main/java/co/elastic/apm/agent/report/serialize/MetricRegistrySerializer.java +++ b/apm-agent-core/src/main/java/co/elastic/apm/agent/report/serialize/MetricRegistrySerializer.java @@ -19,7 +19,7 @@ package co.elastic.apm.agent.report.serialize; import co.elastic.apm.agent.tracer.service.ServiceInfo; -import co.elastic.apm.agent.metrics.DoubleSupplier; +import co.elastic.apm.agent.tracer.metrics.DoubleSupplier; import co.elastic.apm.agent.metrics.MetricSet; import co.elastic.apm.agent.metrics.Timer; import com.dslplatform.json.DslJson; diff --git a/apm-agent-core/src/main/resources/META-INF/services/co.elastic.apm.agent.context.LifecycleListener b/apm-agent-core/src/main/resources/META-INF/services/co.elastic.apm.agent.tracer.LifecycleListener similarity index 100% rename from apm-agent-core/src/main/resources/META-INF/services/co.elastic.apm.agent.context.LifecycleListener rename to apm-agent-core/src/main/resources/META-INF/services/co.elastic.apm.agent.tracer.LifecycleListener diff --git a/apm-agent-core/src/test/java/co/elastic/apm/agent/impl/ElasticApmTracerTest.java b/apm-agent-core/src/test/java/co/elastic/apm/agent/impl/ElasticApmTracerTest.java index b2771cfd8a..b365039737 100644 --- a/apm-agent-core/src/test/java/co/elastic/apm/agent/impl/ElasticApmTracerTest.java +++ b/apm-agent-core/src/test/java/co/elastic/apm/agent/impl/ElasticApmTracerTest.java @@ -34,7 +34,7 @@ import co.elastic.apm.agent.impl.transaction.Span; import co.elastic.apm.agent.impl.transaction.TraceContext; import co.elastic.apm.agent.impl.transaction.Transaction; -import co.elastic.apm.agent.metrics.Labels; +import co.elastic.apm.agent.tracer.metrics.Labels; import co.elastic.apm.agent.objectpool.TestObjectPoolFactory; import co.elastic.apm.agent.report.ApmServerClient; import co.elastic.apm.agent.tracer.Outcome; diff --git a/apm-agent-core/src/test/java/co/elastic/apm/agent/impl/LifecycleTest.java b/apm-agent-core/src/test/java/co/elastic/apm/agent/impl/LifecycleTest.java index 9ba0dbc469..ddf693bd5e 100644 --- a/apm-agent-core/src/test/java/co/elastic/apm/agent/impl/LifecycleTest.java +++ b/apm-agent-core/src/test/java/co/elastic/apm/agent/impl/LifecycleTest.java @@ -21,7 +21,7 @@ import co.elastic.apm.agent.MockReporter; import co.elastic.apm.agent.bci.ElasticApmAgent; import co.elastic.apm.agent.configuration.SpyConfiguration; -import co.elastic.apm.agent.context.AbstractLifecycleListener; +import co.elastic.apm.agent.tracer.AbstractLifecycleListener; import co.elastic.apm.agent.objectpool.TestObjectPoolFactory; import net.bytebuddy.agent.ByteBuddyAgent; import org.junit.jupiter.api.AfterEach; @@ -145,12 +145,12 @@ void testStartDisabled() throws Exception { .reporter(new MockReporter()) .withLifecycleListener(new AbstractLifecycleListener() { @Override - public void init(ElasticApmTracer tracer) { + public void init(co.elastic.apm.agent.tracer.Tracer tracer) { initialized.set(true); } @Override - public void start(ElasticApmTracer tracer) throws Exception { + public void start(co.elastic.apm.agent.tracer.Tracer tracer) throws Exception { started.set(true); } }) @@ -163,7 +163,7 @@ public void start(ElasticApmTracer tracer) throws Exception { /* * Has an entry in - * src/test/resources/META-INF/services/co.elastic.apm.agent.context.LifecycleListener + * src/test/resources/META-INF/services/co.elastic.apm.agent.tracer.LifecycleListener */ public static class TestLifecycleListener extends AbstractLifecycleListener { @@ -178,7 +178,7 @@ public TestLifecycleListener() { } @Override - public void start(ElasticApmTracer tracer) { + public void start(co.elastic.apm.agent.tracer.Tracer tracer) { start.incrementAndGet(); } diff --git a/apm-agent-core/src/test/java/co/elastic/apm/agent/impl/SpanTypeBreakdownTest.java b/apm-agent-core/src/test/java/co/elastic/apm/agent/impl/SpanTypeBreakdownTest.java index a090c71566..d8147bdf33 100644 --- a/apm-agent-core/src/test/java/co/elastic/apm/agent/impl/SpanTypeBreakdownTest.java +++ b/apm-agent-core/src/test/java/co/elastic/apm/agent/impl/SpanTypeBreakdownTest.java @@ -26,7 +26,7 @@ import co.elastic.apm.agent.impl.transaction.AbstractSpan; import co.elastic.apm.agent.impl.transaction.Span; import co.elastic.apm.agent.impl.transaction.Transaction; -import co.elastic.apm.agent.metrics.Labels; +import co.elastic.apm.agent.tracer.metrics.Labels; import co.elastic.apm.agent.metrics.MetricSet; import co.elastic.apm.agent.metrics.Timer; import org.junit.jupiter.api.AfterEach; diff --git a/apm-agent-core/src/test/java/co/elastic/apm/agent/metrics/LabelsTest.java b/apm-agent-core/src/test/java/co/elastic/apm/agent/metrics/LabelsTest.java index 21e55850c0..2041a4a784 100644 --- a/apm-agent-core/src/test/java/co/elastic/apm/agent/metrics/LabelsTest.java +++ b/apm-agent-core/src/test/java/co/elastic/apm/agent/metrics/LabelsTest.java @@ -18,6 +18,7 @@ */ package co.elastic.apm.agent.metrics; +import co.elastic.apm.agent.tracer.metrics.Labels; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; diff --git a/apm-agent-core/src/test/java/co/elastic/apm/agent/metrics/MetricRegistryTest.java b/apm-agent-core/src/test/java/co/elastic/apm/agent/metrics/MetricRegistryTest.java index 2b445c9e54..5590fea3cc 100644 --- a/apm-agent-core/src/test/java/co/elastic/apm/agent/metrics/MetricRegistryTest.java +++ b/apm-agent-core/src/test/java/co/elastic/apm/agent/metrics/MetricRegistryTest.java @@ -21,6 +21,8 @@ import co.elastic.apm.agent.configuration.MetricsConfiguration; import co.elastic.apm.agent.common.util.WildcardMatcher; import co.elastic.apm.agent.report.ReporterConfiguration; +import co.elastic.apm.agent.tracer.metrics.DoubleSupplier; +import co.elastic.apm.agent.tracer.metrics.Labels; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/apm-agent-core/src/test/java/co/elastic/apm/agent/metrics/builtin/AgentOverheadMetricsTest.java b/apm-agent-core/src/test/java/co/elastic/apm/agent/metrics/builtin/AgentOverheadMetricsTest.java index 814bc84cfc..093782f979 100644 --- a/apm-agent-core/src/test/java/co/elastic/apm/agent/metrics/builtin/AgentOverheadMetricsTest.java +++ b/apm-agent-core/src/test/java/co/elastic/apm/agent/metrics/builtin/AgentOverheadMetricsTest.java @@ -20,7 +20,7 @@ import co.elastic.apm.agent.configuration.MetricsConfiguration; import co.elastic.apm.agent.common.util.WildcardMatcher; -import co.elastic.apm.agent.metrics.Labels; +import co.elastic.apm.agent.tracer.metrics.Labels; import co.elastic.apm.agent.metrics.MetricRegistry; import co.elastic.apm.agent.metrics.MetricSet; import co.elastic.apm.agent.report.ReporterConfiguration; diff --git a/apm-agent-core/src/test/java/co/elastic/apm/agent/metrics/builtin/AgentReporterMetricsTest.java b/apm-agent-core/src/test/java/co/elastic/apm/agent/metrics/builtin/AgentReporterMetricsTest.java index bc86fd0cda..83527ffe6b 100644 --- a/apm-agent-core/src/test/java/co/elastic/apm/agent/metrics/builtin/AgentReporterMetricsTest.java +++ b/apm-agent-core/src/test/java/co/elastic/apm/agent/metrics/builtin/AgentReporterMetricsTest.java @@ -20,7 +20,7 @@ import co.elastic.apm.agent.configuration.MetricsConfiguration; import co.elastic.apm.agent.common.util.WildcardMatcher; -import co.elastic.apm.agent.metrics.Labels; +import co.elastic.apm.agent.tracer.metrics.Labels; import co.elastic.apm.agent.metrics.MetricRegistry; import co.elastic.apm.agent.metrics.MetricSet; import co.elastic.apm.agent.report.ReporterConfiguration; diff --git a/apm-agent-core/src/test/java/co/elastic/apm/agent/metrics/builtin/CGroupMetricsTest.java b/apm-agent-core/src/test/java/co/elastic/apm/agent/metrics/builtin/CGroupMetricsTest.java index a8d80db1e0..5dd24ae174 100644 --- a/apm-agent-core/src/test/java/co/elastic/apm/agent/metrics/builtin/CGroupMetricsTest.java +++ b/apm-agent-core/src/test/java/co/elastic/apm/agent/metrics/builtin/CGroupMetricsTest.java @@ -19,7 +19,7 @@ package co.elastic.apm.agent.metrics.builtin; import co.elastic.apm.agent.configuration.MetricsConfiguration; -import co.elastic.apm.agent.metrics.Labels; +import co.elastic.apm.agent.tracer.metrics.Labels; import co.elastic.apm.agent.metrics.MetricRegistry; import co.elastic.apm.agent.report.ReporterConfiguration; import org.junit.jupiter.api.Test; diff --git a/apm-agent-core/src/test/java/co/elastic/apm/agent/metrics/builtin/JvmFdMetricsTest.java b/apm-agent-core/src/test/java/co/elastic/apm/agent/metrics/builtin/JvmFdMetricsTest.java index dc15f3874c..3f87b5c70c 100644 --- a/apm-agent-core/src/test/java/co/elastic/apm/agent/metrics/builtin/JvmFdMetricsTest.java +++ b/apm-agent-core/src/test/java/co/elastic/apm/agent/metrics/builtin/JvmFdMetricsTest.java @@ -19,7 +19,7 @@ package co.elastic.apm.agent.metrics.builtin; import co.elastic.apm.agent.configuration.MetricsConfiguration; -import co.elastic.apm.agent.metrics.Labels; +import co.elastic.apm.agent.tracer.metrics.Labels; import co.elastic.apm.agent.metrics.MetricRegistry; import co.elastic.apm.agent.report.ReporterConfiguration; import org.junit.jupiter.api.condition.DisabledOnOs; diff --git a/apm-agent-core/src/test/java/co/elastic/apm/agent/metrics/builtin/JvmMemoryMetricsTest.java b/apm-agent-core/src/test/java/co/elastic/apm/agent/metrics/builtin/JvmMemoryMetricsTest.java index 05c4fe4348..413b148d5c 100644 --- a/apm-agent-core/src/test/java/co/elastic/apm/agent/metrics/builtin/JvmMemoryMetricsTest.java +++ b/apm-agent-core/src/test/java/co/elastic/apm/agent/metrics/builtin/JvmMemoryMetricsTest.java @@ -19,7 +19,7 @@ package co.elastic.apm.agent.metrics.builtin; import co.elastic.apm.agent.configuration.MetricsConfiguration; -import co.elastic.apm.agent.metrics.Labels; +import co.elastic.apm.agent.tracer.metrics.Labels; import co.elastic.apm.agent.metrics.MetricRegistry; import co.elastic.apm.agent.report.ReporterConfiguration; import org.assertj.core.api.AbstractDoubleAssert; diff --git a/apm-agent-core/src/test/java/co/elastic/apm/agent/metrics/builtin/SystemMetricsTest.java b/apm-agent-core/src/test/java/co/elastic/apm/agent/metrics/builtin/SystemMetricsTest.java index dea7de26c2..3226241264 100644 --- a/apm-agent-core/src/test/java/co/elastic/apm/agent/metrics/builtin/SystemMetricsTest.java +++ b/apm-agent-core/src/test/java/co/elastic/apm/agent/metrics/builtin/SystemMetricsTest.java @@ -19,7 +19,7 @@ package co.elastic.apm.agent.metrics.builtin; import co.elastic.apm.agent.configuration.MetricsConfiguration; -import co.elastic.apm.agent.metrics.Labels; +import co.elastic.apm.agent.tracer.metrics.Labels; import co.elastic.apm.agent.metrics.MetricRegistry; import co.elastic.apm.agent.report.ReporterConfiguration; import org.junit.jupiter.api.Test; diff --git a/apm-agent-core/src/test/java/co/elastic/apm/agent/metrics/builtin/ThreadMetricsTest.java b/apm-agent-core/src/test/java/co/elastic/apm/agent/metrics/builtin/ThreadMetricsTest.java index 287047b2ea..4fec12cf1a 100644 --- a/apm-agent-core/src/test/java/co/elastic/apm/agent/metrics/builtin/ThreadMetricsTest.java +++ b/apm-agent-core/src/test/java/co/elastic/apm/agent/metrics/builtin/ThreadMetricsTest.java @@ -19,7 +19,7 @@ package co.elastic.apm.agent.metrics.builtin; import co.elastic.apm.agent.configuration.MetricsConfiguration; -import co.elastic.apm.agent.metrics.Labels; +import co.elastic.apm.agent.tracer.metrics.Labels; import co.elastic.apm.agent.metrics.MetricRegistry; import co.elastic.apm.agent.report.ReporterConfiguration; import org.junit.jupiter.api.Test; diff --git a/apm-agent-core/src/test/java/co/elastic/apm/agent/report/serialize/MetricSetSerializationTest.java b/apm-agent-core/src/test/java/co/elastic/apm/agent/report/serialize/MetricSetSerializationTest.java index 7f696af5f1..1abc82a114 100644 --- a/apm-agent-core/src/test/java/co/elastic/apm/agent/report/serialize/MetricSetSerializationTest.java +++ b/apm-agent-core/src/test/java/co/elastic/apm/agent/report/serialize/MetricSetSerializationTest.java @@ -20,7 +20,7 @@ import co.elastic.apm.agent.configuration.MetricsConfiguration; import co.elastic.apm.agent.tracer.service.ServiceInfo; -import co.elastic.apm.agent.metrics.Labels; +import co.elastic.apm.agent.tracer.metrics.Labels; import co.elastic.apm.agent.metrics.MetricCollector; import co.elastic.apm.agent.metrics.MetricRegistry; import co.elastic.apm.agent.metrics.MetricsProvider; diff --git a/apm-agent-core/src/test/resources/META-INF/services/co.elastic.apm.agent.context.LifecycleListener b/apm-agent-core/src/test/resources/META-INF/services/co.elastic.apm.agent.tracer.LifecycleListener similarity index 100% rename from apm-agent-core/src/test/resources/META-INF/services/co.elastic.apm.agent.context.LifecycleListener rename to apm-agent-core/src/test/resources/META-INF/services/co.elastic.apm.agent.tracer.LifecycleListener diff --git a/apm-agent-plugins/apm-jmx-plugin/pom.xml b/apm-agent-plugins/apm-jmx-plugin/pom.xml index 13cc08d1cb..30376a6b41 100644 --- a/apm-agent-plugins/apm-jmx-plugin/pom.xml +++ b/apm-agent-plugins/apm-jmx-plugin/pom.xml @@ -15,13 +15,4 @@ ${project.basedir}/../.. - - - - ${project.groupId} - apm-agent-core - ${project.version} - - - diff --git a/apm-agent-plugins/apm-jmx-plugin/src/main/java/co/elastic/apm/agent/jmx/JmxMetric.java b/apm-agent-plugins/apm-jmx-plugin/src/main/java/co/elastic/apm/agent/jmx/JmxMetric.java index 9fa1b4da6d..9409e810af 100644 --- a/apm-agent-plugins/apm-jmx-plugin/src/main/java/co/elastic/apm/agent/jmx/JmxMetric.java +++ b/apm-agent-plugins/apm-jmx-plugin/src/main/java/co/elastic/apm/agent/jmx/JmxMetric.java @@ -18,12 +18,11 @@ */ package co.elastic.apm.agent.jmx; -import co.elastic.apm.agent.metrics.Labels; +import co.elastic.apm.agent.tracer.metrics.Labels; import org.stagemonitor.configuration.converter.AbstractValueConverter; import javax.annotation.Nonnull; import javax.annotation.Nullable; -import javax.management.MBeanServer; import javax.management.MalformedObjectNameException; import javax.management.ObjectName; import java.util.ArrayList; diff --git a/apm-agent-plugins/apm-jmx-plugin/src/main/java/co/elastic/apm/agent/jmx/JmxMetricTracker.java b/apm-agent-plugins/apm-jmx-plugin/src/main/java/co/elastic/apm/agent/jmx/JmxMetricTracker.java index 685eb59992..4d90364b89 100644 --- a/apm-agent-plugins/apm-jmx-plugin/src/main/java/co/elastic/apm/agent/jmx/JmxMetricTracker.java +++ b/apm-agent-plugins/apm-jmx-plugin/src/main/java/co/elastic/apm/agent/jmx/JmxMetricTracker.java @@ -18,11 +18,10 @@ */ package co.elastic.apm.agent.jmx; -import co.elastic.apm.agent.context.AbstractLifecycleListener; -import co.elastic.apm.agent.impl.ElasticApmTracer; -import co.elastic.apm.agent.metrics.DoubleSupplier; -import co.elastic.apm.agent.metrics.Labels; -import co.elastic.apm.agent.metrics.MetricRegistry; +import co.elastic.apm.agent.tracer.AbstractLifecycleListener; +import co.elastic.apm.agent.tracer.metrics.DoubleSupplier; +import co.elastic.apm.agent.tracer.Tracer; +import co.elastic.apm.agent.tracer.metrics.Labels; import co.elastic.apm.agent.tracer.GlobalLocks; import co.elastic.apm.agent.sdk.logging.Logger; import co.elastic.apm.agent.sdk.logging.LoggerFactory; @@ -63,18 +62,18 @@ public class JmxMetricTracker extends AbstractLifecycleListener { private volatile Thread logManagerPropertyPoller; @Nullable private volatile MBeanServer server; + private final Tracer tracer; private final JmxConfiguration jmxConfiguration; - private final MetricRegistry metricRegistry; @Nullable private volatile NotificationListener listener; - public JmxMetricTracker(ElasticApmTracer tracer) { + public JmxMetricTracker(Tracer tracer) { + this.tracer = tracer; jmxConfiguration = tracer.getConfig(JmxConfiguration.class); - metricRegistry = tracer.getMetricRegistry(); } @Override - public void start(ElasticApmTracer tracer) { + public void start(Tracer tracer) { ConfigurationOption.ChangeListener> captureJmxListener = new ConfigurationOption.ChangeListener>() { @Override public void onChange(ConfigurationOption configurationOption, List oldValue, List newValue) { @@ -179,10 +178,10 @@ public void onChange(ConfigurationOption configurationOption, List List newRegistrations = compileJmxMetricRegistrations(newValue, platformMBeanServer); for (JmxMetricRegistration addedRegistration : removeAll(oldRegistrations, newRegistrations)) { - addedRegistration.register(platformMBeanServer, metricRegistry); + addedRegistration.register(platformMBeanServer, tracer); } for (JmxMetricRegistration deletedRegistration : removeAll(newRegistrations, oldRegistrations)) { - deletedRegistration.unregister(metricRegistry); + deletedRegistration.unregister(tracer); } } @@ -282,7 +281,7 @@ private static List removeAll(List removeFromThis, List toRemove) { private void register(List jmxMetrics, MBeanServer server) { for (JmxMetricRegistration registration : compileJmxMetricRegistrations(jmxMetrics, server)) { - registration.register(server, metricRegistry); + registration.register(server, tracer); } } @@ -421,9 +420,9 @@ private JmxMetricRegistration(String metricName, Labels labels, String jmxAttrib } - void register(final MBeanServer server, final MetricRegistry metricRegistry) { + void register(final MBeanServer server, final Tracer tracer) { logger.debug("Registering JMX metric {} {}.{} as metric_name: {} labels: {}", objectName, jmxAttribute, compositeDataKey, metricName, labels); - metricRegistry.add(metricName, labels, new DoubleSupplier() { + tracer.addGauge(metricName, labels, new DoubleSupplier() { @Override public double get() { try { @@ -433,7 +432,7 @@ public double get() { return ((Number) ((CompositeData) server.getAttribute(objectName, jmxAttribute)).get(compositeDataKey)).doubleValue(); } } catch (InstanceNotFoundException | AttributeNotFoundException e) { - unregister(metricRegistry); + unregister(tracer); return Double.NaN; } catch (Exception e) { return Double.NaN; @@ -442,9 +441,9 @@ public double get() { }); } - void unregister(MetricRegistry metricRegistry) { + void unregister(Tracer tracer) { logger.debug("Unregistering JMX metric {} {}.{} metric_name: {} labels: {}", objectName, jmxAttribute, compositeDataKey, metricName, labels); - metricRegistry.removeGauge(metricName, labels); + tracer.removeGauge(metricName, labels); } @Override diff --git a/apm-agent-plugins/apm-jmx-plugin/src/main/resources/META-INF/services/co.elastic.apm.agent.context.LifecycleListener b/apm-agent-plugins/apm-jmx-plugin/src/main/resources/META-INF/services/co.elastic.apm.agent.tracer.LifecycleListener similarity index 100% rename from apm-agent-plugins/apm-jmx-plugin/src/main/resources/META-INF/services/co.elastic.apm.agent.context.LifecycleListener rename to apm-agent-plugins/apm-jmx-plugin/src/main/resources/META-INF/services/co.elastic.apm.agent.tracer.LifecycleListener diff --git a/apm-agent-plugins/apm-jmx-plugin/src/test/java/co/elastic/apm/agent/jmx/JmxMetricTrackerTest.java b/apm-agent-plugins/apm-jmx-plugin/src/test/java/co/elastic/apm/agent/jmx/JmxMetricTrackerTest.java index cebd3c78c5..603f308284 100644 --- a/apm-agent-plugins/apm-jmx-plugin/src/test/java/co/elastic/apm/agent/jmx/JmxMetricTrackerTest.java +++ b/apm-agent-plugins/apm-jmx-plugin/src/test/java/co/elastic/apm/agent/jmx/JmxMetricTrackerTest.java @@ -21,7 +21,7 @@ import co.elastic.apm.agent.MockTracer; import co.elastic.apm.agent.configuration.SpyConfiguration; import co.elastic.apm.agent.impl.ElasticApmTracer; -import co.elastic.apm.agent.metrics.Labels; +import co.elastic.apm.agent.tracer.metrics.Labels; import co.elastic.apm.agent.metrics.MetricRegistry; import co.elastic.apm.agent.report.serialize.MetricRegistrySerializer; import org.junit.jupiter.api.AfterEach; diff --git a/apm-agent-plugins/apm-micrometer-plugin/pom.xml b/apm-agent-plugins/apm-micrometer-plugin/pom.xml index be1e349bca..fdcdd72156 100644 --- a/apm-agent-plugins/apm-micrometer-plugin/pom.xml +++ b/apm-agent-plugins/apm-micrometer-plugin/pom.xml @@ -20,12 +20,6 @@ - - - ${project.groupId} - apm-agent-core - ${project.version} - io.micrometer micrometer-core diff --git a/apm-agent-plugins/apm-micrometer-plugin/src/main/java/co/elastic/apm/agent/micrometer/AbstractMicrometerInstrumentation.java b/apm-agent-plugins/apm-micrometer-plugin/src/main/java/co/elastic/apm/agent/micrometer/AbstractMicrometerInstrumentation.java index f9ac5ef254..056daf8df2 100644 --- a/apm-agent-plugins/apm-micrometer-plugin/src/main/java/co/elastic/apm/agent/micrometer/AbstractMicrometerInstrumentation.java +++ b/apm-agent-plugins/apm-micrometer-plugin/src/main/java/co/elastic/apm/agent/micrometer/AbstractMicrometerInstrumentation.java @@ -18,7 +18,6 @@ */ package co.elastic.apm.agent.micrometer; -import co.elastic.apm.agent.impl.ElasticApmTracer; import co.elastic.apm.agent.sdk.ElasticApmInstrumentation; import co.elastic.apm.agent.tracer.GlobalTracer; import co.elastic.apm.agent.tracer.Tracer; @@ -30,7 +29,7 @@ public abstract class AbstractMicrometerInstrumentation extends ElasticApmInstru private static final Tracer tracer = GlobalTracer.get(); - static final MicrometerMetricsReporter reporter = new MicrometerMetricsReporter(tracer.require(ElasticApmTracer.class)); + static final MicrometerMetricsReporter reporter = new MicrometerMetricsReporter(tracer); public Collection getInstrumentationGroupNames() { return Collections.singletonList("micrometer"); diff --git a/apm-agent-plugins/apm-micrometer-plugin/src/main/java/co/elastic/apm/agent/micrometer/MicrometerMetricsReporter.java b/apm-agent-plugins/apm-micrometer-plugin/src/main/java/co/elastic/apm/agent/micrometer/MicrometerMetricsReporter.java index 3379ce66cd..858d64b2d9 100644 --- a/apm-agent-plugins/apm-micrometer-plugin/src/main/java/co/elastic/apm/agent/micrometer/MicrometerMetricsReporter.java +++ b/apm-agent-plugins/apm-micrometer-plugin/src/main/java/co/elastic/apm/agent/micrometer/MicrometerMetricsReporter.java @@ -18,17 +18,14 @@ */ package co.elastic.apm.agent.micrometer; -import co.elastic.apm.agent.impl.ElasticApmTracer; -import co.elastic.apm.agent.impl.Tracer; import co.elastic.apm.agent.common.util.WildcardMatcher; -import co.elastic.apm.agent.report.Reporter; import co.elastic.apm.agent.sdk.logging.Logger; import co.elastic.apm.agent.sdk.logging.LoggerFactory; import co.elastic.apm.agent.sdk.weakconcurrent.WeakConcurrent; import co.elastic.apm.agent.sdk.weakconcurrent.WeakMap; +import co.elastic.apm.agent.tracer.Tracer; import co.elastic.apm.agent.tracer.configuration.MetricsConfiguration; import co.elastic.apm.agent.tracer.configuration.ReporterConfiguration; -import com.dslplatform.json.JsonWriter; import io.micrometer.core.instrument.Meter; import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.core.instrument.composite.CompositeMeterRegistry; @@ -90,19 +87,17 @@ public class MicrometerMetricsReporter implements Runnable, Closeable { private final WeakMap meterRegistries = WeakConcurrent.buildMap(); private final WeakMap configMap = WeakConcurrent.buildMap(); private final MicrometerMeterRegistrySerializer serializer; - private final Reporter reporter; - private final ElasticApmTracer tracer; + private final Tracer tracer; private final AtomicBoolean scheduledReporting = new AtomicBoolean(); private final boolean disableScheduler; - public MicrometerMetricsReporter(ElasticApmTracer tracer) { + public MicrometerMetricsReporter(Tracer tracer) { this(tracer, false); } //constructor split up to have this available for testing - MicrometerMetricsReporter(ElasticApmTracer tracer, boolean disableSchedulerThread) { + MicrometerMetricsReporter(Tracer tracer, boolean disableSchedulerThread) { this.tracer = tracer; - this.reporter = tracer.getReporter(); tracer.addShutdownHook(this); serializer = new MicrometerMeterRegistrySerializer(tracer.getConfig(MetricsConfiguration.class)); this.disableScheduler = disableSchedulerThread; @@ -135,7 +130,7 @@ private synchronized void scheduleReporting() { // called for every class loader that loaded micrometer // that's because a new MicrometerMetricsReporter instance is created in every IndyPluginClassLoader // for example if multiple webapps use potentially different versions of Micrometer - tracer.getSharedSingleThreadedPool().scheduleAtFixedRate(this, 0, INTERVAL_BETWEEN_CHECKS_IN_MILLISECONDS, TimeUnit.MILLISECONDS); + tracer.schedule(this, INTERVAL_BETWEEN_CHECKS_IN_MILLISECONDS, TimeUnit.MILLISECONDS); } } @@ -147,7 +142,7 @@ public void run() { //run split up to have this available for testing void run(final long now) { - if (tracer.getState() != Tracer.TracerState.RUNNING) { + if (!tracer.isRunning()) { return; } long metricsIntervalMs = tracer.getConfig(ReporterConfiguration.class).getMetricsIntervalMs(); @@ -220,7 +215,7 @@ private long getStep(MeterRegistry meterRegistry) { public void close() { // flushing out metrics before shutting down // this is especially important for counters as the counts that were accumulated between the last report and the shutdown would otherwise get lost - tracer.getSharedSingleThreadedPool().submit(this); + tracer.submit(this); } private static class MeterMapConsumer implements Consumer { diff --git a/apm-agent-plugins/apm-opentelemetry/apm-opentelemetry-embedded-metrics-sdk/src/main/java/co/elastic/apm/agent/embeddedotel/EmbeddedSdkManager.java b/apm-agent-plugins/apm-opentelemetry/apm-opentelemetry-embedded-metrics-sdk/src/main/java/co/elastic/apm/agent/embeddedotel/EmbeddedSdkManager.java index 9793bbbe76..95c57c60c3 100644 --- a/apm-agent-plugins/apm-opentelemetry/apm-opentelemetry-embedded-metrics-sdk/src/main/java/co/elastic/apm/agent/embeddedotel/EmbeddedSdkManager.java +++ b/apm-agent-plugins/apm-opentelemetry/apm-opentelemetry-embedded-metrics-sdk/src/main/java/co/elastic/apm/agent/embeddedotel/EmbeddedSdkManager.java @@ -18,11 +18,11 @@ */ package co.elastic.apm.agent.embeddedotel; -import co.elastic.apm.agent.context.AbstractLifecycleListener; +import co.elastic.apm.agent.tracer.AbstractLifecycleListener; import co.elastic.apm.agent.embeddedotel.proxy.ProxyMeterProvider; -import co.elastic.apm.agent.impl.ElasticApmTracer; import co.elastic.apm.agent.sdk.logging.Logger; import co.elastic.apm.agent.sdk.logging.LoggerFactory; +import co.elastic.apm.agent.tracer.Tracer; import io.opentelemetry.sdk.metrics.SdkMeterProvider; import io.opentelemetry.sdk.metrics.SdkMeterProviderBuilder; @@ -40,14 +40,14 @@ public class EmbeddedSdkManager extends AbstractLifecycleListener { private static final Logger logger = LoggerFactory.getLogger(EmbeddedSdkManager.class); @Nullable - private ElasticApmTracer tracer; + private Tracer tracer; @Nullable private volatile SdkMeterProvider sdkInstance; private boolean isShutdown = false; @Override - public synchronized void start(ElasticApmTracer tracer) throws Exception { + public synchronized void start(Tracer tracer) throws Exception { this.tracer = tracer; } diff --git a/apm-agent-plugins/apm-opentelemetry/apm-opentelemetry-embedded-metrics-sdk/src/main/resources/META-INF/services/co.elastic.apm.agent.context.LifecycleListener b/apm-agent-plugins/apm-opentelemetry/apm-opentelemetry-embedded-metrics-sdk/src/main/resources/META-INF/services/co.elastic.apm.agent.tracer.LifecycleListener similarity index 100% rename from apm-agent-plugins/apm-opentelemetry/apm-opentelemetry-embedded-metrics-sdk/src/main/resources/META-INF/services/co.elastic.apm.agent.context.LifecycleListener rename to apm-agent-plugins/apm-opentelemetry/apm-opentelemetry-embedded-metrics-sdk/src/main/resources/META-INF/services/co.elastic.apm.agent.tracer.LifecycleListener diff --git a/apm-agent-plugins/apm-profiling-plugin/src/main/java/co/elastic/apm/agent/profiler/ProfilingFactory.java b/apm-agent-plugins/apm-profiling-plugin/src/main/java/co/elastic/apm/agent/profiler/ProfilingFactory.java index 400e28623c..e7ddcb77a4 100644 --- a/apm-agent-plugins/apm-profiling-plugin/src/main/java/co/elastic/apm/agent/profiler/ProfilingFactory.java +++ b/apm-agent-plugins/apm-profiling-plugin/src/main/java/co/elastic/apm/agent/profiler/ProfilingFactory.java @@ -18,8 +18,9 @@ */ package co.elastic.apm.agent.profiler; -import co.elastic.apm.agent.context.AbstractLifecycleListener; +import co.elastic.apm.agent.tracer.AbstractLifecycleListener; import co.elastic.apm.agent.impl.ElasticApmTracer; +import co.elastic.apm.agent.tracer.Tracer; public class ProfilingFactory extends AbstractLifecycleListener { @@ -35,9 +36,10 @@ public ProfilingFactory(ElasticApmTracer tracer) { } @Override - public void start(ElasticApmTracer tracer) { + public void start(Tracer tracer) throws Exception { profiler.start(tracer); - tracer.registerSpanListener(new ProfilingActivationListener(tracer, profiler)); + ElasticApmTracer elasticApmTracer = tracer.require(ElasticApmTracer.class); + elasticApmTracer.registerSpanListener(new ProfilingActivationListener(elasticApmTracer, profiler)); } @Override diff --git a/apm-agent-plugins/apm-profiling-plugin/src/main/java/co/elastic/apm/agent/profiler/SamplingProfiler.java b/apm-agent-plugins/apm-profiling-plugin/src/main/java/co/elastic/apm/agent/profiler/SamplingProfiler.java index 1a33248b5a..0c8cb3f674 100644 --- a/apm-agent-plugins/apm-profiling-plugin/src/main/java/co/elastic/apm/agent/profiler/SamplingProfiler.java +++ b/apm-agent-plugins/apm-profiling-plugin/src/main/java/co/elastic/apm/agent/profiler/SamplingProfiler.java @@ -19,7 +19,7 @@ package co.elastic.apm.agent.profiler; import co.elastic.apm.agent.common.util.WildcardMatcher; -import co.elastic.apm.agent.context.AbstractLifecycleListener; +import co.elastic.apm.agent.tracer.AbstractLifecycleListener; import co.elastic.apm.agent.impl.ElasticApmTracer; import co.elastic.apm.agent.impl.transaction.Span; import co.elastic.apm.agent.impl.transaction.StackFrame; @@ -30,6 +30,7 @@ import co.elastic.apm.agent.sdk.internal.util.ExecutorUtils; import co.elastic.apm.agent.sdk.logging.Logger; import co.elastic.apm.agent.sdk.logging.LoggerFactory; +import co.elastic.apm.agent.tracer.Tracer; import co.elastic.apm.agent.tracer.configuration.CoreConfiguration; import co.elastic.apm.agent.tracer.configuration.TimeDuration; import co.elastic.apm.agent.tracer.pooling.Allocator; @@ -697,7 +698,7 @@ void copyFromFiles(Path activationEvents, Path traces) throws IOException { } @Override - public void start(ElasticApmTracer tracer) { + public void start(Tracer tracer) { scheduler.submit(this); } diff --git a/apm-agent-plugins/apm-profiling-plugin/src/main/resources/META-INF/services/co.elastic.apm.agent.context.LifecycleListener b/apm-agent-plugins/apm-profiling-plugin/src/main/resources/META-INF/services/co.elastic.apm.agent.tracer.LifecycleListener similarity index 100% rename from apm-agent-plugins/apm-profiling-plugin/src/main/resources/META-INF/services/co.elastic.apm.agent.context.LifecycleListener rename to apm-agent-plugins/apm-profiling-plugin/src/main/resources/META-INF/services/co.elastic.apm.agent.tracer.LifecycleListener diff --git a/apm-agent-core/src/main/java/co/elastic/apm/agent/context/AbstractLifecycleListener.java b/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/AbstractLifecycleListener.java similarity index 83% rename from apm-agent-core/src/main/java/co/elastic/apm/agent/context/AbstractLifecycleListener.java rename to apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/AbstractLifecycleListener.java index 02c4f0c0be..6489ae1441 100644 --- a/apm-agent-core/src/main/java/co/elastic/apm/agent/context/AbstractLifecycleListener.java +++ b/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/AbstractLifecycleListener.java @@ -16,17 +16,15 @@ * specific language governing permissions and limitations * under the License. */ -package co.elastic.apm.agent.context; - -import co.elastic.apm.agent.impl.ElasticApmTracer; +package co.elastic.apm.agent.tracer; public abstract class AbstractLifecycleListener implements LifecycleListener { @Override - public void init(ElasticApmTracer tracer) throws Exception { + public void init(Tracer tracer) throws Exception { } @Override - public void start(ElasticApmTracer tracer) throws Exception { + public void start(Tracer tracer) throws Exception { } @Override diff --git a/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/GlobalTracer.java b/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/GlobalTracer.java index fa843ed2cc..78886f4d3d 100644 --- a/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/GlobalTracer.java +++ b/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/GlobalTracer.java @@ -19,6 +19,8 @@ package co.elastic.apm.agent.tracer; import co.elastic.apm.agent.tracer.dispatch.HeaderGetter; +import co.elastic.apm.agent.tracer.metrics.DoubleSupplier; +import co.elastic.apm.agent.tracer.metrics.Labels; import co.elastic.apm.agent.tracer.pooling.ObjectPoolFactory; import co.elastic.apm.agent.tracer.reference.ReferenceCounted; import co.elastic.apm.agent.tracer.reference.ReferenceCountedMap; @@ -26,6 +28,7 @@ import javax.annotation.Nullable; import java.util.Set; +import java.util.concurrent.TimeUnit; public class GlobalTracer implements Tracer { @@ -160,4 +163,24 @@ public void flush() { public void completeMetaData(String name, String version, String id, String region) { tracer.completeMetaData(name, version, id, region); } + + @Override + public void removeGauge(String name, Labels.Immutable labels) { + tracer.removeGauge(name, labels); + } + + @Override + public void addGauge(String name, Labels.Immutable labels, DoubleSupplier supplier) { + tracer.addGauge(name, labels, supplier); + } + + @Override + public void submit(Runnable job) { + tracer.submit(job); + } + + @Override + public void schedule(Runnable job, long interval, TimeUnit timeUnit) { + tracer.schedule(job, interval, timeUnit); + } } diff --git a/apm-agent-core/src/main/java/co/elastic/apm/agent/context/LifecycleListener.java b/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/LifecycleListener.java similarity index 93% rename from apm-agent-core/src/main/java/co/elastic/apm/agent/context/LifecycleListener.java rename to apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/LifecycleListener.java index 3b4716518c..40ce5c69ae 100644 --- a/apm-agent-core/src/main/java/co/elastic/apm/agent/context/LifecycleListener.java +++ b/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/LifecycleListener.java @@ -16,16 +16,13 @@ * specific language governing permissions and limitations * under the License. */ -package co.elastic.apm.agent.context; - -import co.elastic.apm.agent.impl.ElasticApmTracer; -import co.elastic.apm.agent.impl.Tracer; +package co.elastic.apm.agent.tracer; /** * A {@link LifecycleListener} notifies about the start and stop event of the {@link ElasticApmTracer}. *

* Implement this interface and register it as a {@linkplain java.util.ServiceLoader service} under - * {@code src/main/resources/META-INF/services/co.elastic.apm.agent.context.LifecycleListener}. + * {@code src/main/resources/META-INF/services/co.elastic.apm.agent.tracer.LifecycleListener}. *

*

* Implementations may have a constructor with an {@link ElasticApmTracer} argument @@ -34,21 +31,21 @@ public interface LifecycleListener { /** - * Callback for tracer initialization. As opposed to {@link LifecycleListener#start(ElasticApmTracer)}, which may + * Callback for tracer initialization. As opposed to {@link LifecycleListener#start(Tracer)}, which may * be called in a delay, this callback is called at the bootstrap of the JVM, before anything else start. * This may be useful for listeners that need to operate very early on, for example such that setup class loading * requirement to support OSGi systems. * @param tracer the tracer * @throws Exception */ - void init(ElasticApmTracer tracer) throws Exception; + void init(Tracer tracer) throws Exception; /** * Callback for when the {@link ElasticApmTracer} starts. * * @param tracer The tracer. */ - void start(ElasticApmTracer tracer) throws Exception; + void start(Tracer tracer) throws Exception; /** * Callback for when {@link ElasticApmTracer#pause()} has been called. diff --git a/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/NoopTracer.java b/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/NoopTracer.java index e668c247e4..beb1ea5a6e 100644 --- a/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/NoopTracer.java +++ b/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/NoopTracer.java @@ -19,6 +19,8 @@ package co.elastic.apm.agent.tracer; import co.elastic.apm.agent.tracer.dispatch.HeaderGetter; +import co.elastic.apm.agent.tracer.metrics.DoubleSupplier; +import co.elastic.apm.agent.tracer.metrics.Labels; import co.elastic.apm.agent.tracer.pooling.ObjectPoolFactory; import co.elastic.apm.agent.tracer.reference.ReferenceCounted; import co.elastic.apm.agent.tracer.reference.ReferenceCountedMap; @@ -28,6 +30,7 @@ import java.io.IOException; import java.util.Collections; import java.util.Set; +import java.util.concurrent.TimeUnit; class NoopTracer implements Tracer { @@ -134,4 +137,20 @@ public void flush() { @Override public void completeMetaData(String name, String version, String id, String region) { } + + @Override + public void addGauge(String name, Labels.Immutable labels, DoubleSupplier supplier) { + } + + @Override + public void removeGauge(String name, Labels.Immutable labels) { + } + + @Override + public void submit(Runnable job) { + } + + @Override + public void schedule(Runnable job, long interval, TimeUnit timeUnit) { + } } diff --git a/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/Tracer.java b/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/Tracer.java index da0ddbbf30..a714622546 100644 --- a/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/Tracer.java +++ b/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/Tracer.java @@ -19,6 +19,8 @@ package co.elastic.apm.agent.tracer; import co.elastic.apm.agent.tracer.dispatch.HeaderGetter; +import co.elastic.apm.agent.tracer.metrics.DoubleSupplier; +import co.elastic.apm.agent.tracer.metrics.Labels; import co.elastic.apm.agent.tracer.pooling.ObjectPoolFactory; import co.elastic.apm.agent.tracer.reference.ReferenceCounted; import co.elastic.apm.agent.tracer.reference.ReferenceCountedMap; @@ -28,6 +30,7 @@ import java.io.Flushable; import java.io.IOException; import java.util.Set; +import java.util.concurrent.TimeUnit; public interface Tracer extends Flushable { @@ -95,4 +98,14 @@ public interface Tracer extends Flushable { void flush(); void completeMetaData(String name, String version, String id, String region); + + void removeGauge(String name, Labels.Immutable labels); + + void addGauge(String name, Labels.Immutable labels, DoubleSupplier supplier); + + void submit(Runnable job); + + void schedule(Runnable job, long interval, TimeUnit timeUnit); + + void addShutdownHook(AutoCloseable hook); } diff --git a/apm-agent-core/src/main/java/co/elastic/apm/agent/metrics/DoubleSupplier.java b/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/metrics/DoubleSupplier.java similarity index 94% rename from apm-agent-core/src/main/java/co/elastic/apm/agent/metrics/DoubleSupplier.java rename to apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/metrics/DoubleSupplier.java index 120a72221d..7f5087b653 100644 --- a/apm-agent-core/src/main/java/co/elastic/apm/agent/metrics/DoubleSupplier.java +++ b/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/metrics/DoubleSupplier.java @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package co.elastic.apm.agent.metrics; +package co.elastic.apm.agent.tracer.metrics; public interface DoubleSupplier { diff --git a/apm-agent-core/src/main/java/co/elastic/apm/agent/metrics/Labels.java b/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/metrics/Labels.java similarity index 98% rename from apm-agent-core/src/main/java/co/elastic/apm/agent/metrics/Labels.java rename to apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/metrics/Labels.java index c6a2e0475d..a48076bbed 100644 --- a/apm-agent-core/src/main/java/co/elastic/apm/agent/metrics/Labels.java +++ b/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/metrics/Labels.java @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package co.elastic.apm.agent.metrics; +package co.elastic.apm.agent.tracer.metrics; import co.elastic.apm.agent.tracer.pooling.Recyclable; @@ -31,10 +31,6 @@ * However, there are also top-level labels which are not nested under the {@code labels} object, * for example {@link #getTransactionName()}, {@link #getTransactionType()}, {@link #getSpanType()} and {@link #getSpanSubType()}. *

- * Metrics are structured into multiple {@link MetricSet}s. - * For each distinct combination of {@link Labels}, there is one {@link MetricSet}. - *

- *

* Labels allow for {@link CharSequence}s as a value, * thus avoiding allocations for {@code transaction.name.toString()} when tracking breakdown metrics for a transaction. * Iterations over the labels also don't allocate an Iterator, in contrast to {@code Map.entrySet().iterator()}. From 4bcbeea5b3558315e93c21f0567c41a9be2752f9 Mon Sep 17 00:00:00 2001 From: Rafael Winterhalter Date: Tue, 6 Feb 2024 20:35:40 +0100 Subject: [PATCH 5/9] Factor out JSON DSL for metrics. --- apm-agent-core/pom.xml | 5 - .../apm/agent/impl/ElasticApmTracer.java | 6 + .../report/serialize/DslJsonSerializer.java | 146 +++++++----------- .../serialize/MetricRegistrySerializer.java | 7 +- .../serialize/SerializationConstants.java | 3 +- .../MicrometerMeterRegistrySerializer.java | 16 +- .../micrometer/MicrometerMetricsReporter.java | 3 +- .../otelmetricsdk/MetricSetSerializer.java | 12 +- apm-agent-tracer/pom.xml | 5 + .../apm/agent/tracer/GlobalTracer.java | 11 ++ .../apm/agent/tracer/LifecycleListener.java | 23 ++- .../elastic/apm/agent/tracer/NoopTracer.java | 10 +- .../co/elastic/apm/agent/tracer/Tracer.java | 4 +- .../apm/agent/tracer/metrics/DslJsonUtil.java | 80 ++++++++++ .../apm/agent/tracer}/metrics/LabelsTest.java | 3 +- 15 files changed, 202 insertions(+), 132 deletions(-) create mode 100644 apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/metrics/DslJsonUtil.java rename {apm-agent-core/src/test/java/co/elastic/apm/agent => apm-agent-tracer/src/test/java/co/elastic/apm/agent/tracer}/metrics/LabelsTest.java (98%) diff --git a/apm-agent-core/pom.xml b/apm-agent-core/pom.xml index 355bc1b3c0..b91c80903e 100644 --- a/apm-agent-core/pom.xml +++ b/apm-agent-core/pom.xml @@ -139,11 +139,6 @@ ${version.jetty-server} test - - com.dslplatform - dsl-json - 1.9.3 - commons-math 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 35cf1f416c..cc795e8d52 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 @@ -68,6 +68,7 @@ import co.elastic.apm.agent.tracer.reference.ReferenceCountedMap; import co.elastic.apm.agent.util.DependencyInjectingServiceLoader; import co.elastic.apm.agent.util.ExecutorUtils; +import com.dslplatform.json.JsonWriter; import org.stagemonitor.configuration.ConfigurationOption; import org.stagemonitor.configuration.ConfigurationOptionProvider; import org.stagemonitor.configuration.ConfigurationRegistry; @@ -1047,4 +1048,9 @@ public void submit(Runnable job) { public void schedule(Runnable job, long interval, TimeUnit timeUnit) { sharedPool.scheduleAtFixedRate(job, 0, interval, timeUnit); } + + @Override + public void reportMetric(JsonWriter metrics) { + reporter.reportMetrics(metrics); + } } diff --git a/apm-agent-core/src/main/java/co/elastic/apm/agent/report/serialize/DslJsonSerializer.java b/apm-agent-core/src/main/java/co/elastic/apm/agent/report/serialize/DslJsonSerializer.java index 2549fea0b2..e56bb1b1e3 100644 --- a/apm-agent-core/src/main/java/co/elastic/apm/agent/report/serialize/DslJsonSerializer.java +++ b/apm-agent-core/src/main/java/co/elastic/apm/agent/report/serialize/DslJsonSerializer.java @@ -66,6 +66,7 @@ import co.elastic.apm.agent.sdk.logging.LoggerFactory; import co.elastic.apm.agent.tracer.metadata.PotentiallyMultiValuedMap; import co.elastic.apm.agent.tracer.pooling.Recyclable; +import co.elastic.apm.agent.tracer.metrics.DslJsonUtil; import com.dslplatform.json.BoolConverter; import com.dslplatform.json.DslJson; import com.dslplatform.json.JsonWriter; @@ -98,7 +99,6 @@ public class DslJsonSerializer { private static final byte NEW_LINE = (byte) '\n'; private static final Logger logger = LoggerFactory.getLogger(DslJsonSerializer.class); - private static final String[] DISALLOWED_IN_PROPERTY_NAME = new String[]{".", "*", "\""}; private static final List excludedStackFramesPrefixes = Arrays.asList("java.lang.reflect.", "com.sun.", "sun.", "jdk.internal."); @@ -165,16 +165,16 @@ static void serializeMetadata(MetaData metaData, private static void serializeGlobalLabels(ArrayList globalLabelKeys, ArrayList globalLabelValues, final StringBuilder replaceBuilder, JsonWriter jw) { if (!globalLabelKeys.isEmpty()) { - writeFieldName("labels", jw); + DslJsonUtil.writeFieldName("labels", jw); jw.writeByte(OBJECT_START); - writeStringValue(sanitizePropertyName(globalLabelKeys.get(0), replaceBuilder), replaceBuilder, jw); + DslJsonUtil.writeStringValue(DslJsonUtil.sanitizePropertyName(globalLabelKeys.get(0), replaceBuilder), replaceBuilder, jw); jw.writeByte(JsonWriter.SEMI); - writeStringValue(globalLabelValues.get(0), replaceBuilder, jw); + DslJsonUtil.writeStringValue(globalLabelValues.get(0), replaceBuilder, jw); for (int i = 1; i < globalLabelKeys.size(); i++) { jw.writeByte(COMMA); - writeStringValue(sanitizePropertyName(globalLabelKeys.get(i), replaceBuilder), replaceBuilder, jw); + DslJsonUtil.writeStringValue(DslJsonUtil.sanitizePropertyName(globalLabelKeys.get(i), replaceBuilder), replaceBuilder, jw); jw.writeByte(JsonWriter.SEMI); - writeStringValue(globalLabelValues.get(i), replaceBuilder, jw); + DslJsonUtil.writeStringValue(globalLabelValues.get(i), replaceBuilder, jw); } jw.writeByte(OBJECT_END); jw.writeByte(COMMA); @@ -182,7 +182,7 @@ private static void serializeGlobalLabels(ArrayList globalLabelKeys, Arr } private static void serializeService(final Service service, final StringBuilder replaceBuilder, final JsonWriter jw, boolean supportsAgentActivationMethod) { - writeFieldName("service", jw); + DslJsonUtil.writeFieldName("service", jw); jw.writeByte(JsonWriter.OBJECT_START); writeField("name", service.getName(), replaceBuilder, jw); @@ -224,17 +224,17 @@ private static void serializeService(@Nullable final CharSequence serviceName, @ return; } - writeFieldName("service", jw); + DslJsonUtil.writeFieldName("service", jw); jw.writeByte(OBJECT_START); if (serviceName != null) { - writeFieldName("name", jw); - writeStringValue(serviceName, replaceBuilder, jw); + DslJsonUtil.writeFieldName("name", jw); + DslJsonUtil.writeStringValue(serviceName, replaceBuilder, jw); if (serviceVersion != null) { jw.writeByte(COMMA); - writeFieldName("version", jw); - writeStringValue(serviceVersion, replaceBuilder, jw); + DslJsonUtil.writeFieldName("version", jw); + DslJsonUtil.writeStringValue(serviceVersion, replaceBuilder, jw); } } @@ -242,22 +242,22 @@ private static void serializeService(@Nullable final CharSequence serviceName, @ if (serviceName != null) { jw.writeByte(COMMA); } - writeFieldName("target", jw); + DslJsonUtil.writeFieldName("target", jw); jw.writeByte(OBJECT_START); CharSequence targetType = serviceTarget.getType(); CharSequence targetName = serviceTarget.getName(); if (targetType != null) { - writeFieldName("type", jw); - writeStringValue(targetType, replaceBuilder, jw); + DslJsonUtil.writeFieldName("type", jw); + DslJsonUtil.writeStringValue(targetType, replaceBuilder, jw); } if (targetName != null) { if (targetType != null) { jw.writeByte(COMMA); } - writeFieldName("name", jw); - writeStringValue(targetName, replaceBuilder, jw); + DslJsonUtil.writeFieldName("name", jw); + DslJsonUtil.writeStringValue(targetName, replaceBuilder, jw); } jw.writeByte(OBJECT_END); @@ -271,7 +271,7 @@ private static void serializeService(@Nullable String name, @Nullable String ver } private static void serializeAgent(final Agent agent, final StringBuilder replaceBuilder, final JsonWriter jw, boolean supportsAgentActivationMethod) { - writeFieldName("agent", jw); + DslJsonUtil.writeFieldName("agent", jw); jw.writeByte(JsonWriter.OBJECT_START); if (supportsAgentActivationMethod) { writeField("activation_method", agent.getActivationMethod(), replaceBuilder, jw); @@ -284,7 +284,7 @@ private static void serializeAgent(final Agent agent, final StringBuilder replac } private static void serializeLanguage(final Language language, final StringBuilder replaceBuilder, final JsonWriter jw) { - writeFieldName("language", jw); + DslJsonUtil.writeFieldName("language", jw); jw.writeByte(JsonWriter.OBJECT_START); writeField("name", language.getName(), replaceBuilder, jw); writeLastField("version", language.getVersion(), replaceBuilder, jw); @@ -293,7 +293,7 @@ private static void serializeLanguage(final Language language, final StringBuild } private static void serializeFramework(final Framework framework, final StringBuilder replaceBuilder, final JsonWriter jw) { - writeFieldName("framework", jw); + DslJsonUtil.writeFieldName("framework", jw); jw.writeByte(JsonWriter.OBJECT_START); writeField("name", framework.getName(), replaceBuilder, jw); writeLastField("version", framework.getVersion(), replaceBuilder, jw); @@ -302,7 +302,7 @@ private static void serializeFramework(final Framework framework, final StringBu } private static void serializeNode(final Node node, final StringBuilder replaceBuilder, final JsonWriter jw) { - writeFieldName("node", jw); + DslJsonUtil.writeFieldName("node", jw); jw.writeByte(JsonWriter.OBJECT_START); writeLastField("configured_name", node.getName(), replaceBuilder, jw); jw.writeByte(JsonWriter.OBJECT_END); @@ -310,7 +310,7 @@ private static void serializeNode(final Node node, final StringBuilder replaceBu } private static void serializeRuntime(final RuntimeInfo runtime, final StringBuilder replaceBuilder, final JsonWriter jw) { - writeFieldName("runtime", jw); + DslJsonUtil.writeFieldName("runtime", jw); jw.writeByte(JsonWriter.OBJECT_START); writeField("name", runtime.getName(), replaceBuilder, jw); writeLastField("version", runtime.getVersion(), replaceBuilder, jw); @@ -319,7 +319,7 @@ private static void serializeRuntime(final RuntimeInfo runtime, final StringBuil } private static void serializeProcess(final ProcessInfo process, final StringBuilder replaceBuilder, final JsonWriter jw) { - writeFieldName("process", jw); + DslJsonUtil.writeFieldName("process", jw); jw.writeByte(JsonWriter.OBJECT_START); writeField("pid", process.getPid(), jw); if (process.getPpid() != null) { @@ -337,7 +337,7 @@ private static void serializeSystem(SystemInfo system, JsonWriter jw, boolean supportsConfiguredAndDetectedHostname) { - writeFieldName("system", jw); + DslJsonUtil.writeFieldName("system", jw); jw.writeByte(JsonWriter.OBJECT_START); serializeContainerInfo(system.getContainerInfo(), replaceBuilder, jw); serializeKubernetesInfo(system.getKubernetesInfo(), replaceBuilder, jw); @@ -360,13 +360,13 @@ private static void serializeSystem(SystemInfo system, } private static void serializeCloudProvider(final CloudProviderInfo cloudProviderInfo, final StringBuilder replaceBuilder, final JsonWriter jw) { - writeFieldName("cloud", jw); + DslJsonUtil.writeFieldName("cloud", jw); jw.writeByte(OBJECT_START); serializeNameAndIdField(cloudProviderInfo.getAccount(), "account", replaceBuilder, jw); serializeNameAndIdField(cloudProviderInfo.getInstance(), "instance", replaceBuilder, jw); serializeNameAndIdField(cloudProviderInfo.getProject(), "project", replaceBuilder, jw); if (cloudProviderInfo.getMachine() != null) { - writeFieldName("machine", jw); + DslJsonUtil.writeFieldName("machine", jw); jw.writeByte(JsonWriter.OBJECT_START); writeLastField("type", cloudProviderInfo.getMachine().getType(), replaceBuilder, jw); jw.writeByte(JsonWriter.OBJECT_END); @@ -375,7 +375,7 @@ private static void serializeCloudProvider(final CloudProviderInfo cloudProvider writeField("availability_zone", cloudProviderInfo.getAvailabilityZone(), replaceBuilder, jw); writeField("region", cloudProviderInfo.getRegion(), replaceBuilder, jw); if (null != cloudProviderInfo.getService()) { - writeFieldName("service", jw); + DslJsonUtil.writeFieldName("service", jw); jw.writeByte(JsonWriter.OBJECT_START); writeLastField("name", cloudProviderInfo.getService().getName(), replaceBuilder, jw); jw.writeByte(JsonWriter.OBJECT_END); @@ -388,13 +388,13 @@ private static void serializeCloudProvider(final CloudProviderInfo cloudProvider private static void serializeNameAndIdField(@Nullable NameAndIdField nameAndIdField, String fieldName, StringBuilder replaceBuilder, JsonWriter jw) { if (nameAndIdField != null && !nameAndIdField.isEmpty()) { - writeFieldName(fieldName, jw); + DslJsonUtil.writeFieldName(fieldName, jw); jw.writeByte(JsonWriter.OBJECT_START); boolean idWritten = false; String id = nameAndIdField.getId(); if (id != null) { - writeFieldName("id", jw); - writeStringValue(id, replaceBuilder, jw); + DslJsonUtil.writeFieldName("id", jw); + DslJsonUtil.writeStringValue(id, replaceBuilder, jw); idWritten = true; } String name = nameAndIdField.getName(); @@ -402,8 +402,8 @@ private static void serializeNameAndIdField(@Nullable NameAndIdField nameAndIdFi if (idWritten) { jw.writeByte(COMMA); } - writeFieldName("name", jw); - writeStringValue(name, replaceBuilder, jw); + DslJsonUtil.writeFieldName("name", jw); + DslJsonUtil.writeStringValue(name, replaceBuilder, jw); } jw.writeByte(JsonWriter.OBJECT_END); jw.writeByte(COMMA); @@ -412,7 +412,7 @@ private static void serializeNameAndIdField(@Nullable NameAndIdField nameAndIdFi private static void serializeContainerInfo(@Nullable SystemInfo.Container container, final StringBuilder replaceBuilder, final JsonWriter jw) { if (container != null) { - writeFieldName("container", jw); + DslJsonUtil.writeFieldName("container", jw); jw.writeByte(JsonWriter.OBJECT_START); writeLastField("id", container.getId(), replaceBuilder, jw); jw.writeByte(JsonWriter.OBJECT_END); @@ -422,7 +422,7 @@ private static void serializeContainerInfo(@Nullable SystemInfo.Container contai private static void serializeKubernetesInfo(@Nullable SystemInfo.Kubernetes kubernetes, final StringBuilder replaceBuilder, final JsonWriter jw) { if (kubernetes != null && kubernetes.hasContent()) { - writeFieldName("kubernetes", jw); + DslJsonUtil.writeFieldName("kubernetes", jw); jw.writeByte(JsonWriter.OBJECT_START); serializeKubeNodeInfo(kubernetes.getNode(), replaceBuilder, jw); serializeKubePodInfo(kubernetes.getPod(), replaceBuilder, jw); @@ -434,7 +434,7 @@ private static void serializeKubernetesInfo(@Nullable SystemInfo.Kubernetes kube private static void serializeKubePodInfo(@Nullable SystemInfo.Kubernetes.Pod pod, final StringBuilder replaceBuilder, final JsonWriter jw) { if (pod != null) { - writeFieldName("pod", jw); + DslJsonUtil.writeFieldName("pod", jw); jw.writeByte(JsonWriter.OBJECT_START); String podName = pod.getName(); if (podName != null) { @@ -448,7 +448,7 @@ private static void serializeKubePodInfo(@Nullable SystemInfo.Kubernetes.Pod pod private static void serializeKubeNodeInfo(@Nullable SystemInfo.Kubernetes.Node node, final StringBuilder replaceBuilder, final JsonWriter jw) { if (node != null) { - writeFieldName("node", jw); + DslJsonUtil.writeFieldName("node", jw); jw.writeByte(JsonWriter.OBJECT_START); writeLastField("name", node.getName(), replaceBuilder, jw); jw.writeByte(JsonWriter.OBJECT_END); @@ -476,13 +476,13 @@ private static void serializeStringKeyScalarValueMap(Iterator kv = it.next(); - writeStringValue(sanitizePropertyName(kv.getKey(), replaceBuilder), replaceBuilder, jw); + DslJsonUtil.writeStringValue(DslJsonUtil.sanitizePropertyName(kv.getKey(), replaceBuilder), replaceBuilder, jw); jw.writeByte(JsonWriter.SEMI); serializeScalarValue(replaceBuilder, jw, kv.getValue(), extendedStringLimit, supportsNonStringValues); while (it.hasNext()) { jw.writeByte(COMMA); kv = it.next(); - writeStringValue(sanitizePropertyName(kv.getKey(), replaceBuilder), replaceBuilder, jw); + DslJsonUtil.writeStringValue(DslJsonUtil.sanitizePropertyName(kv.getKey(), replaceBuilder), replaceBuilder, jw); jw.writeByte(JsonWriter.SEMI); serializeScalarValue(replaceBuilder, jw, kv.getValue(), extendedStringLimit, supportsNonStringValues); } @@ -498,7 +498,7 @@ static void serializeLabels(Labels labels, final String serviceName, final Strin } if (!labels.isEmpty()) { if (labels.getTransactionName() != null || labels.getTransactionType() != null) { - writeFieldName("transaction", jw); + DslJsonUtil.writeFieldName("transaction", jw); jw.writeByte(OBJECT_START); writeField("name", labels.getTransactionName(), replaceBuilder, jw); writeLastField("type", labels.getTransactionType(), replaceBuilder, jw); @@ -507,7 +507,7 @@ static void serializeLabels(Labels labels, final String serviceName, final Strin } if (labels.getSpanType() != null || labels.getSpanSubType() != null) { - writeFieldName("span", jw); + DslJsonUtil.writeFieldName("span", jw); jw.writeByte(OBJECT_START); writeField("type", labels.getSpanType(), replaceBuilder, jw); writeLastField("subtype", labels.getSpanSubType(), replaceBuilder, jw); @@ -515,7 +515,7 @@ static void serializeLabels(Labels labels, final String serviceName, final Strin jw.writeByte(COMMA); } - writeFieldName("tags", jw); + DslJsonUtil.writeFieldName("tags", jw); jw.writeByte(OBJECT_START); serialize(labels, replaceBuilder, jw); jw.writeByte(OBJECT_END); @@ -528,7 +528,7 @@ private static void serialize(Labels labels, final StringBuilder replaceBuilder, if (i > 0) { jw.writeByte(COMMA); } - writeStringValue(sanitizePropertyName(labels.getKey(i), replaceBuilder), replaceBuilder, jw); + DslJsonUtil.writeStringValue(DslJsonUtil.sanitizePropertyName(labels.getKey(i), replaceBuilder), replaceBuilder, jw); jw.writeByte(JsonWriter.SEMI); serializeScalarValue(replaceBuilder, jw, labels.getValue(i), false, false); } @@ -539,7 +539,7 @@ private static void serializeScalarValue(final StringBuilder replaceBuilder, fin if (extendedStringLimit) { writeLongStringValue((String) value, replaceBuilder, jw); } else { - writeStringValue((String) value, replaceBuilder, jw); + DslJsonUtil.writeStringValue((String) value, replaceBuilder, jw); } } else if (value instanceof Number) { if (supportsNonStringValues) { @@ -559,25 +559,6 @@ private static void serializeScalarValue(final StringBuilder replaceBuilder, fin } } - public static CharSequence sanitizePropertyName(String key, StringBuilder replaceBuilder) { - for (int i = 0; i < DISALLOWED_IN_PROPERTY_NAME.length; i++) { - if (key.contains(DISALLOWED_IN_PROPERTY_NAME[i])) { - return replaceAll(key, DISALLOWED_IN_PROPERTY_NAME, "_", replaceBuilder); - } - } - return key; - } - - private static CharSequence replaceAll(String s, String[] stringsToReplace, String replacement, StringBuilder replaceBuilder) { - // uses a instance variable StringBuilder to avoid allocations - replaceBuilder.setLength(0); - replaceBuilder.append(s); - for (String toReplace : stringsToReplace) { - replace(replaceBuilder, toReplace, replacement, 0); - } - return replaceBuilder; - } - static void replace(StringBuilder replaceBuilder, String toReplace, String replacement, int fromIndex) { for (int i = replaceBuilder.indexOf(toReplace, fromIndex); i != -1; i = replaceBuilder.indexOf(toReplace, fromIndex)) { replaceBuilder.replace(i, i + toReplace.length(), replacement); @@ -601,13 +582,13 @@ static void writeField(final String fieldName, if (value == null) { if (writeNull) { - writeFieldName(fieldName, jw); + DslJsonUtil.writeFieldName(fieldName, jw); jw.writeNull(); jw.writeByte(COMMA); } } else { - writeFieldName(fieldName, jw); - writeStringValue(value, replaceBuilder, jw); + DslJsonUtil.writeFieldName(fieldName, jw); + DslJsonUtil.writeStringValue(value, replaceBuilder, jw); jw.writeByte(COMMA); } } @@ -620,16 +601,6 @@ private static void writeStringBuilderValue(StringBuilder value, JsonWriter jw) jw.writeString(value); } - public static void writeStringValue(CharSequence value, final StringBuilder replaceBuilder, final JsonWriter jw) { - if (value.length() > SerializationConstants.MAX_VALUE_LENGTH) { - replaceBuilder.setLength(0); - replaceBuilder.append(value, 0, Math.min(value.length(), SerializationConstants.MAX_VALUE_LENGTH + 1)); - writeStringBuilderValue(replaceBuilder, jw); - } else { - jw.writeString(value); - } - } - private static void writeLongStringBuilderValue(StringBuilder value, JsonWriter jw) { if (value.length() > SerializationConstants.getMaxLongStringValueLength()) { value.setLength(SerializationConstants.getMaxLongStringValueLength() - 1); @@ -649,30 +620,23 @@ private static void writeLongStringValue(CharSequence value, final StringBuilder } static void writeField(final String fieldName, final long value, final JsonWriter jw) { - writeFieldName(fieldName, jw); + DslJsonUtil.writeFieldName(fieldName, jw); NumberConverter.serialize(value, jw); jw.writeByte(COMMA); } public static void writeLastField(final String fieldName, @Nullable final CharSequence value, StringBuilder replaceBuilder, final JsonWriter jw) { - writeFieldName(fieldName, jw); + DslJsonUtil.writeFieldName(fieldName, jw); if (value != null && value.length() > 0) { - writeStringValue(value, replaceBuilder, jw); + DslJsonUtil.writeStringValue(value, replaceBuilder, jw); } else { jw.writeNull(); } } - public static void writeFieldName(final String fieldName, final JsonWriter jw) { - jw.writeByte(JsonWriter.QUOTE); - jw.writeAscii(fieldName); - jw.writeByte(JsonWriter.QUOTE); - jw.writeByte(JsonWriter.SEMI); - } - static void writeField(final String fieldName, final List values, final JsonWriter jw) { if (values.size() > 0) { - writeFieldName(fieldName, jw); + DslJsonUtil.writeFieldName(fieldName, jw); jw.writeByte(ARRAY_START); jw.writeString(values.get(0)); for (int i = 1; i < values.size(); i++) { @@ -1142,7 +1106,7 @@ private void serializeNumber(Number n, JsonWriter jw) { } private void serializeComposite(Composite composite) { - DslJsonSerializer.writeFieldName("composite", jw); + DslJsonUtil.writeFieldName("composite", jw); jw.writeByte(OBJECT_START); writeField("count", composite.getCount()); writeField("sum", composite.getSumMs()); @@ -1342,7 +1306,7 @@ private void serializeStackTraceElement(StackFrame frame, StringBuilder replaceB frame.appendFileName(replaceBuilder); writeField("filename", replaceBuilder); writeField("function", frame.getMethodName()); - writeField("library_frame", isLibraryFrame(frame.getClassName())); + writeField("library_frame", frame.getClassName() != null && isLibraryFrame(frame.getClassName())); writeLastField("lineno", -1); jw.writeByte(OBJECT_END); } @@ -1675,7 +1639,7 @@ void serializeUrl(final Url url) { } else { // serialize as a string for compatibility // doing it in low-level to avoid allocation - DslJsonSerializer.writeFieldName("port", jw); + DslJsonUtil.writeFieldName("port", jw); jw.writeByte(QUOTE); NumberConverter.serialize(port, jw); jw.writeByte(QUOTE); @@ -1787,7 +1751,7 @@ private void writeStringBuilderValue(StringBuilder value) { } private void writeStringValue(CharSequence value) { - DslJsonSerializer.writeStringValue(value, replaceBuilder, jw); + DslJsonUtil.writeStringValue(value, replaceBuilder, jw); } private void writeLongStringValue(CharSequence value) { @@ -1836,7 +1800,7 @@ void writeLastField(final String fieldName, @Nullable final CharSequence value) } private void writeFieldName(final String fieldName) { - DslJsonSerializer.writeFieldName(fieldName, jw); + DslJsonUtil.writeFieldName(fieldName, jw); } private void writeNonLastIdField(String fieldName, Id id) { diff --git a/apm-agent-core/src/main/java/co/elastic/apm/agent/report/serialize/MetricRegistrySerializer.java b/apm-agent-core/src/main/java/co/elastic/apm/agent/report/serialize/MetricRegistrySerializer.java index 690f02bb7c..afcf9133e1 100644 --- a/apm-agent-core/src/main/java/co/elastic/apm/agent/report/serialize/MetricRegistrySerializer.java +++ b/apm-agent-core/src/main/java/co/elastic/apm/agent/report/serialize/MetricRegistrySerializer.java @@ -22,6 +22,7 @@ import co.elastic.apm.agent.tracer.metrics.DoubleSupplier; import co.elastic.apm.agent.metrics.MetricSet; import co.elastic.apm.agent.metrics.Timer; +import co.elastic.apm.agent.tracer.metrics.DslJsonUtil; import com.dslplatform.json.DslJson; import com.dslplatform.json.JsonWriter; import com.dslplatform.json.NumberConverter; @@ -80,14 +81,14 @@ private static boolean serialize(MetricSet metricSet, long epochMicros, String s boolean hasSamples; jw.writeByte(JsonWriter.OBJECT_START); { - DslJsonSerializer.writeFieldName("metricset", jw); + DslJsonUtil.writeFieldName("metricset", jw); jw.writeByte(JsonWriter.OBJECT_START); { - DslJsonSerializer.writeFieldName("timestamp", jw); + DslJsonUtil.writeFieldName("timestamp", jw); NumberConverter.serialize(epochMicros, jw); jw.writeByte(JsonWriter.COMMA); DslJsonSerializer.serializeLabels(metricSet.getLabels(), serviceName, serviceVersion, replaceBuilder, jw); - DslJsonSerializer.writeFieldName("samples", jw); + DslJsonUtil.writeFieldName("samples", jw); jw.writeByte(JsonWriter.OBJECT_START); hasSamples = serializeGauges(metricSet.getGauges(), jw); hasSamples |= serializeTimers(metricSet.getTimers(), hasSamples, jw); diff --git a/apm-agent-core/src/main/java/co/elastic/apm/agent/report/serialize/SerializationConstants.java b/apm-agent-core/src/main/java/co/elastic/apm/agent/report/serialize/SerializationConstants.java index 8f5e4d2db0..bd927d1b8f 100644 --- a/apm-agent-core/src/main/java/co/elastic/apm/agent/report/serialize/SerializationConstants.java +++ b/apm-agent-core/src/main/java/co/elastic/apm/agent/report/serialize/SerializationConstants.java @@ -19,6 +19,7 @@ package co.elastic.apm.agent.report.serialize; import co.elastic.apm.agent.configuration.CoreConfiguration; +import co.elastic.apm.agent.tracer.metrics.DslJsonUtil; import javax.annotation.Nullable; @@ -31,7 +32,7 @@ public class SerializationConstants { */ public static final int BUFFER_SIZE = 16384; - public static final int MAX_VALUE_LENGTH = 1024; + public static final int MAX_VALUE_LENGTH = DslJsonUtil.MAX_VALUE_LENGTH; @Nullable private static volatile SerializationConstants INSTANCE; diff --git a/apm-agent-plugins/apm-micrometer-plugin/src/main/java/co/elastic/apm/agent/micrometer/MicrometerMeterRegistrySerializer.java b/apm-agent-plugins/apm-micrometer-plugin/src/main/java/co/elastic/apm/agent/micrometer/MicrometerMeterRegistrySerializer.java index 683df9632f..58048dde12 100644 --- a/apm-agent-plugins/apm-micrometer-plugin/src/main/java/co/elastic/apm/agent/micrometer/MicrometerMeterRegistrySerializer.java +++ b/apm-agent-plugins/apm-micrometer-plugin/src/main/java/co/elastic/apm/agent/micrometer/MicrometerMeterRegistrySerializer.java @@ -18,13 +18,13 @@ */ package co.elastic.apm.agent.micrometer; -import co.elastic.apm.agent.report.serialize.DslJsonSerializer; import co.elastic.apm.agent.sdk.internal.util.PrivilegedActionUtils; import co.elastic.apm.agent.sdk.logging.Logger; import co.elastic.apm.agent.sdk.logging.LoggerFactory; import co.elastic.apm.agent.sdk.weakconcurrent.WeakConcurrent; import co.elastic.apm.agent.sdk.weakconcurrent.WeakSet; import co.elastic.apm.agent.tracer.configuration.MetricsConfiguration; +import co.elastic.apm.agent.tracer.metrics.DslJsonUtil; import com.dslplatform.json.DslJson; import com.dslplatform.json.JsonWriter; import com.dslplatform.json.NumberConverter; @@ -100,14 +100,14 @@ boolean serializeMetricSet(List tags, List meters, long epochMicros, boolean dedotMetricName = config.isDedotCustomMetrics(); jw.writeByte(JsonWriter.OBJECT_START); { - DslJsonSerializer.writeFieldName("metricset", jw); + DslJsonUtil.writeFieldName("metricset", jw); jw.writeByte(JsonWriter.OBJECT_START); { - DslJsonSerializer.writeFieldName("timestamp", jw); + DslJsonUtil.writeFieldName("timestamp", jw); NumberConverter.serialize(epochMicros, jw); jw.writeByte(JsonWriter.COMMA); serializeTags(tags, replaceBuilder, jw); - DslJsonSerializer.writeFieldName("samples", jw); + DslJsonUtil.writeFieldName("samples", jw); jw.writeByte(JsonWriter.OBJECT_START); ClassLoader originalContextCL = PrivilegedActionUtils.getContextClassLoader(Thread.currentThread()); @@ -167,16 +167,16 @@ private static void serializeTags(List tags, StringBuilder replaceBuilder, if (tags.isEmpty()) { return; } - DslJsonSerializer.writeFieldName("tags", jw); + DslJsonUtil.writeFieldName("tags", jw); jw.writeByte(OBJECT_START); for (int i = 0, tagsSize = tags.size(); i < tagsSize; i++) { Tag tag = tags.get(i); if (i > 0) { jw.writeByte(COMMA); } - DslJsonSerializer.writeStringValue(DslJsonSerializer.sanitizePropertyName(tag.getKey(), replaceBuilder), replaceBuilder, jw); + DslJsonUtil.writeStringValue(DslJsonUtil.sanitizePropertyName(tag.getKey(), replaceBuilder), replaceBuilder, jw); jw.writeByte(JsonWriter.SEMI); - DslJsonSerializer.writeStringValue(tag.getValue(), replaceBuilder, jw); + DslJsonUtil.writeStringValue(tag.getValue(), replaceBuilder, jw); } jw.writeByte(OBJECT_END); jw.writeByte(COMMA); @@ -320,7 +320,7 @@ private static void serializeValueStart(String key, String suffix, JsonWriter jw private static void serializeObjectStart(String key, String objectName, String suffix, JsonWriter jw, StringBuilder replaceBuilder, boolean dedotMetricName) { replaceBuilder.setLength(0); if (dedotMetricName) { - DslJsonSerializer.sanitizePropertyName(key, replaceBuilder); + DslJsonUtil.sanitizePropertyName(key, replaceBuilder); } else { replaceBuilder.append(key); } diff --git a/apm-agent-plugins/apm-micrometer-plugin/src/main/java/co/elastic/apm/agent/micrometer/MicrometerMetricsReporter.java b/apm-agent-plugins/apm-micrometer-plugin/src/main/java/co/elastic/apm/agent/micrometer/MicrometerMetricsReporter.java index 858d64b2d9..6ec9e2cbaa 100644 --- a/apm-agent-plugins/apm-micrometer-plugin/src/main/java/co/elastic/apm/agent/micrometer/MicrometerMetricsReporter.java +++ b/apm-agent-plugins/apm-micrometer-plugin/src/main/java/co/elastic/apm/agent/micrometer/MicrometerMetricsReporter.java @@ -26,6 +26,7 @@ import co.elastic.apm.agent.tracer.Tracer; import co.elastic.apm.agent.tracer.configuration.MetricsConfiguration; import co.elastic.apm.agent.tracer.configuration.ReporterConfiguration; +import com.dslplatform.json.JsonWriter; import io.micrometer.core.instrument.Meter; import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.core.instrument.composite.CompositeMeterRegistry; @@ -185,7 +186,7 @@ void run(final long now) { } logger.debug("Reporting {} meters", meterConsumer.meters.size()); for (JsonWriter serializedMetricSet : serializer.serialize(meterConsumer.meters, now * 1000)) { - reporter.reportMetrics(serializedMetricSet); + tracer.reportMetric(serializedMetricSet); } } diff --git a/apm-agent-plugins/apm-opentelemetry/apm-opentelemetry-metricsdk-plugin/src/main/java/co/elastic/apm/agent/otelmetricsdk/MetricSetSerializer.java b/apm-agent-plugins/apm-opentelemetry/apm-opentelemetry-metricsdk-plugin/src/main/java/co/elastic/apm/agent/otelmetricsdk/MetricSetSerializer.java index de8021c3bd..6484e08906 100644 --- a/apm-agent-plugins/apm-opentelemetry/apm-opentelemetry-metricsdk-plugin/src/main/java/co/elastic/apm/agent/otelmetricsdk/MetricSetSerializer.java +++ b/apm-agent-plugins/apm-opentelemetry/apm-opentelemetry-metricsdk-plugin/src/main/java/co/elastic/apm/agent/otelmetricsdk/MetricSetSerializer.java @@ -19,7 +19,7 @@ package co.elastic.apm.agent.otelmetricsdk; import co.elastic.apm.agent.report.Reporter; -import co.elastic.apm.agent.report.serialize.DslJsonSerializer; +import co.elastic.apm.agent.tracer.metrics.DslJsonUtil; import com.dslplatform.json.BoolConverter; import com.dslplatform.json.DslJson; import com.dslplatform.json.JsonWriter; @@ -56,14 +56,14 @@ public MetricSetSerializer(Attributes attributes, CharSequence instrumentationSc jw = DSL_JSON.newWriter(INITIAL_BUFFER_SIZE); jw.writeByte(JsonWriter.OBJECT_START); { - DslJsonSerializer.writeFieldName("metricset", jw); + DslJsonUtil.writeFieldName("metricset", jw); jw.writeByte(JsonWriter.OBJECT_START); { - DslJsonSerializer.writeFieldName("timestamp", jw); + DslJsonUtil.writeFieldName("timestamp", jw); NumberConverter.serialize(epochMicros, jw); jw.writeByte(JsonWriter.COMMA); serializeAttributes(instrumentationScopeName, attributes); - DslJsonSerializer.writeFieldName("samples", jw); + DslJsonUtil.writeFieldName("samples", jw); jw.writeByte(JsonWriter.OBJECT_START); } } @@ -188,7 +188,7 @@ private void serializeAttributes(CharSequence instrumentationScopeName, Attribut if (attributeMap.isEmpty() && instrumentationScopeName.length() == 0) { return; } - DslJsonSerializer.writeFieldName("tags", jw); + DslJsonUtil.writeFieldName("tags", jw); jw.writeByte(OBJECT_START); boolean anyWritten = false; if (instrumentationScopeName.length() > 0) { @@ -210,7 +210,7 @@ private boolean serializeAttribute(AttributeKey key, @Nullable Object value, if (prependComma) { jw.writeByte(COMMA); } - DslJsonSerializer.writeStringValue(DslJsonSerializer.sanitizePropertyName(key.getKey(), replaceBuilder), replaceBuilder, jw); + DslJsonUtil.writeStringValue(DslJsonUtil.sanitizePropertyName(key.getKey(), replaceBuilder), replaceBuilder, jw); jw.writeByte(JsonWriter.SEMI); AttributeType type = key.getType(); diff --git a/apm-agent-tracer/pom.xml b/apm-agent-tracer/pom.xml index 7f2aff1054..649c2e4f87 100644 --- a/apm-agent-tracer/pom.xml +++ b/apm-agent-tracer/pom.xml @@ -24,6 +24,11 @@ apm-agent-common ${project.version} + + com.dslplatform + dsl-json + 1.9.3 + net.bytebuddy diff --git a/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/GlobalTracer.java b/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/GlobalTracer.java index 78886f4d3d..2a9c9b86a5 100644 --- a/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/GlobalTracer.java +++ b/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/GlobalTracer.java @@ -25,6 +25,7 @@ import co.elastic.apm.agent.tracer.reference.ReferenceCounted; import co.elastic.apm.agent.tracer.reference.ReferenceCountedMap; import co.elastic.apm.agent.tracer.service.Service; +import com.dslplatform.json.JsonWriter; import javax.annotation.Nullable; import java.util.Set; @@ -183,4 +184,14 @@ public void submit(Runnable job) { public void schedule(Runnable job, long interval, TimeUnit timeUnit) { tracer.schedule(job, interval, timeUnit); } + + @Override + public void addShutdownHook(AutoCloseable hook) { + tracer.addShutdownHook(hook); + } + + @Override + public void reportMetric(JsonWriter metrics) { + tracer.reportMetric(metrics); + } } diff --git a/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/LifecycleListener.java b/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/LifecycleListener.java index 40ce5c69ae..a1b55634c4 100644 --- a/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/LifecycleListener.java +++ b/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/LifecycleListener.java @@ -19,13 +19,13 @@ package co.elastic.apm.agent.tracer; /** - * A {@link LifecycleListener} notifies about the start and stop event of the {@link ElasticApmTracer}. + * A {@link LifecycleListener} notifies about the start and stop event of the {@link Tracer}. *

* Implement this interface and register it as a {@linkplain java.util.ServiceLoader service} under * {@code src/main/resources/META-INF/services/co.elastic.apm.agent.tracer.LifecycleListener}. *

*

- * Implementations may have a constructor with an {@link ElasticApmTracer} argument + * Implementations may have a constructor with an {@link Tracer} argument *

*/ public interface LifecycleListener { @@ -41,14 +41,14 @@ public interface LifecycleListener { void init(Tracer tracer) throws Exception; /** - * Callback for when the {@link ElasticApmTracer} starts. + * Callback for when the {@link Tracer} starts. * * @param tracer The tracer. */ void start(Tracer tracer) throws Exception; /** - * Callback for when {@link ElasticApmTracer#pause()} has been called. + * Callback for when the {@link Tracer} is paused. *

* Typically, this method is used to reduce overhead on the application to a minimum. This can be done by cleaning * up resources like object pools, as well as by avoiding tracing-related overhead. @@ -62,7 +62,7 @@ public interface LifecycleListener { void pause() throws Exception; /** - * Callback for when {@link ElasticApmTracer#resume()} has been called. + * Callback for when {@link Tracer} resumes. *

* Typically, used in order to revert the actions taken by the {@link LifecycleListener#pause()} method, allowing * the agent to restore all tracing capabilities @@ -76,7 +76,7 @@ public interface LifecycleListener { void resume() throws Exception; /** - * Callback for when {@link ElasticApmTracer#stop()} has been called. + * Callback for when the {@link Tracer} is stopped. *

* Typically, this method is used to clean up resources like thread pools * so that there are no class loader leaks when a webapp is redeployed in an application server. @@ -93,17 +93,14 @@ public interface LifecycleListener { * The order in which lifecycle listeners are called is non-deterministic. * *

  • - * The {@link ElasticApmTracer#getSharedSingleThreadedPool()} is shut down gracefully, + * Any {@link Tracer}-managed thread pool is shut down gracefully, * waiting a moment for the already scheduled tasks to be completed. * This means that implementations of this method can schedule a last command to this pool that is executed before shutdown. - * The {@link Tracer#getState()} will still be {@link Tracer.TracerState#RUNNING} in the tasks scheduled to - * {@link ElasticApmTracer#getSharedSingleThreadedPool()} within this method. + * The {@link Tracer#isRunning()} will still be {@code true} in the tasks scheduled to + * complete within {@link Tracer}-managed threads within this method. *
  • *
  • - * The tracer state is set to {@link co.elastic.apm.agent.impl.Tracer.TracerState#STOPPED}. - *
  • - *
  • - * The {@link co.elastic.apm.agent.report.Reporter} is closed. + * The tracer state is set to {@link Tracer#isRunning()} being {@code false}. *
  • * * diff --git a/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/NoopTracer.java b/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/NoopTracer.java index beb1ea5a6e..4d86e45a1c 100644 --- a/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/NoopTracer.java +++ b/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/NoopTracer.java @@ -25,9 +25,9 @@ import co.elastic.apm.agent.tracer.reference.ReferenceCounted; import co.elastic.apm.agent.tracer.reference.ReferenceCountedMap; import co.elastic.apm.agent.tracer.service.Service; +import com.dslplatform.json.JsonWriter; import javax.annotation.Nullable; -import java.io.IOException; import java.util.Collections; import java.util.Set; import java.util.concurrent.TimeUnit; @@ -153,4 +153,12 @@ public void submit(Runnable job) { @Override public void schedule(Runnable job, long interval, TimeUnit timeUnit) { } + + @Override + public void addShutdownHook(AutoCloseable hook) { + } + + @Override + public void reportMetric(JsonWriter metrics) { + } } diff --git a/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/Tracer.java b/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/Tracer.java index a714622546..9e4ac01ff9 100644 --- a/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/Tracer.java +++ b/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/Tracer.java @@ -25,10 +25,10 @@ import co.elastic.apm.agent.tracer.reference.ReferenceCounted; import co.elastic.apm.agent.tracer.reference.ReferenceCountedMap; import co.elastic.apm.agent.tracer.service.Service; +import com.dslplatform.json.JsonWriter; import javax.annotation.Nullable; import java.io.Flushable; -import java.io.IOException; import java.util.Set; import java.util.concurrent.TimeUnit; @@ -108,4 +108,6 @@ public interface Tracer extends Flushable { void schedule(Runnable job, long interval, TimeUnit timeUnit); void addShutdownHook(AutoCloseable hook); + + void reportMetric(JsonWriter metrics); // TODO: replace with internalized DSL writer that only accepts data. } diff --git a/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/metrics/DslJsonUtil.java b/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/metrics/DslJsonUtil.java new file mode 100644 index 0000000000..256c8def4d --- /dev/null +++ b/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/metrics/DslJsonUtil.java @@ -0,0 +1,80 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package co.elastic.apm.agent.tracer.metrics; + +import com.dslplatform.json.JsonWriter; + +public class DslJsonUtil { + + public static final int MAX_VALUE_LENGTH = 1024; + + private static final String[] DISALLOWED_IN_PROPERTY_NAME = new String[]{".", "*", "\""}; + + public static void writeFieldName(final String fieldName, final JsonWriter jw) { + jw.writeByte(JsonWriter.QUOTE); + jw.writeAscii(fieldName); + jw.writeByte(JsonWriter.QUOTE); + jw.writeByte(JsonWriter.SEMI); + } + + + public static CharSequence sanitizePropertyName(String key, StringBuilder replaceBuilder) { + for (int i = 0; i < DISALLOWED_IN_PROPERTY_NAME.length; i++) { + if (key.contains(DISALLOWED_IN_PROPERTY_NAME[i])) { + return replaceAll(key, DISALLOWED_IN_PROPERTY_NAME, "_", replaceBuilder); + } + } + return key; + } + + private static CharSequence replaceAll(String s, String[] stringsToReplace, String replacement, StringBuilder replaceBuilder) { + // uses a instance variable StringBuilder to avoid allocations + replaceBuilder.setLength(0); + replaceBuilder.append(s); + for (String toReplace : stringsToReplace) { + replace(replaceBuilder, toReplace, replacement, 0); + } + return replaceBuilder; + } + + static void replace(StringBuilder replaceBuilder, String toReplace, String replacement, int fromIndex) { + for (int i = replaceBuilder.indexOf(toReplace, fromIndex); i != -1; i = replaceBuilder.indexOf(toReplace, fromIndex)) { + replaceBuilder.replace(i, i + toReplace.length(), replacement); + fromIndex = i; + } + } + + public static void writeStringValue(CharSequence value, final StringBuilder replaceBuilder, final JsonWriter jw) { + if (value.length() > MAX_VALUE_LENGTH) { + replaceBuilder.setLength(0); + replaceBuilder.append(value, 0, Math.min(value.length(), MAX_VALUE_LENGTH + 1)); + writeStringBuilderValue(replaceBuilder, jw); + } else { + jw.writeString(value); + } + } + + private static void writeStringBuilderValue(StringBuilder value, JsonWriter jw) { + if (value.length() > MAX_VALUE_LENGTH) { + value.setLength(MAX_VALUE_LENGTH - 1); + value.append('…'); + } + jw.writeString(value); + } +} diff --git a/apm-agent-core/src/test/java/co/elastic/apm/agent/metrics/LabelsTest.java b/apm-agent-tracer/src/test/java/co/elastic/apm/agent/tracer/metrics/LabelsTest.java similarity index 98% rename from apm-agent-core/src/test/java/co/elastic/apm/agent/metrics/LabelsTest.java rename to apm-agent-tracer/src/test/java/co/elastic/apm/agent/tracer/metrics/LabelsTest.java index 2041a4a784..ef68d9a229 100644 --- a/apm-agent-core/src/test/java/co/elastic/apm/agent/metrics/LabelsTest.java +++ b/apm-agent-tracer/src/test/java/co/elastic/apm/agent/tracer/metrics/LabelsTest.java @@ -16,9 +16,8 @@ * specific language governing permissions and limitations * under the License. */ -package co.elastic.apm.agent.metrics; +package co.elastic.apm.agent.tracer.metrics; -import co.elastic.apm.agent.tracer.metrics.Labels; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; From 9e478cf7353a24ff273948bacecb5274bdf13fba Mon Sep 17 00:00:00 2001 From: Rafael Winterhalter Date: Sat, 24 Feb 2024 23:20:21 +0100 Subject: [PATCH 6/9] Fix import issue. --- .../java/co/elastic/apm/agent/impl/ElasticApmTracer.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) 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 7f2ffb50bc..718ed863b8 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 @@ -29,6 +29,10 @@ import co.elastic.apm.agent.configuration.MetricsConfiguration; import co.elastic.apm.agent.configuration.ServerlessConfiguration; import co.elastic.apm.agent.impl.error.RedactedException; +import co.elastic.apm.agent.impl.metadata.FaaSMetaDataExtension; +import co.elastic.apm.agent.impl.metadata.Framework; +import co.elastic.apm.agent.impl.metadata.MetaDataFuture; +import co.elastic.apm.agent.impl.metadata.NameAndIdField; import co.elastic.apm.agent.impl.metadata.ServiceFactory; import co.elastic.apm.agent.sdk.internal.util.LoggerUtils; import co.elastic.apm.agent.tracer.service.Service; @@ -81,10 +85,7 @@ import java.util.List; import java.util.Map; import java.util.Set; -import java.util.concurrent.Callable; -import java.util.concurrent.CopyOnWriteArrayList; -import java.util.concurrent.ScheduledThreadPoolExecutor; -import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.*; /** From 2c32bed6371c69d7ad58b4a44a989362270c1317 Mon Sep 17 00:00:00 2001 From: Rafael Winterhalter Date: Sat, 24 Feb 2024 23:34:23 +0100 Subject: [PATCH 7/9] Fix imports. --- .../src/main/java/co/elastic/apm/agent/jmx/JmxMetricTracker.java | 1 - 1 file changed, 1 deletion(-) diff --git a/apm-agent-plugins/apm-jmx-plugin/src/main/java/co/elastic/apm/agent/jmx/JmxMetricTracker.java b/apm-agent-plugins/apm-jmx-plugin/src/main/java/co/elastic/apm/agent/jmx/JmxMetricTracker.java index 75d5677afa..1c666566c0 100644 --- a/apm-agent-plugins/apm-jmx-plugin/src/main/java/co/elastic/apm/agent/jmx/JmxMetricTracker.java +++ b/apm-agent-plugins/apm-jmx-plugin/src/main/java/co/elastic/apm/agent/jmx/JmxMetricTracker.java @@ -84,7 +84,6 @@ public class JmxMetricTracker extends AbstractLifecycleListener { public JmxMetricTracker(Tracer tracer) { this.tracer = tracer; jmxConfiguration = tracer.getConfig(JmxConfiguration.class); - metricRegistry = tracer.getMetricRegistry(); // using a synchronized list so adding to the list does not require synchronization failedMetrics = Collections.synchronizedList(new ArrayList()); From e5cced34656b5d2665fe95a63cac17cc33f0dec8 Mon Sep 17 00:00:00 2001 From: Rafael Winterhalter Date: Sat, 24 Feb 2024 23:40:39 +0100 Subject: [PATCH 8/9] Fix imports. --- .../java/co/elastic/apm/agent/jmx/JmxMetricTracker.java | 6 ------ 1 file changed, 6 deletions(-) diff --git a/apm-agent-plugins/apm-jmx-plugin/src/main/java/co/elastic/apm/agent/jmx/JmxMetricTracker.java b/apm-agent-plugins/apm-jmx-plugin/src/main/java/co/elastic/apm/agent/jmx/JmxMetricTracker.java index 1c666566c0..5c3733a639 100644 --- a/apm-agent-plugins/apm-jmx-plugin/src/main/java/co/elastic/apm/agent/jmx/JmxMetricTracker.java +++ b/apm-agent-plugins/apm-jmx-plugin/src/main/java/co/elastic/apm/agent/jmx/JmxMetricTracker.java @@ -23,16 +23,10 @@ import co.elastic.apm.agent.tracer.Tracer; import co.elastic.apm.agent.tracer.metrics.Labels; import co.elastic.apm.agent.tracer.GlobalLocks; -import co.elastic.apm.agent.context.AbstractLifecycleListener; -import co.elastic.apm.agent.impl.ElasticApmTracer; -import co.elastic.apm.agent.metrics.DoubleSupplier; -import co.elastic.apm.agent.metrics.Labels; -import co.elastic.apm.agent.metrics.MetricRegistry; import co.elastic.apm.agent.sdk.internal.util.ExecutorUtils; import co.elastic.apm.agent.sdk.internal.util.PrivilegedActionUtils; import co.elastic.apm.agent.sdk.logging.Logger; import co.elastic.apm.agent.sdk.logging.LoggerFactory; -import co.elastic.apm.agent.tracer.GlobalLocks; import co.elastic.apm.agent.tracer.configuration.TimeDuration; import org.stagemonitor.configuration.ConfigurationOption; From 92f9c41771bba51dd9319035cebf15a7dfef4aba Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Tue, 12 Mar 2024 16:52:39 +0100 Subject: [PATCH 9/9] fix formatting --- .../src/main/java/co/elastic/apm/agent/tracer/Tracer.java | 1 + 1 file changed, 1 insertion(+) diff --git a/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/Tracer.java b/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/Tracer.java index b958442209..4f1d6efc2e 100644 --- a/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/Tracer.java +++ b/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/Tracer.java @@ -107,6 +107,7 @@ public interface Tracer { void addShutdownHook(AutoCloseable hook); void reportMetric(JsonWriter metrics); // TODO: replace with internalized DSL writer that only accepts data. + void flush(); void completeMetaData(String name, String version, String id, String region);