Skip to content

Commit 8942aba

Browse files
authored
updating dependency creation (#1039)
1 parent a77bdc4 commit 8942aba

File tree

6 files changed

+115
-83
lines changed

6 files changed

+115
-83
lines changed

src/DotNetWorker.ApplicationInsights/DotNetWorker.ApplicationInsights.csproj

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,14 @@
88
<MajorProductVersion>1</MajorProductVersion>
99
<MinorProductVersion>0</MinorProductVersion>
1010
<PatchProductVersion>0</PatchProductVersion>
11-
<VersionSuffix>-preview1</VersionSuffix>
11+
<VersionSuffix>-preview2</VersionSuffix>
1212
</PropertyGroup>
1313

1414
<Import Project="..\..\build\Common.props" />
1515

1616
<ItemGroup>
17-
<PackageReference Include="Microsoft.ApplicationInsights.WorkerService" Version="2.20.0" />
18-
</ItemGroup>
19-
20-
<ItemGroup>
21-
<ProjectReference Include="..\DotNetWorker.Core\DotNetWorker.Core.csproj" />
17+
<PackageReference Include="Microsoft.Azure.Functions.Worker.Core" Version="1.7.0-preview1" />
18+
<PackageReference Include="Microsoft.ApplicationInsights.WorkerService" Version="2.21.0" />
2219
</ItemGroup>
2320

2421
</Project>

src/DotNetWorker.ApplicationInsights/FunctionActivitySource.cs

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// Copyright (c) .NET Foundation. All rights reserved.
22
// Licensed under the MIT License. See License.txt in the project root for license information.
33

4+
using System.Collections.Generic;
45
using System.Diagnostics;
56

67
namespace Microsoft.Azure.Functions.Worker.Core.Diagnostics
@@ -18,16 +19,17 @@ internal static class FunctionActivitySource
1819

1920
public static Activity? StartInvoke(FunctionContext context)
2021
{
21-
var activity = _activitySource.StartActivity("Invoke", ActivityKind.Internal, context.TraceContext.TraceParent);
22-
23-
if (activity is not null)
24-
{
25-
activity.AddTag(InvocationIdKey, context.InvocationId);
26-
activity.AddTag(NameKey, context.FunctionDefinition.Name);
27-
activity.AddTag(ProcessIdKey, _processId);
28-
}
22+
var activity = _activitySource.StartActivity("Invoke", ActivityKind.Internal, context.TraceContext.TraceParent,
23+
tags: GetTags(context));
2924

3025
return activity;
3126
}
27+
28+
private static IEnumerable<KeyValuePair<string, object?>> GetTags(FunctionContext context)
29+
{
30+
yield return new KeyValuePair<string, object?>(InvocationIdKey, context.InvocationId);
31+
yield return new KeyValuePair<string, object?>(NameKey, context.FunctionDefinition.Name);
32+
yield return new KeyValuePair<string, object?>(ProcessIdKey, _processId);
33+
}
3234
}
3335
}

src/DotNetWorker.ApplicationInsights/FunctionsTelemetryModule.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,15 @@ public void Initialize(TelemetryConfiguration configuration)
2323
ShouldListenTo = source => source.Name.StartsWith("Microsoft.Azure.Functions.Worker"),
2424
ActivityStarted = activity =>
2525
{
26-
var dependency = new DependencyTelemetry("Azure.Functions", activity.OperationName, activity.OperationName, null);
26+
var dependency = _telemetryClient.StartOperation<DependencyTelemetry>(activity);
27+
dependency.Telemetry.Type = "Azure.Functions";
2728
activity.SetCustomProperty("_depTel", dependency);
28-
dependency.Start();
2929
},
3030
ActivityStopped = activity =>
3131
{
32-
var dependency = activity.GetCustomProperty("_depTel") as DependencyTelemetry;
33-
dependency.Stop();
34-
_telemetryClient.TrackDependency(dependency);
32+
var dependency = activity.GetCustomProperty("_depTel") as IOperationHolder<DependencyTelemetry>;
33+
_telemetryClient.StopOperation(dependency);
34+
dependency?.Dispose();
3535
},
3636
Sample = (ref ActivityCreationOptions<ActivityContext> _) => ActivitySamplingResult.AllData,
3737
SampleUsingParentId = (ref ActivityCreationOptions<string> _) => ActivitySamplingResult.AllData

