diff --git a/apm-agent-builds/apm-agent/src/test/java/co/elastic/apm/agent/configuration/ConfigurationExporter.java b/apm-agent-builds/apm-agent/src/test/java/co/elastic/apm/agent/configuration/ConfigurationExporter.java index 811054c294..50687d38f2 100644 --- a/apm-agent-builds/apm-agent/src/test/java/co/elastic/apm/agent/configuration/ConfigurationExporter.java +++ b/apm-agent-builds/apm-agent/src/test/java/co/elastic/apm/agent/configuration/ConfigurationExporter.java @@ -21,6 +21,7 @@ import co.elastic.apm.agent.impl.ElasticApmTracer; import co.elastic.apm.agent.tracer.GlobalTracer; import co.elastic.apm.agent.impl.Tracer; +import co.elastic.apm.agent.tracer.reporting.ReportingTracer; import org.stagemonitor.configuration.ConfigurationOptionProvider; import org.stagemonitor.configuration.ConfigurationRegistry; @@ -38,7 +39,7 @@ public class ConfigurationExporter { public static void main(String[] args) throws Exception { ElasticApmTracer tracer = mock(ElasticApmTracer.class); - doReturn(tracer).when(tracer).require(ElasticApmTracer.class); + doReturn(tracer).when(tracer).require(ReportingTracer.class); doReturn(Tracer.TracerState.UNINITIALIZED).when(tracer).getState(); GlobalTracer.init(tracer); try { diff --git a/apm-agent-builds/apm-agent/src/test/java/co/elastic/apm/agent/configuration/ConfigurationExporterTest.java b/apm-agent-builds/apm-agent/src/test/java/co/elastic/apm/agent/configuration/ConfigurationExporterTest.java index 22e8534486..9b2877b6ff 100644 --- a/apm-agent-builds/apm-agent/src/test/java/co/elastic/apm/agent/configuration/ConfigurationExporterTest.java +++ b/apm-agent-builds/apm-agent/src/test/java/co/elastic/apm/agent/configuration/ConfigurationExporterTest.java @@ -23,6 +23,7 @@ import co.elastic.apm.agent.tracer.GlobalTracer; import co.elastic.apm.agent.impl.Tracer; import co.elastic.apm.agent.sdk.ElasticApmInstrumentation; +import co.elastic.apm.agent.tracer.reporting.ReportingTracer; import co.elastic.apm.agent.util.DependencyInjectingServiceLoader; import freemarker.template.Configuration; import freemarker.template.Template; @@ -88,7 +89,7 @@ class ConfigurationExporterTest { void setUp() { renderedDocumentationPath = Paths.get("../../docs/configuration.asciidoc"); ElasticApmTracer tracer = mock(ElasticApmTracer.class); - doReturn(tracer).when(tracer).require(ElasticApmTracer.class); + doReturn(tracer).when(tracer).require(ReportingTracer.class); doReturn(Tracer.TracerState.UNINITIALIZED).when(tracer).getState(); GlobalTracer.init(tracer); configurationRegistry = ConfigurationRegistry.builder() 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..d942f54641 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,19 +19,20 @@ 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.LifecycleListener; +import co.elastic.apm.agent.tracer.Tracer; import java.util.ArrayList; import java.util.Collections; -public class InstrumentationStatsLifecycleListener extends AbstractLifecycleListener { +public class InstrumentationStatsLifecycleListener extends AbstractLifecycleListener implements LifecycleListener { 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..8143045ddf 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,7 @@ */ 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.util.ExecutorUtils; import co.elastic.apm.agent.sdk.logging.Logger; import co.elastic.apm.agent.sdk.logging.LoggerFactory; @@ -41,7 +40,7 @@ public WeakMapCleaner() { } @Override - public void start(ElasticApmTracer tracer) { + public void start() { 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..c74539917d 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.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.LifecycleListener; +import co.elastic.apm.agent.tracer.Tracer; import co.elastic.apm.agent.util.ExecutorUtils; import com.dslplatform.json.DslJson; import com.dslplatform.json.JsonReader; @@ -62,6 +63,9 @@ public class ApmServerConfigurationSource extends AbstractConfigurationSource im private final byte[] buffer = new byte[4096]; private final DslJsonSerializer.Writer payloadSerializer; private final ApmServerClient apmServerClient; + + @Nullable + private ElasticApmTracer tracer; @Nullable private String etag; private volatile Map config = Collections.emptyMap(); @@ -111,12 +115,12 @@ public void reload() { } @Override - public void init(ElasticApmTracer tracer) throws Exception { - // noop + public void init(Tracer tracer) { + this.tracer = tracer.require(ElasticApmTracer.class); } @Override - public void start(final ElasticApmTracer tracer) { + public void start() { threadPool = ExecutorUtils.createSingleThreadDaemonPool("remote-config-poller", 1); threadPool.execute(new Runnable() { @Override diff --git a/apm-agent-core/src/main/java/co/elastic/apm/agent/configuration/CoreConfiguration.java b/apm-agent-core/src/main/java/co/elastic/apm/agent/configuration/CoreConfiguration.java index 7200f1ab4f..188949066f 100644 --- a/apm-agent-core/src/main/java/co/elastic/apm/agent/configuration/CoreConfiguration.java +++ b/apm-agent-core/src/main/java/co/elastic/apm/agent/configuration/CoreConfiguration.java @@ -876,6 +876,7 @@ public ConfigurationOption getServiceNameConfig() { } @Nullable + @Override public String getServiceNodeName() { String nodeName = serviceNodeName.get(); if (nodeName == null || nodeName.trim().isEmpty()) { @@ -889,6 +890,7 @@ public long getDelayTracerStartMs() { } @Nullable + @Override public String getServiceVersion() { return serviceVersion.get(); } @@ -899,6 +901,7 @@ public String getHostname() { } @Nullable + @Override public String getEnvironment() { return environment.get(); } diff --git a/apm-agent-core/src/main/java/co/elastic/apm/agent/configuration/ServerlessConfiguration.java b/apm-agent-core/src/main/java/co/elastic/apm/agent/configuration/ServerlessConfiguration.java index 36875fbf04..7856019607 100644 --- a/apm-agent-core/src/main/java/co/elastic/apm/agent/configuration/ServerlessConfiguration.java +++ b/apm-agent-core/src/main/java/co/elastic/apm/agent/configuration/ServerlessConfiguration.java @@ -22,11 +22,16 @@ import org.stagemonitor.configuration.ConfigurationOption; import org.stagemonitor.configuration.ConfigurationOptionProvider; +import javax.annotation.Nullable; + public class ServerlessConfiguration extends ConfigurationOptionProvider implements co.elastic.apm.agent.tracer.configuration.ServerlessConfiguration { public static final String SERVERLESS_CATEGORY = "Serverless"; private final boolean runsOnAwsLambda; + @Nullable + private final String awsLambdaLogStreamName = PrivilegedActionUtils.getEnv("AWS_LAMBDA_LOG_STREAM_NAME"); + public ServerlessConfiguration() { String lambdaName = PrivilegedActionUtils.getEnv("AWS_LAMBDA_FUNCTION_NAME"); this.runsOnAwsLambda = null != lambdaName && !lambdaName.isEmpty(); @@ -65,4 +70,9 @@ public boolean runsOnAwsLambda() { return runsOnAwsLambda; } + @Override + @Nullable + public String awsLambdaLogStreamName() { + return awsLambdaLogStreamName; + } } 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..fd4d752b57 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,6 +18,9 @@ */ package co.elastic.apm.agent.context; +import co.elastic.apm.agent.tracer.AbstractLifecycleListener; +import co.elastic.apm.agent.tracer.LifecycleListener; + import java.io.Closeable; public class ClosableLifecycleListenerAdapter extends AbstractLifecycleListener { 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 586511857e..5116c2f089 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,10 +26,14 @@ 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.report.serialize.DslJsonDataWriter; +import co.elastic.apm.agent.tracer.reporting.DataWriter; +import co.elastic.apm.agent.tracer.reporting.DoubleSupplier; +import co.elastic.apm.agent.tracer.reporting.Labels; 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; @@ -62,6 +66,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.DslJson; import org.stagemonitor.configuration.ConfigurationOption; import org.stagemonitor.configuration.ConfigurationOptionProvider; import org.stagemonitor.configuration.ConfigurationRegistry; @@ -106,6 +111,8 @@ public class ElasticApmTracer implements Tracer { private static volatile boolean classloaderCheckOk = false; + private final DslJson dslJson = new DslJson<>(new DslJson.Settings<>()); + private final ConfigurationRegistry configurationRegistry; private final StacktraceConfiguration stacktraceConfiguration; private final ApmServerClient apmServerClient; @@ -732,7 +739,7 @@ private synchronized void startSync() { reporter.start(); for (LifecycleListener lifecycleListener : lifecycleListeners) { try { - lifecycleListener.start(this); + lifecycleListener.start(); } catch (Exception e) { logger.error("Failed to start " + lifecycleListener.getClass().getName(), e); } @@ -944,10 +951,37 @@ public MetaDataFuture getMetaDataFuture() { return metaDataFuture; } + @Override + public void addMetric(String name, Labels labels, DoubleSupplier metric) { + metricRegistry.add(name, labels, metric); + } + + @Override + public void removeMetric(String name, Labels labels) { + metricRegistry.removeGauge(name, labels); + } + + @Override + public void reportLog(String log) { + reporter.reportLog(log); + } + + @Override + public void reportLog(byte[] log) { + reporter.reportLog(log); + } + + @Override + public DataWriter newWriter(int maxSerializedSize) { + return new DslJsonDataWriter(dslJson.newWriter(maxSerializedSize), reporter); + } + + @Override public ScheduledThreadPoolExecutor getSharedSingleThreadedPool() { return sharedPool; } + @Override public void addShutdownHook(Closeable closeable) { lifecycleListeners.add(ClosableLifecycleListenerAdapter.of(closeable)); } 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/Tracer.java b/apm-agent-core/src/main/java/co/elastic/apm/agent/impl/Tracer.java index f645420cd9..61d2c5b899 100644 --- a/apm-agent-core/src/main/java/co/elastic/apm/agent/impl/Tracer.java +++ b/apm-agent-core/src/main/java/co/elastic/apm/agent/impl/Tracer.java @@ -30,7 +30,9 @@ import javax.annotation.Nullable; -public interface Tracer extends co.elastic.apm.agent.tracer.service.ServiceAwareTracer, co.elastic.apm.agent.tracer.Tracer { +public interface Tracer extends co.elastic.apm.agent.tracer.Tracer, + co.elastic.apm.agent.tracer.reporting.ReportingTracer, + co.elastic.apm.agent.tracer.service.ServiceAwareTracer { @Nullable @Override 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..ab8953256a 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,7 +18,7 @@ */ 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.util.ExecutorUtils; import co.elastic.apm.agent.sdk.logging.Logger; @@ -50,7 +50,7 @@ public CircuitBreaker(ElasticApmTracer tracer) { } @Override - public void start(ElasticApmTracer tracer) { + public void start() { // failsafe loading of stress monitors in isolation loadGCStressMonitor(tracer); loadSystemCpuStressMonitor(tracer); 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..e9f59a6095 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.reporting.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..0e0a8e89eb 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.impl.ElasticApmTracer; import co.elastic.apm.agent.report.Reporter; +import co.elastic.apm.agent.tracer.LifecycleListener; +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; @@ -101,12 +102,13 @@ public void append(LogEvent event) { } public LifecycleListener getInitListener() { - return new AbstractLifecycleListener() { + class InitListener extends AbstractLifecycleListener { @Override - public void init(ElasticApmTracer tracer) throws Exception { - initStreaming(tracer.getConfig(LoggingConfiguration.class), tracer.getReporter()); + public void init(Tracer tracer) { + initStreaming(tracer.getConfig(LoggingConfiguration.class), tracer.require(ElasticApmTracer.class).getReporter()); } - }; + } + return new InitListener(); } private void initStreaming(LoggingConfiguration config, Reporter reporter) { 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..e7dadaa2c6 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.reporting.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..f0378cbbe2 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.reporting.DoubleSupplier; +import co.elastic.apm.agent.tracer.reporting.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..07d8b354d5 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 @@ -19,6 +19,8 @@ package co.elastic.apm.agent.metrics; import co.elastic.apm.agent.tracer.pooling.Recyclable; +import co.elastic.apm.agent.tracer.reporting.DoubleSupplier; +import co.elastic.apm.agent.tracer.reporting.Labels; import javax.annotation.Nullable; import java.util.Map; 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..08bd932169 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,12 +19,13 @@ 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.reporting.Labels; import co.elastic.apm.agent.metrics.MetricCollector; import co.elastic.apm.agent.metrics.MetricRegistry; import co.elastic.apm.agent.metrics.MetricsProvider; +import co.elastic.apm.agent.tracer.GlobalTracer; import co.elastic.apm.agent.util.ElasticThreadStateListener; import co.elastic.apm.agent.util.ExecutorUtils; import co.elastic.apm.agent.util.JmxUtils; @@ -77,6 +78,7 @@ private ThreadInfo(String threadPurpose) { } } + private final ElasticApmTracer tracer; private final ThreadMXBean threadBean; private final OperatingSystemMXBean osBean; @@ -93,7 +95,8 @@ private ThreadInfo(String threadPurpose) { private final long processCpuTimeScalingFactor; - public AgentOverheadMetrics() { + public AgentOverheadMetrics(ElasticApmTracer tracer) { + this.tracer = tracer; osBean = ManagementFactory.getOperatingSystemMXBean(); getProcessCpuLoad = JmxUtils.getOperatingSystemMBeanMethod(osBean, "getProcessCpuLoad"); getProcessCpuTime = JmxUtils.getOperatingSystemMBeanMethod(osBean, "getProcessCpuTime"); @@ -113,7 +116,7 @@ public AgentOverheadMetrics() { } @Override - public void start(ElasticApmTracer tracer) throws Exception { + public void start() throws Exception { MetricRegistry metricRegistry = tracer.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..ff8818968d 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.reporting.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..a37ce90ee5 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,10 @@ */ 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.reporting.DoubleSupplier; +import co.elastic.apm.agent.tracer.reporting.Labels; import co.elastic.apm.agent.metrics.MetricRegistry; import co.elastic.apm.agent.sdk.logging.Logger; import co.elastic.apm.agent.sdk.logging.LoggerFactory; @@ -60,15 +60,17 @@ public class CGroupMetrics extends AbstractLifecycleListener { private static final Logger logger = LoggerFactory.getLogger(CGroupMetrics.class); + private final ElasticApmTracer tracer; @Nullable private final CgroupFiles cgroupFiles; - public CGroupMetrics() { - this(new File(PROC_SELF_CGROUP), new File(PROC_SELF_MOUNTINFO)); + public CGroupMetrics(ElasticApmTracer tracer) { + this(tracer, new File(PROC_SELF_CGROUP), new File(PROC_SELF_MOUNTINFO)); } - CGroupMetrics(File procSelfCgroup, File mountInfo) { + CGroupMetrics(ElasticApmTracer tracer, File procSelfCgroup, File mountInfo) { + this.tracer = tracer; cgroupFiles = findCgroupFiles(procSelfCgroup, mountInfo); } @@ -213,7 +215,7 @@ private File getMaxMemoryFile(File maxMemoryFile, String cgroupUnlimitedConstant } @Override - public void start(ElasticApmTracer tracer) { + public void start() { bindTo(tracer.getMetricRegistry()); } 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..4ba2f16931 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,10 @@ */ 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.reporting.DoubleSupplier; +import co.elastic.apm.agent.tracer.reporting.Labels; import co.elastic.apm.agent.metrics.MetricRegistry; import javax.annotation.Nullable; @@ -39,8 +39,14 @@ public class JvmFdMetrics extends AbstractLifecycleListener { private static final MethodHandle getOpenFileDescriptorCount = getMethodHandle("getOpenFileDescriptorCount"); private static final MethodHandle getMaxFileDescriptorCount = getMethodHandle("getMaxFileDescriptorCount"); + private final ElasticApmTracer tracer; + + public JvmFdMetrics(ElasticApmTracer tracer) { + this.tracer = tracer; + } + @Override - public void start(ElasticApmTracer tracer) { + public void start() { bindTo(tracer.getMetricRegistry()); } 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..1ad0fb24b0 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,10 @@ */ 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.reporting.DoubleSupplier; +import co.elastic.apm.agent.tracer.reporting.Labels; import co.elastic.apm.agent.metrics.MetricRegistry; import com.sun.management.ThreadMXBean; import org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement; @@ -32,10 +32,16 @@ public class JvmGcMetrics extends AbstractLifecycleListener { + private final ElasticApmTracer tracer; + private final List garbageCollectorMXBeans = ManagementFactory.getGarbageCollectorMXBeans(); + public JvmGcMetrics(ElasticApmTracer tracer) { + this.tracer = tracer; + } + @Override - public void start(ElasticApmTracer tracer) { + public void start() { bindTo(tracer.getMetricRegistry()); } 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..7add5f4d11 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,10 @@ */ 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.reporting.DoubleSupplier; +import co.elastic.apm.agent.tracer.reporting.Labels; import co.elastic.apm.agent.metrics.MetricRegistry; import co.elastic.apm.agent.sdk.logging.Logger; import co.elastic.apm.agent.sdk.logging.LoggerFactory; @@ -35,8 +35,14 @@ public class JvmMemoryMetrics extends AbstractLifecycleListener { private static final Logger logger = LoggerFactory.getLogger(JvmMemoryMetrics.class); + private final ElasticApmTracer tracer; + + public JvmMemoryMetrics(ElasticApmTracer tracer) { + this.tracer = tracer; + } + @Override - public void start(ElasticApmTracer tracer) { + public void start() { bindTo(tracer.getMetricRegistry()); } 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..61d1a8b876 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,12 +18,13 @@ */ 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.reporting.DoubleSupplier; +import co.elastic.apm.agent.tracer.reporting.Labels; import co.elastic.apm.agent.metrics.MetricRegistry; +import co.elastic.apm.agent.tracer.GlobalTracer; import co.elastic.apm.agent.util.JmxUtils; import org.stagemonitor.util.StringUtils; @@ -55,6 +56,8 @@ */ public class SystemMetrics extends AbstractLifecycleListener { + private final ElasticApmTracer tracer; + private final OperatingSystemMXBean operatingSystemBean; @Nullable @@ -73,11 +76,12 @@ public class SystemMetrics extends AbstractLifecycleListener { private final Method virtualProcessMemory; private final File memInfoFile; - public SystemMetrics() { - this(new File("/proc/meminfo")); + public SystemMetrics(ElasticApmTracer tracer) { + this(tracer, new File("/proc/meminfo")); } - SystemMetrics(File memInfoFile) { + SystemMetrics(ElasticApmTracer tracer, File memInfoFile) { + this.tracer = tracer; this.operatingSystemBean = ManagementFactory.getOperatingSystemMXBean(); this.systemCpuUsage = JmxUtils.getOperatingSystemMBeanMethod(operatingSystemBean, "getSystemCpuLoad"); this.processCpuUsage = JmxUtils.getOperatingSystemMBeanMethod(operatingSystemBean, "getProcessCpuLoad"); @@ -88,7 +92,7 @@ public SystemMetrics() { } @Override - public void start(ElasticApmTracer tracer) { + public void start() { bindTo(tracer.getMetricRegistry()); } 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..9be546121f 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,10 @@ */ 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.reporting.DoubleSupplier; +import co.elastic.apm.agent.tracer.reporting.Labels; import co.elastic.apm.agent.metrics.MetricRegistry; import java.lang.management.ManagementFactory; @@ -29,8 +29,14 @@ public class ThreadMetrics extends AbstractLifecycleListener { + private final ElasticApmTracer tracer; + + public ThreadMetrics(ElasticApmTracer tracer) { + this.tracer = tracer; + } + @Override - public void start(ElasticApmTracer tracer) { + public void start() { bindTo(tracer.getMetricRegistry()); } diff --git a/apm-agent-core/src/main/java/co/elastic/apm/agent/report/serialize/DslJsonDataWriter.java b/apm-agent-core/src/main/java/co/elastic/apm/agent/report/serialize/DslJsonDataWriter.java new file mode 100644 index 0000000000..235c7cd76d --- /dev/null +++ b/apm-agent-core/src/main/java/co/elastic/apm/agent/report/serialize/DslJsonDataWriter.java @@ -0,0 +1,145 @@ +/* + * 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.report.serialize; + +import co.elastic.apm.agent.report.Reporter; +import co.elastic.apm.agent.tracer.reporting.DataWriter; +import com.dslplatform.json.BoolConverter; +import com.dslplatform.json.JsonWriter; +import com.dslplatform.json.NumberConverter; + +import javax.annotation.Nullable; + +public class DslJsonDataWriter implements DataWriter { + + private final JsonWriter jw; + + private final Reporter reporter; + + private final StringBuilder replaceBuilder = new StringBuilder(); + + public DslJsonDataWriter(JsonWriter jw, Reporter reporter) { + this.jw = jw; + this.reporter = reporter; + } + + @Override + public void writeStructure(StructureType type) { + switch (type) { + case OBJECT_START: + jw.writeByte(JsonWriter.OBJECT_START); + break; + case OBJECT_END: + jw.writeByte(JsonWriter.OBJECT_END); + break; + case ARRAY_START: + jw.writeByte(JsonWriter.ARRAY_START); + break; + case ARRAY_END: + jw.writeByte(JsonWriter.ARRAY_END); + break; + case NEXT: + jw.writeByte(JsonWriter.COMMA); + break; + case NEW: + jw.writeByte((byte) '\n'); + break; + default: + throw new IllegalArgumentException(); + } + } + + @Override + public void writeKey(CharSequence name) { + jw.writeString(name); + jw.writeByte(JsonWriter.SEMI); + } + + @Override + public void writeKey(CharSequence name, boolean sanitized) { + if (sanitized) { + DslJsonSerializer.writeStringValue(DslJsonSerializer.sanitizePropertyName(name.toString(), replaceBuilder), replaceBuilder, jw); + jw.writeByte(JsonWriter.SEMI); + } else { + writeKey(name); + } + } + + @Override + public void writeKey(CharSequence name, boolean sanitized, @Nullable String suffix) { + replaceBuilder.setLength(0); + if (sanitized) { + DslJsonSerializer.sanitizePropertyName(name.toString(), replaceBuilder); + } else { + replaceBuilder.append(name); + } + if (suffix != null) { + if (replaceBuilder.length() == 0) { + replaceBuilder.append(name); + } + replaceBuilder.append(suffix); + } + jw.writeString(replaceBuilder); + jw.writeByte(JsonWriter.SEMI); + } + + @Override + public void writeValue(boolean value) { + BoolConverter.serialize(value, jw); + } + + @Override + public void writeValue(long value) { + NumberConverter.serialize(value, jw); + } + + @Override + public void writeValue(double value) { + NumberConverter.serialize(value, jw); + } + + @Override + public void writeValue(CharSequence value) { + jw.writeString(value); + } + + @Override + public void writeValue(CharSequence value, boolean trimmed) { + if (trimmed) { + DslJsonSerializer.writeStringValue(value, replaceBuilder, jw); + } else { + writeValue(value); + } + } + + @Override + public int size() { + return jw.size(); + } + + @Override + public void report() { + reporter.reportMetrics(jw); + } + + @Override + public String toString() { + return jw.toString(); + } +} 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..05c91a4e29 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.reporting.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..369fca596d 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 @@ -19,9 +19,9 @@ package co.elastic.apm.agent.report.serialize; 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.reporting.Labels; import co.elastic.apm.agent.metrics.MetricRegistry; import co.elastic.apm.agent.metrics.MetricSet; import co.elastic.apm.agent.report.Reporter; @@ -47,7 +47,7 @@ public MetricRegistryReporter(ElasticApmTracer tracer) { } @Override - public void start(ElasticApmTracer tracer) { + public void start() { long intervalMs = tracer.getConfig(ReporterConfiguration.class).getMetricsIntervalMs(); if (intervalMs > 0) { tracer.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..70391123b4 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.reporting.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 5283795cf5..2b85dc0543 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.reporting.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..e7be8559f4 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; @@ -138,22 +138,23 @@ void testStartInactive() throws IOException { @Test void testStartDisabled() throws Exception { ConfigurationRegistry configRegistry = SpyConfiguration.createSpyConfig(SimpleSource.forTest("enabled", "false")); - AtomicBoolean initialized = new AtomicBoolean(); - AtomicBoolean started = new AtomicBoolean(); + final AtomicBoolean initialized = new AtomicBoolean(); + final AtomicBoolean started = new AtomicBoolean(); + class TestListener extends AbstractLifecycleListener { + @Override + public void init(Tracer tracer) { + initialized.set(true); + } + + @Override + public void start() { + started.set(true); + } + } ElasticApmTracer tracer = new ElasticApmTracerBuilder() .configurationRegistry(configRegistry) .reporter(new MockReporter()) - .withLifecycleListener(new AbstractLifecycleListener() { - @Override - public void init(ElasticApmTracer tracer) { - initialized.set(true); - } - - @Override - public void start(ElasticApmTracer tracer) throws Exception { - started.set(true); - } - }) + .withLifecycleListener(new TestListener()) .build(); ElasticApmAgent.initInstrumentation(tracer, ByteBuddyAgent.install()); assertThat(tracer.isRunning()).isFalse(); @@ -163,7 +164,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 +179,7 @@ public TestLifecycleListener() { } @Override - public void start(ElasticApmTracer tracer) { + public void start() { 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..c5bd601ae3 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.reporting.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/MetricRegistryTest.java b/apm-agent-core/src/test/java/co/elastic/apm/agent/metrics/MetricRegistryTest.java index 2b445c9e54..1b8fe9174f 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.reporting.DoubleSupplier; +import co.elastic.apm.agent.tracer.reporting.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..21f37585e0 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,8 @@ 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.impl.ElasticApmTracer; +import co.elastic.apm.agent.tracer.reporting.Labels; import co.elastic.apm.agent.metrics.MetricRegistry; import co.elastic.apm.agent.metrics.MetricSet; import co.elastic.apm.agent.report.ReporterConfiguration; @@ -49,6 +50,7 @@ import static org.awaitility.Awaitility.await; import static org.hamcrest.Matchers.equalTo; import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; public class AgentOverheadMetricsTest { @@ -65,7 +67,7 @@ public void setUp() { spyReporterConfig = spy(ReporterConfiguration.class); spyMetricsConfig = spy(MetricsConfiguration.class); - overheadMetrics = new AgentOverheadMetrics(); + overheadMetrics = new AgentOverheadMetrics(mock(ElasticApmTracer.class)); metricRegistry = new MetricRegistry(spyReporterConfig, spyMetricsConfig); } @@ -384,10 +386,11 @@ public void testDisableMetric(String metric) throws InterruptedException { } private static void awaitNonZeroProcessCpuLoad() { + ElasticApmTracer tracer = mock(ElasticApmTracer.class); long start = System.nanoTime(); Double load = null; while ((System.nanoTime() - start) < 5_000_000_000L) { - load = new AgentOverheadMetrics().getProcessCpuLoad(); + load = new AgentOverheadMetrics(tracer).getProcessCpuLoad(); if (load != null && load > 0.0) break; } assertThat(load).isGreaterThan(0.0); 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..c9b2cea731 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.reporting.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..85ad8c8446 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,8 @@ 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.impl.ElasticApmTracer; +import co.elastic.apm.agent.tracer.reporting.Labels; import co.elastic.apm.agent.metrics.MetricRegistry; import co.elastic.apm.agent.report.ReporterConfiguration; import org.junit.jupiter.api.Test; @@ -48,7 +49,9 @@ private CGroupMetrics createUnlimitedSystemMetrics() throws URISyntaxException, fw.write("39 30 0:35 / " + mountInfo.getAbsolutePath() + " rw,nosuid,nodev,noexec,relatime shared:10 - cgroup cgroup rw,seclabel,memory\n"); fw.close(); - return new CGroupMetrics(new File(getClass().getResource("/proc/cgroup").toURI()), + return new CGroupMetrics( + mock(ElasticApmTracer.class), + new File(getClass().getResource("/proc/cgroup").toURI()), fileTmp ); } @@ -73,7 +76,9 @@ void testFreeCgroupMemory(long value, String selfCGroup, String sysFsGroup, Stri } fw.close(); - CGroupMetrics cgroupMetrics = new CGroupMetrics(new File(getClass().getResource(selfCGroup).toURI()), + CGroupMetrics cgroupMetrics = new CGroupMetrics( + mock(ElasticApmTracer.class), + new File(getClass().getResource(selfCGroup).toURI()), fileTmp ); cgroupMetrics.bindTo(metricRegistry); 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..707a0eb50b 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,8 @@ 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.impl.ElasticApmTracer; +import co.elastic.apm.agent.tracer.reporting.Labels; import co.elastic.apm.agent.metrics.MetricRegistry; import co.elastic.apm.agent.report.ReporterConfiguration; import org.junit.jupiter.api.condition.DisabledOnOs; @@ -34,8 +35,7 @@ class JvmFdMetricsTest { - private final JvmFdMetrics jvmFdMetrics = new JvmFdMetrics(); - + private final JvmFdMetrics jvmFdMetrics = new JvmFdMetrics(mock(ElasticApmTracer.class)); @ParameterizedTest(name = "{0}") @ValueSource(strings = { diff --git a/apm-agent-core/src/test/java/co/elastic/apm/agent/metrics/builtin/JvmGcMetricsTest.java b/apm-agent-core/src/test/java/co/elastic/apm/agent/metrics/builtin/JvmGcMetricsTest.java index 434df65c8d..22820fb14a 100644 --- a/apm-agent-core/src/test/java/co/elastic/apm/agent/metrics/builtin/JvmGcMetricsTest.java +++ b/apm-agent-core/src/test/java/co/elastic/apm/agent/metrics/builtin/JvmGcMetricsTest.java @@ -18,6 +18,7 @@ */ package co.elastic.apm.agent.metrics.builtin; +import co.elastic.apm.agent.impl.ElasticApmTracer; import co.elastic.apm.agent.metrics.MetricRegistry; import org.junit.jupiter.api.Test; @@ -30,7 +31,7 @@ class JvmGcMetricsTest { - private final JvmGcMetrics jvmGcMetrics = new JvmGcMetrics(); + private final JvmGcMetrics jvmGcMetrics = new JvmGcMetrics(mock(ElasticApmTracer.class)); private MetricRegistry registry = mock(MetricRegistry.class); @Test 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..1e04d3bb45 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,8 @@ 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.impl.ElasticApmTracer; +import co.elastic.apm.agent.tracer.reporting.Labels; import co.elastic.apm.agent.metrics.MetricRegistry; import co.elastic.apm.agent.report.ReporterConfiguration; import org.assertj.core.api.AbstractDoubleAssert; @@ -38,7 +39,7 @@ class JvmMemoryMetricsTest { - private final JvmMemoryMetrics jvmMemoryMetrics = new JvmMemoryMetrics(); + private final JvmMemoryMetrics jvmMemoryMetrics = new JvmMemoryMetrics(mock(ElasticApmTracer.class)); @Test void testMetrics() { 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..b72eb4c289 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,8 @@ 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.impl.ElasticApmTracer; +import co.elastic.apm.agent.tracer.reporting.Labels; import co.elastic.apm.agent.metrics.MetricRegistry; import co.elastic.apm.agent.report.ReporterConfiguration; import org.junit.jupiter.api.Test; @@ -37,7 +38,7 @@ class SystemMetricsTest { private MetricRegistry metricRegistry = new MetricRegistry(mock(ReporterConfiguration.class), spy(MetricsConfiguration.class)); - private SystemMetrics systemMetrics = new SystemMetrics(); + private SystemMetrics systemMetrics = new SystemMetrics(mock(ElasticApmTracer.class)); @Test @DisabledOnOs(OS.MAC) @@ -59,7 +60,9 @@ void testSystemMetrics() throws InterruptedException { "/proc/meminfo-3.14, 556630016" }) void testFreeMemoryMeminfo(String file, long value) throws Exception { - SystemMetrics systemMetrics = new SystemMetrics(new File(getClass().getResource(file).toURI())); + SystemMetrics systemMetrics = new SystemMetrics( + mock(ElasticApmTracer.class), + new File(getClass().getResource(file).toURI())); systemMetrics.bindTo(metricRegistry); assertThat(metricRegistry.getGaugeValue("system.memory.actual.free", Labels.EMPTY)).isEqualTo(value); assertThat(metricRegistry.getGaugeValue("system.memory.total", Labels.EMPTY)).isEqualTo(7964778496L); 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..488449ecdc 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,8 @@ 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.impl.ElasticApmTracer; +import co.elastic.apm.agent.tracer.reporting.Labels; import co.elastic.apm.agent.metrics.MetricRegistry; import co.elastic.apm.agent.report.ReporterConfiguration; import org.junit.jupiter.api.Test; @@ -31,7 +32,7 @@ class ThreadMetricsTest { private static final double NUM_ADDED_THREADS = 12.0; - private final ThreadMetrics threadMetrics = new ThreadMetrics(); + private final ThreadMetrics threadMetrics = new ThreadMetrics(mock(ElasticApmTracer.class)); private MetricRegistry registry = new MetricRegistry(mock(ReporterConfiguration.class), spy(MetricsConfiguration.class)); @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..1399acf058 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.reporting.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-ecs-logging-plugin/pom.xml b/apm-agent-plugins/apm-ecs-logging-plugin/pom.xml index e61eda6307..d7e58d8a3b 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-jmx-plugin/pom.xml b/apm-agent-plugins/apm-jmx-plugin/pom.xml index db560509a5..989ddb4d36 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 7427494bad..84bbcc5b59 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.reporting.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 300cbb22de..d1c862ffb6 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,15 +18,14 @@ */ 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.reporting.DoubleSupplier; +import co.elastic.apm.agent.tracer.reporting.Labels; import co.elastic.apm.agent.tracer.GlobalLocks; import co.elastic.apm.agent.sdk.logging.Logger; import co.elastic.apm.agent.sdk.logging.LoggerFactory; import co.elastic.apm.agent.sdk.internal.util.PrivilegedActionUtils; +import co.elastic.apm.agent.tracer.reporting.ReportingTracer; import org.stagemonitor.configuration.ConfigurationOption; import javax.annotation.Nullable; @@ -60,18 +59,18 @@ public class JmxMetricTracker extends AbstractLifecycleListener { private volatile Thread logManagerPropertyPoller; @Nullable private volatile MBeanServer server; + private final ReportingTracer tracer; private final JmxConfiguration jmxConfiguration; - private final MetricRegistry metricRegistry; @Nullable private volatile NotificationListener listener; - public JmxMetricTracker(ElasticApmTracer tracer) { + public JmxMetricTracker(ReportingTracer tracer) { + this.tracer = tracer; jmxConfiguration = tracer.getConfig(JmxConfiguration.class); - metricRegistry = tracer.getMetricRegistry(); } @Override - public void start(ElasticApmTracer tracer) { + public void start() { ConfigurationOption.ChangeListener> captureJmxListener = new ConfigurationOption.ChangeListener>() { @Override public void onChange(ConfigurationOption configurationOption, List oldValue, List newValue) { @@ -176,10 +175,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); } } @@ -279,7 +278,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); } } @@ -360,9 +359,9 @@ private JmxMetricRegistration(String metricName, Labels labels, String jmxAttrib } - void register(final MBeanServer server, final MetricRegistry metricRegistry) { + void register(final MBeanServer server, final ReportingTracer tracer) { logger.debug("Registering JMX metric {} {}.{} as metric_name: {} labels: {}", objectName, jmxAttribute, compositeDataKey, metricName, labels); - metricRegistry.add(metricName, labels, new DoubleSupplier() { + tracer.addMetric(metricName, labels, new DoubleSupplier() { @Override public double get() { try { @@ -372,7 +371,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; @@ -381,9 +380,9 @@ public double get() { }); } - void unregister(MetricRegistry metricRegistry) { + void unregister(ReportingTracer tracer) { logger.debug("Unregistering JMX metric {} {}.{} metric_name: {} labels: {}", objectName, jmxAttribute, compositeDataKey, metricName, labels); - metricRegistry.removeGauge(metricName, labels); + tracer.removeMetric(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 17fa88bae5..cc7aebbd30 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.reporting.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-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..a9434394ad 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.reporting.ReportingTracer; 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(ReportingTracer 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..08922e9640 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.reporting.ReportingTracer; 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 ReportingTracer tracer; private final Formatter formatter; - public JulLogSenderHandler(Reporter reporter, Formatter formatter) { - this.reporter = reporter; + public JulLogSenderHandler(ReportingTracer 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..33bebb273b 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.reporting.ReportingTracer; 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(ReportingTracer 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..f82fb4043a 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.reporting.ReportingTracer; 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 ReportingTracer tracer; private final Layout formatter; - public LogSenderAppender(Reporter reporter, Layout formatter) { - this.reporter = reporter; + public LogSenderAppender(ReportingTracer 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..c5871947b3 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.reporting.ReportingTracer; 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(ReportingTracer 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..6d31e4e892 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.reporting.ReportingTracer; 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 ReportingTracer tracer; private final StringLayout ecsLayout; - public Log4j2LogSenderAppender(Reporter reporter, StringLayout ecsLayout) { + public Log4j2LogSenderAppender(ReportingTracer 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..67c1120486 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.reporting.ReportingTracer; 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(ReportingTracer 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..e8e260be47 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.reporting.ReportingTracer; import co.elastic.logging.logback.EcsEncoder; public class LogbackLogSenderAppender extends UnsynchronizedAppenderBase { - private final Reporter reporter; + private final ReportingTracer tracer; private final EcsEncoder formatter; - public LogbackLogSenderAppender(Reporter reporter, Encoder formatter) { - this.reporter = reporter; + public LogbackLogSenderAppender(ReportingTracer 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..9a1ccb23b9 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,23 +18,19 @@ */ 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; import co.elastic.apm.agent.sdk.state.GlobalState; 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.CoreConfiguration; import co.elastic.apm.agent.tracer.configuration.LoggingConfiguration; import co.elastic.apm.agent.tracer.configuration.ServerlessConfiguration; +import co.elastic.apm.agent.tracer.reporting.ReportingTracer; import javax.annotation.Nullable; import java.util.List; @@ -152,6 +148,8 @@ public abstract class AbstractEcsReformattingHelper { */ private static final ThreadLocal configForCurrentLogEvent = new ThreadLocal<>(); + private final ReportingTracer tracer; + private final LoggingConfiguration loggingConfiguration; @Nullable @@ -168,26 +166,22 @@ public abstract class AbstractEcsReformattingHelper { @Nullable private final Map additionalFields; - private final Reporter reporter; public AbstractEcsReformattingHelper() { - Tracer tracer = GlobalTracer.get(); + tracer = GlobalTracer.get().require(ReportingTracer.class); 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(); + CoreConfiguration config = tracer.getConfig(CoreConfiguration.class); + globalServiceName = config.getServiceName(); + globalServiceVersion = config.getServiceVersion(); + String configuredServiceNodeName = config.getServiceNodeName(); + if (configuredServiceNodeName == null) { + ServerlessConfiguration serverlessConfiguration = tracer.getConfig(ServerlessConfiguration.class); + this.configuredServiceNodeName = serverlessConfiguration.awsLambdaLogStreamName(); } else { - configuredServiceNodeName = null; + this.configuredServiceNodeName = configuredServiceNodeName; } - environment = service.getEnvironment(); - reporter = tracer.require(ElasticApmTracer.class).getReporter(); + environment = config.getEnvironment(); } /** @@ -330,7 +324,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 +532,7 @@ protected long getDefaultMaxLogFileSize() { protected abstract void closeShadeAppender(A shadeAppender); - protected abstract B createAndStartLogSendingAppender(Reporter reporter, F formatter); + protected abstract B createAndStartLogSendingAppender(ReportingTracer 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 760825e2e5..db4083919e 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-plugins/apm-micrometer-plugin/pom.xml b/apm-agent-plugins/apm-micrometer-plugin/pom.xml index 1939b8ca2f..61b8f25b10 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..2675ea1937 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,10 +18,10 @@ */ 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; +import co.elastic.apm.agent.tracer.reporting.ReportingTracer; import java.util.Collection; import java.util.Collections; @@ -30,7 +30,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.require(ReportingTracer.class)); public Collection getInstrumentationGroupNames() { return Collections.singletonList("micrometer"); 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..2bd44e23ed 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,16 +18,14 @@ */ 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 com.dslplatform.json.DslJson; -import com.dslplatform.json.JsonWriter; -import com.dslplatform.json.NumberConverter; +import co.elastic.apm.agent.tracer.reporting.DataWriter; +import co.elastic.apm.agent.tracer.reporting.ReportingTracer; import io.micrometer.core.instrument.Counter; import io.micrometer.core.instrument.DistributionSummary; import io.micrometer.core.instrument.FunctionCounter; @@ -46,35 +44,35 @@ import java.util.Map; import java.util.concurrent.TimeUnit; -import static com.dslplatform.json.JsonWriter.COMMA; -import static com.dslplatform.json.JsonWriter.OBJECT_END; -import static com.dslplatform.json.JsonWriter.OBJECT_START; +import static co.elastic.apm.agent.tracer.reporting.DataWriter.StructureType.ARRAY_END; +import static co.elastic.apm.agent.tracer.reporting.DataWriter.StructureType.ARRAY_START; +import static co.elastic.apm.agent.tracer.reporting.DataWriter.StructureType.NEXT; +import static co.elastic.apm.agent.tracer.reporting.DataWriter.StructureType.NEW; +import static co.elastic.apm.agent.tracer.reporting.DataWriter.StructureType.OBJECT_END; +import static co.elastic.apm.agent.tracer.reporting.DataWriter.StructureType.OBJECT_START; public class MicrometerMeterRegistrySerializer { - private static final byte NEW_LINE = (byte) '\n'; - private static final int BUFFER_SIZE_LIMIT = 2048; private static final Logger logger = LoggerFactory.getLogger(MicrometerMeterRegistrySerializer.class); - - private final DslJson dslJson = new DslJson<>(new DslJson.Settings<>()); - private final StringBuilder replaceBuilder = new StringBuilder(); private final MetricsConfiguration config; + private final ReportingTracer tracer; private final WeakSet internallyDisabledMeters = WeakConcurrent.buildSet(); private int maxSerializedSize = 512; - public MicrometerMeterRegistrySerializer(MetricsConfiguration config) { + public MicrometerMeterRegistrySerializer(MetricsConfiguration config, ReportingTracer tracer) { this.config = config; + this.tracer = tracer; } Iterable getFailedMeters() { return internallyDisabledMeters; } - public List serialize(final Map metersById, final long epochMicros) { - List serializedMeters = new ArrayList<>(); + public List serialize(final Map metersById, final long epochMicros) { + List serializedMeters = new ArrayList<>(); final Map, List> metersGroupedByTags = new HashMap<>(); for (Map.Entry entry : metersById.entrySet()) { List tags = entry.getKey().getTags(); @@ -86,29 +84,29 @@ public List serialize(final Map metersById, final l meters.add(entry.getValue()); } for (Map.Entry, List> entry : metersGroupedByTags.entrySet()) { - JsonWriter jw = dslJson.newWriter(maxSerializedSize); - if (serializeMetricSet(entry.getKey(), entry.getValue(), epochMicros, replaceBuilder, jw)) { - serializedMeters.add(jw); - maxSerializedSize = Math.max(Math.min(jw.size(), BUFFER_SIZE_LIMIT), maxSerializedSize); + DataWriter writer = tracer.newWriter(maxSerializedSize); + if (serializeMetricSet(entry.getKey(), entry.getValue(), epochMicros, writer)) { + serializedMeters.add(writer); + maxSerializedSize = Math.max(Math.min(writer.size(), BUFFER_SIZE_LIMIT), maxSerializedSize); } } return serializedMeters; } - boolean serializeMetricSet(List tags, List meters, long epochMicros, StringBuilder replaceBuilder, JsonWriter jw) { + boolean serializeMetricSet(List tags, List meters, long epochMicros, DataWriter writer) { boolean hasSamples = false; boolean dedotMetricName = config.isDedotCustomMetrics(); - jw.writeByte(JsonWriter.OBJECT_START); + writer.writeStructure(OBJECT_START); { - DslJsonSerializer.writeFieldName("metricset", jw); - jw.writeByte(JsonWriter.OBJECT_START); + writer.writeKey("metricset"); + writer.writeStructure(OBJECT_START); { - DslJsonSerializer.writeFieldName("timestamp", jw); - NumberConverter.serialize(epochMicros, jw); - jw.writeByte(JsonWriter.COMMA); - serializeTags(tags, replaceBuilder, jw); - DslJsonSerializer.writeFieldName("samples", jw); - jw.writeByte(JsonWriter.OBJECT_START); + writer.writeKey("timestamp"); + writer.writeValue(epochMicros); + writer.writeStructure(NEXT); + serializeTags(tags, writer); + writer.writeKey("samples"); + writer.writeStructure(OBJECT_START); ClassLoader originalContextCL = PrivilegedActionUtils.getContextClassLoader(Thread.currentThread()); try { @@ -122,25 +120,25 @@ boolean serializeMetricSet(List tags, List meters, long epochMicros, PrivilegedActionUtils.setContextClassLoader(Thread.currentThread(), PrivilegedActionUtils.getClassLoader(meter.getClass())); if (meter instanceof Timer) { Timer timer = (Timer) meter; - hasSamples = serializeTimer(jw, timer.takeSnapshot(), timer.getId(), timer.count(), timer.totalTime(TimeUnit.MICROSECONDS), hasSamples, replaceBuilder, dedotMetricName); + hasSamples = serializeTimer(writer, timer.takeSnapshot(), timer.getId(), timer.count(), timer.totalTime(TimeUnit.MICROSECONDS), hasSamples, dedotMetricName); } else if (meter instanceof FunctionTimer) { FunctionTimer timer = (FunctionTimer) meter; - hasSamples = serializeTimer(jw, null, timer.getId(), (long) timer.count(), timer.totalTime(TimeUnit.MICROSECONDS), hasSamples, replaceBuilder, dedotMetricName); + hasSamples = serializeTimer(writer, null, timer.getId(), (long) timer.count(), timer.totalTime(TimeUnit.MICROSECONDS), hasSamples, dedotMetricName); } else if (meter instanceof LongTaskTimer) { LongTaskTimer timer = (LongTaskTimer) meter; - hasSamples = serializeTimer(jw, timer.takeSnapshot(), timer.getId(), timer.activeTasks(), timer.duration(TimeUnit.MICROSECONDS), hasSamples, replaceBuilder, dedotMetricName); + hasSamples = serializeTimer(writer, timer.takeSnapshot(), timer.getId(), timer.activeTasks(), timer.duration(TimeUnit.MICROSECONDS), hasSamples, dedotMetricName); } else if (meter instanceof DistributionSummary) { DistributionSummary summary = (DistributionSummary) meter; - hasSamples = serializeDistributionSummary(jw, summary.takeSnapshot(), summary.getId(), summary.count(), summary.totalAmount(), hasSamples, replaceBuilder, dedotMetricName); + hasSamples = serializeDistributionSummary(writer, summary.takeSnapshot(), summary.getId(), summary.count(), summary.totalAmount(), hasSamples, dedotMetricName); } else if (meter instanceof Gauge) { Gauge gauge = (Gauge) meter; - hasSamples = serializeValue(gauge.getId(), gauge.value(), hasSamples, jw, replaceBuilder, dedotMetricName); + hasSamples = serializeValue(gauge.getId(), gauge.value(), hasSamples, writer, dedotMetricName); } else if (meter instanceof Counter) { Counter counter = (Counter) meter; - hasSamples = serializeValue(counter.getId(), counter.count(), hasSamples, jw, replaceBuilder, dedotMetricName); + hasSamples = serializeValue(counter.getId(), counter.count(), hasSamples, writer, dedotMetricName); } else if (meter instanceof FunctionCounter) { FunctionCounter counter = (FunctionCounter) meter; - hasSamples = serializeValue(counter.getId(), counter.count(), hasSamples, jw, replaceBuilder, dedotMetricName); + hasSamples = serializeValue(counter.getId(), counter.count(), hasSamples, writer, dedotMetricName); } } catch (Throwable throwable) { String meterName = meter.getId().getName(); @@ -154,56 +152,54 @@ boolean serializeMetricSet(List tags, List meters, long epochMicros, } finally { PrivilegedActionUtils.setContextClassLoader(Thread.currentThread(), originalContextCL); } - jw.writeByte(JsonWriter.OBJECT_END); + writer.writeStructure(OBJECT_END); } - jw.writeByte(JsonWriter.OBJECT_END); + writer.writeStructure(OBJECT_END); } - jw.writeByte(JsonWriter.OBJECT_END); - jw.writeByte(NEW_LINE); + writer.writeStructure(OBJECT_END); + writer.writeStructure(NEW); return hasSamples; } - private static void serializeTags(List tags, StringBuilder replaceBuilder, JsonWriter jw) { + private static void serializeTags(List tags, DataWriter writer) { if (tags.isEmpty()) { return; } - DslJsonSerializer.writeFieldName("tags", jw); - jw.writeByte(OBJECT_START); + writer.writeKey("tags"); + writer.writeStructure(OBJECT_START); for (int i = 0, tagsSize = tags.size(); i < tagsSize; i++) { Tag tag = tags.get(i); if (i > 0) { - jw.writeByte(COMMA); + writer.writeStructure(NEXT); } - DslJsonSerializer.writeStringValue(DslJsonSerializer.sanitizePropertyName(tag.getKey(), replaceBuilder), replaceBuilder, jw); - jw.writeByte(JsonWriter.SEMI); - DslJsonSerializer.writeStringValue(tag.getValue(), replaceBuilder, jw); + writer.writeKey(tag.getKey(), true); + writer.writeValue(tag.getValue(), true); } - jw.writeByte(OBJECT_END); - jw.writeByte(COMMA); + writer.writeStructure(OBJECT_END); + writer.writeStructure(NEXT); } /** * Conditionally serializes a {@link Timer} if the total time is valid, i.e. neither Double.NaN nor +/-Infinite * - * @param jw writer + * @param writer writer * @param histogramSnapshot * @param id meter ID * @param count count * @param totalTime total time * @param hasValue whether a value has already been written - * @param replaceBuilder * @param dedotMetricName * @return true if a value has been written before, including this one; false otherwise */ - private static boolean serializeTimer(JsonWriter jw, HistogramSnapshot histogramSnapshot, Meter.Id id, long count, double totalTime, boolean hasValue, StringBuilder replaceBuilder, boolean dedotMetricName) { + private static boolean serializeTimer(DataWriter writer, HistogramSnapshot histogramSnapshot, Meter.Id id, long count, double totalTime, boolean hasValue, boolean dedotMetricName) { if (isValidValue(totalTime)) { - if (hasValue) jw.writeByte(JsonWriter.COMMA); - serializeValue(id, ".count", count, jw, replaceBuilder, dedotMetricName); - jw.writeByte(JsonWriter.COMMA); - serializeValue(id, ".sum.us", totalTime, jw, replaceBuilder, dedotMetricName); + if (hasValue) writer.writeStructure(NEXT); + serializeValue(id, ".count", count, writer, dedotMetricName); + writer.writeStructure(NEXT); + serializeValue(id, ".sum.us", totalTime, writer, dedotMetricName); if (histogramSnapshot != null && histogramSnapshot.histogramCounts().length > 0) { - jw.writeByte(JsonWriter.COMMA); - serializeHistogram(id, histogramSnapshot, jw, replaceBuilder, dedotMetricName); + writer.writeStructure(NEXT); + serializeHistogram(id, histogramSnapshot, writer, dedotMetricName); } return true; } @@ -213,78 +209,75 @@ private static boolean serializeTimer(JsonWriter jw, HistogramSnapshot histogram /** * Conditionally serializes a {@link DistributionSummary} if the total amount is valid, i.e. neither Double.NaN nor +/-Infinite * - * @param jw writer + * @param writer writer * @param histogramSnapshot * @param id meter ID * @param count count * @param totalAmount total amount of recorded events * @param hasValue whether a value has already been written - * @param replaceBuilder * @param dedotMetricName * @return true if a value has been written before, including this one; false otherwise */ - private static boolean serializeDistributionSummary(JsonWriter jw, HistogramSnapshot histogramSnapshot, Meter.Id id, long count, double totalAmount, boolean hasValue, StringBuilder replaceBuilder, boolean dedotMetricName) { + private static boolean serializeDistributionSummary(DataWriter writer, HistogramSnapshot histogramSnapshot, Meter.Id id, long count, double totalAmount, boolean hasValue, boolean dedotMetricName) { if (isValidValue(totalAmount)) { - if (hasValue) jw.writeByte(JsonWriter.COMMA); - serializeValue(id, ".count", count, jw, replaceBuilder, dedotMetricName); - jw.writeByte(JsonWriter.COMMA); - serializeValue(id, ".sum", totalAmount, jw, replaceBuilder, dedotMetricName); + if (hasValue) writer.writeStructure(NEXT); + serializeValue(id, ".count", count, writer, dedotMetricName); + writer.writeStructure(NEXT); + serializeValue(id, ".sum", totalAmount, writer, dedotMetricName); if (histogramSnapshot != null && histogramSnapshot.histogramCounts().length > 0) { - jw.writeByte(JsonWriter.COMMA); - serializeHistogram(id, histogramSnapshot, jw, replaceBuilder, dedotMetricName); + writer.writeStructure(NEXT); + serializeHistogram(id, histogramSnapshot, writer, dedotMetricName); } return true; } return hasValue; } - private static void serializeHistogram(Meter.Id id, HistogramSnapshot histogramSnapshot, JsonWriter jw, StringBuilder replaceBuilder, boolean dedotMetricName) { + private static void serializeHistogram(Meter.Id id, HistogramSnapshot histogramSnapshot, DataWriter writer, boolean dedotMetricName) { if (histogramSnapshot == null) { return; } String suffix = ".histogram"; CountAtBucket[] bucket = histogramSnapshot.histogramCounts(); - serializeObjectStart(id.getName(), "values", suffix, jw, replaceBuilder, dedotMetricName); - jw.writeByte(JsonWriter.ARRAY_START); + serializeObjectStart(id.getName(), "values", suffix, writer, dedotMetricName); + writer.writeStructure(ARRAY_START); if (bucket.length > 0) { - NumberConverter.serialize(bucket[0].bucket(), jw); + writer.writeValue(bucket[0].bucket()); for (int i = 1; i < bucket.length; i++) { - jw.writeByte(JsonWriter.COMMA); - NumberConverter.serialize(bucket[i].bucket(), jw); + writer.writeStructure(NEXT); + writer.writeValue(bucket[i].bucket()); } } - jw.writeByte(JsonWriter.ARRAY_END); - jw.writeByte(JsonWriter.COMMA); - jw.writeByte(JsonWriter.QUOTE); - jw.writeAscii("counts"); - jw.writeByte(JsonWriter.QUOTE); - jw.writeByte(JsonWriter.SEMI); - jw.writeByte(JsonWriter.ARRAY_START); + writer.writeStructure(ARRAY_END); + writer.writeStructure(NEXT); + writer.writeKey("counts"); + writer.writeStructure(ARRAY_START); // Micrometer bucket counts are cumulative: E.g. the count at bucket with upper // boundary X is the total number of observations smaller than X // including values which have already been counted for smaller buckets. // Elastic however expects non-cumulative bucket counts if (bucket.length > 0) { - NumberConverter.serialize((long) bucket[0].count(), jw); + writer.writeValue((long) bucket[0].count()); double prevBucketCount = bucket[0].count(); for (int i = 1; i < bucket.length; i++) { - jw.writeByte(JsonWriter.COMMA); - NumberConverter.serialize((long) (bucket[i].count() - prevBucketCount), jw); + writer.writeStructure(NEXT); + writer.writeValue((long) (bucket[i].count() - prevBucketCount)); prevBucketCount = bucket[i].count(); } } - jw.writeByte(JsonWriter.ARRAY_END); + writer.writeStructure(ARRAY_END); - jw.writeByte(JsonWriter.COMMA); - jw.writeAscii("\"type\":\"histogram\""); + writer.writeStructure(NEXT); + writer.writeKey("type"); + writer.writeValue("histogram"); - jw.writeByte(JsonWriter.OBJECT_END); + writer.writeStructure(OBJECT_END); } - private static void serializeValue(Meter.Id id, String suffix, long value, JsonWriter jw, StringBuilder replaceBuilder, boolean dedotMetricName) { - serializeValueStart(id.getName(), suffix, jw, replaceBuilder, dedotMetricName); - NumberConverter.serialize(value, jw); - jw.writeByte(JsonWriter.OBJECT_END); + private static void serializeValue(Meter.Id id, String suffix, long value, DataWriter writer, boolean dedotMetricName) { + serializeValueStart(id.getName(), suffix, writer, dedotMetricName); + writer.writeValue(value); + writer.writeStructure(OBJECT_END); } /** @@ -293,51 +286,33 @@ private static void serializeValue(Meter.Id id, String suffix, long value, JsonW * @param id meter ID * @param value meter value * @param hasValue whether a value has already been written - * @param jw writer - * @param replaceBuilder + * @param writer writer * @param dedotMetricName * @return true if a value has been written before, including this one; false otherwise */ - private static boolean serializeValue(Meter.Id id, double value, boolean hasValue, JsonWriter jw, StringBuilder replaceBuilder, boolean dedotMetricName) { + private static boolean serializeValue(Meter.Id id, double value, boolean hasValue, DataWriter writer, boolean dedotMetricName) { if (isValidValue(value)) { - if (hasValue) jw.writeByte(JsonWriter.COMMA); - serializeValue(id, "", value, jw, replaceBuilder, dedotMetricName); + if (hasValue) writer.writeStructure(NEXT); + serializeValue(id, "", value, writer, dedotMetricName); return true; } return hasValue; } - private static void serializeValue(Meter.Id id, String suffix, double value, JsonWriter jw, StringBuilder replaceBuilder, boolean dedotMetricName) { - serializeValueStart(id.getName(), suffix, jw, replaceBuilder, dedotMetricName); - NumberConverter.serialize(value, jw); - jw.writeByte(JsonWriter.OBJECT_END); + private static void serializeValue(Meter.Id id, String suffix, double value, DataWriter writer, boolean dedotMetricName) { + serializeValueStart(id.getName(), suffix, writer, dedotMetricName); + writer.writeValue(value); + writer.writeStructure(OBJECT_END); } - private static void serializeValueStart(String key, String suffix, JsonWriter jw, StringBuilder replaceBuilder, boolean dedotMetricName) { - serializeObjectStart(key, "value", suffix, jw, replaceBuilder, dedotMetricName); + private static void serializeValueStart(String key, String suffix, DataWriter writer, boolean dedotMetricName) { + serializeObjectStart(key, "value", suffix, writer, dedotMetricName); } - 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); - } else { - replaceBuilder.append(key); - } - if (suffix != null) { - if (replaceBuilder.length() == 0) { - replaceBuilder.append(key); - } - replaceBuilder.append(suffix); - } - jw.writeString(replaceBuilder); - - jw.writeByte(JsonWriter.SEMI); - jw.writeByte(JsonWriter.OBJECT_START); - jw.writeByte(JsonWriter.QUOTE); - jw.writeAscii(objectName); - jw.writeByte(JsonWriter.QUOTE); - jw.writeByte(JsonWriter.SEMI); + private static void serializeObjectStart(String key, String objectName, String suffix, DataWriter writer, boolean dedotMetricName) { + writer.writeKey(key, dedotMetricName, suffix); + writer.writeStructure(OBJECT_START); + writer.writeKey(objectName); } private static boolean isValidValue(double value) { 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..c18ec24a47 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,15 @@ */ 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.configuration.MetricsConfiguration; import co.elastic.apm.agent.tracer.configuration.ReporterConfiguration; -import com.dslplatform.json.JsonWriter; +import co.elastic.apm.agent.tracer.reporting.DataWriter; +import co.elastic.apm.agent.tracer.reporting.ReportingTracer; import io.micrometer.core.instrument.Meter; import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.core.instrument.composite.CompositeMeterRegistry; @@ -90,21 +88,19 @@ 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 ReportingTracer tracer; private final AtomicBoolean scheduledReporting = new AtomicBoolean(); private final boolean disableScheduler; - public MicrometerMetricsReporter(ElasticApmTracer tracer) { + public MicrometerMetricsReporter(ReportingTracer tracer) { this(tracer, false); } //constructor split up to have this available for testing - MicrometerMetricsReporter(ElasticApmTracer tracer, boolean disableSchedulerThread) { + MicrometerMetricsReporter(ReportingTracer tracer, boolean disableSchedulerThread) { this.tracer = tracer; - this.reporter = tracer.getReporter(); tracer.addShutdownHook(this); - serializer = new MicrometerMeterRegistrySerializer(tracer.getConfig(MetricsConfiguration.class)); + serializer = new MicrometerMeterRegistrySerializer(tracer.getConfig(MetricsConfiguration.class), tracer); this.disableScheduler = disableSchedulerThread; } @@ -147,7 +143,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(); @@ -189,8 +185,8 @@ void run(final long now) { registry.forEachMeter(meterConsumer); } logger.debug("Reporting {} meters", meterConsumer.meters.size()); - for (JsonWriter serializedMetricSet : serializer.serialize(meterConsumer.meters, now * 1000)) { - reporter.reportMetrics(serializedMetricSet); + for (DataWriter serializedMetricSet : serializer.serialize(meterConsumer.meters, now * 1000)) { + serializedMetricSet.report(); } } diff --git a/apm-agent-plugins/apm-micrometer-plugin/src/test/java/co/elastic/apm/agent/micrometer/MicrometerMeterRegistrySerializerTest.java b/apm-agent-plugins/apm-micrometer-plugin/src/test/java/co/elastic/apm/agent/micrometer/MicrometerMeterRegistrySerializerTest.java index 026936f4fc..f47dc58f5b 100644 --- a/apm-agent-plugins/apm-micrometer-plugin/src/test/java/co/elastic/apm/agent/micrometer/MicrometerMeterRegistrySerializerTest.java +++ b/apm-agent-plugins/apm-micrometer-plugin/src/test/java/co/elastic/apm/agent/micrometer/MicrometerMeterRegistrySerializerTest.java @@ -19,7 +19,11 @@ package co.elastic.apm.agent.micrometer; import co.elastic.apm.agent.configuration.MetricsConfiguration; -import com.dslplatform.json.JsonWriter; +import co.elastic.apm.agent.report.Reporter; +import co.elastic.apm.agent.report.serialize.DslJsonDataWriter; +import co.elastic.apm.agent.tracer.reporting.DataWriter; +import co.elastic.apm.agent.tracer.reporting.ReportingTracer; +import com.dslplatform.json.DslJson; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; @@ -35,6 +39,8 @@ import io.micrometer.core.instrument.simple.SimpleMeterRegistry; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; import java.util.ArrayList; import java.util.Collections; @@ -43,7 +49,9 @@ import java.util.concurrent.TimeUnit; import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; public class MicrometerMeterRegistrySerializerTest { static MicrometerMeterRegistrySerializer serializer; @@ -51,12 +59,22 @@ public class MicrometerMeterRegistrySerializerTest { @BeforeAll static void setup() { MetricsConfiguration config = mock(MetricsConfiguration.class); - serializer = new MicrometerMeterRegistrySerializer(config); + ReportingTracer tracer = mock(ReportingTracer.class); + Reporter reporter = mock(Reporter.class); + DslJson dslJson = new DslJson<>(new DslJson.Settings<>()); + when(tracer.newWriter(anyInt())).thenAnswer(new Answer() { + @Override + public DataWriter answer(InvocationOnMock invocationOnMock) { + int maxSerializedSize = invocationOnMock.getArgument(0); + return new DslJsonDataWriter(dslJson.newWriter(maxSerializedSize), reporter); + } + }); + serializer = new MicrometerMeterRegistrySerializer(config, tracer); } @Test void serializeEmpty() { - List serialized = serializer.serialize(Collections.emptyMap(), 0); + List serialized = serializer.serialize(Collections.emptyMap(), 0); assertThat(serialized).isEmpty(); } @@ -104,7 +122,7 @@ void serializeOneMeter(TestMeter testMeter) { SimpleMeterRegistry registry = new SimpleMeterRegistry(); testMeter.addToMeterRegistry(registry); testMeter.populateValues(); - List serialized = serializer.serialize(Map.of(testMeter.meter().getId(), testMeter.meter()), 0); + List serialized = serializer.serialize(Map.of(testMeter.meter().getId(), testMeter.meter()), 0); assertThat(serialized.size()).isEqualTo(1); JsonNode jsonNode = readJsonString(serialized.get(0).toString()); testMeter.checkSerialization(jsonNode); @@ -121,7 +139,7 @@ void serializeTwoMeters(TestMeter testMeter1, TestMeter testMeter2) { testMeter2.addToMeterRegistry(registry); testMeter1.populateValues(); testMeter2.populateValues(); - List serialized = serializer.serialize(Map.of( + List serialized = serializer.serialize(Map.of( testMeter1.meter().getId(), testMeter1.meter(), testMeter2.meter().getId(), testMeter2.meter() ), 0); 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..0974fdcb06 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; @@ -39,15 +39,13 @@ public class EmbeddedSdkManager extends AbstractLifecycleListener { private static final Logger logger = LoggerFactory.getLogger(EmbeddedSdkManager.class); - @Nullable - private ElasticApmTracer tracer; + private final Tracer tracer; @Nullable private volatile SdkMeterProvider sdkInstance; private boolean isShutdown = false; - @Override - public synchronized void start(ElasticApmTracer tracer) throws Exception { + public EmbeddedSdkManager(Tracer tracer) { 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-opentelemetry/apm-opentelemetry-metricsdk-plugin/src/main/java/co/elastic/apm/agent/otelmetricsdk/ElasticOtelMetricsExporter.java b/apm-agent-plugins/apm-opentelemetry/apm-opentelemetry-metricsdk-plugin/src/main/java/co/elastic/apm/agent/otelmetricsdk/ElasticOtelMetricsExporter.java index 941cf14f05..631ac30ad8 100644 --- a/apm-agent-plugins/apm-opentelemetry/apm-opentelemetry-metricsdk-plugin/src/main/java/co/elastic/apm/agent/otelmetricsdk/ElasticOtelMetricsExporter.java +++ b/apm-agent-plugins/apm-opentelemetry/apm-opentelemetry-metricsdk-plugin/src/main/java/co/elastic/apm/agent/otelmetricsdk/ElasticOtelMetricsExporter.java @@ -18,13 +18,12 @@ */ package co.elastic.apm.agent.otelmetricsdk; -import co.elastic.apm.agent.impl.ElasticApmTracer; -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.ExecutorUtils; import co.elastic.apm.agent.tracer.configuration.MetricsConfiguration; import co.elastic.apm.agent.tracer.configuration.ReporterConfiguration; +import co.elastic.apm.agent.tracer.reporting.ReportingTracer; import io.opentelemetry.sdk.common.CompletableResultCode; import io.opentelemetry.sdk.metrics.Aggregation; import io.opentelemetry.sdk.metrics.InstrumentType; @@ -48,13 +47,11 @@ public class ElasticOtelMetricsExporter implements MetricExporter { private final OtelMetricSerializer serializer; - private final Reporter reporter; - - public static void createAndRegisterOn(SdkMeterProviderBuilder builder, ElasticApmTracer tracer) { + public static void createAndRegisterOn(SdkMeterProviderBuilder builder, ReportingTracer tracer) { MetricsConfiguration metricsConfig = tracer.getConfig(MetricsConfiguration.class); ReporterConfiguration reporterConfig = tracer.getConfig(ReporterConfiguration.class); - ElasticOtelMetricsExporter exporter = new ElasticOtelMetricsExporter(tracer.getReporter(), metricsConfig, reporterConfig); + ElasticOtelMetricsExporter exporter = new ElasticOtelMetricsExporter(tracer, metricsConfig, reporterConfig); PeriodicMetricReader metricReader = PeriodicMetricReader.builder(exporter) .setExecutor(ExecutorUtils.createSingleThreadSchedulingDaemonPool("otel-metrics-exporter")) @@ -64,9 +61,8 @@ public static void createAndRegisterOn(SdkMeterProviderBuilder builder, ElasticA builder.registerMetricReader(metricReader); } - private ElasticOtelMetricsExporter(Reporter reporter, MetricsConfiguration metricsConfig, ReporterConfiguration reporterConfig) { - serializer = new OtelMetricSerializer(reporterConfig); - this.reporter = reporter; + private ElasticOtelMetricsExporter(ReportingTracer tracer, MetricsConfiguration metricsConfig, ReporterConfiguration reporterConfig) { + serializer = new OtelMetricSerializer(reporterConfig, tracer); this.defaultHistogramAggregation = Aggregation.explicitBucketHistogram(metricsConfig.getCustomMetricsHistogramBoundaries()); } @@ -79,7 +75,7 @@ public CompletableResultCode export(Collection metrics) { serializer.addValues(metric); } - serializer.flushAndReset(reporter); + serializer.flushAndReset(); return CompletableResultCode.ofSuccess(); } 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..1ae06fd81e 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 @@ -18,53 +18,44 @@ */ package co.elastic.apm.agent.otelmetricsdk; -import co.elastic.apm.agent.report.Reporter; -import co.elastic.apm.agent.report.serialize.DslJsonSerializer; -import com.dslplatform.json.BoolConverter; -import com.dslplatform.json.DslJson; -import com.dslplatform.json.JsonWriter; -import com.dslplatform.json.Nullable; -import com.dslplatform.json.NumberConverter; +import co.elastic.apm.agent.tracer.reporting.DataWriter; +import co.elastic.apm.agent.tracer.reporting.ReportingTracer; import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.AttributeType; import io.opentelemetry.api.common.Attributes; +import javax.annotation.Nullable; import java.util.List; import java.util.Map; -import static com.dslplatform.json.JsonWriter.ARRAY_END; -import static com.dslplatform.json.JsonWriter.ARRAY_START; -import static com.dslplatform.json.JsonWriter.COMMA; -import static com.dslplatform.json.JsonWriter.OBJECT_END; -import static com.dslplatform.json.JsonWriter.OBJECT_START; +import static co.elastic.apm.agent.tracer.reporting.DataWriter.StructureType.ARRAY_END; +import static co.elastic.apm.agent.tracer.reporting.DataWriter.StructureType.ARRAY_START; +import static co.elastic.apm.agent.tracer.reporting.DataWriter.StructureType.NEXT; +import static co.elastic.apm.agent.tracer.reporting.DataWriter.StructureType.NEW; +import static co.elastic.apm.agent.tracer.reporting.DataWriter.StructureType.OBJECT_END; +import static co.elastic.apm.agent.tracer.reporting.DataWriter.StructureType.OBJECT_START; class MetricSetSerializer { - private static final byte NEW_LINE = '\n'; - private static final int INITIAL_BUFFER_SIZE = 2048; - private static final DslJson DSL_JSON = new DslJson<>(new DslJson.Settings<>()); - - private final StringBuilder replaceBuilder; - private final JsonWriter jw; + private final DataWriter writer; private boolean anySamplesWritten; - public MetricSetSerializer(Attributes attributes, CharSequence instrumentationScopeName, long epochMicros, StringBuilder replaceBuilder) { - this.replaceBuilder = replaceBuilder; + public MetricSetSerializer(ReportingTracer tracer, Attributes attributes, CharSequence instrumentationScopeName, long epochMicros) { anySamplesWritten = false; - jw = DSL_JSON.newWriter(INITIAL_BUFFER_SIZE); - jw.writeByte(JsonWriter.OBJECT_START); + writer = tracer.newWriter(INITIAL_BUFFER_SIZE); + writer.writeStructure(OBJECT_START); { - DslJsonSerializer.writeFieldName("metricset", jw); - jw.writeByte(JsonWriter.OBJECT_START); + writer.writeKey("metricset"); + writer.writeStructure(OBJECT_START); { - DslJsonSerializer.writeFieldName("timestamp", jw); - NumberConverter.serialize(epochMicros, jw); - jw.writeByte(JsonWriter.COMMA); + writer.writeKey("timestamp"); + writer.writeValue(epochMicros); + writer.writeStructure(NEXT); serializeAttributes(instrumentationScopeName, attributes); - DslJsonSerializer.writeFieldName("samples", jw); - jw.writeByte(JsonWriter.OBJECT_START); + writer.writeKey("samples"); + writer.writeStructure(OBJECT_START); } } } @@ -79,19 +70,19 @@ public void addValue(CharSequence metricName, long value) { private void addValue(CharSequence metricName, boolean isDouble, long longVal, double doubleVal) { if (anySamplesWritten) { - jw.writeByte(COMMA); + writer.writeStructure(NEXT); } - serializeFieldKey(metricName); - jw.writeByte(JsonWriter.OBJECT_START); + writer.writeKey(metricName); + writer.writeStructure(OBJECT_START); { - serializeFieldKeyAscii("value"); + writer.writeKey("value"); if (isDouble) { - NumberConverter.serialize(doubleVal, jw); + writer.writeValue(doubleVal); } else { - NumberConverter.serialize(longVal, jw); + writer.writeValue(longVal); } } - jw.writeByte(JsonWriter.OBJECT_END); + writer.writeStructure(OBJECT_END); anySamplesWritten = true; } @@ -101,20 +92,21 @@ public void addExplicitBucketHistogram(CharSequence metricName, List bou return; } if (anySamplesWritten) { - jw.writeByte(COMMA); + writer.writeStructure(NEXT); } - serializeFieldKey(metricName); - jw.writeByte(JsonWriter.OBJECT_START); + writer.writeKey(metricName); + writer.writeStructure(OBJECT_START); { - serializeFieldKeyAscii("values"); + writer.writeKey("values"); convertAndSerializeHistogramBucketBoundaries(boundaries, counts); - jw.writeByte(COMMA); - serializeFieldKeyAscii("counts"); + writer.writeStructure(NEXT); + writer.writeKey("counts"); convertAndSerializeHistogramBucketCounts(counts); - jw.writeByte(COMMA); - jw.writeAscii("\"type\":\"histogram\""); + writer.writeStructure(NEXT); + writer.writeKey("type"); + writer.writeValue("histogram"); } - jw.writeByte(JsonWriter.OBJECT_END); + writer.writeStructure(OBJECT_END); anySamplesWritten = true; } @@ -128,29 +120,29 @@ private boolean isEmptyHistogram(List boundaries, List counts) { } private void convertAndSerializeHistogramBucketCounts(List counts) { - jw.writeByte(ARRAY_START); + writer.writeStructure(ARRAY_START); boolean firstElement = true; for (long count : counts) { if (count != 0) { if (!firstElement) { - jw.writeByte(COMMA); + writer.writeStructure(NEXT); } firstElement = false; - NumberConverter.serialize(count, jw); + writer.writeValue(count); } } - jw.writeByte(ARRAY_END); + writer.writeStructure(ARRAY_END); } private void convertAndSerializeHistogramBucketBoundaries(List boundaries, List counts) { - jw.writeByte(ARRAY_START); + writer.writeStructure(ARRAY_START); boolean firstElement = true; //Bucket boundary conversion algorithm is copied from APM server int bucketCount = counts.size(); for (int i = 0; i < bucketCount; i++) { if (counts.get(i) != 0) { if (!firstElement) { - jw.writeByte(COMMA); + writer.writeStructure(NEXT); } firstElement = false; if (i == 0) { @@ -158,29 +150,17 @@ private void convertAndSerializeHistogramBucketBoundaries(List boundarie if (bounds > 0) { bounds /= 2; } - NumberConverter.serialize(bounds, jw); + writer.writeValue(bounds); } else if (i == bucketCount - 1) { - NumberConverter.serialize(boundaries.get(bucketCount - 2), jw); + writer.writeValue(boundaries.get(bucketCount - 2)); } else { double lower = boundaries.get(i - 1); double upper = boundaries.get(i); - NumberConverter.serialize(lower + (upper - lower) / 2, jw); + writer.writeValue(lower + (upper - lower) / 2); } } } - jw.writeByte(ARRAY_END); - } - - private void serializeFieldKey(CharSequence fieldName) { - jw.writeString(fieldName); - jw.writeByte(JsonWriter.SEMI); - } - - private void serializeFieldKeyAscii(String fieldName) { - jw.writeByte(JsonWriter.QUOTE); - jw.writeAscii(fieldName); - jw.writeByte(JsonWriter.QUOTE); - jw.writeByte(JsonWriter.SEMI); + writer.writeStructure(ARRAY_END); } private void serializeAttributes(CharSequence instrumentationScopeName, Attributes attributes) { @@ -188,12 +168,12 @@ private void serializeAttributes(CharSequence instrumentationScopeName, Attribut if (attributeMap.isEmpty() && instrumentationScopeName.length() == 0) { return; } - DslJsonSerializer.writeFieldName("tags", jw); - jw.writeByte(OBJECT_START); + writer.writeKey("tags"); + writer.writeStructure(OBJECT_START); boolean anyWritten = false; if (instrumentationScopeName.length() > 0) { - jw.writeAscii("\"otel_instrumentation_scope_name\":"); - jw.writeString(instrumentationScopeName); + writer.writeKey("otel_instrumentation_scope_name"); + writer.writeValue(instrumentationScopeName); anyWritten = true; } for (Map.Entry, Object> entry : attributeMap.entrySet()) { @@ -201,31 +181,30 @@ private void serializeAttributes(CharSequence instrumentationScopeName, Attribut Object value = entry.getValue(); anyWritten |= serializeAttribute(key, value, anyWritten); } - jw.writeByte(OBJECT_END); - jw.writeByte(COMMA); + writer.writeStructure(OBJECT_END); + writer.writeStructure(NEXT); } private boolean serializeAttribute(AttributeKey key, @Nullable Object value, boolean prependComma) { if (isValidAttributeValue(key, value)) { if (prependComma) { - jw.writeByte(COMMA); + writer.writeStructure(NEXT); } - DslJsonSerializer.writeStringValue(DslJsonSerializer.sanitizePropertyName(key.getKey(), replaceBuilder), replaceBuilder, jw); - jw.writeByte(JsonWriter.SEMI); + writer.writeKey(key.getKey(), true); AttributeType type = key.getType(); switch (type) { case STRING: - jw.writeString((CharSequence) value); + writer.writeValue((CharSequence) value); return true; case BOOLEAN: - BoolConverter.serialize((Boolean) value, jw); + writer.writeValue((Boolean) value); return true; case LONG: - NumberConverter.serialize(((Number) value).longValue(), jw); + writer.writeValue(((Number) value).longValue()); return true; case DOUBLE: - NumberConverter.serialize(((Number) value).doubleValue(), jw); + writer.writeValue(((Number) value).doubleValue()); return true; case STRING_ARRAY: case BOOLEAN_ARRAY: @@ -266,19 +245,19 @@ private void serializeMetricSetEnd() { { /*"samples":*/ { - jw.writeByte(JsonWriter.OBJECT_END); + writer.writeStructure(OBJECT_END); } } - jw.writeByte(JsonWriter.OBJECT_END); + writer.writeStructure(OBJECT_END); } - jw.writeByte(JsonWriter.OBJECT_END); - jw.writeByte(NEW_LINE); + writer.writeStructure(OBJECT_END); + writer.writeStructure(NEW); } - public void finishAndReport(Reporter reporter) { + public void finishAndReport() { if (anySamplesWritten) { serializeMetricSetEnd(); - reporter.reportMetrics(jw); + writer.report(); } } } diff --git a/apm-agent-plugins/apm-opentelemetry/apm-opentelemetry-metricsdk-plugin/src/main/java/co/elastic/apm/agent/otelmetricsdk/OtelMetricSerializer.java b/apm-agent-plugins/apm-opentelemetry/apm-opentelemetry-metricsdk-plugin/src/main/java/co/elastic/apm/agent/otelmetricsdk/OtelMetricSerializer.java index 70b9040fb6..525635315f 100644 --- a/apm-agent-plugins/apm-opentelemetry/apm-opentelemetry-metricsdk-plugin/src/main/java/co/elastic/apm/agent/otelmetricsdk/OtelMetricSerializer.java +++ b/apm-agent-plugins/apm-opentelemetry/apm-opentelemetry-metricsdk-plugin/src/main/java/co/elastic/apm/agent/otelmetricsdk/OtelMetricSerializer.java @@ -19,10 +19,10 @@ package co.elastic.apm.agent.otelmetricsdk; 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.configuration.ReporterConfiguration; +import co.elastic.apm.agent.tracer.reporting.ReportingTracer; import io.opentelemetry.api.common.Attributes; import io.opentelemetry.sdk.metrics.data.AggregationTemporality; import io.opentelemetry.sdk.metrics.data.Data; @@ -43,8 +43,7 @@ public class OtelMetricSerializer { private static final Logger logger = LoggerFactory.getLogger(OtelMetricSerializer.class); private final ReporterConfiguration reporterConfig; - private final StringBuilder serializationTempBuilder; - + private final ReportingTracer tracer; private final Set metricsWithBadAggregations = Collections.newSetFromMap(new ConcurrentHashMap<>()); private final Map> metricSets; @@ -52,10 +51,10 @@ public class OtelMetricSerializer { @Nullable private InstrumentationScopeAndTimestamp lastCreatedInstrScopeAndTimestamp; - public OtelMetricSerializer(ReporterConfiguration reporterConfig) { + public OtelMetricSerializer(ReporterConfiguration reporterConfig, ReportingTracer tracer) { this.reporterConfig = reporterConfig; + this.tracer = tracer; metricSets = new HashMap<>(); - serializationTempBuilder = new StringBuilder(); } public void addValues(MetricData metric) { @@ -150,16 +149,16 @@ private MetricSetSerializer getOrCreateMetricSet(CharSequence instrScopeName, lo MetricSetSerializer ms = timestampMetricSets.get(attributes); if (ms == null) { - ms = new MetricSetSerializer(attributes, key.instrumentationScopeName, key.timestamp, serializationTempBuilder); + ms = new MetricSetSerializer(tracer, attributes, key.instrumentationScopeName, key.timestamp); timestampMetricSets.put(attributes, ms); } return ms; } - public void flushAndReset(Reporter reporter) { + public void flushAndReset() { for (Map map : metricSets.values()) { for (MetricSetSerializer metricSet : map.values()) { - metricSet.finishAndReport(reporter); + metricSet.finishAndReport(); } } metricSets.clear(); diff --git a/apm-agent-plugins/apm-opentelemetry/apm-opentelemetry-metricsdk-plugin/src/main/java/co/elastic/apm/agent/otelmetricsdk/SdkMeterProviderBuilderInstrumentation.java b/apm-agent-plugins/apm-opentelemetry/apm-opentelemetry-metricsdk-plugin/src/main/java/co/elastic/apm/agent/otelmetricsdk/SdkMeterProviderBuilderInstrumentation.java index 2cc64c554c..9763ab10b5 100644 --- a/apm-agent-plugins/apm-opentelemetry/apm-opentelemetry-metricsdk-plugin/src/main/java/co/elastic/apm/agent/otelmetricsdk/SdkMeterProviderBuilderInstrumentation.java +++ b/apm-agent-plugins/apm-opentelemetry/apm-opentelemetry-metricsdk-plugin/src/main/java/co/elastic/apm/agent/otelmetricsdk/SdkMeterProviderBuilderInstrumentation.java @@ -18,7 +18,6 @@ */ package co.elastic.apm.agent.otelmetricsdk; -import co.elastic.apm.agent.impl.ElasticApmTracer; import co.elastic.apm.agent.sdk.ElasticApmInstrumentation; import co.elastic.apm.agent.sdk.internal.util.LoggerUtils; import co.elastic.apm.agent.sdk.logging.Logger; @@ -26,6 +25,7 @@ import co.elastic.apm.agent.sdk.weakconcurrent.WeakConcurrent; import co.elastic.apm.agent.sdk.weakconcurrent.WeakSet; import co.elastic.apm.agent.tracer.GlobalTracer; +import co.elastic.apm.agent.tracer.reporting.ReportingTracer; import io.opentelemetry.sdk.metrics.SdkMeterProviderBuilder; import io.opentelemetry.sdk.metrics.export.MetricExporter; import net.bytebuddy.asm.Advice; @@ -74,7 +74,7 @@ public static class SdkMeterProviderBuilderAdvice { private static final Logger unsupportedVersionLogger = LoggerUtils.logOnce(logger); private static final WeakSet ALREADY_REGISTERED_BUILDERS = WeakConcurrent.buildSet(); - private static final ElasticApmTracer tracer = GlobalTracer.get().require(ElasticApmTracer.class); + private static final ReportingTracer tracer = GlobalTracer.get().require(ReportingTracer.class); @Advice.OnMethodEnter(suppress = Throwable.class, inline = false) public static void onEnter(@Advice.This SdkMeterProviderBuilder thiz) { 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..a9573bc6ba 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,7 +18,7 @@ */ 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; public class ProfilingFactory extends AbstractLifecycleListener { @@ -26,7 +26,10 @@ public class ProfilingFactory extends AbstractLifecycleListener { private final SamplingProfiler profiler; private final NanoClock nanoClock; + private final ElasticApmTracer tracer; + public ProfilingFactory(ElasticApmTracer tracer) { + this.tracer = tracer; boolean envTest = false; // in unit tests, where assertions are enabled, this envTest is true assert envTest = true; @@ -35,8 +38,8 @@ public ProfilingFactory(ElasticApmTracer tracer) { } @Override - public void start(ElasticApmTracer tracer) { - profiler.start(tracer); + public void start() { + profiler.start(); tracer.registerSpanListener(new ProfilingActivationListener(tracer, profiler)); } 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..09f4f6c854 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; @@ -697,7 +697,7 @@ void copyFromFiles(Path activationEvents, Path traces) throws IOException { } @Override - public void start(ElasticApmTracer tracer) { + public void start() { 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-plugins/apm-profiling-plugin/src/test/java/co/elastic/apm/agent/profiler/SamplingProfilerTest.java b/apm-agent-plugins/apm-profiling-plugin/src/test/java/co/elastic/apm/agent/profiler/SamplingProfilerTest.java index 6e5816777e..6d1626cea4 100644 --- a/apm-agent-plugins/apm-profiling-plugin/src/test/java/co/elastic/apm/agent/profiler/SamplingProfilerTest.java +++ b/apm-agent-plugins/apm-profiling-plugin/src/test/java/co/elastic/apm/agent/profiler/SamplingProfilerTest.java @@ -139,7 +139,7 @@ void shouldNotDeleteProvidedFiles() throws Exception { SamplingProfiler otherProfiler = new SamplingProfiler(tracer, new FixedNanoClock(), tempFile1.toFile(), tempFile2.toFile()); - otherProfiler.start(tracer); + otherProfiler.start(); awaitProfilerStarted(otherProfiler); otherProfiler.stop(); diff --git a/apm-agent-plugins/apm-servlet-plugin/pom.xml b/apm-agent-plugins/apm-servlet-plugin/pom.xml index 4dc94472f6..fd12db82dd 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 278620fef0..744f6460ee 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/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..6b8383e860 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,16 @@ * 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() 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 031f927381..897c7cf1b3 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 @@ -24,6 +24,7 @@ import co.elastic.apm.agent.tracer.reference.ReferenceCountedMap; import javax.annotation.Nullable; +import java.io.Closeable; import java.util.Set; public class GlobalTracer implements Tracer { @@ -133,4 +134,9 @@ public Transaction startChildTransaction(@Nullable C headerCarrier, He public ErrorCapture captureException(@Nullable Throwable e, @Nullable ClassLoader initiatingClassLoader) { return tracer.captureException(e, initiatingClassLoader); } + + @Override + public void addShutdownHook(Closeable job) { + tracer.addShutdownHook(job); + } } 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 71% 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..f305924942 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,42 +16,42 @@ * specific language governing permissions and limitations * under the License. */ -package co.elastic.apm.agent.context; +package co.elastic.apm.agent.tracer; -import co.elastic.apm.agent.impl.ElasticApmTracer; -import co.elastic.apm.agent.impl.Tracer; +import co.elastic.apm.agent.tracer.reporting.ReportingTracer; /** - * 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.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 + * Implementations may have a constructor with a {@link Tracer} argument + *

+ *

+ * Listeners are instantiated before the {@link GlobalTracer} is initiated. To get hold of an instance, + * it needs to be injected via its constructor as the global tracer might neither be initialized within + * this instance's lifecycle methods. *

*/ public interface LifecycleListener { /** - * Callback for tracer initialization. As opposed to {@link LifecycleListener#start(ElasticApmTracer)}, which may - * be called in a delay, this callback is called at the bootstrap of the JVM, before anything else start. + * Callback for tracer initialization. As opposed to {@link LifecycleListener#start()}, which may + * be called in a delay, this callback is called at the bootstrap of the JVM, before anything else starts. * 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. + * Callback for when the {@link Tracer} starts. */ - void start(ElasticApmTracer tracer) throws Exception; + void start() throws Exception; /** - * Callback for when {@link ElasticApmTracer#pause()} has been called. + * Callback for when {@link Tracer} has been 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. @@ -65,7 +65,7 @@ public interface LifecycleListener { void pause() throws Exception; /** - * Callback for when {@link ElasticApmTracer#resume()} has been called. + * Callback for when {@link Tracer} is resumed. *

* Typically, used in order to revert the actions taken by the {@link LifecycleListener#pause()} method, allowing * the agent to restore all tracing capabilities @@ -79,7 +79,7 @@ public interface LifecycleListener { void resume() throws Exception; /** - * Callback for when {@link ElasticApmTracer#stop()} has been called. + * Callback for when {@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. @@ -96,17 +96,14 @@ public interface LifecycleListener { * The order in which lifecycle listeners are called is non-deterministic. * *

  • - * The {@link ElasticApmTracer#getSharedSingleThreadedPool()} is shut down gracefully, + * The {@link ReportingTracer#getSharedSingleThreadedPool()} 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 tracer state is set to {@link co.elastic.apm.agent.impl.Tracer.TracerState#STOPPED}. + * The {@link Tracer#isRunning()} will still be true in the tasks scheduled to + * {@link ReportingTracer#getSharedSingleThreadedPool()} within this method. *
  • *
  • - * The {@link co.elastic.apm.agent.report.Reporter} is closed. + * {@link Tracer#isRunning()} is set to 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 6088e75683..356c77eb77 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 @@ -24,6 +24,7 @@ import co.elastic.apm.agent.tracer.reference.ReferenceCountedMap; import javax.annotation.Nullable; +import java.io.Closeable; import java.util.Collections; import java.util.Set; @@ -110,4 +111,8 @@ public Transaction startChildTransaction(@Nullable C headerCarrier, He public ErrorCapture captureException(@Nullable Throwable e, @Nullable ClassLoader initiatingClassLoader) { return null; } + + @Override + public void addShutdownHook(Closeable job) { + } } 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..369d4ef8a0 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 @@ -24,6 +24,7 @@ import co.elastic.apm.agent.tracer.reference.ReferenceCountedMap; import javax.annotation.Nullable; +import java.io.Closeable; import java.util.Set; public interface Tracer { @@ -80,4 +81,6 @@ public interface Tracer { @Nullable ErrorCapture captureException(@Nullable Throwable e, @Nullable ClassLoader initiatingClassLoader); + + void addShutdownHook(Closeable job); } diff --git a/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/configuration/CoreConfiguration.java b/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/configuration/CoreConfiguration.java index 3d166ca595..347bf7b3a0 100644 --- a/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/configuration/CoreConfiguration.java +++ b/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/configuration/CoreConfiguration.java @@ -21,6 +21,7 @@ import co.elastic.apm.agent.common.util.WildcardMatcher; import co.elastic.apm.agent.configuration.ActivationMethod; +import javax.annotation.Nullable; import java.util.Collection; import java.util.List; @@ -40,10 +41,13 @@ public interface CoreConfiguration { String getServiceName(); + @Nullable String getServiceVersion(); + @Nullable String getServiceNodeName(); + @Nullable String getEnvironment(); ActivationMethod getActivationMethod(); diff --git a/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/configuration/ServerlessConfiguration.java b/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/configuration/ServerlessConfiguration.java index cb3a5e3fbe..bb1ba1c347 100644 --- a/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/configuration/ServerlessConfiguration.java +++ b/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/configuration/ServerlessConfiguration.java @@ -18,6 +18,8 @@ */ package co.elastic.apm.agent.tracer.configuration; +import javax.annotation.Nullable; + public interface ServerlessConfiguration { String getAwsLambdaHandler(); @@ -25,4 +27,7 @@ public interface ServerlessConfiguration { long getDataFlushTimeout(); boolean runsOnAwsLambda(); + + @Nullable + String awsLambdaLogStreamName(); } diff --git a/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/reporting/DataWriter.java b/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/reporting/DataWriter.java new file mode 100644 index 0000000000..80232a06b1 --- /dev/null +++ b/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/reporting/DataWriter.java @@ -0,0 +1,55 @@ +/* + * 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.reporting; + +import javax.annotation.Nullable; + +public interface DataWriter { + + void writeStructure(StructureType type); + + void writeKey(CharSequence name); + + void writeKey(CharSequence name, boolean sanitized); + + void writeKey(CharSequence name, boolean sanitized, @Nullable String suffix); + + void writeValue(boolean value); + + void writeValue(long value); + + void writeValue(double value); + + void writeValue(CharSequence value); + + void writeValue(CharSequence value, boolean trimmed); + + int size(); + + void report(); + + enum StructureType { + OBJECT_START, + OBJECT_END, + ARRAY_START, + ARRAY_END, + NEXT, + NEW + } +} 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/reporting/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/reporting/DoubleSupplier.java index 120a72221d..390dfe97e2 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/reporting/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.reporting; 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/reporting/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/reporting/Labels.java index c6a2e0475d..7bfcee52dc 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/reporting/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.reporting; 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()}. diff --git a/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/reporting/ReportingTracer.java b/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/reporting/ReportingTracer.java new file mode 100644 index 0000000000..9d0d195f1c --- /dev/null +++ b/apm-agent-tracer/src/main/java/co/elastic/apm/agent/tracer/reporting/ReportingTracer.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.reporting; + +import co.elastic.apm.agent.tracer.Tracer; + +import java.io.Closeable; +import java.util.concurrent.ScheduledExecutorService; + +public interface ReportingTracer extends Tracer { + + void addMetric(String name, Labels labels, DoubleSupplier metric); + + void removeMetric(String name, Labels labels); + + /** + * Reports an ECS-logging formatted log message. + * + * @param log log message generated by ecs-logging + */ + void reportLog(String log); + + /** + * Reports an ECS-logging formatted log message. + * + * @param log log message generated by ecs-logging + */ + void reportLog(byte[] log); + + DataWriter newWriter(int maxSerializedSize); + + ScheduledExecutorService getSharedSingleThreadedPool(); +} 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/reporting/LabelsTest.java similarity index 99% 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/reporting/LabelsTest.java index 21e55850c0..a27919baec 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/reporting/LabelsTest.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.reporting; import org.junit.jupiter.api.Test; diff --git a/integration-tests/spring-boot-1-5/pom.xml b/integration-tests/spring-boot-1-5/pom.xml index 5b22443a05..d2f63afae8 100644 --- a/integration-tests/spring-boot-1-5/pom.xml +++ b/integration-tests/spring-boot-1-5/pom.xml @@ -28,6 +28,13 @@ apm-servlet-plugin ${project.version} + + + ${project.groupId} + apm-agent-core + ${project.version} + test + ${project.groupId} apm-agent-core