From 369b4a857f411fc09aa4b6a1efffd8213dba07c6 Mon Sep 17 00:00:00 2001 From: Martijn Laarman Date: Wed, 11 Sep 2024 09:57:50 +0200 Subject: [PATCH] Ensure isEnabled = false won't start worker loop (#2436) Inside PayloadSenderV2, we also now early exit when events get queued. Removed early exit from constructor, allow readonly fields to be initialized so that when we start adding nullable annotations not all of them have to be nullable --- src/Elastic.Apm/Report/PayloadSenderV2.cs | 27 +++++++++++++++++------ 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/src/Elastic.Apm/Report/PayloadSenderV2.cs b/src/Elastic.Apm/Report/PayloadSenderV2.cs index 1c29bfe9b..5898fa340 100644 --- a/src/Elastic.Apm/Report/PayloadSenderV2.cs +++ b/src/Elastic.Apm/Report/PayloadSenderV2.cs @@ -58,6 +58,7 @@ internal class PayloadSenderV2 : BackendCommComponentBase, IPayloadSender, IPayl private readonly ElasticVersion _brokenActivationMethodVersion; private readonly string _cachedActivationMethod; + private readonly bool _isEnabled; public PayloadSenderV2( IApmLogger logger, @@ -73,14 +74,14 @@ public PayloadSenderV2( ) : base(isEnabled, logger, ThisClassName, service, configuration, httpMessageHandler) { - if (!isEnabled) - return; - _logger = logger?.Scoped(ThisClassName + (dbgName == null ? "" : $" (dbgName: `{dbgName}')")); + _isEnabled = isEnabled; + if (!_isEnabled) + _logger?.Debug()?.Log($"{nameof(PayloadSenderV2)} is not enabled, work loop won't be started."); + _payloadItemSerializer = new PayloadItemSerializer(); _configuration = configuration; _brokenActivationMethodVersion = new ElasticVersion(8, 7, 0); - _intakeV2EventsAbsoluteUrl = BackendCommUtils.ApmServerEndpoints.BuildIntakeV2EventsAbsoluteUrl(configuration.ServerUrl); System = system; @@ -88,12 +89,15 @@ public PayloadSenderV2( _cloudMetadataProviderCollection = new CloudMetadataProviderCollection(configuration.CloudProvider, _logger, environmentVariables); _apmServerInfo = apmServerInfo ?? new ApmServerInfo(); _serverInfoCallback = serverInfoCallback; + var process = ProcessInformation.Create(); _metadata = new Metadata { Service = service, System = System, Process = process }; foreach (var globalLabelKeyValue in configuration.GlobalLabels) _metadata.Labels.Add(globalLabelKeyValue.Key, globalLabelKeyValue.Value); _cachedActivationMethod = _metadata.Service?.Agent.ActivationMethod; - ResetActivationMethodIfKnownBrokenApmServer(); + + if (_isEnabled) + ResetActivationMethodIfKnownBrokenApmServer(); if (configuration.MaxQueueEventCount < configuration.MaxBatchEventCount) { @@ -123,7 +127,9 @@ public PayloadSenderV2( _eventQueue = new BatchBlock(configuration.MaxBatchEventCount); SetUpFilters(TransactionFilters, SpanFilters, ErrorFilters, apmServerInfo, logger); - StartWorkLoop(); + + if (_isEnabled) + StartWorkLoop(); } internal static void SetUpFilters( @@ -175,6 +181,9 @@ protected override void Dispose(bool disposing) internal async Task EnqueueEventInternal(object eventObj, string dbgEventKind) { + if (!_isEnabled) + return true; + // Enforce _maxQueueEventCount manually instead of using BatchBlock's BoundedCapacity // because of the issue of Post returning false when TriggerBatch is in progress. For more details see // https://stackoverflow.com/questions/35626955/unexpected-behaviour-tpl-dataflow-batchblock-rejects-items-while-triggerbatch @@ -217,8 +226,12 @@ internal async Task EnqueueEventInternal(object eventObj, string dbgEventK return true; } - internal void EnqueueEvent(object eventObj, string dbgEventKind) => + internal void EnqueueEvent(object eventObj, string dbgEventKind) + { + if (!_isEnabled) + return; Task.Run(async () => await EnqueueEventInternal(eventObj, dbgEventKind)); + } /// /// Runs on the background thread dedicated to sending data to APM Server. It's ok to block this thread.