test/DotNetWorkerTests/ApplicationInsights/ApplicationInsightsConfigurationTests.cs

Lines changed: 71 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -41,27 +41,30 @@ public void AddApplicationInsights_AddsDefaults()
4141
modules = services.Where(s => s.ServiceType == typeof(ITelemetryModule));
4242
});
4343

44-
var provider = builder.Build().Services;
44+
using (var host = builder.Build())
45+
{
46+
var provider = host.Services;
4547

46-
Assert.Collection(initializers,
47-
t => Assert.Equal(typeof(FunctionsTelemetryInitializer), t.ImplementationType),
48-
t => Assert.Equal(typeof(AzureWebAppRoleEnvironmentTelemetryInitializer), t.ImplementationType),
49-
t => Assert.Equal(typeof(Microsoft.ApplicationInsights.WorkerService.TelemetryInitializers.DomainNameRoleInstanceTelemetryInitializer), t.ImplementationType),
50-
t => Assert.Equal(typeof(HttpDependenciesParsingTelemetryInitializer), t.ImplementationType),
51-
t => Assert.Equal(typeof(ComponentVersionTelemetryInitializer), t.ImplementationType));
48+
Assert.Collection(initializers,
49+
t => Assert.Equal(typeof(FunctionsTelemetryInitializer), t.ImplementationType),
50+
t => Assert.Equal(typeof(AzureWebAppRoleEnvironmentTelemetryInitializer), t.ImplementationType),
51+
t => Assert.Equal(typeof(Microsoft.ApplicationInsights.WorkerService.TelemetryInitializers.DomainNameRoleInstanceTelemetryInitializer), t.ImplementationType),
52+
t => Assert.Equal(typeof(HttpDependenciesParsingTelemetryInitializer), t.ImplementationType),
53+
t => Assert.Equal(typeof(ComponentVersionTelemetryInitializer), t.ImplementationType));
5254

53-
Assert.Collection(modules,
54-
t => Assert.Equal(typeof(FunctionsTelemetryModule), t.ImplementationType),
55-
t => Assert.Equal(typeof(DiagnosticsTelemetryModule), t.ImplementationType),
56-
t => Assert.Equal(typeof(AppServicesHeartbeatTelemetryModule), t.ImplementationType),
57-
t => Assert.Equal(typeof(AzureInstanceMetadataTelemetryModule), t.ImplementationType),
58-
t => Assert.Equal(typeof(PerformanceCollectorModule), t.ImplementationType),
59-
t => Assert.Equal(typeof(QuickPulseTelemetryModule), t.ImplementationType),
60-
t => Assert.Equal(typeof(DependencyTrackingTelemetryModule), t.ImplementationType),
61-
t => Assert.Equal(typeof(EventCounterCollectionModule), t.ImplementationType));
62-
63-
var middleware = provider.GetRequiredService<FunctionActivitySourceMiddleware>();
64-
Assert.NotNull(middleware);
55+
Assert.Collection(modules,
56+
t => Assert.Equal(typeof(FunctionsTelemetryModule), t.ImplementationType),
57+
t => Assert.Equal(typeof(DiagnosticsTelemetryModule), t.ImplementationType),
58+
t => Assert.Equal(typeof(AppServicesHeartbeatTelemetryModule), t.ImplementationType),
59+
t => Assert.Equal(typeof(AzureInstanceMetadataTelemetryModule), t.ImplementationType),
60+
t => Assert.Equal(typeof(PerformanceCollectorModule), t.ImplementationType),
61+
t => Assert.Equal(typeof(QuickPulseTelemetryModule), t.ImplementationType),
62+
t => Assert.Equal(typeof(DependencyTrackingTelemetryModule), t.ImplementationType),
63+
t => Assert.Equal(typeof(EventCounterCollectionModule), t.ImplementationType));
64+
65+
var middleware = provider.GetRequiredService<FunctionActivitySourceMiddleware>();
66+
Assert.NotNull(middleware);
67+
}
6568
}
6669

