Skip to content

Commit 0b7d098

Browse files
Merge pull request #3069 from microsoft/rajrang/classicaspnetconfig
Add comprehensive applicationinsights.config support
2 parents 7e9e2e9 + a28ee7a commit 0b7d098

12 files changed

+1398
-26
lines changed

NETCORE/src/Shared/ActivityFilterProcessor.cs

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#if AI_ASPNETCORE_WEB
22
namespace Microsoft.ApplicationInsights.AspNetCore.Extensions
3+
#elif AI_CLASSIC_WEB
4+
namespace Microsoft.ApplicationInsights.Web.Implementation
35
#else
46
namespace Microsoft.ApplicationInsights.WorkerService
57
#endif
@@ -17,10 +19,22 @@ namespace Microsoft.ApplicationInsights.WorkerService
1719
internal sealed class ActivityFilterProcessor : BaseProcessor<Activity>
1820
{
1921
private readonly bool enableDependencyTracking;
20-
#if AI_ASPNETCORE_WEB
22+
#if AI_ASPNETCORE_WEB || AI_CLASSIC_WEB
2123
private readonly bool enableRequestTracking;
2224
#endif
2325

26+
#if AI_CLASSIC_WEB
27+
/// <summary>
28+
/// Initializes a new instance of the <see cref="ActivityFilterProcessor"/> class for classic ASP.NET.
29+
/// </summary>
30+
/// <param name="enableDependencyTracking">Whether dependency tracking is enabled.</param>
31+
/// <param name="enableRequestTracking">Whether request tracking is enabled.</param>
32+
public ActivityFilterProcessor(bool enableDependencyTracking, bool enableRequestTracking)
33+
{
34+
this.enableDependencyTracking = enableDependencyTracking;
35+
this.enableRequestTracking = enableRequestTracking;
36+
}
37+
#else
2438
/// <summary>
2539
/// Initializes a new instance of the <see cref="ActivityFilterProcessor"/> class.
2640
/// </summary>
@@ -33,6 +47,7 @@ public ActivityFilterProcessor(IOptions<ApplicationInsightsServiceOptions> optio
3347
this.enableRequestTracking = serviceOptions.EnableRequestTrackingTelemetryModule;
3448
#endif
3549
}
50+
#endif
3651

3752
/// <summary>
3853
/// Called when an activity is started. Applies filtering logic based on activity kind and service options.
@@ -58,9 +73,8 @@ public override void OnStart(Activity activity)
5873
}
5974
}
6075

