diff --git a/Microsoft.FeatureManagement.sln b/Microsoft.FeatureManagement.sln index 2da0237c..3b8c8661 100644 --- a/Microsoft.FeatureManagement.sln +++ b/Microsoft.FeatureManagement.sln @@ -27,8 +27,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.FeatureManagement EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EvaluationDataToApplicationInsights", "examples\EvaluationDataToApplicationInsights\EvaluationDataToApplicationInsights.csproj", "{1502529E-47E9-4306-98C4-BF6CF7C7C275}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.FeatureManagement.Telemetry.ApplicationInsights.AspNetCore", "src\Microsoft.FeatureManagement.Telemetry.ApplicationInsights.AspNetCore\Microsoft.FeatureManagement.Telemetry.ApplicationInsights.AspNetCore.csproj", "{C647611B-A8E5-4AD7-9DBA-60DDE276644B}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BlazorServerApp", "examples\BlazorServerApp\BlazorServerApp.csproj", "{12BAB5A6-4EEB-4917-B5D9-4AFB6253008E}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "VariantServiceDemo", "examples\VariantServiceDemo\VariantServiceDemo.csproj", "{E8E17CB9-434E-4386-BF96-FA53BBFDCD6F}" @@ -79,10 +77,6 @@ Global {1502529E-47E9-4306-98C4-BF6CF7C7C275}.Debug|Any CPU.Build.0 = Debug|Any CPU {1502529E-47E9-4306-98C4-BF6CF7C7C275}.Release|Any CPU.ActiveCfg = Release|Any CPU {1502529E-47E9-4306-98C4-BF6CF7C7C275}.Release|Any CPU.Build.0 = Release|Any CPU - {C647611B-A8E5-4AD7-9DBA-60DDE276644B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {C647611B-A8E5-4AD7-9DBA-60DDE276644B}.Debug|Any CPU.Build.0 = Debug|Any CPU - {C647611B-A8E5-4AD7-9DBA-60DDE276644B}.Release|Any CPU.ActiveCfg = Release|Any CPU - {C647611B-A8E5-4AD7-9DBA-60DDE276644B}.Release|Any CPU.Build.0 = Release|Any CPU {12BAB5A6-4EEB-4917-B5D9-4AFB6253008E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {12BAB5A6-4EEB-4917-B5D9-4AFB6253008E}.Debug|Any CPU.Build.0 = Debug|Any CPU {12BAB5A6-4EEB-4917-B5D9-4AFB6253008E}.Release|Any CPU.ActiveCfg = Release|Any CPU diff --git a/examples/EvaluationDataToApplicationInsights/EvaluationDataToApplicationInsights.csproj b/examples/EvaluationDataToApplicationInsights/EvaluationDataToApplicationInsights.csproj index d3a84c9d..f4f7bbc6 100644 --- a/examples/EvaluationDataToApplicationInsights/EvaluationDataToApplicationInsights.csproj +++ b/examples/EvaluationDataToApplicationInsights/EvaluationDataToApplicationInsights.csproj @@ -12,7 +12,6 @@ - diff --git a/examples/EvaluationDataToApplicationInsights/Program.cs b/examples/EvaluationDataToApplicationInsights/Program.cs index 2274fcb0..bf83d5d6 100644 --- a/examples/EvaluationDataToApplicationInsights/Program.cs +++ b/examples/EvaluationDataToApplicationInsights/Program.cs @@ -4,7 +4,7 @@ using EvaluationDataToApplicationInsights; using Microsoft.ApplicationInsights.Extensibility; using Microsoft.FeatureManagement; -using Microsoft.FeatureManagement.Telemetry.ApplicationInsights.AspNetCore; +using Microsoft.FeatureManagement.Telemetry.ApplicationInsights; var builder = WebApplication.CreateBuilder(args); diff --git a/examples/VariantServiceDemo/Program.cs b/examples/VariantServiceDemo/Program.cs index b3a4bcfa..89e17c2c 100644 --- a/examples/VariantServiceDemo/Program.cs +++ b/examples/VariantServiceDemo/Program.cs @@ -4,7 +4,7 @@ using VariantServiceDemo; using Microsoft.ApplicationInsights.Extensibility; using Microsoft.FeatureManagement; -using Microsoft.FeatureManagement.Telemetry.ApplicationInsights.AspNetCore; +using Microsoft.FeatureManagement.Telemetry.ApplicationInsights; var builder = WebApplication.CreateBuilder(args); diff --git a/examples/VariantServiceDemo/VariantServiceDemo.csproj b/examples/VariantServiceDemo/VariantServiceDemo.csproj index d3a84c9d..f4f7bbc6 100644 --- a/examples/VariantServiceDemo/VariantServiceDemo.csproj +++ b/examples/VariantServiceDemo/VariantServiceDemo.csproj @@ -12,7 +12,6 @@ - diff --git a/pack.ps1 b/pack.ps1 index 12274bbd..efe1835e 100644 --- a/pack.ps1 +++ b/pack.ps1 @@ -22,8 +22,7 @@ $targetProjects = @( "Microsoft.FeatureManagement", "Microsoft.FeatureManagement.AspNetCore", - "Microsoft.FeatureManagement.Telemetry.ApplicationInsights", - "Microsoft.FeatureManagement.Telemetry.ApplicationInsights.AspNetCore" + "Microsoft.FeatureManagement.Telemetry.ApplicationInsights" ) # Create the log directory. diff --git a/src/Microsoft.FeatureManagement.AspNetCore/TargetingHttpContextMiddleware.cs b/src/Microsoft.FeatureManagement.AspNetCore/TargetingHttpContextMiddleware.cs index 8dd2378f..6103bfa1 100644 --- a/src/Microsoft.FeatureManagement.AspNetCore/TargetingHttpContextMiddleware.cs +++ b/src/Microsoft.FeatureManagement.AspNetCore/TargetingHttpContextMiddleware.cs @@ -3,9 +3,11 @@ // using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Http.Features; using Microsoft.Extensions.Logging; using Microsoft.FeatureManagement.FeatureFilters; using System; +using System.Net.Http; using System.Threading.Tasks; namespace Microsoft.FeatureManagement @@ -23,7 +25,8 @@ public class TargetingHttpContextMiddleware /// /// Creates an instance of the TargetingHttpContextMiddleware /// - public TargetingHttpContextMiddleware(RequestDelegate next, ILoggerFactory loggerFactory) { + public TargetingHttpContextMiddleware(RequestDelegate next, ILoggerFactory loggerFactory) + { _next = next ?? throw new ArgumentNullException(nameof(next)); _logger = loggerFactory?.CreateLogger() ?? throw new ArgumentNullException(nameof(loggerFactory)); } @@ -31,14 +34,14 @@ public TargetingHttpContextMiddleware(RequestDelegate next, ILoggerFactory logge /// /// Adds targeting information to the HTTP context. /// - /// The to add the targeting information to. + /// The to add the targeting information to. /// The to retrieve the targeting information from. /// Thrown if the provided context or targetingContextAccessor is null. - public async Task InvokeAsync(HttpContext context, ITargetingContextAccessor targetingContextAccessor) + public async Task InvokeAsync(HttpContext httpContext, ITargetingContextAccessor targetingContextAccessor) { - if (context == null) + if (httpContext == null) { - throw new ArgumentNullException(nameof(context)); + throw new ArgumentNullException(nameof(httpContext)); } if (targetingContextAccessor == null) @@ -50,14 +53,27 @@ public async Task InvokeAsync(HttpContext context, ITargetingContextAccessor tar if (targetingContext != null) { - context.Items[TargetingIdKey] = targetingContext.UserId; + var activityFeature = httpContext.Features.Get(); + + if (activityFeature == null) + { + _logger.LogDebug("The IHttpActivityFeature from the IFeatureCollection was null"); + } + else if (activityFeature.Activity == null) + { + _logger.LogDebug("The Activity on the IHttpActivityFeature was null"); + } + else + { + activityFeature.Activity.AddBaggage(TargetingIdKey, targetingContext.UserId); + } } else { _logger.LogDebug("The targeting context accessor returned a null TargetingContext"); } - await _next(context); + await _next(httpContext); } } } diff --git a/src/Microsoft.FeatureManagement.Telemetry.ApplicationInsights.AspNetCore/Microsoft.FeatureManagement.Telemetry.ApplicationInsights.AspNetCore.csproj b/src/Microsoft.FeatureManagement.Telemetry.ApplicationInsights.AspNetCore/Microsoft.FeatureManagement.Telemetry.ApplicationInsights.AspNetCore.csproj deleted file mode 100644 index 0c4eb847..00000000 --- a/src/Microsoft.FeatureManagement.Telemetry.ApplicationInsights.AspNetCore/Microsoft.FeatureManagement.Telemetry.ApplicationInsights.AspNetCore.csproj +++ /dev/null @@ -1,52 +0,0 @@ - - - - - - 4 - 0 - 0 - -preview3 - - - - - - net6.0;net7.0;net8.0 - enable - true - false - ..\..\build\Microsoft.FeatureManagement.snk - - - - Microsoft.FeatureManagement.Telemetry.ApplicationInsights.AspNetCore provides a solution for tagging Application Insights telemetry with Microsoft.FeatureManagement targeting information. - Microsoft - Microsoft - https://licenses.nuget.org/MIT - https://github.com/Azure/AppConfiguration - Release notes can be found at https://aka.ms/MicrosoftFeatureManagementReleaseNotes - Microsoft FeatureManagement FeatureFlags ApplicationInsights - https://aka.ms/AzureAppConfigurationPackageIcon - © Microsoft Corporation. All rights reserved. - - - - - - - - - - - - - - bin\$(Configuration)\$(TargetFramework)\$(RuntimeIdentifier)\XMLComments\$(MSBuildProjectName).xml - - - - - - - diff --git a/src/Microsoft.FeatureManagement.Telemetry.ApplicationInsights.AspNetCore/TargetingTelemetryInitializer.cs b/src/Microsoft.FeatureManagement.Telemetry.ApplicationInsights.AspNetCore/TargetingTelemetryInitializer.cs deleted file mode 100644 index e01bd9e4..00000000 --- a/src/Microsoft.FeatureManagement.Telemetry.ApplicationInsights.AspNetCore/TargetingTelemetryInitializer.cs +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT license. -// - -using Microsoft.ApplicationInsights.AspNetCore.TelemetryInitializers; -using Microsoft.ApplicationInsights.Channel; -using Microsoft.ApplicationInsights.DataContracts; -using Microsoft.AspNetCore.Http; - -namespace Microsoft.FeatureManagement.Telemetry.ApplicationInsights.AspNetCore -{ - /// - /// Used to add targeting information to outgoing Application Insights telemetry. - /// - public class TargetingTelemetryInitializer : TelemetryInitializerBase - { - private const string TargetingIdKey = $"Microsoft.FeatureManagement.TargetingId"; - - /// - /// Creates an instance of the TargetingTelemetryInitializer - /// - public TargetingTelemetryInitializer(IHttpContextAccessor httpContextAccessor) : base(httpContextAccessor) - { - } - - /// - /// When telemetry is initialized, adds targeting information to all relevant telemetry. - /// - /// The to get the targeting information from. - /// The relevant to the telemetry. - /// The to be initialized. - /// Thrown if the any param is null. - protected override void OnInitializeTelemetry(HttpContext httpContext, RequestTelemetry requestTelemetry, ITelemetry telemetry) - { - if (telemetry == null) - { - throw new ArgumentNullException(nameof(telemetry)); - } - - if (httpContext == null) - { - throw new ArgumentNullException(nameof(httpContext)); - } - - // Extract the targeting id from the http context - string targetingId = null; - - if (httpContext.Items.TryGetValue(TargetingIdKey, out object value)) - { - targetingId = value?.ToString(); - } - - if (!string.IsNullOrEmpty(targetingId)) - { - // Telemetry.Properties is deprecated in favor of ISupportProperties - if (telemetry is ISupportProperties telemetryWithSupportProperties) - { - telemetryWithSupportProperties.Properties["TargetingId"] = targetingId; - } - } - } - } -} diff --git a/src/Microsoft.FeatureManagement.Telemetry.ApplicationInsights/TargetingTelemetryInitializer.cs b/src/Microsoft.FeatureManagement.Telemetry.ApplicationInsights/TargetingTelemetryInitializer.cs new file mode 100644 index 00000000..7c2948e6 --- /dev/null +++ b/src/Microsoft.FeatureManagement.Telemetry.ApplicationInsights/TargetingTelemetryInitializer.cs @@ -0,0 +1,47 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. +// + +using Microsoft.ApplicationInsights.Channel; +using Microsoft.ApplicationInsights.DataContracts; +using Microsoft.ApplicationInsights.Extensibility; +using System.Diagnostics; + +namespace Microsoft.FeatureManagement.Telemetry.ApplicationInsights +{ + /// + /// Used to add targeting information to outgoing Application Insights telemetry. + /// + public class TargetingTelemetryInitializer : ITelemetryInitializer + { + private const string TargetingIdKey = $"Microsoft.FeatureManagement.TargetingId"; + + /// + /// When telemetry is initialized, adds targeting information to all relevant telemetry. + /// + /// The to be initialized. + /// Thrown if the any param is null. + public void Initialize(ITelemetry telemetry) + { + if (telemetry == null) + { + throw new ArgumentNullException(nameof(telemetry)); + } + + // Extract the targeting id from the current activity's baggage + string targetingId = Activity.Current?.Baggage.FirstOrDefault(t => t.Key == TargetingIdKey).Value; + + // Don't modify telemetry if there's no available targeting id + if (string.IsNullOrEmpty(targetingId)) + { + return; + } + + // Telemetry.Properties is deprecated in favor of ISupportProperties + if (telemetry is ISupportProperties telemetryWithSupportProperties) + { + telemetryWithSupportProperties.Properties["TargetingId"] = targetingId; + } + } + } +}