6770
[Fact]
@@ -80,14 +83,17 @@ public void AddApplicationInsights_CallsConfigure()
8083

8184
Assert.False(called);
8285

83-
var provider = builder.Build().Services;
84-
var options = provider.GetRequiredService<IOptions<ApplicationInsightsServiceOptions>>();
85-
Assert.NotNull(options.Value);
86+
using (var host = builder.Build())
87+
{
88+
var provider = host.Services;
89+
var options = provider.GetRequiredService<IOptions<ApplicationInsightsServiceOptions>>();
90+
Assert.NotNull(options.Value);
8691

87-
var middleware = provider.GetRequiredService<FunctionActivitySourceMiddleware>();
88-
Assert.NotNull(middleware);
92+
var middleware = provider.GetRequiredService<FunctionActivitySourceMiddleware>();
93+
Assert.NotNull(middleware);
8994

90-
Assert.True(called);
95+
Assert.True(called);
96+
}
9197
}
9298

9399
[Fact]
@@ -119,21 +125,24 @@ public void AddApplicationInsightsLogger_AddsDefaults()
119125
called = true;
120126
});
121127

122-
var serviceProvider = builder.Build().Services;
128+
using (var host = builder.Build())
129+
{
130+
var serviceProvider = host.Services;
123131

124-
var appInsightsOptions = serviceProvider.GetRequiredService<IOptions<ApplicationInsightsLoggerOptions>>();
125-
Assert.False(appInsightsOptions.Value.IncludeScopes);
132+
var appInsightsOptions = serviceProvider.GetRequiredService<IOptions<ApplicationInsightsLoggerOptions>>();
133+
Assert.False(appInsightsOptions.Value.IncludeScopes);
126134

127-
var userWriter = serviceProvider.GetRequiredService<IUserLogWriter>();
128-
Assert.IsType<NullUserLogWriter>(userWriter);
135+
var userWriter = serviceProvider.GetRequiredService<IUserLogWriter>();
136+
Assert.IsType<NullUserLogWriter>(userWriter);
129137

130-
var systemWriter = serviceProvider.GetRequiredService<ISystemLogWriter>();
131-
Assert.IsNotType<NullLogWriter>(systemWriter);
138+
var systemWriter = serviceProvider.GetRequiredService<ISystemLogWriter>();
139+
Assert.IsNotType<NullLogWriter>(systemWriter);
132140

133-
var middleware = serviceProvider.GetRequiredService<FunctionActivitySourceMiddleware>();
134-
Assert.NotNull(middleware);
141+
var middleware = serviceProvider.GetRequiredService<FunctionActivitySourceMiddleware>();
142+
Assert.NotNull(middleware);
135143

136-
Assert.True(called);
144+
Assert.True(called);
145+
}
137146
}
138147

139148
[Fact]
@@ -152,14 +161,17 @@ public void AddApplicationInsightsLogger_CallsConfigure()
152161

153162
Assert.False(called);
154163

155-
var provider = builder.Build().Services;
156-
var options = provider.GetRequiredService<IOptions<ApplicationInsightsLoggerOptions>>();
157-
Assert.NotNull(options.Value);
164+
using (var host = builder.Build())
165+
{
166+
var provider = host.Services;
167+
var options = provider.GetRequiredService<IOptions<ApplicationInsightsLoggerOptions>>();
168+
Assert.NotNull(options.Value);
158169

159-
var middleware = provider.GetRequiredService<FunctionActivitySourceMiddleware>();
160-
Assert.NotNull(middleware);
170+
var middleware = provider.GetRequiredService<FunctionActivitySourceMiddleware>();
171+
Assert.NotNull(middleware);
161172

162-
Assert.True(called);
173+
Assert.True(called);
174+
}
163175
}
164176

