Skip to content

Commit c691a0e

Browse files
committed
Refactor DynamicConfigurationManager to make it testable
1 parent e9022c3 commit c691a0e

File tree

2 files changed

+61
-35
lines changed

2 files changed

+61
-35
lines changed

tracer/src/Datadog.Trace/Configuration/DynamicConfigurationManager.cs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -66,20 +66,20 @@ public void Dispose()
6666
}
6767
}
6868

69-
internal static void OnlyForTests_ApplyConfiguration(IConfigurationSource dynamicConfig)
69+
internal static void OnlyForTests_ApplyConfiguration(IConfigurationSource dynamicConfig, TracerSettings tracerSettings)
7070
{
71-
OnConfigurationChanged(dynamicConfig);
71+
OnConfigurationChanged(dynamicConfig, tracerSettings);
7272
}
7373

74-
private static void OnConfigurationChanged(IConfigurationSource dynamicConfig)
74+
private static void OnConfigurationChanged(IConfigurationSource dynamicConfig, TracerSettings tracerSettings)
7575
{
7676
var manualConfig = GlobalConfigurationSource.ManualConfigurationSource;
7777

7878
// We save this immediately, even if there's no manifest changes in the final settings
7979
// so that it can be picked up by other configuration updaters, e.g. config in code
8080
GlobalConfigurationSource.UpdateDynamicConfigConfigurationSource(dynamicConfig);
8181

82-
var wasUpdated = Tracer.Instance.Settings.Manager.UpdateSettings(dynamicConfig, manualConfig, TelemetryFactory.Config);
82+
var wasUpdated = tracerSettings.Manager.UpdateSettings(dynamicConfig, manualConfig, TelemetryFactory.Config);
8383
if (wasUpdated)
8484
{
8585
Log.Information("Setting updates made via configuration in code were applied");
@@ -189,7 +189,8 @@ private ApplyDetails[] ConfigurationUpdated(
189189
private void ApplyMergedConfiguration(List<RemoteConfiguration> remoteConfigurations)
190190
{
191191
// Get current service/environment for filtering
192-
var currentSettings = Tracer.Instance.CurrentTraceSettings.Settings;
192+
var tracer = Tracer.Instance;
193+
var currentSettings = tracer.CurrentTraceSettings.Settings;
193194

194195
var mergedConfigJToken = ApmTracingConfigMerger.MergeConfigurations(
195196
remoteConfigurations,
@@ -198,7 +199,7 @@ private void ApplyMergedConfiguration(List<RemoteConfiguration> remoteConfigurat
198199

199200
var configurationSource = new DynamicConfigConfigurationSource(mergedConfigJToken, ConfigurationOrigins.RemoteConfig);
200201

201-
OnConfigurationChanged(configurationSource);
202+
OnConfigurationChanged(configurationSource, tracer.Settings);
202203
}
203204
}
204205
}

tracer/test/Datadog.Trace.Tests/Configuration/DynamicConfigurationTests.cs

Lines changed: 54 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ public void ApplyServiceMappingToNewTraces()
2929
Tracer.Instance.CurrentTraceSettings.GetServiceName("test")
3030
.Should().Be($"{Tracer.Instance.DefaultServiceName}-test");
3131

32-
DynamicConfigurationManager.OnlyForTests_ApplyConfiguration(CreateConfig(("tracing_service_mapping", "test:ok")));
32+
DynamicConfigurationManager.OnlyForTests_ApplyConfiguration(CreateConfig(("tracing_service_mapping", "test:ok")), Tracer.Instance.Settings);
3333

3434
Tracer.Instance.CurrentTraceSettings.GetServiceName("test")
3535
.Should().Be($"{Tracer.Instance.DefaultServiceName}-test", "the old configuration should be used inside of the active trace");
@@ -45,13 +45,13 @@ public void ApplyConfigurationTwice()
4545
{
4646
var tracer = TracerManager.Instance;
4747

48-
DynamicConfigurationManager.OnlyForTests_ApplyConfiguration(CreateConfig(("tracing_sampling_rate", 0.4)));
48+
DynamicConfigurationManager.OnlyForTests_ApplyConfiguration(CreateConfig(("tracing_sampling_rate", 0.4)), tracer.Settings);
4949

5050
var newTracer = TracerManager.Instance;
5151

5252
newTracer.Should().NotBeSameAs(tracer);
5353

54-
DynamicConfigurationManager.OnlyForTests_ApplyConfiguration(CreateConfig(("tracing_sampling_rate", 0.4)));
54+
DynamicConfigurationManager.OnlyForTests_ApplyConfiguration(CreateConfig(("tracing_sampling_rate", 0.4)), tracer.Settings);
5555

5656
TracerManager.Instance.Should().BeSameAs(newTracer);
5757
}
@@ -60,14 +60,17 @@ public void ApplyConfigurationTwice()
6060
public void ApplyTagsToDirectLogs()
6161
{
6262
var tracerSettings = TracerSettings.Create(new() { { ConfigurationKeys.GlobalTags, "key1:value1" } });
63-
TracerManager.ReplaceGlobalManager(tracerSettings, TracerManagerFactory.Instance);
6463

65-
TracerManager.Instance.DirectLogSubmission.Formatter.Tags.Should().Be("key1:value1");
64+
// emulate the one-time subscribe that TracerManager.Instance does
65+
var tracerManager = TracerManagerFactory.Instance.CreateTracerManager(tracerSettings, null);
66+
using var sub = tracerSettings.Manager.SubscribeToChanges(x => tracerManager = UpdateTracerManager(x, tracerSettings, tracerManager));
67+
68+
tracerManager.DirectLogSubmission.Formatter.Tags.Should().Be("key1:value1");
6669

6770
var configBuilder = CreateConfig(("tracing_tags", new[] { "key2:value2" }));
68-
DynamicConfigurationManager.OnlyForTests_ApplyConfiguration(configBuilder);
71+
DynamicConfigurationManager.OnlyForTests_ApplyConfiguration(configBuilder, tracerSettings);
6972

70-
TracerManager.Instance.DirectLogSubmission.Formatter.Tags.Should().Be("key2:value2");
73+
tracerManager.DirectLogSubmission.Formatter.Tags.Should().Be("key2:value2");
7174
}
7275

7376
[Fact]
@@ -79,14 +82,15 @@ public void DoesNotOverrideDirectLogsTags()
7982
{ ConfigurationKeys.DirectLogSubmission.EnabledIntegrations, "xunit" },
8083
{ ConfigurationKeys.GlobalTags, "key2:value2" },
8184
});
82-
TracerManager.ReplaceGlobalManager(tracerSettings, TracerManagerFactory.Instance);
85+
var tracerManager = TracerManagerFactory.Instance.CreateTracerManager(tracerSettings, null);
86+
using var sub = tracerSettings.Manager.SubscribeToChanges(x => tracerManager = UpdateTracerManager(x, tracerSettings, tracerManager));
8387

84-
TracerManager.Instance.DirectLogSubmission.Formatter.Tags.Should().Be("key1:value1");
88+
tracerManager.DirectLogSubmission.Formatter.Tags.Should().Be("key1:value1");
8589

8690
var configBuilder = CreateConfig(("tracing_tags", new[] { "key3:value3" }));
87-
DynamicConfigurationManager.OnlyForTests_ApplyConfiguration(configBuilder);
91+
DynamicConfigurationManager.OnlyForTests_ApplyConfiguration(configBuilder, tracerSettings);
8892

89-
TracerManager.Instance.DirectLogSubmission.Formatter.Tags.Should().Be("key1:value1");
93+
tracerManager.DirectLogSubmission.Formatter.Tags.Should().Be("key1:value1");
9094
}
9195

