diff --git a/CHANGELOG.md b/CHANGELOG.md
index da30970e..201f5f46 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -12,6 +12,7 @@
- [Added ability to remove any default Telemetry Module.](https://github.com/Microsoft/ApplicationInsights-aspnetcore/issues/633)
- [TelemetryChannel is configured via DI, making it easier to override channel](https://github.com/Microsoft/ApplicationInsights-aspnetcore/issues/641)
- [Fixed a bug which caused QuickPulse and Sampling to be enabled only if ServerTelemetryChannel was used](https://github.com/Microsoft/ApplicationInsights-aspnetcore/issues/642)
+- [QuickPulseTelemetryModule is constructed via DI, make it possible for users to configure it.] (https://github.com/Microsoft/ApplicationInsights-aspnetcore/issues/639)
## Version 2.2.1
- Updated Web/Base SDK version dependency to 2.5.1 which addresses a bug.
diff --git a/src/Microsoft.ApplicationInsights.AspNetCore/Extensibility/Implementation/Tracing/AspNetEventSource.cs b/src/Microsoft.ApplicationInsights.AspNetCore/Extensibility/Implementation/Tracing/AspNetEventSource.cs
index c91e53f1..38e576a4 100644
--- a/src/Microsoft.ApplicationInsights.AspNetCore/Extensibility/Implementation/Tracing/AspNetEventSource.cs
+++ b/src/Microsoft.ApplicationInsights.AspNetCore/Extensibility/Implementation/Tracing/AspNetEventSource.cs
@@ -140,6 +140,12 @@ public void UnableToFindModuleToConfigure(string moduleType, string appDomainNam
this.WriteEvent(11, moduleType, this.ApplicationName);
}
+ [Event(12, Message = "Unable to find QuickPulseTelemetryModule in service collection. LiveMetrics feature will not be available. Please add QuickPulseTelemetryModule to services collection in the ConfigureServices method of your application Startup class.", Level = EventLevel.Error, Keywords = Keywords.Diagnostics)]
+ public void UnableToFindQuickPulseModuleInDI(string appDomainName = "Incorrect")
+ {
+ this.WriteEvent(12, this.ApplicationName);
+ }
+
///
/// Keywords for the AspNetEventSource.
///
diff --git a/src/Microsoft.ApplicationInsights.AspNetCore/Extensions/ApplicationInsightsExtensions.cs b/src/Microsoft.ApplicationInsights.AspNetCore/Extensions/ApplicationInsightsExtensions.cs
index 05c0018f..86c4d59a 100644
--- a/src/Microsoft.ApplicationInsights.AspNetCore/Extensions/ApplicationInsightsExtensions.cs
+++ b/src/Microsoft.ApplicationInsights.AspNetCore/Extensions/ApplicationInsightsExtensions.cs
@@ -15,6 +15,7 @@ namespace Microsoft.Extensions.DependencyInjection
using Microsoft.ApplicationInsights.Channel;
using Microsoft.ApplicationInsights.DependencyCollector;
using Microsoft.ApplicationInsights.Extensibility;
+ using Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.QuickPulse;
using Microsoft.ApplicationInsights.WindowsServer;
using Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel;
using Microsoft.AspNetCore.Hosting;
@@ -164,6 +165,7 @@ public static IServiceCollection AddApplicationInsightsTelemetry(this IServiceCo
#endif
services.AddSingleton();
services.AddSingleton();
+ services.AddSingleton();
services.AddSingleton(provider => provider.GetService>().Value);
services.AddSingleton(provider => new CorrelationIdLookupHelper(() => provider.GetService>().Value));
diff --git a/src/Microsoft.ApplicationInsights.AspNetCore/Implementation/TelemetryConfigurationOptionsSetup.cs b/src/Microsoft.ApplicationInsights.AspNetCore/Implementation/TelemetryConfigurationOptionsSetup.cs
index 078bea54..38899475 100644
--- a/src/Microsoft.ApplicationInsights.AspNetCore/Implementation/TelemetryConfigurationOptionsSetup.cs
+++ b/src/Microsoft.ApplicationInsights.AspNetCore/Implementation/TelemetryConfigurationOptionsSetup.cs
@@ -75,20 +75,18 @@ public void Configure(TelemetryConfiguration configuration)
foreach (ITelemetryProcessorFactory processorFactory in this.telemetryProcessorFactories)
{
configuration.TelemetryProcessorChainBuilder.Use(processorFactory.Create);
- }
- configuration.TelemetryProcessorChainBuilder.Build();
+ }
}
+ // Fallback to default channel (InMemoryChannel) created by base sdk if no channel is found in DI
+ configuration.TelemetryChannel = this.telemetryChannel ?? configuration.TelemetryChannel;
+ (configuration.TelemetryChannel as ITelemetryModule)?.Initialize(configuration);
+
this.AddQuickPulse(configuration);
this.AddSampling(configuration);
this.DisableHeartBeatIfConfigured();
-
- (configuration.TelemetryChannel as ITelemetryModule)?.Initialize(configuration);
-
- configuration.TelemetryProcessorChainBuilder.Build();
-
- // Fallback to default channel (InMemoryChannel) created by base sdk if no channel is found in DI
- configuration.TelemetryChannel = this.telemetryChannel ?? configuration.TelemetryChannel;
+
+ configuration.TelemetryProcessorChainBuilder.Build();
if (this.applicationInsightsServiceOptions.DeveloperMode != null)
{
@@ -121,20 +119,25 @@ public void Configure(TelemetryConfiguration configuration)
}
private void AddQuickPulse(TelemetryConfiguration configuration)
- {
+ {
if (this.applicationInsightsServiceOptions.EnableQuickPulseMetricStream)
- {
- var quickPulseModule = new QuickPulseTelemetryModule();
- quickPulseModule.Initialize(configuration);
-
- QuickPulseTelemetryProcessor processor = null;
- configuration.TelemetryProcessorChainBuilder.Use((next) =>
+ {
+ QuickPulseTelemetryModule quickPulseModule = this.modules.FirstOrDefault(((module) => module.GetType() == typeof(QuickPulseTelemetryModule))) as QuickPulseTelemetryModule;
+ if (quickPulseModule != null)
+ {
+ QuickPulseTelemetryProcessor processor = null;
+ configuration.TelemetryProcessorChainBuilder.Use((next) =>
+ {
+ processor = new QuickPulseTelemetryProcessor(next);
+ quickPulseModule.RegisterTelemetryProcessor(processor);
+ return processor;
+ });
+ }
+ else
{
- processor = new QuickPulseTelemetryProcessor(next);
- quickPulseModule.RegisterTelemetryProcessor(processor);
- return processor;
- });
- }
+ AspNetCoreEventSource.Instance.UnableToFindQuickPulseModuleInDI();
+ }
+ }
}
private void AddSampling(TelemetryConfiguration configuration)
diff --git a/test/Microsoft.ApplicationInsights.AspNetCore.Tests/Extensions/ApplicationInsightsExtensionsTests.cs b/test/Microsoft.ApplicationInsights.AspNetCore.Tests/Extensions/ApplicationInsightsExtensionsTests.cs
index 59533fb6..3c8cb846 100644
--- a/test/Microsoft.ApplicationInsights.AspNetCore.Tests/Extensions/ApplicationInsightsExtensionsTests.cs
+++ b/test/Microsoft.ApplicationInsights.AspNetCore.Tests/Extensions/ApplicationInsightsExtensionsTests.cs
@@ -348,15 +348,24 @@ public static void RegistersTelemetryConfigurationFactoryMethodThatPopulatesItWi
Assert.NotNull(modules);
#if NET46
- Assert.Equal(4, modules.Count());
+ Assert.Equal(5, modules.Count());
var perfCounterModule = services.FirstOrDefault(t => t.ImplementationType == typeof(PerformanceCollectorModule));
Assert.NotNull(perfCounterModule);
#else
- Assert.Equal(3, modules.Count());
+ Assert.Equal(4, modules.Count());
#endif
var dependencyModuleDescriptor = services.FirstOrDefault(t => t.ImplementationType == typeof(DependencyTrackingTelemetryModule));
- Assert.NotNull(dependencyModuleDescriptor);
+ Assert.NotNull(dependencyModuleDescriptor);
+
+ var appServiceHeartBeatModuleDescriptor = services.FirstOrDefault(t => t.ImplementationType == typeof(AppServicesHeartbeatTelemetryModule));
+ Assert.NotNull(appServiceHeartBeatModuleDescriptor);
+
+ var azureMetadataHeartBeatModuleDescriptor = services.FirstOrDefault(t => t.ImplementationType == typeof(AzureInstanceMetadataTelemetryModule));
+ Assert.NotNull(azureMetadataHeartBeatModuleDescriptor);
+
+ var quickPulseModuleDescriptor = services.FirstOrDefault(t => t.ImplementationType == typeof(QuickPulseTelemetryModule));
+ Assert.NotNull(quickPulseModuleDescriptor);
}
[Fact]
public static void RegistersTelemetryConfigurationFactoryMethodThatPopulatesDependencyCollectorWithDefaultValues()