From 31436856d24e5239b505e6f510c55737337397e0 Mon Sep 17 00:00:00 2001 From: xxia Date: Fri, 10 Sep 2021 10:13:41 -0700 Subject: [PATCH 01/10] harvest span events for any app name --- .../agent/service/analytics/SpanEventsServiceImpl.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/newrelic-agent/src/main/java/com/newrelic/agent/service/analytics/SpanEventsServiceImpl.java b/newrelic-agent/src/main/java/com/newrelic/agent/service/analytics/SpanEventsServiceImpl.java index 432d4d8374..922cd8f7ce 100644 --- a/newrelic-agent/src/main/java/com/newrelic/agent/service/analytics/SpanEventsServiceImpl.java +++ b/newrelic-agent/src/main/java/com/newrelic/agent/service/analytics/SpanEventsServiceImpl.java @@ -222,12 +222,9 @@ public void clearReservoir() { */ @Override public void addHarvestableToService(String appName) { - final String primaryApplication = ServiceFactory.getConfigService().getDefaultAgentConfig().getApplicationName(); - if (primaryApplication.equals(appName)) { Harvestable harvestable = new SpanEventHarvestableImpl(this, appName); ServiceFactory.getHarvestService().addHarvestable(harvestable); harvestables.add(harvestable); - } } @Override From 653732b678c8e4af62cd46cde55a796dd436a335 Mon Sep 17 00:00:00 2001 From: xxia Date: Fri, 10 Sep 2021 10:59:57 -0700 Subject: [PATCH 02/10] remove unused method --- .../com/newrelic/agent/tracing/DistributedTraceUtil.java | 7 ------- 1 file changed, 7 deletions(-) diff --git a/newrelic-agent/src/main/java/com/newrelic/agent/tracing/DistributedTraceUtil.java b/newrelic-agent/src/main/java/com/newrelic/agent/tracing/DistributedTraceUtil.java index 5d0cc5e804..935b881cdb 100644 --- a/newrelic-agent/src/main/java/com/newrelic/agent/tracing/DistributedTraceUtil.java +++ b/newrelic-agent/src/main/java/com/newrelic/agent/tracing/DistributedTraceUtil.java @@ -36,11 +36,4 @@ private DistributedTraceUtil() { public static boolean isSampledPriority(float priority) { return priority >= 1.0f; } - - public static AtomicReference getSpanEventPriority() { - SamplingPriorityQueue spanReservoir = ServiceFactory.getServiceManager() - .getSpanEventsService().getOrCreateDistributedSamplingReservoir(); - return new AtomicReference<>(ServiceFactory.getDistributedTraceService().calculatePriority(null, spanReservoir)); - } - } From 1a7b11b073c7a289e63bcd0d6c65ffeea7f73543 Mon Sep 17 00:00:00 2001 From: xxia Date: Fri, 10 Sep 2021 11:08:26 -0700 Subject: [PATCH 03/10] consider appName for reservoir in SpanEventService --- .../introspec/internal/IntrospectorSpanEventService.java | 2 +- .../agent/service/analytics/SpanEventsService.java | 2 +- .../agent/service/analytics/SpanEventsServiceImpl.java | 7 ++++--- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/instrumentation-test/src/main/java/com/newrelic/agent/introspec/internal/IntrospectorSpanEventService.java b/instrumentation-test/src/main/java/com/newrelic/agent/introspec/internal/IntrospectorSpanEventService.java index 19c4dd7000..11f005beaa 100644 --- a/instrumentation-test/src/main/java/com/newrelic/agent/introspec/internal/IntrospectorSpanEventService.java +++ b/instrumentation-test/src/main/java/com/newrelic/agent/introspec/internal/IntrospectorSpanEventService.java @@ -72,7 +72,7 @@ public void dispatcherTransactionFinished(TransactionData transactionData, Trans } @Override - public DistributedSamplingPriorityQueue getOrCreateDistributedSamplingReservoir() { + public DistributedSamplingPriorityQueue getOrCreateDistributedSamplingReservoir(String appName) { return new DistributedSamplingPriorityQueue<>(10); } diff --git a/newrelic-agent/src/main/java/com/newrelic/agent/service/analytics/SpanEventsService.java b/newrelic-agent/src/main/java/com/newrelic/agent/service/analytics/SpanEventsService.java index 4861ceaee6..d5dc1eb382 100644 --- a/newrelic-agent/src/main/java/com/newrelic/agent/service/analytics/SpanEventsService.java +++ b/newrelic-agent/src/main/java/com/newrelic/agent/service/analytics/SpanEventsService.java @@ -17,5 +17,5 @@ public interface SpanEventsService extends EventService { void addHarvestableToService(String appName); - SamplingPriorityQueue getOrCreateDistributedSamplingReservoir(); + SamplingPriorityQueue getOrCreateDistributedSamplingReservoir(String appName); } diff --git a/newrelic-agent/src/main/java/com/newrelic/agent/service/analytics/SpanEventsServiceImpl.java b/newrelic-agent/src/main/java/com/newrelic/agent/service/analytics/SpanEventsServiceImpl.java index 922cd8f7ce..53813e4700 100644 --- a/newrelic-agent/src/main/java/com/newrelic/agent/service/analytics/SpanEventsServiceImpl.java +++ b/newrelic-agent/src/main/java/com/newrelic/agent/service/analytics/SpanEventsServiceImpl.java @@ -97,7 +97,8 @@ private void createAndStoreSpanEvent(Tracer tracer, TransactionData transactionD return; } - SamplingPriorityQueue reservoir = getOrCreateDistributedSamplingReservoir(); + String appName = transactionData.getApplicationName(); + SamplingPriorityQueue reservoir = getOrCreateDistributedSamplingReservoir(appName); if (reservoir.isFull() && reservoir.getMinPriority() >= transactionData.getPriority()) { // The reservoir is full and this event wouldn't make it in, so lets prevent some object allocations reservoir.incrementNumberOfTries(); @@ -240,8 +241,8 @@ public void configChanged(String appName, AgentConfig agentConfig) { } @Override - public SamplingPriorityQueue getOrCreateDistributedSamplingReservoir() { - return reservoirManager.getOrCreateReservoir(); + public SamplingPriorityQueue getOrCreateDistributedSamplingReservoir(String appName) { + return reservoirManager.getOrCreateReservoir(appName); } public static Builder builder() { From 739548e5b8491cc3e69c234671e2e2a5190e77fc Mon Sep 17 00:00:00 2001 From: xxia Date: Fri, 10 Sep 2021 11:12:01 -0700 Subject: [PATCH 04/10] consider appName in reservoir manager --- .../com/newrelic/agent/interfaces/NoOpReservoirManager.java | 2 +- .../java/com/newrelic/agent/interfaces/ReservoirManager.java | 2 +- .../agent/service/ReservoirAddingSpanEventConsumer.java | 3 ++- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/agent-interfaces/src/main/java/com/newrelic/agent/interfaces/NoOpReservoirManager.java b/agent-interfaces/src/main/java/com/newrelic/agent/interfaces/NoOpReservoirManager.java index fcc00dd2d9..bccfcc72fb 100644 --- a/agent-interfaces/src/main/java/com/newrelic/agent/interfaces/NoOpReservoirManager.java +++ b/agent-interfaces/src/main/java/com/newrelic/agent/interfaces/NoOpReservoirManager.java @@ -17,7 +17,7 @@ public HarvestResult attemptToSendReservoir(String appName, EventSender event } @Override - public SamplingPriorityQueue getOrCreateReservoir() { + public SamplingPriorityQueue getOrCreateReservoir(String appName) { return null; } diff --git a/agent-interfaces/src/main/java/com/newrelic/agent/interfaces/ReservoirManager.java b/agent-interfaces/src/main/java/com/newrelic/agent/interfaces/ReservoirManager.java index 9c709965e2..4d12084878 100644 --- a/agent-interfaces/src/main/java/com/newrelic/agent/interfaces/ReservoirManager.java +++ b/agent-interfaces/src/main/java/com/newrelic/agent/interfaces/ReservoirManager.java @@ -17,7 +17,7 @@ */ public interface ReservoirManager { - SamplingPriorityQueue getOrCreateReservoir(); + SamplingPriorityQueue getOrCreateReservoir(String appName); void clearReservoir(); diff --git a/newrelic-agent/src/main/java/com/newrelic/agent/service/ReservoirAddingSpanEventConsumer.java b/newrelic-agent/src/main/java/com/newrelic/agent/service/ReservoirAddingSpanEventConsumer.java index 4b00f52990..2227d4eaf7 100644 --- a/newrelic-agent/src/main/java/com/newrelic/agent/service/ReservoirAddingSpanEventConsumer.java +++ b/newrelic-agent/src/main/java/com/newrelic/agent/service/ReservoirAddingSpanEventConsumer.java @@ -26,7 +26,8 @@ public ReservoirAddingSpanEventConsumer(ReservoirManager reservoirMan @Override public void accept(SpanEvent spanEvent) { if (isSpanEventsEnabled()) { - SamplingPriorityQueue reservoir = reservoirManager.getOrCreateReservoir(); + String appName = spanEvent.getAppName(); + SamplingPriorityQueue reservoir = reservoirManager.getOrCreateReservoir(appName); reservoir.add(spanEvent); } } From 10453c1465f8a97e727f13f0d7e1afae9137227d Mon Sep 17 00:00:00 2001 From: xxia Date: Fri, 10 Sep 2021 11:19:18 -0700 Subject: [PATCH 05/10] WIP create a span reservoir for each app name --- .../CollectorSpanEventReservoirManager.java | 44 +++++++++++-------- 1 file changed, 25 insertions(+), 19 deletions(-) diff --git a/newrelic-agent/src/main/java/com/newrelic/agent/service/analytics/CollectorSpanEventReservoirManager.java b/newrelic-agent/src/main/java/com/newrelic/agent/service/analytics/CollectorSpanEventReservoirManager.java index 466f982dab..1a00c2226d 100644 --- a/newrelic-agent/src/main/java/com/newrelic/agent/service/analytics/CollectorSpanEventReservoirManager.java +++ b/newrelic-agent/src/main/java/com/newrelic/agent/service/analytics/CollectorSpanEventReservoirManager.java @@ -18,12 +18,13 @@ import java.util.Collections; import java.util.Comparator; +import java.util.concurrent.ConcurrentHashMap; import java.util.logging.Level; public class CollectorSpanEventReservoirManager implements ReservoirManager { private final ConfigService configService; - private SamplingPriorityQueue reservoir; + private ConcurrentHashMap> spanReservoirsForApp = new ConcurrentHashMap<>(); private volatile int maxSamplesStored; public CollectorSpanEventReservoirManager(ConfigService configService) { @@ -32,15 +33,18 @@ public CollectorSpanEventReservoirManager(ConfigService configService) { } @Override - public SamplingPriorityQueue getOrCreateReservoir() { + public SamplingPriorityQueue getOrCreateReservoir(String appName) { + SamplingPriorityQueue reservoir = spanReservoirsForApp.get(appName); if (reservoir == null) { - reservoir = createDistributedSamplingReservoir(0); + reservoir = spanReservoirsForApp.putIfAbsent(appName, createDistributedSamplingReservoir(appName, 0)); + if (reservoir == null) { + reservoir = spanReservoirsForApp.get(appName); + } } return reservoir; } - private SamplingPriorityQueue createDistributedSamplingReservoir(int decidedLast) { - String appName = configService.getDefaultAgentConfig().getApplicationName(); + private SamplingPriorityQueue createDistributedSamplingReservoir(String appName, int decidedLast) { SpanEventsConfig spanEventsConfig = configService.getDefaultAgentConfig().getSpanEventsConfig(); int target = spanEventsConfig.getTargetSamplesStored(); return new DistributedSamplingPriorityQueue<>(appName, "Span Event Service", maxSamplesStored, decidedLast, target, SPAN_EVENT_COMPARATOR); @@ -48,7 +52,7 @@ private SamplingPriorityQueue createDistributedSamplingReservoir(int @Override public void clearReservoir() { - getOrCreateReservoir().clear(); + spanReservoirsForApp.forEach((appName, reservoir) -> reservoir.clear() ); } @Override @@ -59,11 +63,15 @@ public HarvestResult attemptToSendReservoir(final String appName, EventSender toSend = reservoir; - reservoir = createDistributedSamplingReservoir(decidedLast); + final SamplingPriorityQueue toSend = spanReservoirsForApp.get(appName); + spanReservoirsForApp.put(appName, createDistributedSamplingReservoir(appName, decidedLast)); + + //todo: this was here for a retry exception. The reservoir is used again to retryAll. Not sure what to do in case of discardHarvestData + // this doens't make sense...why create a new empty reservoir and retryAll with it in th catch of a tryign to save data??? + //reservoir = createDistributedSamplingReservoir(appName, decidedLast)); if (toSend == null || toSend.size() <= 0) { return null; @@ -80,7 +88,8 @@ public HarvestResult attemptToSendReservoir(final String appName, EventSender> newMaxSpanReservoirs = new ConcurrentHashMap<>(); + spanReservoirsForApp.forEach((appName,reservoir ) -> newMaxSpanReservoirs.putIfAbsent(appName, createDistributedSamplingReservoir(appName, 0))); + spanReservoirsForApp = newMaxSpanReservoirs; } // This is where you can add secondary sorting for Span Events - private static final Comparator SPAN_EVENT_COMPARATOR = new Comparator() { - @Override - public int compare(SpanEvent left, SpanEvent right) { - return ComparisonChain.start() - .compare(right.getPriority(), left.getPriority()) // Take highest priority first - .result(); - } - }; + private static final Comparator SPAN_EVENT_COMPARATOR = (left, right) -> ComparisonChain.start() + .compare(right.getPriority(), left.getPriority()) // Take highest priority first + .result(); } From 257c6a70e87db0ee4dfad4520e9f1ddc46203a76 Mon Sep 17 00:00:00 2001 From: xi xia Date: Mon, 22 Nov 2021 16:15:18 -0800 Subject: [PATCH 06/10] retry send events if exception is not discard --- .../analytics/CollectorSpanEventReservoirManager.java | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/newrelic-agent/src/main/java/com/newrelic/agent/service/analytics/CollectorSpanEventReservoirManager.java b/newrelic-agent/src/main/java/com/newrelic/agent/service/analytics/CollectorSpanEventReservoirManager.java index 1a00c2226d..6e0bc8d5a0 100644 --- a/newrelic-agent/src/main/java/com/newrelic/agent/service/analytics/CollectorSpanEventReservoirManager.java +++ b/newrelic-agent/src/main/java/com/newrelic/agent/service/analytics/CollectorSpanEventReservoirManager.java @@ -69,10 +69,6 @@ public HarvestResult attemptToSendReservoir(final String appName, EventSender toSend = spanReservoirsForApp.get(appName); spanReservoirsForApp.put(appName, createDistributedSamplingReservoir(appName, decidedLast)); - //todo: this was here for a retry exception. The reservoir is used again to retryAll. Not sure what to do in case of discardHarvestData - // this doens't make sense...why create a new empty reservoir and retryAll with it in th catch of a tryign to save data??? - //reservoir = createDistributedSamplingReservoir(appName, decidedLast)); - if (toSend == null || toSend.size() <= 0) { return null; } @@ -88,8 +84,7 @@ public HarvestResult attemptToSendReservoir(final String appName, EventSender Date: Tue, 23 Nov 2021 20:52:39 -0800 Subject: [PATCH 07/10] add missing parameter to refactored method --- .../javax/xml/rpc/XmlRpcPointCutTest.java | 3 +- .../test/agent/DistributedTracingTest.java | 6 +- .../agent/spans/RootSpanStatusErrorsTest.java | 8 +- .../test/agent/spans/SpanErrorsTest.java | 8 +- .../test/agent/spans/SpanIdOnErrorsTest.java | 7 +- .../test/agent/spans/SpanParentTest.java | 7 +- .../TransactionAttributesOnSpanTest.java | 3 +- .../DataCollectionConfigCrossAgentTest.java | 2 +- .../agent/DistributedTraceCrossAgentTest.java | 8 +- .../java/com/newrelic/agent/SegmentTest.java | 6 +- .../ReservoirAddingSpanEventConsumerTest.java | 2 +- .../service/SpanEventsServiceFactoryTest.java | 10 ++- ...ollectorSpanEventReservoirManagerTest.java | 85 ++++++++----------- .../analytics/SpanEventsServiceTest.java | 31 +++---- .../agent/tracers/DefaultSqlTracerTest.java | 9 +- .../agent/tracers/DefaultTracerTest.java | 19 +++-- .../agent/tracers/ExternalTracerTest.java | 5 +- .../W3CTraceContextCrossAgentTest.java | 10 ++- 18 files changed, 117 insertions(+), 112 deletions(-) diff --git a/functional_test/src/test/java/com/newrelic/agent/instrumentation/pointcuts/javax/xml/rpc/XmlRpcPointCutTest.java b/functional_test/src/test/java/com/newrelic/agent/instrumentation/pointcuts/javax/xml/rpc/XmlRpcPointCutTest.java index 29d65398e6..1e8f215513 100644 --- a/functional_test/src/test/java/com/newrelic/agent/instrumentation/pointcuts/javax/xml/rpc/XmlRpcPointCutTest.java +++ b/functional_test/src/test/java/com/newrelic/agent/instrumentation/pointcuts/javax/xml/rpc/XmlRpcPointCutTest.java @@ -30,7 +30,8 @@ public void externalTest() throws Exception { doCall(); SpanEventsService spanEventsService = ServiceFactory.getServiceManager().getSpanEventsService(); - SamplingPriorityQueue spanEventsPool = spanEventsService.getOrCreateDistributedSamplingReservoir(); + String appName = ServiceFactory.getConfigService().getDefaultAgentConfig().getApplicationName(); + SamplingPriorityQueue spanEventsPool = spanEventsService.getOrCreateDistributedSamplingReservoir(appName); assertNotNull(spanEventsPool); List spanEvents = spanEventsPool.asList(); diff --git a/functional_test/src/test/java/test/newrelic/test/agent/DistributedTracingTest.java b/functional_test/src/test/java/test/newrelic/test/agent/DistributedTracingTest.java index 3301e8a38a..5c89a25f44 100644 --- a/functional_test/src/test/java/test/newrelic/test/agent/DistributedTracingTest.java +++ b/functional_test/src/test/java/test/newrelic/test/agent/DistributedTracingTest.java @@ -51,7 +51,8 @@ public void testLateAcceptPayload() throws Exception { deepTransaction(payload); SpanEventsService spanEventsService = ServiceFactory.getServiceManager().getSpanEventsService(); - SamplingPriorityQueue spanEventsPool = spanEventsService.getOrCreateDistributedSamplingReservoir(); + String appName = ServiceFactory.getConfigService().getDefaultAgentConfig().getApplicationName(); + SamplingPriorityQueue spanEventsPool = spanEventsService.getOrCreateDistributedSamplingReservoir(appName); assertNotNull(spanEventsPool); List spanEvents = spanEventsPool.asList(); assertNotNull(spanEvents); @@ -94,7 +95,8 @@ public void dispatcherTransactionStatsFinished(TransactionData transactionData, latch.await(30, TimeUnit.SECONDS); SpanEventsService spanEventsService = ServiceFactory.getServiceManager().getSpanEventsService(); - SamplingPriorityQueue spanEventsPool = spanEventsService.getOrCreateDistributedSamplingReservoir(); + String appName = ServiceFactory.getConfigService().getDefaultAgentConfig().getApplicationName(); + SamplingPriorityQueue spanEventsPool = spanEventsService.getOrCreateDistributedSamplingReservoir(appName); assertNotNull(spanEventsPool); List spanEvents = spanEventsPool.asList(); assertNotNull(spanEvents); diff --git a/functional_test/src/test/java/test/newrelic/test/agent/spans/RootSpanStatusErrorsTest.java b/functional_test/src/test/java/test/newrelic/test/agent/spans/RootSpanStatusErrorsTest.java index 9e00bdea89..bcd2a7a5ce 100644 --- a/functional_test/src/test/java/test/newrelic/test/agent/spans/RootSpanStatusErrorsTest.java +++ b/functional_test/src/test/java/test/newrelic/test/agent/spans/RootSpanStatusErrorsTest.java @@ -24,6 +24,7 @@ import static org.junit.Assert.assertTrue; public class RootSpanStatusErrorsTest { + private String APP_NAME; private static final String CONFIG_FILE = "configs/span_events_test.yml"; private static final ClassLoader CLASS_LOADER = RootSpanStatusErrorsTest.class.getClassLoader(); @@ -33,9 +34,10 @@ public class RootSpanStatusErrorsTest { public void before() throws Exception { holder = new EnvironmentHolder(new EnvironmentHolderSettingsGenerator(CONFIG_FILE, "all_enabled_test", CLASS_LOADER)); holder.setupEnvironment(); + APP_NAME = ServiceFactory.getConfigService().getDefaultAgentConfig().getApplicationName(); ServiceFactory.getSpanEventService() - .getOrCreateDistributedSamplingReservoir() + .getOrCreateDistributedSamplingReservoir(APP_NAME) .clear(); } @@ -44,7 +46,7 @@ public void after() { holder.close(); ServiceFactory.getSpanEventService() - .getOrCreateDistributedSamplingReservoir() + .getOrCreateDistributedSamplingReservoir(APP_NAME) .clear(); } @@ -64,7 +66,7 @@ public void statusCodeShouldOnlyBeStringOnErrorClassOnRootSpan() { private void assertRootSpanAttributes(Integer expectedStatus, String errorClass) { SamplingPriorityQueue reservoir = ServiceFactory.getSpanEventService() - .getOrCreateDistributedSamplingReservoir(); + .getOrCreateDistributedSamplingReservoir(APP_NAME); assertTrue(reservoir.asList().size() > 0); List seenNames = new LinkedList<>(); for(SpanEvent event : reservoir.asList()) { diff --git a/functional_test/src/test/java/test/newrelic/test/agent/spans/SpanErrorsTest.java b/functional_test/src/test/java/test/newrelic/test/agent/spans/SpanErrorsTest.java index c40f8c2b1b..917f230ddd 100644 --- a/functional_test/src/test/java/test/newrelic/test/agent/spans/SpanErrorsTest.java +++ b/functional_test/src/test/java/test/newrelic/test/agent/spans/SpanErrorsTest.java @@ -25,6 +25,7 @@ import static org.junit.Assert.*; public class SpanErrorsTest { + private String APP_NAME; private static final String CONFIG_FILE = "configs/span_events_test.yml"; private static final ClassLoader CLASS_LOADER = SpanErrorsTest.class.getClassLoader(); @@ -34,9 +35,10 @@ public class SpanErrorsTest { public void before() throws Exception { holder = new EnvironmentHolder(new EnvironmentHolderSettingsGenerator(CONFIG_FILE, "all_enabled_test", CLASS_LOADER)); holder.setupEnvironment(); + APP_NAME = ServiceFactory.getConfigService().getDefaultAgentConfig().getApplicationName(); ServiceFactory.getSpanEventService() - .getOrCreateDistributedSamplingReservoir() + .getOrCreateDistributedSamplingReservoir(APP_NAME) .clear(); } @@ -45,7 +47,7 @@ public void after() { holder.close(); ServiceFactory.getSpanEventService() - .getOrCreateDistributedSamplingReservoir() + .getOrCreateDistributedSamplingReservoir(APP_NAME) .clear(); } @@ -130,7 +132,7 @@ private void checkSpansNoOtherAttributes(Map> spanChecks) { private void checkSpans(Map> spanChecks, List defaultChecks) { SamplingPriorityQueue reservoir = ServiceFactory.getSpanEventService() - .getOrCreateDistributedSamplingReservoir(); + .getOrCreateDistributedSamplingReservoir(APP_NAME); assertTrue(reservoir.asList().size() > 0); for (SpanEvent event : reservoir.asList()) { diff --git a/functional_test/src/test/java/test/newrelic/test/agent/spans/SpanIdOnErrorsTest.java b/functional_test/src/test/java/test/newrelic/test/agent/spans/SpanIdOnErrorsTest.java index 6960b5c36d..bd2d3cc3ed 100644 --- a/functional_test/src/test/java/test/newrelic/test/agent/spans/SpanIdOnErrorsTest.java +++ b/functional_test/src/test/java/test/newrelic/test/agent/spans/SpanIdOnErrorsTest.java @@ -29,6 +29,7 @@ import static org.junit.Assert.assertTrue; public class SpanIdOnErrorsTest { + private String APP_NAME; private static final String CONFIG_FILE = "configs/span_events_test.yml"; private static final ClassLoader CLASS_LOADER = SpanParentTest.class.getClassLoader(); @@ -38,6 +39,8 @@ public class SpanIdOnErrorsTest { public void before() throws Exception { holder = new EnvironmentHolder(new EnvironmentHolderSettingsGenerator(CONFIG_FILE, "all_enabled_test", CLASS_LOADER)); holder.setupEnvironment(); + APP_NAME = ServiceFactory.getConfigService().getDefaultAgentConfig().getApplicationName(); + cleanup(); } @@ -52,7 +55,7 @@ private void cleanup() { ServiceFactory.getRPMService().getErrorService().clearReservoir(); Transaction.clearTransaction(); ServiceFactory.getSpanEventService() - .getOrCreateDistributedSamplingReservoir() + .getOrCreateDistributedSamplingReservoir(APP_NAME) .clear(); ServiceFactory.getTransactionEventsService() .getOrCreateDistributedSamplingReservoir(ServiceFactory.getRPMService().getApplicationName()) @@ -111,7 +114,7 @@ private void matchFirstErrorToOriginatingSpan(String expectedSpanName) { private void assertMethodWhereErrorOriginatedHasThisSpanId(Object spanId, String expectedSpanName) { List seenSpanNames = new LinkedList<>(); - for(SpanEvent spanEvent : ServiceFactory.getSpanEventService().getOrCreateDistributedSamplingReservoir().asList()) { + for(SpanEvent spanEvent : ServiceFactory.getSpanEventService().getOrCreateDistributedSamplingReservoir(APP_NAME).asList()) { if (spanEvent.getGuid().equals(spanId)) { assertEquals(expectedSpanName, spanEvent.getName()); return; diff --git a/functional_test/src/test/java/test/newrelic/test/agent/spans/SpanParentTest.java b/functional_test/src/test/java/test/newrelic/test/agent/spans/SpanParentTest.java index 454c32e815..a270ef88df 100644 --- a/functional_test/src/test/java/test/newrelic/test/agent/spans/SpanParentTest.java +++ b/functional_test/src/test/java/test/newrelic/test/agent/spans/SpanParentTest.java @@ -124,7 +124,8 @@ public void testCrossProcessOnly() throws Exception { assertEquals(4, tracers2.size()); // 1 "rootTracer" (not in this list) + 2 non-external/datastore tracers + 2 external datastore tracers SpanEventsService spanEventsService = ServiceFactory.getServiceManager().getSpanEventsService(); - SamplingPriorityQueue spanEventsPool = spanEventsService.getOrCreateDistributedSamplingReservoir(); + String appName = ServiceFactory.getConfigService().getDefaultAgentConfig().getApplicationName(); + SamplingPriorityQueue spanEventsPool = spanEventsService.getOrCreateDistributedSamplingReservoir(appName); assertNotNull(spanEventsPool); List spanEvents = spanEventsPool.asList(); spanEventsPool.clear(); @@ -167,9 +168,9 @@ public void testSpanAndTransactionParenting() throws Exception { Collection tracers2 = tx2.getTracers(); assertEquals(4, tracers2.size()); // 1 "rootTracer" (not in this list) + 2 non-external/datastore tracers + 2 external datastore tracers - String appName = ServiceFactory.getConfigService().getDefaultAgentConfig().getApplicationName(); SpanEventsService spanEventsService = ServiceFactory.getServiceManager().getSpanEventsService(); - SamplingPriorityQueue spanEventsPool = spanEventsService.getOrCreateDistributedSamplingReservoir(); + String appName = ServiceFactory.getConfigService().getDefaultAgentConfig().getApplicationName(); + SamplingPriorityQueue spanEventsPool = spanEventsService.getOrCreateDistributedSamplingReservoir(appName); assertNotNull(spanEventsPool); List spanEvents = spanEventsPool.asList(); spanEventsPool.clear(); diff --git a/functional_test/src/test/java/test/newrelic/test/agent/spans/TransactionAttributesOnSpanTest.java b/functional_test/src/test/java/test/newrelic/test/agent/spans/TransactionAttributesOnSpanTest.java index 7341e33cb2..289e631a53 100644 --- a/functional_test/src/test/java/test/newrelic/test/agent/spans/TransactionAttributesOnSpanTest.java +++ b/functional_test/src/test/java/test/newrelic/test/agent/spans/TransactionAttributesOnSpanTest.java @@ -59,7 +59,8 @@ public static Collection data() { public void before() throws Exception { holder = new EnvironmentHolder(new EnvironmentHolderSettingsGenerator(CONFIG_FILE, ymlEnvironmentName, CLASS_LOADER)); holder.setupEnvironment(); - spanEventPool = ServiceFactory.getSpanEventService().getOrCreateDistributedSamplingReservoir(); + String appName = ServiceFactory.getConfigService().getDefaultAgentConfig().getApplicationName(); + spanEventPool = ServiceFactory.getSpanEventService().getOrCreateDistributedSamplingReservoir(appName); } @After diff --git a/newrelic-agent/src/test/java/com/newrelic/agent/DataCollectionConfigCrossAgentTest.java b/newrelic-agent/src/test/java/com/newrelic/agent/DataCollectionConfigCrossAgentTest.java index 30fbd95fdf..4b7748bd9e 100644 --- a/newrelic-agent/src/test/java/com/newrelic/agent/DataCollectionConfigCrossAgentTest.java +++ b/newrelic-agent/src/test/java/com/newrelic/agent/DataCollectionConfigCrossAgentTest.java @@ -269,7 +269,7 @@ private void createAndVerifySpanEvents(Long expectedCount, Long expectedEndpoint } // Verify that the correct number of events were stored in the reservoir - SamplingPriorityQueue eventQueue = spanEventsService.getOrCreateDistributedSamplingReservoir(); + SamplingPriorityQueue eventQueue = spanEventsService.getOrCreateDistributedSamplingReservoir(APP_NAME); assertNotNull(eventQueue); assertEquals(expectedCount.intValue(), eventQueue.size()); diff --git a/newrelic-agent/src/test/java/com/newrelic/agent/DistributedTraceCrossAgentTest.java b/newrelic-agent/src/test/java/com/newrelic/agent/DistributedTraceCrossAgentTest.java index 05c33c36e7..84a4c30cbd 100644 --- a/newrelic-agent/src/test/java/com/newrelic/agent/DistributedTraceCrossAgentTest.java +++ b/newrelic-agent/src/test/java/com/newrelic/agent/DistributedTraceCrossAgentTest.java @@ -77,6 +77,8 @@ public class DistributedTraceCrossAgentTest { private Instrumentation savedInstrumentation; private com.newrelic.agent.bridge.Agent savedAgent; + private final String APP_NAME = "Test"; + @Parameterized.Parameters(name = "{index}:{0}") public static Collection getParameters() throws Exception { JSONArray tests = CrossAgentInput.readJsonAndGetTests("com/newrelic/agent/cross_agent_tests/distributed_tracing/distributed_tracing.json"); @@ -108,7 +110,7 @@ public void setUp() throws Exception { ServiceFactory.setServiceManager(serviceManager); Map config = new HashMap<>(); - config.put(AgentConfigImpl.APP_NAME, "Test"); + config.put(AgentConfigImpl.APP_NAME, APP_NAME); Map dtConfig = new HashMap<>(); dtConfig.put("enabled", true); @@ -193,7 +195,7 @@ public void runTest() throws ParseException, IOException { TransactionData transactionData = new TransactionData(tx, 0); TransactionStats transactionStats = transactionData.getTransaction().getTransactionActivity().getTransactionStats(); - SamplingPriorityQueue eventPool = spanEventsService.getOrCreateDistributedSamplingReservoir(); + SamplingPriorityQueue eventPool = spanEventsService.getOrCreateDistributedSamplingReservoir(APP_NAME); Tracer rootTracer; if (webTransaction) { @@ -256,7 +258,7 @@ public void tearDown() { private void replaceConfig(boolean spanEventsEnabled) { Map config = new HashMap<>(); - config.put(AgentConfigImpl.APP_NAME, "Test"); + config.put(AgentConfigImpl.APP_NAME, APP_NAME); Map dtConfig = new HashMap<>(); dtConfig.put("enabled", true); diff --git a/newrelic-agent/src/test/java/com/newrelic/agent/SegmentTest.java b/newrelic-agent/src/test/java/com/newrelic/agent/SegmentTest.java index a7dff36e5e..c594ebdb2b 100644 --- a/newrelic-agent/src/test/java/com/newrelic/agent/SegmentTest.java +++ b/newrelic-agent/src/test/java/com/newrelic/agent/SegmentTest.java @@ -83,6 +83,8 @@ public class SegmentTest implements ExtendedTransactionListener { private static Instrumentation savedInstrumentation; private static com.newrelic.agent.bridge.Agent savedAgent; + private static final String APP_NAME = "Unit Test"; + // Wrap the ExpirationService so we can know when a segment has fully ended private static class InlineExpirationService extends ExpirationService { @@ -895,7 +897,7 @@ public void testDefaultTracedActivityName() { private static Map createConfigMap() { Map map = new HashMap<>(); - map.put(AgentConfigImpl.APP_NAME, "Unit Test"); + map.put(AgentConfigImpl.APP_NAME, APP_NAME); map.put("traced_activity_timeout", 3); map.put("token_timeout", 2); map.put(AgentConfigImpl.THREAD_CPU_TIME_ENABLED, Boolean.TRUE); @@ -1161,7 +1163,7 @@ public void dispatcherTransactionFinished(TransactionData transactionData, @Test public void testSpanParenting() { SpanEventsService spanEventService = ServiceFactory.getSpanEventService(); - SamplingPriorityQueue eventPool = spanEventService.getOrCreateDistributedSamplingReservoir(); + SamplingPriorityQueue eventPool = spanEventService.getOrCreateDistributedSamplingReservoir(APP_NAME); Transaction.clearTransaction(); Tracer rootTracer = makeTransaction(); diff --git a/newrelic-agent/src/test/java/com/newrelic/agent/service/ReservoirAddingSpanEventConsumerTest.java b/newrelic-agent/src/test/java/com/newrelic/agent/service/ReservoirAddingSpanEventConsumerTest.java index 0e217eb614..0de4627eed 100644 --- a/newrelic-agent/src/test/java/com/newrelic/agent/service/ReservoirAddingSpanEventConsumerTest.java +++ b/newrelic-agent/src/test/java/com/newrelic/agent/service/ReservoirAddingSpanEventConsumerTest.java @@ -35,7 +35,6 @@ public void setup(){ agentConfig = mock(AgentConfig.class); spanEventsConfig = mock(SpanEventsConfig.class); event = SpanEvent.builder().putAgentAttribute("foo", "burg").build(); - when(reservoirManager.getOrCreateReservoir()).thenReturn(reservoir); when(configService.getDefaultAgentConfig()).thenReturn(agentConfig); when(agentConfig.getSpanEventsConfig()).thenReturn(spanEventsConfig); } @@ -44,6 +43,7 @@ public void setup(){ public void testConfigEnabled() throws Exception { when(spanEventsConfig.isEnabled()).thenReturn(true); when(reservoirManager.getMaxSamplesStored()).thenReturn(1024); + when(reservoirManager.getOrCreateReservoir(any())).thenReturn(reservoir); ReservoirAddingSpanEventConsumer testClass = new ReservoirAddingSpanEventConsumer(reservoirManager, configService); testClass.accept(event); verify(reservoir).add(event); diff --git a/newrelic-agent/src/test/java/com/newrelic/agent/service/SpanEventsServiceFactoryTest.java b/newrelic-agent/src/test/java/com/newrelic/agent/service/SpanEventsServiceFactoryTest.java index 640a4eb139..ff577292cc 100644 --- a/newrelic-agent/src/test/java/com/newrelic/agent/service/SpanEventsServiceFactoryTest.java +++ b/newrelic-agent/src/test/java/com/newrelic/agent/service/SpanEventsServiceFactoryTest.java @@ -27,12 +27,15 @@ import org.mockito.MockitoAnnotations; import static org.junit.Assert.assertSame; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; public class SpanEventsServiceFactoryTest { + private final String APP_NAME = "fakeyMcFakeApp"; + SpanEvent event; @Mock ConfigService configService; @@ -63,15 +66,16 @@ public void setup() { when(agentConfig.getSpanEventsConfig()).thenReturn(spanEventsConfig); when(agentConfig.getInfiniteTracingConfig()).thenReturn(infiniteTracingConfig); when(reservoirManager.getMaxSamplesStored()).thenReturn(90210); - when(reservoirManager.getOrCreateReservoir()).thenReturn(reservoir); + when(reservoirManager.getOrCreateReservoir(APP_NAME)).thenReturn(reservoir); } @Test public void testBuildPicksStorageBackend_collector() throws Exception { - when(agentConfig.getApplicationName()).thenReturn("fakeyMcFakeApp"); + when(agentConfig.getApplicationName()).thenReturn(APP_NAME); when(infiniteTracingConfig.isEnabled()).thenReturn(false); when(spanEventsConfig.isEnabled()).thenReturn(true); + when(reservoirManager.getOrCreateReservoir(any())).thenReturn(reservoir); SpanEventsService service = SpanEventsServiceFactory.builder() .configService(configService) @@ -97,7 +101,7 @@ public void testBuildPicksStorageBackend_collector() throws Exception { @Test public void testBuildPicksStorageBackend_infiniteTracing() throws Exception { - when(agentConfig.getApplicationName()).thenReturn("fakeyMcFakeApp"); + when(agentConfig.getApplicationName()).thenReturn(APP_NAME); when(infiniteTracingConfig.isEnabled()).thenReturn(true); when(spanEventsConfig.isEnabled()).thenReturn(true); diff --git a/newrelic-agent/src/test/java/com/newrelic/agent/service/analytics/CollectorSpanEventReservoirManagerTest.java b/newrelic-agent/src/test/java/com/newrelic/agent/service/analytics/CollectorSpanEventReservoirManagerTest.java index 9dee17e108..d97e1fb700 100644 --- a/newrelic-agent/src/test/java/com/newrelic/agent/service/analytics/CollectorSpanEventReservoirManagerTest.java +++ b/newrelic-agent/src/test/java/com/newrelic/agent/service/analytics/CollectorSpanEventReservoirManagerTest.java @@ -17,8 +17,6 @@ import org.junit.Test; import org.mockito.Mockito; -import java.util.List; - import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; @@ -28,6 +26,8 @@ import static org.mockito.Mockito.when; public class CollectorSpanEventReservoirManagerTest { + private final String APP_NAME = "blerg"; + @Test public void maxSamplesStoredConfiguredAfterConstruction() { ConfigService mockConfigService = mock21Samples(); @@ -39,8 +39,8 @@ public void maxSamplesStoredConfiguredAfterConstruction() { public void getOrCreateReturnsSameReservoir() { ConfigService mockConfigService = mock21Samples(); CollectorSpanEventReservoirManager target = initWith25Tries(mockConfigService); - assertEquals(21, target.getOrCreateReservoir().size()); - assertTrue(target.getOrCreateReservoir().isFull()); + assertEquals(21, target.getOrCreateReservoir(APP_NAME).size()); + assertTrue(target.getOrCreateReservoir(APP_NAME).isFull()); } @Test @@ -52,16 +52,13 @@ public void attemptToSendDoesSend() { // boolean arrays can be final so that nested classes can use them final boolean[] resultFlags = new boolean[] { false }; ReservoirManager.HarvestResult harvestResult = target.attemptToSendReservoir( - "blerg", - new ReservoirManager.EventSender() { - @Override - public void sendEvents(String appName, int reservoirSize, int eventsSeen, List events) { - assertEquals("blerg", appName); - assertEquals(21, reservoirSize); - assertEquals(25, eventsSeen); - assertEquals(21, events.size()); - resultFlags[0] = true; - } + APP_NAME, + (appName, reservoirSize, eventsSeen, events) -> { + assertEquals(APP_NAME, appName); + assertEquals(21, reservoirSize); + assertEquals(25, eventsSeen); + assertEquals(21, events.size()); + resultFlags[0] = true; }, mock(Logger.class) ); @@ -78,19 +75,16 @@ public void retryOnHttpErrorWithNoDiscard() { CollectorSpanEventReservoirManager target = initWith25Tries(mockConfigService); ReservoirManager.HarvestResult harvestResult = target.attemptToSendReservoir( - "blerg", - new ReservoirManager.EventSender() { - @Override - public void sendEvents(String appName, int reservoirSize, int eventsSeen, List events) throws Exception { - throw new HttpError("don't discard", 429, 1234); - } + APP_NAME, + (appName, reservoirSize, eventsSeen, events) -> { + throw new HttpError("don't discard", 429, 1234); }, mock(Logger.class) ); assertNull(harvestResult); - assertEquals(21, target.getOrCreateReservoir().size()); - assertEquals(21, target.getOrCreateReservoir().getNumberOfTries()); + assertEquals(21, target.getOrCreateReservoir(APP_NAME).size()); + assertEquals(21, target.getOrCreateReservoir(APP_NAME).getNumberOfTries()); } @Test @@ -100,24 +94,21 @@ public void httpErrorTriggerDiscard() { CollectorSpanEventReservoirManager target = initWith25Tries(mockConfigService); ReservoirManager.HarvestResult harvestResult = target.attemptToSendReservoir( - "blerg", - new ReservoirManager.EventSender() { - @Override - public void sendEvents(String appName, int reservoirSize, int eventsSeen, List events) throws Exception { - throw new HttpError("message", 0, 0) { - @Override - public boolean discardHarvestData() { - return true; - } - }; - } + APP_NAME, + (appName, reservoirSize, eventsSeen, events) -> { + throw new HttpError("message", 0, 0) { + @Override + public boolean discardHarvestData() { + return true; + } + }; }, mock(Logger.class) ); assertNull(harvestResult); - assertEquals(0, target.getOrCreateReservoir().size()); - assertEquals(0, target.getOrCreateReservoir().getNumberOfTries()); + assertEquals(0, target.getOrCreateReservoir(APP_NAME).size()); + assertEquals(0, target.getOrCreateReservoir(APP_NAME).getNumberOfTries()); } @Test @@ -127,19 +118,16 @@ public void exceptionTriggerDiscard() { CollectorSpanEventReservoirManager target = initWith25Tries(mockConfigService); ReservoirManager.HarvestResult harvestResult = target.attemptToSendReservoir( - "blerg", - new ReservoirManager.EventSender() { - @Override - public void sendEvents(String appName, int reservoirSize, int eventsSeen, List events) { - throw new RuntimeException("~~ oops ~~"); - } + APP_NAME, + (appName, reservoirSize, eventsSeen, events) -> { + throw new RuntimeException("~~ oops ~~"); }, mock(Logger.class) ); assertNull(harvestResult); - assertEquals(0, target.getOrCreateReservoir().size()); - assertEquals(0, target.getOrCreateReservoir().getNumberOfTries()); + assertEquals(0, target.getOrCreateReservoir(APP_NAME).size()); + assertEquals(0, target.getOrCreateReservoir(APP_NAME).getNumberOfTries()); } @Test @@ -150,13 +138,8 @@ public void doesNotSendWithEmptyReservoir() { final boolean[] wasSent = new boolean[] { false }; ReservoirManager.HarvestResult harvestResult = target.attemptToSendReservoir( - "blerg", - new ReservoirManager.EventSender() { - @Override - public void sendEvents(String appName, int reservoirSize, int eventsSeen, List events) { - wasSent[0] = true; - } - }, + APP_NAME, + (appName, reservoirSize, eventsSeen, events) -> wasSent[0] = true, mock(Logger.class) ); @@ -179,7 +162,7 @@ public ConfigService mock21Samples() { public CollectorSpanEventReservoirManager initWith25Tries(ConfigService mockConfigService) { CollectorSpanEventReservoirManager target = new CollectorSpanEventReservoirManager(mockConfigService); for (int i = 0; i < 25; i++) { - target.getOrCreateReservoir().add(SpanEvent.builder().priority(i).build()); + target.getOrCreateReservoir(APP_NAME).add(SpanEvent.builder().priority(i).build()); } return target; } diff --git a/newrelic-agent/src/test/java/com/newrelic/agent/service/analytics/SpanEventsServiceTest.java b/newrelic-agent/src/test/java/com/newrelic/agent/service/analytics/SpanEventsServiceTest.java index ce3ce19642..42b7f9fb56 100644 --- a/newrelic-agent/src/test/java/com/newrelic/agent/service/analytics/SpanEventsServiceTest.java +++ b/newrelic-agent/src/test/java/com/newrelic/agent/service/analytics/SpanEventsServiceTest.java @@ -38,7 +38,7 @@ public class SpanEventsServiceTest { - private final String appName = "Unit Test"; + private final String APP_NAME = "Unit Test"; MockServiceManager serviceManager; @Mock @@ -50,7 +50,7 @@ public void before() throws Exception { serviceManager = new MockServiceManager(); Map localSettings = new HashMap<>(); - localSettings.put(AgentConfigImpl.APP_NAME, appName); + localSettings.put(AgentConfigImpl.APP_NAME, APP_NAME); localSettings.put("distributed_tracing", Collections.singletonMap("enabled", true)); localSettings.put("span_events", Collections.singletonMap("collect_span_events", true)); when(spanEventCreationDecider.shouldCreateSpans(any(TransactionData.class))).thenReturn(true); @@ -63,12 +63,7 @@ public void before() throws Exception { serviceManager.setTransactionService(new TransactionService()); serviceManager.setThreadService(new ThreadService()); final MockSpanEventReservoirManager reservoirManager = new MockSpanEventReservoirManager(configService); - Consumer backendConsumer = new Consumer() { - @Override - public void accept(SpanEvent spanEvent) { - reservoirManager.getOrCreateReservoir().add(spanEvent); - } - }; + Consumer backendConsumer = spanEvent -> reservoirManager.getOrCreateReservoir(APP_NAME).add(spanEvent); SpanErrorBuilder defaultSpanErrorBuilder = new SpanErrorBuilder( new ErrorAnalyzerImpl(agentConfig.getErrorCollectorConfig()), @@ -102,7 +97,7 @@ public void after() { @Test public void testSpanEvent() { TransactionData transactionData = new TransactionDataTestBuilder( - appName, + APP_NAME, ServiceFactory.getConfigService().getDefaultAgentConfig(), new MockDispatcherTracer()) .setTracers(Collections.emptyList()) @@ -115,7 +110,7 @@ public void testSpanEvent() { SpanEventsServiceImpl spanEventsService = (SpanEventsServiceImpl) ServiceFactory.getSpanEventService(); spanEventsService.dispatcherTransactionFinished(transactionData, new TransactionStats()); - SamplingPriorityQueue reservoir = spanEventsService.getOrCreateDistributedSamplingReservoir(); + SamplingPriorityQueue reservoir = spanEventsService.getOrCreateDistributedSamplingReservoir(APP_NAME); assertEquals(1, reservoir.getSampled()); } @@ -125,7 +120,7 @@ public void testMaxSamplesStored() { spanEventsService.setMaxSamplesStored(0); - final SpanEvent event = new SpanEventFactory(appName) + final SpanEvent event = new SpanEventFactory(APP_NAME) .setCategory(SpanCategory.generic) .setDecider(true) .setPriority(1.23f) @@ -137,7 +132,7 @@ public void testMaxSamplesStored() { .build(); spanEventsService.storeEvent(event); - SamplingPriorityQueue reservoir = spanEventsService.getOrCreateDistributedSamplingReservoir(); + SamplingPriorityQueue reservoir = spanEventsService.getOrCreateDistributedSamplingReservoir(APP_NAME); assertEquals(0, reservoir.size()); spanEventsService.setMaxSamplesStored(2); @@ -148,7 +143,7 @@ public void testMaxSamplesStored() { spanEventsService.storeEvent(event); spanEventsService.storeEvent(event); - reservoir = spanEventsService.getOrCreateDistributedSamplingReservoir(); + reservoir = spanEventsService.getOrCreateDistributedSamplingReservoir(APP_NAME); assertEquals(2, reservoir.size()); spanEventsService.setMaxSamplesStored(13); @@ -157,14 +152,14 @@ public void testMaxSamplesStored() { spanEventsService.storeEvent(event); } - reservoir = spanEventsService.getOrCreateDistributedSamplingReservoir(); + reservoir = spanEventsService.getOrCreateDistributedSamplingReservoir(APP_NAME); assertEquals(13, reservoir.size()); } @Test public void testDoesNotCreateSpansIfToldNotTo() { TransactionData transactionData = new TransactionDataTestBuilder( - appName, + APP_NAME, ServiceFactory.getConfigService().getDefaultAgentConfig(), new MockDispatcherTracer()) .setTracers(Collections.emptyList()) @@ -179,7 +174,7 @@ public void testDoesNotCreateSpansIfToldNotTo() { SpanEventsServiceImpl spanEventsService = (SpanEventsServiceImpl) ServiceFactory.getSpanEventService(); spanEventsService.dispatcherTransactionFinished(transactionData, null); - SamplingPriorityQueue reservoir = spanEventsService.getOrCreateDistributedSamplingReservoir(); + SamplingPriorityQueue reservoir = spanEventsService.getOrCreateDistributedSamplingReservoir(APP_NAME); assertEquals(0, reservoir.getSampled()); } @@ -187,13 +182,13 @@ public void testDoesNotCreateSpansIfToldNotTo() { public void spanEventsServiceMaxSamplesStoredRespectsServerSide() { //given MockRPMService mockRPMService = new MockRPMService(); - mockRPMService.setApplicationName(appName); + mockRPMService.setApplicationName(APP_NAME); RPMServiceManager mockRPMServiceManager = mock(RPMServiceManager.class); when(mockRPMServiceManager.getRPMService()).thenReturn(mockRPMService); serviceManager.setRPMServiceManager(mockRPMServiceManager); serviceManager.setHarvestService(new HarvestServiceImpl()); SpanEventsService spanEventsService = serviceManager.getSpanEventsService(); - spanEventsService.addHarvestableToService(appName); + spanEventsService.addHarvestableToService(APP_NAME); HarvestServiceImpl harvestService = (HarvestServiceImpl) serviceManager.getHarvestService(); Map connectionInfo = new HashMap<>(); diff --git a/newrelic-agent/src/test/java/com/newrelic/agent/tracers/DefaultSqlTracerTest.java b/newrelic-agent/src/test/java/com/newrelic/agent/tracers/DefaultSqlTracerTest.java index deaff33a05..538f8bae2c 100644 --- a/newrelic-agent/src/test/java/com/newrelic/agent/tracers/DefaultSqlTracerTest.java +++ b/newrelic-agent/src/test/java/com/newrelic/agent/tracers/DefaultSqlTracerTest.java @@ -52,6 +52,7 @@ public class DefaultSqlTracerTest { + private String APP_NAME; private DefaultDatabaseStatementParser statementParser; @AfterClass @@ -66,8 +67,8 @@ public static void afterClass() throws Exception { public void before() throws Exception { String configPath = getFullPath("/com/newrelic/agent/config/span_events.yml"); System.setProperty("newrelic.config.file", configPath); - MockCoreService.getMockAgentAndBootstrapTheServiceManager(); + APP_NAME = ServiceFactory.getConfigService().getDefaultAgentConfig().getApplicationName(); AgentHelper.clearMetrics(); statementParser = new DefaultDatabaseStatementParser(); @@ -618,7 +619,7 @@ public void testSpanEventDatastore() throws SQLException { SpanEventsService spanEventService = ServiceFactory.getSpanEventService(); ((SpanEventsServiceImpl) spanEventService).dispatcherTransactionFinished(new TransactionData(tracer.getTransaction(), 1024), new TransactionStats()); - SamplingPriorityQueue eventPool = spanEventService.getOrCreateDistributedSamplingReservoir(); + SamplingPriorityQueue eventPool = spanEventService.getOrCreateDistributedSamplingReservoir(APP_NAME); List spanEvents = eventPool.asList(); assertNotNull(spanEvents); assertEquals(1, spanEvents.size()); @@ -652,7 +653,7 @@ public void testSpanEventDatastoreTruncation() throws SQLException { SpanEventsService spanEventService = ServiceFactory.getSpanEventService(); ((SpanEventsServiceImpl) spanEventService).dispatcherTransactionFinished(new TransactionData(tracer.getTransaction(), 1024), new TransactionStats()); - SamplingPriorityQueue eventPool = spanEventService.getOrCreateDistributedSamplingReservoir(); + SamplingPriorityQueue eventPool = spanEventService.getOrCreateDistributedSamplingReservoir(APP_NAME); List spanEvents = eventPool.asList(); assertNotNull(spanEvents); assertEquals(1, spanEvents.size()); @@ -687,7 +688,7 @@ public void testSpanEventDatastoreTruncationAtExactLimit() throws SQLException { SpanEventsService spanEventService = ServiceFactory.getSpanEventService(); ((SpanEventsServiceImpl) spanEventService).dispatcherTransactionFinished(new TransactionData(tracer.getTransaction(), 1024), new TransactionStats()); - SamplingPriorityQueue eventPool = spanEventService.getOrCreateDistributedSamplingReservoir(); + SamplingPriorityQueue eventPool = spanEventService.getOrCreateDistributedSamplingReservoir(APP_NAME); List spanEvents = eventPool.asList(); assertNotNull(spanEvents); assertEquals(1, spanEvents.size()); diff --git a/newrelic-agent/src/test/java/com/newrelic/agent/tracers/DefaultTracerTest.java b/newrelic-agent/src/test/java/com/newrelic/agent/tracers/DefaultTracerTest.java index 2717e83740..9af1c15ce6 100644 --- a/newrelic-agent/src/test/java/com/newrelic/agent/tracers/DefaultTracerTest.java +++ b/newrelic-agent/src/test/java/com/newrelic/agent/tracers/DefaultTracerTest.java @@ -85,6 +85,8 @@ public class DefaultTracerTest { + private String APP_NAME; + @BeforeClass public static void beforeClass() throws Exception { String configPath = getFullPath("/com/newrelic/agent/config/span_events.yml"); @@ -104,7 +106,8 @@ public static void afterClass() throws Exception { @Before public void before() throws Exception { SpanEventsService spanEventService = ServiceFactory.getSpanEventService(); - SamplingPriorityQueue eventPool = spanEventService.getOrCreateDistributedSamplingReservoir(); + APP_NAME = ServiceFactory.getConfigService().getDefaultAgentConfig().getApplicationName(); + SamplingPriorityQueue eventPool = spanEventService.getOrCreateDistributedSamplingReservoir(APP_NAME); eventPool.clear(); } @@ -575,7 +578,7 @@ public void testSpanEvent() { SpanEventsService spanEventService = ServiceFactory.getSpanEventService(); ((SpanEventsServiceImpl) spanEventService).dispatcherTransactionFinished(new TransactionData(tracer.getTransaction(), 1024), new TransactionStats()); - SamplingPriorityQueue eventPool = spanEventService.getOrCreateDistributedSamplingReservoir(); + SamplingPriorityQueue eventPool = spanEventService.getOrCreateDistributedSamplingReservoir(APP_NAME); List spanEvents = eventPool.asList(); assertNotNull(spanEvents); assertEquals(1, spanEvents.size()); @@ -604,7 +607,7 @@ public void testSpanEventHttp() { SpanEventsService spanEventService = ServiceFactory.getSpanEventService(); ((SpanEventsServiceImpl) spanEventService).dispatcherTransactionFinished(new TransactionData(tracer.getTransaction(), 1024), new TransactionStats()); - SamplingPriorityQueue eventPool = spanEventService.getOrCreateDistributedSamplingReservoir(); + SamplingPriorityQueue eventPool = spanEventService.getOrCreateDistributedSamplingReservoir(APP_NAME); List spanEvents = eventPool.asList(); assertNotNull(spanEvents); assertEquals(1, spanEvents.size()); @@ -633,7 +636,7 @@ public void testSpanEventDatastore() { SpanEventsService spanEventService = ServiceFactory.getSpanEventService(); ((SpanEventsServiceImpl) spanEventService).dispatcherTransactionFinished(new TransactionData(tracer.getTransaction(), 1024), new TransactionStats()); - SamplingPriorityQueue eventPool = spanEventService.getOrCreateDistributedSamplingReservoir(); + SamplingPriorityQueue eventPool = spanEventService.getOrCreateDistributedSamplingReservoir(APP_NAME); List spanEvents = eventPool.asList(); assertNotNull(spanEvents); assertEquals(1, spanEvents.size()); @@ -692,7 +695,7 @@ public void testMultiTransactionSpanEvents() { ((SpanEventsServiceImpl) spanEventService).dispatcherTransactionFinished(new TransactionData(thirdTracer.getTransaction(), 1024), new TransactionStats()); ((SpanEventsServiceImpl) spanEventService).dispatcherTransactionFinished(new TransactionData(fourthTracer.getTransaction(), 1024), new TransactionStats()); - SamplingPriorityQueue eventPool = spanEventService.getOrCreateDistributedSamplingReservoir(); + SamplingPriorityQueue eventPool = spanEventService.getOrCreateDistributedSamplingReservoir(APP_NAME); List spanEvents = eventPool.asList(); assertNotNull(spanEvents); assertEquals(4, spanEvents.size()); @@ -743,7 +746,7 @@ public void testParent() { SpanEventsService spanEventService = ServiceFactory.getSpanEventService(); ((SpanEventsServiceImpl) spanEventService).dispatcherTransactionFinished(new TransactionData(tracer.getTransaction(), 1024), new TransactionStats()); - SamplingPriorityQueue eventPool = spanEventService.getOrCreateDistributedSamplingReservoir(); + SamplingPriorityQueue eventPool = spanEventService.getOrCreateDistributedSamplingReservoir(APP_NAME); List spanEvents = eventPool.asList(); assertNotNull(spanEvents); assertEquals(4, spanEvents.size()); @@ -861,7 +864,7 @@ public void testTransactionABParenting() { final TransactionData tdB = new TransactionData(txB, 1024); ((SpanEventsServiceImpl) spanEventService).dispatcherTransactionFinished(tdB, new TransactionStats()); - SamplingPriorityQueue eventPool = spanEventService.getOrCreateDistributedSamplingReservoir(); + SamplingPriorityQueue eventPool = spanEventService.getOrCreateDistributedSamplingReservoir(APP_NAME); List spanEvents = eventPool.asList(); assertEquals(5, spanEvents.size()); @@ -930,7 +933,7 @@ public void testSpanParentingEvent() { SpanEventsService spanEventService = ServiceFactory.getSpanEventService(); ((SpanEventsServiceImpl) spanEventService).dispatcherTransactionFinished(new TransactionData(tracer.getTransaction(), 1024), new TransactionStats()); - SamplingPriorityQueue eventPool = spanEventService.getOrCreateDistributedSamplingReservoir(); + SamplingPriorityQueue eventPool = spanEventService.getOrCreateDistributedSamplingReservoir(APP_NAME); List spanEvents = eventPool.asList(); assertNotNull(spanEvents); assertEquals(1, spanEvents.size()); diff --git a/newrelic-agent/src/test/java/com/newrelic/agent/tracers/ExternalTracerTest.java b/newrelic-agent/src/test/java/com/newrelic/agent/tracers/ExternalTracerTest.java index 631aa17c4c..a244cfd5d4 100644 --- a/newrelic-agent/src/test/java/com/newrelic/agent/tracers/ExternalTracerTest.java +++ b/newrelic-agent/src/test/java/com/newrelic/agent/tracers/ExternalTracerTest.java @@ -10,6 +10,7 @@ import com.newrelic.agent.MockCoreService; import com.newrelic.agent.Transaction; import com.newrelic.agent.TransactionActivity; +import com.newrelic.agent.config.AgentConfigFactory; import com.newrelic.agent.config.TransactionTracerConfig; import com.newrelic.agent.database.SqlObfuscator; import com.newrelic.agent.interfaces.SamplingPriorityQueue; @@ -42,10 +43,10 @@ public void after() throws Exception { public void before(String ymlPath) throws Exception { String configPath = getFullPath(ymlPath); System.setProperty("newrelic.config.file", configPath); - MockCoreService.getMockAgentAndBootstrapTheServiceManager(); SpanEventsService spanEventService = ServiceFactory.getSpanEventService(); - SamplingPriorityQueue eventPool = spanEventService.getOrCreateDistributedSamplingReservoir(); + String appName = ServiceFactory.getConfigService().getDefaultAgentConfig().getApplicationName(); + SamplingPriorityQueue eventPool = spanEventService.getOrCreateDistributedSamplingReservoir(appName); eventPool.clear(); } diff --git a/newrelic-agent/src/test/java/com/newrelic/agent/tracing/W3CTraceContextCrossAgentTest.java b/newrelic-agent/src/test/java/com/newrelic/agent/tracing/W3CTraceContextCrossAgentTest.java index 5ce35dc866..0f604fb999 100644 --- a/newrelic-agent/src/test/java/com/newrelic/agent/tracing/W3CTraceContextCrossAgentTest.java +++ b/newrelic-agent/src/test/java/com/newrelic/agent/tracing/W3CTraceContextCrossAgentTest.java @@ -66,6 +66,8 @@ public class W3CTraceContextCrossAgentTest { private SpanEventsService spanEventService; + private final String APP_NAME = "Test"; + @Parameterized.Parameter(0) public String testName; @@ -96,7 +98,7 @@ public void setup() throws Exception { ServiceFactory.setServiceManager(serviceManager); Map config = Maps.newHashMap(); - config.put(AgentConfigImpl.APP_NAME, "Test"); + config.put(AgentConfigImpl.APP_NAME, APP_NAME); Map dtConfig = Maps.newHashMap(); dtConfig.put("enabled", true); @@ -207,7 +209,7 @@ public void testTraceContext() throws Exception { TransactionData transactionData = new TransactionData(tx, 0); TransactionStats transactionStats = transactionData.getTransaction().getTransactionActivity().getTransactionStats(); - eventPool = spanEventService.getOrCreateDistributedSamplingReservoir(); + eventPool = spanEventService.getOrCreateDistributedSamplingReservoir(APP_NAME); List parents = Lists.newArrayList(); List states = Lists.newArrayList(); @@ -284,7 +286,7 @@ public void testTraceContext() throws Exception { TransactionEvent transactionEvent = serviceManager.getTransactionEventsService().createEvent(transactionData, transactionStats, "wat"); JSONObject txnEvents = serializeAndParseEvents(transactionEvent); - StatsEngine statsEngine = statsService.getStatsEngineForHarvest("Test"); + StatsEngine statsEngine = statsService.getStatsEngineForHarvest(APP_NAME); assertExpectedMetrics(expectedMetrics, statsEngine); for (Object event : targetEvents) { @@ -300,7 +302,7 @@ public void testTraceContext() throws Exception { private void replaceConfig(boolean spanEventsEnabled) { Map config = Maps.newHashMap(); - config.put(AgentConfigImpl.APP_NAME, "Test"); + config.put(AgentConfigImpl.APP_NAME, APP_NAME); Map dtConfig = Maps.newHashMap(); dtConfig.put("enabled", true); From 472eee2336b185a0d602f576d2b8017e2176c65d Mon Sep 17 00:00:00 2001 From: xi xia Date: Tue, 23 Nov 2021 20:55:20 -0800 Subject: [PATCH 08/10] update mock for spans and auto app names --- .../agent/MockSpanEventReservoirManager.java | 22 ++++++++++++------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/newrelic-agent/src/test/java/com/newrelic/agent/MockSpanEventReservoirManager.java b/newrelic-agent/src/test/java/com/newrelic/agent/MockSpanEventReservoirManager.java index 1e5567bc58..00c05d2567 100644 --- a/newrelic-agent/src/test/java/com/newrelic/agent/MockSpanEventReservoirManager.java +++ b/newrelic-agent/src/test/java/com/newrelic/agent/MockSpanEventReservoirManager.java @@ -17,10 +17,11 @@ import com.newrelic.api.agent.Logger; import java.util.Comparator; +import java.util.concurrent.ConcurrentHashMap; public class MockSpanEventReservoirManager implements ReservoirManager { private final ConfigService configService; - private SamplingPriorityQueue reservoir; + private ConcurrentHashMap> spanReservoirsForApp = new ConcurrentHashMap<>(); private volatile int maxSamplesStored; public MockSpanEventReservoirManager(ConfigService configService) { @@ -29,15 +30,18 @@ public MockSpanEventReservoirManager(ConfigService configService) { } @Override - public SamplingPriorityQueue getOrCreateReservoir() { + public SamplingPriorityQueue getOrCreateReservoir(String appName) { + SamplingPriorityQueue reservoir = spanReservoirsForApp.get(appName); if (reservoir == null) { - reservoir = createDistributedSamplingReservoir(0); + reservoir = spanReservoirsForApp.putIfAbsent(appName, createDistributedSamplingReservoir(appName, 0)); + if (reservoir == null) { + reservoir = spanReservoirsForApp.get(appName); + } } return reservoir; } - private SamplingPriorityQueue createDistributedSamplingReservoir(int decidedLast) { - String appName = configService.getDefaultAgentConfig().getApplicationName(); + private SamplingPriorityQueue createDistributedSamplingReservoir(String appName, int decidedLast) { SpanEventsConfig spanEventsConfig = configService.getDefaultAgentConfig().getSpanEventsConfig(); int target = spanEventsConfig.getTargetSamplesStored(); return new DistributedSamplingPriorityQueue<>(appName, "Span Event Service", maxSamplesStored, decidedLast, target, SPAN_EVENT_COMPARATOR); @@ -46,7 +50,7 @@ private SamplingPriorityQueue createDistributedSamplingReservoir(int @Override public void clearReservoir() { - getOrCreateReservoir().clear(); + spanReservoirsForApp.forEach((appName, reservoir) -> reservoir.clear() ); } @Override @@ -61,8 +65,10 @@ public int getMaxSamplesStored() { @Override public void setMaxSamplesStored(int newMax) { - this.maxSamplesStored = newMax; - this.reservoir = createDistributedSamplingReservoir(0); + maxSamplesStored = newMax; + ConcurrentHashMap> newMaxSpanReservoirs = new ConcurrentHashMap<>(); + spanReservoirsForApp.forEach((appName,reservoir ) -> newMaxSpanReservoirs.putIfAbsent(appName, createDistributedSamplingReservoir(appName, 0))); + spanReservoirsForApp = newMaxSpanReservoirs; } // This is where you can add secondary sorting for Span Events From 5b47e615ce7920db550d8c01eb7703267e85f01a Mon Sep 17 00:00:00 2001 From: xi xia Date: Tue, 23 Nov 2021 20:59:40 -0800 Subject: [PATCH 09/10] clear reservoirs --- .../service/analytics/CollectorSpanEventReservoirManager.java | 2 +- .../java/com/newrelic/agent/MockSpanEventReservoirManager.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/newrelic-agent/src/main/java/com/newrelic/agent/service/analytics/CollectorSpanEventReservoirManager.java b/newrelic-agent/src/main/java/com/newrelic/agent/service/analytics/CollectorSpanEventReservoirManager.java index 6e0bc8d5a0..48d796f163 100644 --- a/newrelic-agent/src/main/java/com/newrelic/agent/service/analytics/CollectorSpanEventReservoirManager.java +++ b/newrelic-agent/src/main/java/com/newrelic/agent/service/analytics/CollectorSpanEventReservoirManager.java @@ -52,7 +52,7 @@ private SamplingPriorityQueue createDistributedSamplingReservoir(Stri @Override public void clearReservoir() { - spanReservoirsForApp.forEach((appName, reservoir) -> reservoir.clear() ); + spanReservoirsForApp.clear(); } @Override diff --git a/newrelic-agent/src/test/java/com/newrelic/agent/MockSpanEventReservoirManager.java b/newrelic-agent/src/test/java/com/newrelic/agent/MockSpanEventReservoirManager.java index 00c05d2567..6fce728051 100644 --- a/newrelic-agent/src/test/java/com/newrelic/agent/MockSpanEventReservoirManager.java +++ b/newrelic-agent/src/test/java/com/newrelic/agent/MockSpanEventReservoirManager.java @@ -50,7 +50,7 @@ private SamplingPriorityQueue createDistributedSamplingReservoir(Stri @Override public void clearReservoir() { - spanReservoirsForApp.forEach((appName, reservoir) -> reservoir.clear() ); + spanReservoirsForApp.clear(); } @Override From 62093c1ed90188b901271d63371808a1e1179653 Mon Sep 17 00:00:00 2001 From: xi xia Date: Mon, 29 Nov 2021 14:07:28 -0800 Subject: [PATCH 10/10] remove comment about only one harvestable --- .../agent/service/analytics/SpanEventsServiceImpl.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/newrelic-agent/src/main/java/com/newrelic/agent/service/analytics/SpanEventsServiceImpl.java b/newrelic-agent/src/main/java/com/newrelic/agent/service/analytics/SpanEventsServiceImpl.java index 53813e4700..4d24ea2ab4 100644 --- a/newrelic-agent/src/main/java/com/newrelic/agent/service/analytics/SpanEventsServiceImpl.java +++ b/newrelic-agent/src/main/java/com/newrelic/agent/service/analytics/SpanEventsServiceImpl.java @@ -218,9 +218,6 @@ public void clearReservoir() { reservoirManager.clearReservoir(); } - /** - * There is only one event reservoir for Distributed Tracing so there only needs to be one harvestable for it. - */ @Override public void addHarvestableToService(String appName) { Harvestable harvestable = new SpanEventHarvestableImpl(this, appName);