9296
[Fact]
@@ -97,32 +101,34 @@ public void DoesNotReplaceRuntimeMetricsWriter()
97101
{ ConfigurationKeys.RuntimeMetricsEnabled, "true" },
98102
{ ConfigurationKeys.GlobalTags, "key1:value1" },
99103
});
100-
TracerManager.ReplaceGlobalManager(tracerSettings, TracerManagerFactory.Instance);
104+
var tracerManager = TracerManagerFactory.Instance.CreateTracerManager(tracerSettings, null);
105+
using var sub = tracerSettings.Manager.SubscribeToChanges(x => tracerManager = UpdateTracerManager(x, tracerSettings, tracerManager));
101106

102-
var previousRuntimeMetrics = TracerManager.Instance.RuntimeMetrics;
107+
var previousRuntimeMetrics = tracerManager.RuntimeMetrics;
103108

104109
var configBuilder = CreateConfig(("tracing_tags", new[] { "key2:value2" }));
105-
DynamicConfigurationManager.OnlyForTests_ApplyConfiguration(configBuilder);
110+
DynamicConfigurationManager.OnlyForTests_ApplyConfiguration(configBuilder, tracerSettings);
106111

107-
TracerManager.Instance.RuntimeMetrics.Should().Be(previousRuntimeMetrics);
112+
tracerManager.RuntimeMetrics.Should().Be(previousRuntimeMetrics);
108113
}
109114