165177
[Fact]
@@ -182,27 +194,30 @@ public void AddingServiceAndLogger_OnlyAddsServicesOnce()
182194
modules = services.Where(s => s.ServiceType == typeof(ITelemetryModule));
183195
});
184196

185-
var provider = builder.Build().Services;
197+
using (var host = builder.Build())
198+
{
199+
var provider = host.Services;
186200

187-
// Ensure that our Initializer and Module are added alongside the defaults
188-
Assert.Collection(initializers,
201+
// Ensure that our Initializer and Module are added alongside the defaults
202+
Assert.Collection(initializers,
189203
t => Assert.Equal(typeof(FunctionsTelemetryInitializer), t.ImplementationType),
190204
t => Assert.Equal(typeof(AzureWebAppRoleEnvironmentTelemetryInitializer), t.ImplementationType),
191205
t => Assert.Equal(typeof(Microsoft.ApplicationInsights.WorkerService.TelemetryInitializers.DomainNameRoleInstanceTelemetryInitializer), t.ImplementationType),
192206
t => Assert.Equal(typeof(HttpDependenciesParsingTelemetryInitializer), t.ImplementationType),
193207
t => Assert.Equal(typeof(ComponentVersionTelemetryInitializer), t.ImplementationType));
194208

195-
Assert.Collection(modules,
196-
t => Assert.Equal(typeof(FunctionsTelemetryModule), t.ImplementationType),
197-
t => Assert.Equal(typeof(DiagnosticsTelemetryModule), t.ImplementationType),
198-
t => Assert.Equal(typeof(AppServicesHeartbeatTelemetryModule), t.ImplementationType),
199-
t => Assert.Equal(typeof(AzureInstanceMetadataTelemetryModule), t.ImplementationType),
200-
t => Assert.Equal(typeof(PerformanceCollectorModule), t.ImplementationType),
201-
t => Assert.Equal(typeof(QuickPulseTelemetryModule), t.ImplementationType),
202-
t => Assert.Equal(typeof(DependencyTrackingTelemetryModule), t.ImplementationType),
203-
t => Assert.Equal(typeof(EventCounterCollectionModule), t.ImplementationType));
204-
205-
var middleware = provider.GetRequiredService<FunctionActivitySourceMiddleware>();
206-
Assert.NotNull(middleware);
209+
Assert.Collection(modules,
210+
t => Assert.Equal(typeof(FunctionsTelemetryModule), t.ImplementationType),
211+
t => Assert.Equal(typeof(DiagnosticsTelemetryModule), t.ImplementationType),
212+
t => Assert.Equal(typeof(AppServicesHeartbeatTelemetryModule), t.ImplementationType),
213+
t => Assert.Equal(typeof(AzureInstanceMetadataTelemetryModule), t.ImplementationType),
214+
t => Assert.Equal(typeof(PerformanceCollectorModule), t.ImplementationType),
215+
t => Assert.Equal(typeof(QuickPulseTelemetryModule), t.ImplementationType),
216+
t => Assert.Equal(typeof(DependencyTrackingTelemetryModule), t.ImplementationType),
217+
t => Assert.Equal(typeof(EventCounterCollectionModule), t.ImplementationType));
218+
219+
var middleware = provider.GetRequiredService<FunctionActivitySourceMiddleware>();
220+
Assert.NotNull(middleware);
221+
}
207222
}
208223
}

test/DotNetWorkerTests/ApplicationInsights/EndToEndTests.cs

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
using System.Collections.Immutable;
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Collections.Immutable;
24
using System.Diagnostics;
35
using System.Linq;
46
using System.Threading.Tasks;
@@ -15,7 +17,7 @@
1517

1618
namespace Microsoft.Azure.Functions.Worker.Tests.ApplicationInsights;
1719

