Skip to content
This repository has been archived by the owner on Jun 10, 2020. It is now read-only.

Commit

Permalink
Merge branch 'develop' into tilee/refactor_projects
Browse files Browse the repository at this point in the history
  • Loading branch information
TimothyMothra authored Oct 18, 2019
2 parents ba5c4b7 + bcd569e commit 6525d56
Show file tree
Hide file tree
Showing 10 changed files with 573 additions and 35 deletions.
11 changes: 9 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,24 @@
# Changelog


## Version 2.12.0-beta1
- Skipping version numbers to keep in sync with Base SDK.
- [Fix Null/Empty Ikey from ApplicationInsightsServiceOptions overrding one from appsettings.json](https://github.com/microsoft/ApplicationInsights-aspnetcore/issues/989)
- [Provide ApplicationInsightsServiceOptions for easy disabling of any default TelemetryModules](https://github.com/microsoft/ApplicationInsights-aspnetcore/issues/988)
- [Added support for SDK Connection String](https://github.com/microsoft/ApplicationInsights-dotnet/issues/1221)
- [New RoleName initializer for Azure Web App to accurately populate RoleName.](https://github.com/microsoft/ApplicationInsights-dotnet-server/issues/1207)
- Update to Base/Web/Logging SDK to 2.12.0-beta1

## Version 2.8.2
- Updated Web SDK to 2.11.2

## Version 2.8.1
- Updated Web SDK to 2.11.1

## Version 2.8.0
- Updated Bask SDK/Web SDK/Logging Adaptor SDK to 2.11.0
- Updated Base SDK/Web SDK/Logging Adaptor SDK to 2.11.0
- Updated System.Diagnostics.DiagnosticSource to 4.6.0


## Version 2.8.0-beta3
- [Make W3C Correlation default and leverage native W3C support from Activity.](https://github.com/microsoft/ApplicationInsights-aspnetcore/pull/958)
- [Make W3C Correlation default and leverage native W3C support from Activity for Asp.Net Core 3.0.](https://github.com/microsoft/ApplicationInsights-aspnetcore/pull/958)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,17 @@ public void LogInformational(string message, string appDomainName = "Incorrect")
this.WriteEvent(23, message, this.applicationNameProvider.Name);
}

/// <summary>
/// Logs an event when AzureAppServiceRoleNameFromHostNameHeaderInitializer faces errors.
/// </summary>
/// <param name="exception">Exception message.</param>
/// <param name="appDomainName">An ignored placeholder to make EventSource happy.</param>
[Event(24, Message = "An error has occured in AzureAppServiceRoleNameFromHostNameHeaderInitializer. Exception: '{0}'", Level = EventLevel.Warning, Keywords = Keywords.Diagnostics)]
public void LogAzureAppServiceRoleNameFromHostNameHeaderInitializerWarning(string exception, string appDomainName = "Incorrect")
{
this.WriteEvent(24, exception, this.applicationNameProvider.Name);
}

/// <summary>
/// Keywords for the AspNetEventSource.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,35 +1,21 @@
namespace Microsoft.Extensions.DependencyInjection
{
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Reflection;

using Microsoft.ApplicationInsights;
using Microsoft.ApplicationInsights.AspNetCore;
using Microsoft.ApplicationInsights.AspNetCore.Extensibility.Implementation.Tracing;
using Microsoft.ApplicationInsights.AspNetCore.Extensions;
using Microsoft.ApplicationInsights.AspNetCore.TelemetryInitializers;
using Microsoft.ApplicationInsights.Channel;
using Microsoft.ApplicationInsights.DependencyCollector;
using Microsoft.ApplicationInsights.Extensibility;
#if NETSTANDARD2_0
using Microsoft.ApplicationInsights.Extensibility.EventCounterCollector;
#endif
using Microsoft.ApplicationInsights.Extensibility.Implementation.ApplicationId;
using Microsoft.ApplicationInsights.Extensibility.Implementation.Tracing;
using Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector;
using Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.QuickPulse;
using Microsoft.ApplicationInsights.WindowsServer;
using Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Configuration.Memory;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Shared.Implementation;

Expand Down Expand Up @@ -198,6 +184,7 @@ public static IServiceCollection AddApplicationInsightsTelemetry(this IServiceCo

private static void AddAspNetCoreWebTelemetryInitializers(IServiceCollection services)
{
services.AddSingleton<ITelemetryInitializer, AzureAppServiceRoleNameFromHostNameHeaderInitializer>();
services.AddSingleton<ITelemetryInitializer, ClientIpHeaderTelemetryInitializer>();
services.AddSingleton<ITelemetryInitializer, OperationNameTelemetryInitializer>();
services.AddSingleton<ITelemetryInitializer, SyntheticTelemetryInitializer>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,11 @@
<Import Project="..\Shared\Shared.projitems" Label="Shared" />

<ItemGroup>
<PackageReference Include="Microsoft.ApplicationInsights" Version="2.12.0-beta1-build4530" />
<PackageReference Include="Microsoft.ApplicationInsights.DependencyCollector" Version="2.12.0-beta1-build5020" />
<PackageReference Include="Microsoft.ApplicationInsights.PerfCounterCollector" Version="2.12.0-beta1-build5020" />
<PackageReference Include="Microsoft.ApplicationInsights.WindowsServer" Version="2.12.0-beta1-build5020" />
<PackageReference Include="Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel" Version="2.12.0-beta1-build4530" />
<PackageReference Include="Microsoft.ApplicationInsights" Version="2.12.0-beta1" />
<PackageReference Include="Microsoft.ApplicationInsights.DependencyCollector" Version="2.12.0-beta1" />
<PackageReference Include="Microsoft.ApplicationInsights.PerfCounterCollector" Version="2.12.0-beta1" />
<PackageReference Include="Microsoft.ApplicationInsights.WindowsServer" Version="2.12.0-beta1" />
<PackageReference Include="Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel" Version="2.12.0-beta1" />
<PackageReference Include="Microsoft.AspNetCore.Hosting" Version="1.0.2" />
<PackageReference Include="System.Text.Encodings.Web" Version="4.3.1" />
<PackageReference Include="System.Diagnostics.DiagnosticSource" Version="4.6.0" />
Expand All @@ -82,8 +82,8 @@

<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard2.0' ">
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.1.0" />
<PackageReference Include="Microsoft.Extensions.Logging.ApplicationInsights" Version="2.11.0" />
<PackageReference Include="Microsoft.ApplicationInsights.EventCounterCollector" Version="2.12.0-beta1-build5020" />
<PackageReference Include="Microsoft.Extensions.Logging.ApplicationInsights" Version="2.12.0-beta1" />
<PackageReference Include="Microsoft.ApplicationInsights.EventCounterCollector" Version="2.12.0-beta1" />
<PackageReference Include="System.Text.Encodings.Web" Version="4.3.1" />
</ItemGroup>

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
namespace Microsoft.ApplicationInsights.AspNetCore.TelemetryInitializers
{
using System;
using Microsoft.ApplicationInsights.AspNetCore.Extensibility.Implementation.Tracing;
using Microsoft.ApplicationInsights.Channel;
using Microsoft.ApplicationInsights.DataContracts;
using Microsoft.ApplicationInsights.Extensibility;
using Microsoft.ApplicationInsights.Extensibility.Implementation.Tracing;
using Microsoft.AspNetCore.Http;

/// <summary>
/// A telemetry initializer that will gather Azure Web App Role Environment context information to
/// populate TelemetryContext.Cloud.RoleName
/// This uses the http header "WAS-DEFAULT-HOSTNAME" to update role name, if available.
/// Otherwise role name is populated from "WEBSITE_HOSTNAME" environment variable.
/// </summary>
/// <remarks>
/// The RoleName is expected to contain the host name + slot name, but will be same across all instances of
/// a single App Service.
/// Populating RoleName from HOSTNAME environment variable will cause RoleName to be incorrect when a slot swap occurs in AppService.
/// The most accurate way to determine the RoleName is to rely on the header WAS-DEFAULT-HOSTNAME, as its
/// populated from App service front end on every request. Slot swaps are instantly reflected in this header.
/// </remarks>
public class AzureAppServiceRoleNameFromHostNameHeaderInitializer : ITelemetryInitializer
{
private const string WebAppHostNameHeaderName = "WAS-DEFAULT-HOSTNAME";
private const string WebAppHostNameEnvironmentVariable = "WEBSITE_HOSTNAME";
private readonly IHttpContextAccessor httpContextAccessor;
private string roleName;
private bool isAzureWebApp;

/// <summary>
/// Initializes a new instance of the <see cref="AzureAppServiceRoleNameFromHostNameHeaderInitializer" /> class.
/// </summary>
/// <param name="httpContextAccessor">Accessor to provide HttpContext if available.</param>
public AzureAppServiceRoleNameFromHostNameHeaderInitializer(IHttpContextAccessor httpContextAccessor)
: this(httpContextAccessor, ".azurewebsites.net")
{
}

/// <summary>
/// Initializes a new instance of the <see cref="AzureAppServiceRoleNameFromHostNameHeaderInitializer" /> class.
/// </summary>
/// <param name="httpContextAccessor">Accessor to provide HttpContext if available.</param>
/// <param name="webAppSuffix">WebApp name suffix.</param>
public AzureAppServiceRoleNameFromHostNameHeaderInitializer(IHttpContextAccessor httpContextAccessor, string webAppSuffix)
{
this.httpContextAccessor = httpContextAccessor ?? throw new ArgumentNullException(nameof(httpContextAccessor));
this.WebAppSuffix = webAppSuffix;

try
{
var result = Environment.GetEnvironmentVariable(WebAppHostNameEnvironmentVariable);
this.isAzureWebApp = !string.IsNullOrEmpty(result);

if (!string.IsNullOrEmpty(result) && result.EndsWith(this.WebAppSuffix, StringComparison.OrdinalIgnoreCase))
{
result = result.Substring(0, result.Length - this.WebAppSuffix.Length);
}

this.roleName = result;
}
catch (Exception ex)
{
AspNetCoreEventSource.Instance.LogAzureAppServiceRoleNameFromHostNameHeaderInitializerWarning(ex.ToInvariantString());
}
}

/// <summary>
/// Gets or sets suffix of website name. This must be changed when running in non public Azure region.
/// Default value (Public Cloud): ".azurewebsites.net"
/// For US Gov Cloud: ".azurewebsites.us"
/// For Azure Germany: ".azurewebsites.de".
/// </summary>
public string WebAppSuffix { get; set; }

/// <summary>
/// Populates RoleName from the request telemetry associated with the http context.
/// If RoleName is empty on the request telemetry, it'll be updated as well so that other telemetry
/// belonging to the same requests gets it from request telemetry, without having to parse headers again.
/// </summary>
/// <remarks>
/// RoleName is attempted from every incoming request as opposed to doing this periodically. This is
/// done to ensure every request (and associated telemetry) gets the correct RoleName during slot swap.
/// </remarks>
/// <param name="telemetry">The telemetry item for which RoleName is to be set.</param>
public void Initialize(ITelemetry telemetry)
{
try
{
if (!this.isAzureWebApp)
{
// return immediately if not azure web app.
return;
}

if (!string.IsNullOrEmpty(telemetry.Context.Cloud.RoleName))
{
// RoleName is already populated.
return;
}

string roleName = string.Empty;
var context = this.httpContextAccessor.HttpContext;

if (context != null)
{
lock (context)
{
var request = context.Features.Get<RequestTelemetry>();

if (request != null)
{
if (string.IsNullOrEmpty(request.Context.Cloud.RoleName))
{
if (this.TryGetRoleNameFromHeader(context, out roleName))
{
request.Context.Cloud.RoleName = roleName;
}
}
else
{
roleName = request.Context.Cloud.RoleName;
}
}
else
{
if (!this.TryGetRoleNameFromHeader(context, out roleName))
{
roleName = this.roleName;
}
}
}
}

if (string.IsNullOrEmpty(roleName))
{
// Fallback to value from ENV variable.
roleName = this.roleName;
}

telemetry.Context.Cloud.RoleName = roleName;
}
catch (Exception ex)
{
AspNetCoreEventSource.Instance.LogAzureAppServiceRoleNameFromHostNameHeaderInitializerWarning(ex.ToInvariantString());
}
}

private bool TryGetRoleNameFromHeader(HttpContext context, out string roleName)
{
roleName = string.Empty;

if (context.Request?.Headers != null)
{
string headerValue = context.Request.Headers[WebAppHostNameHeaderName];
if (!string.IsNullOrEmpty(headerValue))
{
if (headerValue.EndsWith(this.WebAppSuffix, StringComparison.OrdinalIgnoreCase))
{
headerValue = headerValue.Substring(0, headerValue.Length - this.WebAppSuffix.Length);
}

roleName = headerValue;
return true;
}
}

return false;
}
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
namespace Microsoft.Extensions.DependencyInjection
{
using System;

using Microsoft.ApplicationInsights.Extensibility;
using Microsoft.ApplicationInsights.Extensibility.Implementation.Tracing;
using Microsoft.ApplicationInsights.WindowsServer;
using Microsoft.ApplicationInsights.WorkerService;
using Microsoft.ApplicationInsights.WorkerService.Implementation.Tracing;
using Microsoft.Extensions.Configuration;
Expand Down Expand Up @@ -89,6 +90,7 @@ public static IServiceCollection AddApplicationInsightsTelemetryWorkerService(th
{
if (!IsApplicationInsightsAdded(services))
{
services.AddSingleton<ITelemetryInitializer, AzureWebAppRoleEnvironmentTelemetryInitializer>();
AddCommonInitializers(services);
AddCommonTelemetryModules(services);
AddTelemetryChannel(services);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,13 +58,13 @@
<Import Project="..\Shared\Shared.projitems" Label="Shared" />

<ItemGroup>
<PackageReference Include="Microsoft.ApplicationInsights" Version="2.12.0-beta1-build4530" />
<PackageReference Include="Microsoft.ApplicationInsights.DependencyCollector" Version="2.12.0-beta1-build5020" />
<PackageReference Include="Microsoft.ApplicationInsights.PerfCounterCollector" Version="2.12.0-beta1-build5020" />
<PackageReference Include="Microsoft.ApplicationInsights.WindowsServer" Version="2.12.0-beta1-build5020" />
<PackageReference Include="Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel" Version="2.12.0-beta1-build4530" />
<PackageReference Include="Microsoft.Extensions.Logging.ApplicationInsights" Version="2.11.0" />
<PackageReference Include="Microsoft.ApplicationInsights.EventCounterCollector" Version="2.12.0-beta1-build5020" />
<PackageReference Include="Microsoft.ApplicationInsights" Version="2.12.0-beta1" />
<PackageReference Include="Microsoft.ApplicationInsights.DependencyCollector" Version="2.12.0-beta1" />
<PackageReference Include="Microsoft.ApplicationInsights.PerfCounterCollector" Version="2.12.0-beta1" />
<PackageReference Include="Microsoft.ApplicationInsights.WindowsServer" Version="2.12.0-beta1" />
<PackageReference Include="Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel" Version="2.12.0-beta1" />
<PackageReference Include="Microsoft.Extensions.Logging.ApplicationInsights" Version="2.12.0-beta1" />
<PackageReference Include="Microsoft.ApplicationInsights.EventCounterCollector" Version="2.12.0-beta1" />

<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="2.2.0" />
</ItemGroup>
Expand Down
3 changes: 1 addition & 2 deletions src/Shared/Extensions/ApplicationInsightsExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -302,8 +302,7 @@ private static void AddCommonInitializers(IServiceCollection services)
services.AddSingleton<ITelemetryInitializer, Microsoft.ApplicationInsights.AspNetCore.TelemetryInitializers.DomainNameRoleInstanceTelemetryInitializer>();
#else
services.AddSingleton<ITelemetryInitializer, Microsoft.ApplicationInsights.WorkerService.TelemetryInitializers.DomainNameRoleInstanceTelemetryInitializer>();
#endif
services.AddSingleton<ITelemetryInitializer, AzureWebAppRoleEnvironmentTelemetryInitializer>();
#endif
services.AddSingleton<ITelemetryInitializer, HttpDependenciesParsingTelemetryInitializer>();
services.AddSingleton<ITelemetryInitializer, ComponentVersionTelemetryInitializer>();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public static class AddApplicationInsightsTelemetry
{
[Theory]
[InlineData(typeof(ITelemetryInitializer), typeof(ApplicationInsights.AspNetCore.TelemetryInitializers.DomainNameRoleInstanceTelemetryInitializer), ServiceLifetime.Singleton)]
[InlineData(typeof(ITelemetryInitializer), typeof(AzureWebAppRoleEnvironmentTelemetryInitializer), ServiceLifetime.Singleton)]
[InlineData(typeof(ITelemetryInitializer), typeof(AzureAppServiceRoleNameFromHostNameHeaderInitializer), ServiceLifetime.Singleton)]
[InlineData(typeof(ITelemetryInitializer), typeof(ComponentVersionTelemetryInitializer), ServiceLifetime.Singleton)]
[InlineData(typeof(ITelemetryInitializer), typeof(ClientIpHeaderTelemetryInitializer), ServiceLifetime.Singleton)]
[InlineData(typeof(ITelemetryInitializer), typeof(OperationNameTelemetryInitializer), ServiceLifetime.Singleton)]
Expand All @@ -77,7 +77,7 @@ public static void RegistersExpectedServices(Type serviceType, Type implementati

[Theory]
[InlineData(typeof(ITelemetryInitializer), typeof(ApplicationInsights.AspNetCore.TelemetryInitializers.DomainNameRoleInstanceTelemetryInitializer), ServiceLifetime.Singleton)]
[InlineData(typeof(ITelemetryInitializer), typeof(AzureWebAppRoleEnvironmentTelemetryInitializer), ServiceLifetime.Singleton)]
[InlineData(typeof(ITelemetryInitializer), typeof(AzureAppServiceRoleNameFromHostNameHeaderInitializer), ServiceLifetime.Singleton)]
[InlineData(typeof(ITelemetryInitializer), typeof(ComponentVersionTelemetryInitializer), ServiceLifetime.Singleton)]
[InlineData(typeof(ITelemetryInitializer), typeof(ClientIpHeaderTelemetryInitializer), ServiceLifetime.Singleton)]
[InlineData(typeof(ITelemetryInitializer), typeof(OperationNameTelemetryInitializer), ServiceLifetime.Singleton)]
Expand Down
Loading

0 comments on commit 6525d56

Please sign in to comment.