61-
#if AI_ASPNETCORE_WEB
76+
#if AI_ASPNETCORE_WEB || AI_CLASSIC_WEB
6277
// Filter request activities (inbound calls) when EnableRequestTrackingTelemetryModule is false
63-
// Only available in AspNetCore, not WorkerService
6478
if (!this.enableRequestTracking)
6579
{
6680
if (activity.Kind == ActivityKind.Server ||
Lines changed: 340 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,340 @@
1+
namespace Microsoft.ApplicationInsights.Web.Tests
2+
{
3+
using System;
4+
using System.IO;
5+
using System.Xml.Linq;
6+
using Microsoft.ApplicationInsights.Web.Implementation;
7+
using Xunit;
8+
9+
public class ApplicationInsightsConfigurationReaderTests : IDisposable
10+
{
11+
private readonly string configFilePath;
12+
13+
public ApplicationInsightsConfigurationReaderTests()
14+
{
15+
// Create config file in AppDomain base directory where the reader expects it
16+
configFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "ApplicationInsights.config");
17+
18+
// Delete existing config if present
19+
if (File.Exists(configFilePath))
20+
{
21+
File.Delete(configFilePath);
22+
}
23+
}
24+
25+
public void Dispose()
26+
{
27+
// Cleanup config file
28+
try
29+
{
30+
if (File.Exists(configFilePath))
31+
{
32+
File.Delete(configFilePath);
33+
}
34+
}
35+
catch
36+
{
37+
// Ignore cleanup errors
38+
}
39+
}
40+
41+
[Fact]
42+
public void GetConfigurationOptions_ReturnsNull_WhenConfigFileDoesNotExist()
43+
{
44+
// Act
45+
var options = ApplicationInsightsConfigurationReader.GetConfigurationOptions();
46+
47+
// Assert
48+
Assert.Null(options);
49+
}
50+
51+
[Fact]
52+
public void GetConfigurationOptions_ReturnsAllProperties_WhenFullyPopulated()
53+
{
54+
// Arrange
55+
string configContent = @"<?xml version=""1.0"" encoding=""utf-8""?>
56+
<ApplicationInsights xmlns=""http://schemas.microsoft.com/ApplicationInsights/2013/Settings"">
57+
<ConnectionString>InstrumentationKey=12345678-1234-1234-1234-123456789012;IngestionEndpoint=https://test.in.applicationinsights.azure.com/</ConnectionString>
58+
<DisableTelemetry>false</DisableTelemetry>
59+
<SamplingRatio>0.5</SamplingRatio>
60+
<TracesPerSecond>10.5</TracesPerSecond>
61+
<StorageDirectory>C:\Temp\AI</StorageDirectory>
62+
<DisableOfflineStorage>true</DisableOfflineStorage>
63+
<EnableTraceBasedLogsSampler>true</EnableTraceBasedLogsSampler>
64+
<EnableQuickPulseMetricStream>false</EnableQuickPulseMetricStream>
65+
<EnablePerformanceCounterCollectionModule>true</EnablePerformanceCounterCollectionModule>
66+
<AddAutoCollectedMetricExtractor>false</AddAutoCollectedMetricExtractor>
67+
<EnableDependencyTrackingTelemetryModule>true</EnableDependencyTrackingTelemetryModule>
68+
<ApplicationVersion>1.2.3.4</ApplicationVersion>
69+
</ApplicationInsights>";
70+
71+
CreateTestConfigFile(configContent);
72+
73+
// Act
74+
var options = ReadConfigFromTestDirectory();
75+
76+
// Assert
77+
Assert.NotNull(options);
78+
Assert.Equal("InstrumentationKey=12345678-1234-1234-1234-123456789012;IngestionEndpoint=https://test.in.applicationinsights.azure.com/", options.ConnectionString);
79+
Assert.False(options.DisableTelemetry);
80+
Assert.Equal(0.5f, options.SamplingRatio);
81+
Assert.Equal(10.5, options.TracesPerSecond);
82+
Assert.Equal(@"C:\Temp\AI", options.StorageDirectory);
83+
Assert.True(options.DisableOfflineStorage);
84+
Assert.True(options.EnableTraceBasedLogsSampler);
85+
Assert.False(options.EnableQuickPulseMetricStream);
86+
Assert.True(options.EnablePerformanceCounterCollectionModule);
87+
Assert.False(options.AddAutoCollectedMetricExtractor);
88+
Assert.True(options.EnableDependencyTrackingTelemetryModule);
89+
Assert.Equal("1.2.3.4", options.ApplicationVersion);
90+
}
91+
92+
[Fact]
93+
public void GetConfigurationOptions_ReturnsNull_ForMissingProperties()
94+
{
95+
// Arrange
96+
string configContent = @"<?xml version=""1.0"" encoding=""utf-8""?>
97+
<ApplicationInsights xmlns=""http://schemas.microsoft.com/ApplicationInsights/2013/Settings"">
98+
<ConnectionString>InstrumentationKey=test</ConnectionString>
99+
</ApplicationInsights>";
100+
101+
CreateTestConfigFile(configContent);
102+
103+
// Act
104+
var options = ReadConfigFromTestDirectory();
105+
106+
// Assert
107+
Assert.NotNull(options);
108+
Assert.Equal("InstrumentationKey=test", options.ConnectionString);
109+
Assert.Null(options.DisableTelemetry);
110+
Assert.Null(options.SamplingRatio);
111+
Assert.Null(options.TracesPerSecond);
112+
Assert.Null(options.StorageDirectory);
113+
Assert.Null(options.DisableOfflineStorage);
114+
Assert.Null(options.EnableTraceBasedLogsSampler);
115+
Assert.Null(options.EnableQuickPulseMetricStream);
116+
Assert.Null(options.EnablePerformanceCounterCollectionModule);
117+
Assert.Null(options.AddAutoCollectedMetricExtractor);
118+
Assert.Null(options.EnableDependencyTrackingTelemetryModule);
119+
Assert.Null(options.ApplicationVersion);
120+
}
121+
122+
[Fact]
123+
public void GetConfigurationOptions_IgnoresCommentedElements()
124+
{
125+
// Arrange
126+
string configContent = @"<?xml version=""1.0"" encoding=""utf-8""?>
127+
<ApplicationInsights xmlns=""http://schemas.microsoft.com/ApplicationInsights/2013/Settings"">
128+
<ConnectionString>InstrumentationKey=test</ConnectionString>
129+
<!--<SamplingRatio>0.5</SamplingRatio>-->
130+
<!--<DisableTelemetry>true</DisableTelemetry>-->
131+
<EnableQuickPulseMetricStream>true</EnableQuickPulseMetricStream>
132+
</ApplicationInsights>";
133+
134+
CreateTestConfigFile(configContent);
135+
136+
// Act
137+
var options = ReadConfigFromTestDirectory();
138+
139+
// Assert
140+
Assert.NotNull(options);
141+
Assert.Equal("InstrumentationKey=test", options.ConnectionString);
142+
Assert.Null(options.SamplingRatio);
143+
Assert.Null(options.DisableTelemetry);
144+
Assert.True(options.EnableQuickPulseMetricStream);
145+
}
146+
147+
[Fact]
148+
public void GetConfigurationOptions_UsesCultureInvariantParsing_ForFloatValues()
149+
{
150+
// Arrange - use period as decimal separator regardless of current culture
151+
string configContent = @"<?xml version=""1.0"" encoding=""utf-8""?>
152+
<ApplicationInsights xmlns=""http://schemas.microsoft.com/ApplicationInsights/2013/Settings"">
153+
<ConnectionString>test</ConnectionString>
154+
<SamplingRatio>0.75</SamplingRatio>
155+
<TracesPerSecond>15.25</TracesPerSecond>
156+
</ApplicationInsights>";
157+
158+
CreateTestConfigFile(configContent);
159+
160+
// Act
161+
var options = ReadConfigFromTestDirectory();
162+
163+
// Assert
164+
Assert.NotNull(options);
165+
Assert.Equal(0.75f, options.SamplingRatio);
166+
Assert.Equal(15.25, options.TracesPerSecond);
167+
}
168+
169+
[Fact]
170+
public void GetConfigurationOptions_ReturnsNull_ForMalformedBooleanValues()
171+
{
172+
// Arrange
173+
string configContent = @"<?xml version=""1.0"" encoding=""utf-8""?>
174+
<ApplicationInsights xmlns=""http://schemas.microsoft.com/ApplicationInsights/2013/Settings"">
175+
<ConnectionString>test</ConnectionString>
176+
<DisableTelemetry>not-a-bool</DisableTelemetry>
177+
<EnableQuickPulseMetricStream>yes</EnableQuickPulseMetricStream>
178+
</ApplicationInsights>";
179+
180+
CreateTestConfigFile(configContent);
181+
182+
// Act
183+
var options = ReadConfigFromTestDirectory();
184+
185+
// Assert
186+
Assert.NotNull(options);
187+
Assert.Null(options.DisableTelemetry);
188+
Assert.Null(options.EnableQuickPulseMetricStream);
189+
}
190+
191+
[Fact]
192+
public void GetConfigurationOptions_ReturnsNull_ForMalformedNumericValues()
193+
{
194+
// Arrange
195+
string configContent = @"<?xml version=""1.0"" encoding=""utf-8""?>
196+
<ApplicationInsights xmlns=""http://schemas.microsoft.com/ApplicationInsights/2013/Settings"">
197+
<ConnectionString>test</ConnectionString>
198+
<SamplingRatio>not-a-number</SamplingRatio>
199+
<TracesPerSecond>invalid</TracesPerSecond>
200+
</ApplicationInsights>";
201+
202+
CreateTestConfigFile(configContent);
203+
204+
// Act
205+
var options = ReadConfigFromTestDirectory();
206+
207+
// Assert
208+
Assert.NotNull(options);
209+
Assert.Null(options.SamplingRatio);
210+
Assert.Null(options.TracesPerSecond);
211+
}
212+
213+
[Fact]
214+
public void GetConfigurationOptions_ReturnsNull_ForInvalidXml()
215+
{
216+
// Arrange - malformed XML
217+
string configContent = @"<?xml version=""1.0"" encoding=""utf-8""?>
218+
<ApplicationInsights xmlns=""http://schemas.microsoft.com/ApplicationInsights/2013/Settings"">
219+
<ConnectionString>test
220+
</ApplicationInsights>";
221+
222+
CreateTestConfigFile(configContent);
223+
224+
// Act
225+
var options = ReadConfigFromTestDirectory();
226+
227+
// Assert
228+
Assert.Null(options);
229+
}
230+
231+
[Fact]
232+
public void GetConfigurationOptions_ReturnsNull_WhenAllPropertiesAreEmpty()
233+
{
234+
// Arrange
235+
string configContent = @"<?xml version=""1.0"" encoding=""utf-8""?>
236+
<ApplicationInsights xmlns=""http://schemas.microsoft.com/ApplicationInsights/2013/Settings"">
237+
<ConnectionString></ConnectionString>
238+
<DisableTelemetry></DisableTelemetry>
239+
</ApplicationInsights>";
240+
241+
CreateTestConfigFile(configContent);
242+
243+
// Act
244+
var options = ReadConfigFromTestDirectory();
245+
246+
// Assert - should return null when no valid properties found
247+
Assert.Null(options);
248+
}
249+
250+
[Fact]
251+
public void GetConfigurationOptions_TrimsWhitespace_FromStringValues()
252+
{
253+
// Arrange
254+
string configContent = @"<?xml version=""1.0"" encoding=""utf-8""?>
255+
<ApplicationInsights xmlns=""http://schemas.microsoft.com/ApplicationInsights/2013/Settings"">
256+
<ConnectionString> InstrumentationKey=test </ConnectionString>
257+
<StorageDirectory> C:\Temp </StorageDirectory>
258+
<ApplicationVersion> 1.0.0 </ApplicationVersion>
259+
</ApplicationInsights>";
260+
261+
CreateTestConfigFile(configContent);
262+
263+
// Act
264+
var options = ReadConfigFromTestDirectory();
265+
266+
// Assert
267+
Assert.NotNull(options);
268+
Assert.Equal("InstrumentationKey=test", options.ConnectionString);
269+
Assert.Equal(@"C:\Temp", options.StorageDirectory);
270+
Assert.Equal("1.0.0", options.ApplicationVersion);
271+
}
272+
273+
[Fact]
274+
public void GetConfigurationOptions_HandlesBooleanVariations()
275+
{
276+
// Arrange
277+
string configContent = @"<?xml version=""1.0"" encoding=""utf-8""?>
278+
<ApplicationInsights xmlns=""http://schemas.microsoft.com/ApplicationInsights/2013/Settings"">
279+
<ConnectionString>test</ConnectionString>
280+
<DisableTelemetry>True</DisableTelemetry>
281+
<DisableOfflineStorage>FALSE</DisableOfflineStorage>
282+
<EnableTraceBasedLogsSampler>true</EnableTraceBasedLogsSampler>
283+
</ApplicationInsights>";
284+
285+
CreateTestConfigFile(configContent);
286+
287+
// Act
288+
var options = ReadConfigFromTestDirectory();
289+
290+
// Assert
291+
Assert.NotNull(options);
292+
Assert.True(options.DisableTelemetry);
293+
Assert.False(options.DisableOfflineStorage);
294+
Assert.True(options.EnableTraceBasedLogsSampler);
295+
}
296+
297+
[Fact]
298+
public void GetConnectionString_ReturnsConnectionString_WhenPresent()
299+
{
300+
// Arrange
301+
string configContent = @"<?xml version=""1.0"" encoding=""utf-8""?>
302+
<ApplicationInsights xmlns=""http://schemas.microsoft.com/ApplicationInsights/2013/Settings"">
303+
<ConnectionString>InstrumentationKey=12345678-1234-1234-1234-123456789012</ConnectionString>
304+
</ApplicationInsights>";
305+
306+
CreateTestConfigFile(configContent);
307+
308+
// Act
309+
var connectionString = ReadConnectionStringFromTestDirectory();
310+
311+
// Assert
312+
Assert.Equal("InstrumentationKey=12345678-1234-1234-1234-123456789012", connectionString);
313+
}
314+
315+
[Fact]
316+
public void GetConnectionString_ReturnsNull_WhenConfigMissing()
317+
{
318+
// Act
319+
var connectionString = ApplicationInsightsConfigurationReader.GetConnectionString();
320+
321+
// Assert
322+
Assert.Null(connectionString);
323+
}
324+
325+
private void CreateTestConfigFile(string content)
326+
{
327+
File.WriteAllText(configFilePath, content);
328+
}
329+
330+
private ApplicationInsightsConfigOptions ReadConfigFromTestDirectory()
331+
{
332+
return ApplicationInsightsConfigurationReader.GetConfigurationOptions();
333+
}
334+
335+
private string ReadConnectionStringFromTestDirectory()
336+
{
337+
return ApplicationInsightsConfigurationReader.GetConnectionString();
338+
}
339+
}
340+
}

0 commit comments

Comments
 (0)