18-
public class EndToEndTests
20+
public class EndToEndTests : IDisposable
1921
{
2022
private readonly TestTelemetryChannel _channel;
2123
private readonly IHost _host;
@@ -31,7 +33,11 @@ public EndToEndTests()
3133
{
3234
var functionsBuilder = services.AddFunctionsWorkerCore();
3335
functionsBuilder
34-
.AddApplicationInsights(appInsightsOptions => appInsightsOptions.InstrumentationKey = "abc")
36+
.AddApplicationInsights(appInsightsOptions =>
37+
{
38+
appInsightsOptions.InstrumentationKey = "abc";
39+
appInsightsOptions.EnableAdaptiveSampling = false;
40+
})
3541
.AddApplicationInsightsLogger();
3642

3743
functionsBuilder.UseDefaultWorkerMiddleware();
@@ -72,10 +78,16 @@ void ValidateProperties(ISupportProperties props)
7278
}
7379

7480
var activity = AppInsightsFunctionDefinition.LastActivity;
81+
IEnumerable<ITelemetry> telemetries = null;
7582

76-
// App Insights can potentially log this, which causes tests to be flaky. Explicitly ignore.
77-
var aiTelemetry = _channel.Telemetries.Where(p => p is TraceTelemetry t && t.Message.Contains("AI: TelemetryChannel found a telemetry item"));
78-
var telemetries = _channel.Telemetries.Except(aiTelemetry);
83+
// There can be a race while telemetry is flushed. Explicitly wait for what we're looking for.
84+
await Functions.Tests.TestUtility.RetryAsync(() =>
85+
{
86+
// App Insights can potentially log this, which causes tests to be flaky. Explicitly ignore.
87+
var aiTelemetry = _channel.Telemetries.Where(p => p is TraceTelemetry t && t.Message.Contains("AI: TelemetryChannel found a telemetry item"));
88+
telemetries = _channel.Telemetries.Except(aiTelemetry);
89+
return Task.FromResult(telemetries.Count() == 2);
90+
}, timeout: 5000, pollingInterval: 500, userMessageCallback: () => $"Expected 2 telemetries. Found [{string.Join(", ", telemetries.Select(t => t.GetType().Name))}].");
7991

8092
// Log written in test function should go to App Insights directly
8193
Assert.Collection(telemetries,
@@ -84,7 +96,7 @@ void ValidateProperties(ISupportProperties props)
8496
var dependency = (DependencyTelemetry)t;
8597

8698
Assert.Equal("TestName", dependency.Context.Operation.Name);
87-
Assert.Equal(activity.SpanId.ToString(), dependency.Context.Operation.ParentId);
99+
Assert.Equal(activity.RootId, dependency.Context.Operation.Id);
88100

89101
ValidateProperties(dependency);
90102
},
@@ -98,12 +110,17 @@ void ValidateProperties(ISupportProperties props)
98110
Assert.DoesNotContain("AzureFunctions_InvocationId", trace.Properties.Keys);
99111

100112
Assert.Equal("TestName", trace.Context.Operation.Name);
101-
Assert.Equal(activity.SpanId.ToString(), trace.Context.Operation.ParentId);
113+
Assert.Equal(activity.RootId, trace.Context.Operation.Id);
102114

103115
ValidateProperties(trace);
104116
});
105117
}
106118

119+
public void Dispose()
120+
{
121+
_host?.Dispose();
122+
}
123+
107124
internal class AppInsightsFunctionDefinition : FunctionDefinition
108125
{
109126
public static readonly string DefaultPathToAssembly = typeof(AppInsightsFunctionDefinition).Assembly.Location;

test/DotNetWorkerTests/DotNetWorkerTests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
<ProjectReference Include="..\..\extensions\Worker.Extensions.Http\src\Worker.Extensions.Http.csproj" />
2828
<ProjectReference Include="..\..\src\DotNetWorker.ApplicationInsights\DotNetWorker.ApplicationInsights.csproj" />
2929
<ProjectReference Include="..\..\src\DotNetWorker\DotNetWorker.csproj" />
30+
<ProjectReference Include="..\TestUtility\TestUtility.csproj" />
3031
</ItemGroup>
3132

3233
</Project>

0 commit comments

Comments
 (0)