With logger attached, the problem becomes clear, an unhandled NullReferenceException on constructor of PayloadSenderV2:
at Elastic.Apm.Report.PayloadSenderV2..ctor(IApmLogger logger, IConfiguration configuration, Service service, System system, IApmServerInfo apmServerInfo, HttpMessageHandler httpMessageHandler, String dbgName, Boolean isEnabled, IEnvironmentVariables environmentVariables, Action`2 serverInfoCallback)
at Elastic.Apm.AgentComponents..ctor(IApmLogger logger, IConfigurationReader configurationReader, IPayloadSender payloadSender, IMetricsCollector metricsCollector, ICurrentExecutionSegmentsContainer currentExecutionSegmentsContainer, ICentralConfigurationFetcher centralConfigurationFetcher, IApmServerInfo apmServerInfo, BreakdownMetricsProvider breakdownMetricsProvider)
The root cause is the following code:
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();
GlobalLabels
is an undocumented entry in IConfigurationReader, and there is no clue whether it is nullable or not (the Elastic APM package does not yet use the new checks to avoid NullReferenceExceptions such as by
After changing the custom class implementing IConfigurationReader to use:
[NSJ.JsonProperty("GlobalLabels")]
[STJ.JsonPropertyName("GlobalLabels")]
[ConfigurationKeyName("GlobalLabels")]
public IReadOnlyDictionary<string, string> GlobalLabels { get; set; } = new Dictionary<string, string>();
the specific exception does not occur.
Take aways
- Always add a logger, possibly with a crash on an error. The initialization of
AgentComponents
violates the Fail-Fast principle behind Ada.
- I was unable to find a sample implementation of IConfigurationReader and IApmLogger. Take your time to craft one nonetheless.
The maintainer might want to consider adding an if
to the foreach
, or using the new language features to avoid this type of error.