110115
[Fact]
111116
public void EnableTracing()
112117
{
113118
var tracerSettings = new TracerSettings();
114-
TracerManager.ReplaceGlobalManager(tracerSettings, TracerManagerFactory.Instance);
119+
var tracerManager = TracerManagerFactory.Instance.CreateTracerManager(tracerSettings, null);
120+
using var sub = tracerSettings.Manager.SubscribeToChanges(x => tracerManager = UpdateTracerManager(x, tracerSettings, tracerManager));
115121

116122
// tracing is enabled by default
117-
TracerManager.Instance.Settings.TraceEnabled.Should().BeTrue();
123+
tracerManager.Settings.TraceEnabled.Should().BeTrue();
118124

119125
// disable "remotely"
120-
DynamicConfigurationManager.OnlyForTests_ApplyConfiguration(CreateConfig(("tracing_enabled", false)));
121-
TracerManager.Instance.Settings.TraceEnabled.Should().BeFalse();
126+
DynamicConfigurationManager.OnlyForTests_ApplyConfiguration(CreateConfig(("tracing_enabled", false)), tracerSettings);
127+
tracerManager.Settings.TraceEnabled.Should().BeFalse();
122128

123129
// re-enable "remotely"
124-
DynamicConfigurationManager.OnlyForTests_ApplyConfiguration(CreateConfig(("tracing_enabled", true)));
125-
TracerManager.Instance.Settings.TraceEnabled.Should().BeTrue();
130+
DynamicConfigurationManager.OnlyForTests_ApplyConfiguration(CreateConfig(("tracing_enabled", true)), tracerSettings);
131+
tracerManager.Settings.TraceEnabled.Should().BeTrue();
126132
}
127133

128134
[Fact]
@@ -141,12 +147,13 @@ public void SetSamplingRules()
141147
{ "DD_TRACE_SAMPLING_RULES", localSamplingRulesJson }
142148
});
143149

144-
TracerManager.ReplaceGlobalManager(tracerSettings, TracerManagerFactory.Instance);
150+
var tracerManager = TracerManagerFactory.Instance.CreateTracerManager(tracerSettings, null);
151+
using var sub = tracerSettings.Manager.SubscribeToChanges(x => tracerManager = UpdateTracerManager(x, tracerSettings, tracerManager));
145152

146-
TracerManager.Instance.Settings.CustomSamplingRules.Should().Be(localSamplingRulesJson);
147-
TracerManager.Instance.Settings.CustomSamplingRulesIsRemote.Should().BeFalse();
153+
tracerManager.Settings.CustomSamplingRules.Should().Be(localSamplingRulesJson);
154+
tracerManager.Settings.CustomSamplingRulesIsRemote.Should().BeFalse();
148155

149-
var rules = ((TraceSampler)TracerManager.Instance.PerTraceSettings.TraceSampler)!.GetRules();
156+
var rules = ((TraceSampler)tracerManager.PerTraceSettings.TraceSampler)!.GetRules();
150157

151158
rules.Should()
152159
.BeEquivalentTo(
@@ -171,13 +178,13 @@ public void SetSamplingRules()
171178
};
172179

173180
var configBuilder = CreateConfig(("tracing_sampling_rules", remoteSamplingRulesConfig));
174-
DynamicConfigurationManager.OnlyForTests_ApplyConfiguration(configBuilder);
181+
DynamicConfigurationManager.OnlyForTests_ApplyConfiguration(configBuilder, tracerSettings);
175182

176183
var remoteSamplingRulesJson = JsonConvert.SerializeObject(remoteSamplingRulesConfig);
177-
TracerManager.Instance.Settings.CustomSamplingRules.Should().Be(remoteSamplingRulesJson);
178-
TracerManager.Instance.Settings.CustomSamplingRulesIsRemote.Should().BeTrue();
184+
tracerManager.Settings.CustomSamplingRules.Should().Be(remoteSamplingRulesJson);
185+
tracerManager.Settings.CustomSamplingRulesIsRemote.Should().BeTrue();
179186

180-
rules = ((TraceSampler)TracerManager.Instance.PerTraceSettings.TraceSampler)!.GetRules();
187+
rules = ((TraceSampler)tracerManager.PerTraceSettings.TraceSampler)!.GetRules();
181188

182189
// new list should include the remote rules, not the local rules
183190
rules.Should()
@@ -271,5 +278,23 @@ private static DynamicConfigConfigurationSource CreateConfig(params (string Key,
271278

272279
return new DynamicConfigConfigurationSource(configObj, ConfigurationOrigins.RemoteConfig);
273280
}
281+
282+
private static TracerManager UpdateTracerManager(TracerSettings.SettingsManager.SettingChanges updates, TracerSettings settings, TracerManager tracerManager)
283+
{
284+
var newSettings = updates switch
285+
{
286+
{ UpdatedExporter: { } e, UpdatedMutable: { } m } => settings with { Exporter = e, MutableSettings = m },
287+
{ UpdatedExporter: { } e } => settings with { Exporter = e },
288+
{ UpdatedMutable: { } m } => settings with { MutableSettings = m },
289+
_ => null,
290+
};
291+
292+
if (newSettings != null)
293+
{
294+
tracerManager = TracerManagerFactory.Instance.CreateTracerManager(newSettings, tracerManager);
295+
}
296+
297+
return tracerManager;
298+
}
274299
}
275300
}

0 commit comments

Comments
 (0)