Enable ILogger by default (#853)
Enable ILogger by default when enabling application insights monitoring.
This commit is contained in:
Родитель
27181c90de
Коммит
04ec946077
|
@ -1,6 +1,7 @@
|
|||
# Changelog
|
||||
|
||||
## Version 2.7.0-beta3
|
||||
- [Enables Microsoft.Extensions.Logging.ApplicationInsights.ApplicationInsightsLoggerProvider by default. If ApplicationInsightsLoggerProvider was enabled previously using ILoggerFactory extension method, please remove it to prevent duplicate logs.](https://github.com/Microsoft/ApplicationInsights-aspnetcore/issues/854)
|
||||
- [Remove reference to Microsoft.Extensions.DiagnosticAdapter and use DiagnosticSource subscription APIs directly](https://github.com/Microsoft/ApplicationInsights-aspnetcore/pull/852)
|
||||
- [Fix: NullReferenceException in ApplicationInsightsLogger.Log when exception contains a Data entry with a null value](https://github.com/Microsoft/ApplicationInsights-aspnetcore/issues/848)
|
||||
|
||||
|
|
|
@ -3,6 +3,10 @@
|
|||
- [Microsoft.ApplicationInsights.AspNetCore](https://www.nuget.org/packages/Microsoft.ApplicationInsights.AspNetCore/)
|
||||
[![Nuget](https://img.shields.io/nuget/vpre/Microsoft.ApplicationInsights.AspNetCore.svg)](https://nuget.org/packages/Microsoft.ApplicationInsights.AspNetCore)
|
||||
|
||||
Windows: [![Build Status](https://mseng.visualstudio.com/AppInsights/_apis/build/status/ChuckNorris/AI_ASPNETCore_Develop?branchName=develop)](https://mseng.visualstudio.com/AppInsights/_build/latest?definitionId=3717&branchName=develop)
|
||||
|
||||
Linux :[![Build Status](https://mseng.visualstudio.com/AppInsights/_apis/build/status/ChuckNorris/AI-AspNetCoreSDK-develop-linux?branchName=develop)](https://mseng.visualstudio.com/AppInsights/_build/latest?definitionId=6273&branchName=develop)
|
||||
|
||||
|
||||
Microsoft Application Insights for ASP.NET Core applications
|
||||
=============================================================
|
||||
|
|
|
@ -22,8 +22,10 @@
|
|||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Configuration.Memory;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
/// <summary>
|
||||
/// Extension methods for <see cref="IServiceCollection"/> that allow adding Application Insights services to application.
|
||||
|
@ -190,8 +192,6 @@
|
|||
|
||||
services.AddSingleton<TelemetryClient>();
|
||||
|
||||
services.AddSingleton<ApplicationInsightsDebugLogger, ApplicationInsightsDebugLogger>();
|
||||
|
||||
services
|
||||
.TryAddSingleton<IConfigureOptions<ApplicationInsightsServiceOptions>,
|
||||
DefaultApplicationInsightsServiceConfigureOptions>();
|
||||
|
@ -201,12 +201,38 @@
|
|||
// that requires IOptions infrastructure to run and initialize
|
||||
services.AddSingleton<IStartupFilter, ApplicationInsightsStartupFilter>();
|
||||
|
||||
services.AddSingleton<JavaScriptSnippet>();
|
||||
services.AddSingleton<ApplicationInsightsLoggerEvents>();
|
||||
services.AddSingleton<JavaScriptSnippet>();
|
||||
|
||||
services.AddOptions();
|
||||
services.AddSingleton<IOptions<TelemetryConfiguration>, TelemetryConfigurationOptions>();
|
||||
services.AddSingleton<IConfigureOptions<TelemetryConfiguration>, TelemetryConfigurationOptionsSetup>();
|
||||
|
||||
// NetStandard2.0 has a package reference to Microsoft.Extensions.Logging.ApplicationInsights, and
|
||||
// enables ApplicationInsightsLoggerProvider by default.
|
||||
#if NETSTANDARD2_0
|
||||
services.AddLogging(loggingBuilder =>
|
||||
{
|
||||
loggingBuilder.AddApplicationInsights();
|
||||
|
||||
// The default behavior is to capture only logs above Warning level from all categories.
|
||||
// This can achieved with this code level filter -> loggingBuilder.AddFilter<Microsoft.Extensions.Logging.ApplicationInsights.ApplicationInsightsLoggerProvider>("",LogLevel.Warning);
|
||||
// However, this will make it impossible to override this behavior from Configuration like below using appsettings.json:
|
||||
//"ApplicationInsights": {
|
||||
// "LogLevel": {
|
||||
// "": "Error"
|
||||
// }
|
||||
// },
|
||||
// The reason is as both rules will match the filter, the last one added wins.
|
||||
// To ensure that the default filter is in the beginning of filter rules, so that user override from Configuration will always win,
|
||||
// we add code filter rule to the 0th position as below.
|
||||
|
||||
loggingBuilder.Services.Configure<LoggerFilterOptions>
|
||||
(options => options.Rules.Insert(0,
|
||||
new LoggerFilterRule(
|
||||
"Microsoft.Extensions.Logging.ApplicationInsights.ApplicationInsightsLoggerProvider", null,
|
||||
LogLevel.Warning, null)));
|
||||
});
|
||||
#endif
|
||||
}
|
||||
|
||||
return services;
|
||||
|
@ -406,8 +432,8 @@
|
|||
|
||||
private static bool IsApplicationInsightsAdded(IServiceCollection services)
|
||||
{
|
||||
// We treat ApplicationInsightsDebugLogger as a marker that AI services were added to service collection
|
||||
return services.Any(service => service.ServiceType == typeof(ApplicationInsightsDebugLogger));
|
||||
// We treat TelemetryClient as a marker that AI services were added to service collection
|
||||
return services.Any(service => service.ServiceType == typeof(TelemetryClient));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
{
|
||||
using System;
|
||||
using ApplicationInsights;
|
||||
using ApplicationInsights.AspNetCore.Logging;
|
||||
using Microsoft.ApplicationInsights;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
|
@ -16,7 +16,7 @@
|
|||
/// </summary>
|
||||
/// <param name="factory"></param>
|
||||
/// <param name="serviceProvider">The instance of <see cref="IServiceProvider"/> to use for service resolution.</param>
|
||||
[Obsolete("Use Microsoft.Extensions.Logging.ApplicationInsightsLoggingBuilderExtensions.AddApplicationInsights from Microsoft.Extensions.Logging.ApplicationInsights package")]
|
||||
[Obsolete("ApplicationInsightsLoggerProvider is now enabled by default when enabling ApplicationInsights monitoring using UseApplicationInsights extension method on IWebHostBuilder or AddApplicationInsightsTelemetry extension method on IServiceCollection. From 2.7.0-beta3 onwards, calling this method will result in double logging and filters applied will not get applied. If interested in using just logging provider, then please use Microsoft.Extensions.Logging.ApplicationInsightsLoggingBuilderExtensions.AddApplicationInsights from Microsoft.Extensions.Logging.ApplicationInsights package. Read more https://aka.ms/ApplicationInsightsILoggerFaq")]
|
||||
public static ILoggerFactory AddApplicationInsights(this ILoggerFactory factory, IServiceProvider serviceProvider)
|
||||
{
|
||||
return factory.AddApplicationInsights(serviceProvider, LogLevel.Warning);
|
||||
|
@ -28,7 +28,7 @@
|
|||
/// <param name="factory"></param>
|
||||
/// <param name="serviceProvider">The instance of <see cref="IServiceProvider"/> to use for service resolution.</param>
|
||||
/// <param name="minLevel">The minimum <see cref="LogLevel"/> to be logged</param>
|
||||
[Obsolete("Use Microsoft.Extensions.Logging.ApplicationInsightsLoggingBuilderExtensions.AddApplicationInsights from Microsoft.Extensions.Logging.ApplicationInsights package")]
|
||||
[Obsolete("ApplicationInsightsLoggerProvider is now enabled by default when enabling ApplicationInsights monitoring using UseApplicationInsights extension method on IWebHostBuilder or AddApplicationInsightsTelemetry extension method on IServiceCollection. From 2.7.0-beta3 onwards, calling this method will result in double logging and filters applied will not get applied. If interested in using just logging provider, then please use Microsoft.Extensions.Logging.ApplicationInsightsLoggingBuilderExtensions.AddApplicationInsights from Microsoft.Extensions.Logging.ApplicationInsights package. Read more https://aka.ms/ApplicationInsightsILoggerFaq")]
|
||||
public static ILoggerFactory AddApplicationInsights(
|
||||
this ILoggerFactory factory,
|
||||
IServiceProvider serviceProvider,
|
||||
|
@ -44,7 +44,7 @@
|
|||
/// <param name="factory"></param>
|
||||
/// <param name="filter"></param>
|
||||
/// <param name="serviceProvider">The instance of <see cref="IServiceProvider"/> to use for service resolution.</param>
|
||||
[Obsolete("Use Microsoft.Extensions.Logging.ApplicationInsightsLoggingBuilderExtensions.AddApplicationInsights from Microsoft.Extensions.Logging.ApplicationInsights package")]
|
||||
[Obsolete("ApplicationInsightsLoggerProvider is now enabled by default when enabling ApplicationInsights monitoring using UseApplicationInsights extension method on IWebHostBuilder or AddApplicationInsightsTelemetry extension method on IServiceCollection. From 2.7.0-beta3 onwards, calling this method will result in double logging and filters applied will not get applied. If interested in using just logging provider, then please use Microsoft.Extensions.Logging.ApplicationInsightsLoggingBuilderExtensions.AddApplicationInsights from Microsoft.Extensions.Logging.ApplicationInsights package. Read more https://aka.ms/ApplicationInsightsILoggerFaq")]
|
||||
public static ILoggerFactory AddApplicationInsights(
|
||||
this ILoggerFactory factory,
|
||||
IServiceProvider serviceProvider,
|
||||
|
@ -60,20 +60,21 @@
|
|||
/// <param name="filter"></param>
|
||||
/// <param name="serviceProvider">The instance of <see cref="IServiceProvider"/> to use for service resolution.</param>
|
||||
/// <param name="loggerAddedCallback">The callback that gets executed when another ApplicationInsights logger is added.</param>
|
||||
[Obsolete("Use Microsoft.Extensions.Logging.ApplicationInsightsLoggingBuilderExtensions.AddApplicationInsights from Microsoft.Extensions.Logging.ApplicationInsights package")]
|
||||
[Obsolete("ApplicationInsightsLoggerProvider is now enabled by default when enabling ApplicationInsights monitoring using UseApplicationInsights extension method on IWebHostBuilder or AddApplicationInsightsTelemetry extension method on IServiceCollection. From 2.7.0-beta3 onwards, calling this method will result in double logging and filters applied will not get applied. If interested in using just logging provider, then please use Microsoft.Extensions.Logging.ApplicationInsightsLoggingBuilderExtensions.AddApplicationInsights from Microsoft.Extensions.Logging.ApplicationInsights package. Read more https://aka.ms/ApplicationInsightsILoggerFaq")]
|
||||
public static ILoggerFactory AddApplicationInsights(
|
||||
this ILoggerFactory factory,
|
||||
IServiceProvider serviceProvider,
|
||||
Func<string, LogLevel, bool> filter,
|
||||
Action loggerAddedCallback)
|
||||
{
|
||||
{
|
||||
|
||||
var client = serviceProvider.GetService<TelemetryClient>();
|
||||
var debugLoggerControl = serviceProvider.GetService<ApplicationInsightsLoggerEvents>();
|
||||
var options = serviceProvider.GetService<IOptions<ApplicationInsightsLoggerOptions>>();
|
||||
var debugLoggerControl = serviceProvider.GetService<Microsoft.ApplicationInsights.AspNetCore.Logging.ApplicationInsightsLoggerEvents>();
|
||||
var options = serviceProvider.GetService<IOptions<Microsoft.ApplicationInsights.AspNetCore.Logging.ApplicationInsightsLoggerOptions>>();
|
||||
|
||||
if (options == null)
|
||||
{
|
||||
options = Options.Create(new ApplicationInsightsLoggerOptions());
|
||||
options = Options.Create(new Microsoft.ApplicationInsights.AspNetCore.Logging.ApplicationInsightsLoggerOptions());
|
||||
}
|
||||
|
||||
if (debugLoggerControl != null)
|
||||
|
@ -85,8 +86,8 @@
|
|||
debugLoggerControl.LoggerAdded += loggerAddedCallback;
|
||||
}
|
||||
}
|
||||
|
||||
factory.AddProvider(new ApplicationInsightsLoggerProvider(client, filter, options));
|
||||
factory.AddProvider(new Microsoft.ApplicationInsights.AspNetCore.Logging.ApplicationInsightsLoggerProvider(client, filter, options));
|
||||
|
||||
return factory;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,10 @@
|
|||
/// <summary>
|
||||
/// <see cref="ILoggerProvider"/> implementation that creates returns instances of <see cref="ApplicationInsightsLogger"/>
|
||||
/// </summary>
|
||||
#if !NETSTANDARD2_0
|
||||
// For NETSTANDARD2.0 We take dependency on Microsoft.Extensions.Logging.ApplicationInsights which has ApplicationInsightsProvider having the same ProviderAlias and don't want to clash with this ProviderAlias.
|
||||
[ProviderAlias("ApplicationInsights")]
|
||||
#endif
|
||||
internal class ApplicationInsightsLoggerProvider : ILoggerProvider
|
||||
{
|
||||
private readonly TelemetryClient telemetryClient;
|
||||
|
|
|
@ -86,17 +86,18 @@
|
|||
<PackageReference Include="Microsoft.ApplicationInsights.PerfCounterCollector" Version="2.10.0-beta2" />
|
||||
<PackageReference Include="Microsoft.ApplicationInsights.WindowsServer" Version="2.10.0-beta2" />
|
||||
<PackageReference Include="Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel" Version="2.10.0-beta2" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Hosting" Version="1.0.2" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration" Version="1.0.2" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="1.0.2" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="1.0.2" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Hosting" Version="1.0.2" />
|
||||
<PackageReference Include="System.Text.Encodings.Web" Version="4.3.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard2.0' ">
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration" Version="2.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="2.0.0" />
|
||||
<ItemGroup Condition=" '$(TargetFramework)' != 'netstandard2.0' ">
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="1.0.2" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="1.0.2" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard2.0' ">
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.1.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.ApplicationInsights" Version="2.9.1" />
|
||||
<PackageReference Include="System.Text.Encodings.Web" Version="4.3.1" />
|
||||
</ItemGroup>
|
||||
|
||||
|
|
|
@ -13,11 +13,13 @@
|
|||
{
|
||||
private readonly IHttpContextAccessor httpContextAccessor;
|
||||
|
||||
/// <inheritdoc />
|
||||
public TelemetryInitializerBase(IHttpContextAccessor httpContextAccessor)
|
||||
{
|
||||
this.httpContextAccessor = httpContextAccessor ?? throw new ArgumentNullException(nameof(httpContextAccessor));
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Initialize(ITelemetry telemetry)
|
||||
{
|
||||
var context = this.httpContextAccessor.HttpContext;
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
{
|
||||
private const string WebSessionCookieName = "ai_session";
|
||||
|
||||
/// <inheritdoc />
|
||||
public WebSessionTelemetryInitializer(IHttpContextAccessor httpContextAccessor)
|
||||
: base(httpContextAccessor)
|
||||
{
|
||||
|
|
|
@ -5,15 +5,18 @@
|
|||
using Microsoft.ApplicationInsights.DataContracts;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
|
||||
/// <inheritdoc />
|
||||
public class WebUserTelemetryInitializer : TelemetryInitializerBase
|
||||
{
|
||||
private const string WebUserCookieName = "ai_user";
|
||||
|
||||
/// <inheritdoc />
|
||||
public WebUserTelemetryInitializer(IHttpContextAccessor httpContextAccessor)
|
||||
: base(httpContextAccessor)
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void OnInitializeTelemetry(HttpContext platformContext, RequestTelemetry requestTelemetry, ITelemetry telemetry)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(telemetry.Context.User.Id))
|
||||
|
|
|
@ -40,8 +40,9 @@ namespace FunctionalTestUtils
|
|||
|
||||
private TelemetryHttpListenerObservable listener;
|
||||
private readonly Func<IWebHostBuilder, IWebHostBuilder> configureHost;
|
||||
private readonly Action<IServiceCollection> configureServices;
|
||||
|
||||
public InProcessServer(string assemblyName, ITestOutputHelper output, Func<IWebHostBuilder, IWebHostBuilder> configureHost = null)
|
||||
public InProcessServer(string assemblyName, ITestOutputHelper output, Func<IWebHostBuilder, IWebHostBuilder> configureHost = null, Action<IServiceCollection> configureServices = null)
|
||||
{
|
||||
this.output = output;
|
||||
|
||||
|
@ -49,6 +50,7 @@ namespace FunctionalTestUtils
|
|||
var machineName = "localhost";
|
||||
this.url = "http://" + machineName + ":" + random.Next(5000, 14000).ToString();
|
||||
this.configureHost = configureHost;
|
||||
this.configureServices = configureServices;
|
||||
this.httpListenerConnectionString = LauchApplicationAndStartListener(assemblyName);
|
||||
}
|
||||
|
||||
|
@ -155,7 +157,12 @@ namespace FunctionalTestUtils
|
|||
{
|
||||
builder = this.configureHost(builder);
|
||||
}
|
||||
|
||||
|
||||
if (this.configureServices != null)
|
||||
{
|
||||
builder.ConfigureServices(services => this.configureServices(services));
|
||||
}
|
||||
|
||||
this.hostingEngine = builder.Build();
|
||||
this.hostingEngine.Start();
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<VersionPrefix>2.0.0</VersionPrefix>
|
||||
|
@ -56,10 +56,10 @@
|
|||
<PackageReference Include="Microsoft.AspNetCore.Server.Kestrel" Version="2.0.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.0.0" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="2.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="2.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="2.1.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.1.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="2.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="2.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="2.1.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="2.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="2.0.0" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.7.0" />
|
||||
|
|
|
@ -145,10 +145,10 @@ namespace Microsoft.Extensions.DependencyInjection.Test
|
|||
|
||||
/// <summary>
|
||||
/// We determine if Active telemtery needs to be configured based on the assumptions that 'default' configuration
|
||||
// created by base SDK has single preset ITelemetryIntitializer. If it ever changes, change TelemetryConfigurationOptions.IsActiveConfigured method as well.
|
||||
// created by base SDK has single preset ITelemetryInitializer. If it ever changes, change TelemetryConfigurationOptions.IsActiveConfigured method as well.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public static void DefaultTelemetryconfigurationHasOneTelemetryInitializer()
|
||||
public static void DefaultTelemetryConfigurationHasOneTelemetryInitializer()
|
||||
{
|
||||
//
|
||||
var defaultConfig = TelemetryConfiguration.CreateDefault();
|
||||
|
|
|
@ -35,15 +35,18 @@
|
|||
<PackageReference Include="Microsoft.AspNetCore.Http.Extensions" Version="1.0.2" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Http.Features" Version="1.0.2" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.Core" Version="1.0.3" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="1.0.2" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="1.0.2" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="1.0.2" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="1.0.2" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.7.0" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" />
|
||||
<PackageReference Include="xunit" Version="2.3.1" />
|
||||
<DotNetCliToolReference Include="dotnet-xunit" Version="2.3.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition=" '$(TargetFramework)' != 'netcoreapp2.0' ">
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="1.0.2" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="1.0.2" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition=" '$(TargetFramework)' == 'netcoreapp2.0' ">
|
||||
<PackageReference Include="Microsoft.AspNetCore.Hosting" Version="2.0.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Http" Version="2.0.0" />
|
||||
|
@ -51,8 +54,8 @@
|
|||
<PackageReference Include="Microsoft.AspNetCore.Http.Features" Version="2.0.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.Core" Version="2.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="2.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="2.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.1.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="2.1.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition=" '$(TargetFramework)' == 'net46' ">
|
||||
|
|
|
@ -3,12 +3,20 @@ using System.Collections.Generic;
|
|||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace WebApi20.FunctionalTests.Controllers
|
||||
{
|
||||
[Route("api/[controller]")]
|
||||
public class ValuesController : Controller
|
||||
{
|
||||
ILogger<ValuesController> logger;
|
||||
|
||||
public ValuesController(ILogger<ValuesController> logger)
|
||||
{
|
||||
this.logger = logger;
|
||||
}
|
||||
|
||||
// GET api/values
|
||||
[HttpGet]
|
||||
public IEnumerable<string> Get()
|
||||
|
@ -20,6 +28,10 @@ namespace WebApi20.FunctionalTests.Controllers
|
|||
[HttpGet("{id}")]
|
||||
public string Get(int id)
|
||||
{
|
||||
logger.LogError("error logged");
|
||||
logger.LogWarning("warning logged");
|
||||
logger.LogInformation("information logged");
|
||||
logger.LogTrace("trace logged");
|
||||
return "value";
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,150 @@
|
|||
namespace FunctionalTests
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
using FunctionalTestUtils;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.ApplicationInsights.DataContracts;
|
||||
using Microsoft.ApplicationInsights.DependencyCollector;
|
||||
using Xunit;
|
||||
using Xunit.Abstractions;
|
||||
using AI;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
/// <summary>
|
||||
/// These are Functional Tests validating E2E ILogger integration. Though filtering mechanism is done by the ILogger framework itself, we
|
||||
/// are here testing that the integration is done in correct ways.
|
||||
/// Specifically,
|
||||
/// 1. By Default, Warning and above from All categories is expected to captured.
|
||||
/// 2. Any overriding done by user is respected and will override default behaviour
|
||||
/// </summary>
|
||||
public class LoggerTests : TelemetryTestsBase, IDisposable
|
||||
{
|
||||
private const string assemblyName = "WebApi20.FunctionalTests20";
|
||||
public LoggerTests(ITestOutputHelper output) : base (output)
|
||||
{
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestIloggerWarningOrAboveIsCapturedByDefault()
|
||||
{
|
||||
|
||||
#if NETCOREAPP2_0
|
||||
using (var server = new InProcessServer(assemblyName, this.output))
|
||||
{
|
||||
// Make request to this path, which sents one log of each severity Error, Warning, Information, Trace
|
||||
this.ExecuteRequest(server.BaseHost + "/api/values/5");
|
||||
|
||||
// By default, AI is expected to capture Warning, Error
|
||||
var actual = server.Listener.ReceiveItemsOfType<TelemetryItem<MessageData>>(2, TestListenerTimeoutInMs);
|
||||
this.DebugTelemetryItems(actual);
|
||||
|
||||
// Expect 2 items.
|
||||
Assert.Equal(2, actual.Count());
|
||||
|
||||
ValidateMessage(actual[0], new string[] {"error", "warning" });
|
||||
ValidateMessage(actual[1], new string[] { "error", "warning" });
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestIloggerDefaultsCanBeOverridenByUserForAllCategories()
|
||||
{
|
||||
|
||||
#if NETCOREAPP2_0
|
||||
void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
// ARRANGE
|
||||
// AddFilter to capture only Error. This is expected to override default behavior.
|
||||
services.AddLogging(builder => builder.AddFilter<Microsoft.Extensions.Logging.ApplicationInsights.ApplicationInsightsLoggerProvider>("", LogLevel.Error));
|
||||
}
|
||||
|
||||
using (var server = new InProcessServer(assemblyName, this.output,null, ConfigureServices))
|
||||
{
|
||||
// Make request to this path, which sents one log of each severity Error, Warning, Information, Trace
|
||||
this.ExecuteRequest(server.BaseHost + "/api/values/5");
|
||||
|
||||
// AI is now expected to capture only Error
|
||||
var actual = server.Listener.ReceiveItemsOfType<TelemetryItem<MessageData>>(1, TestListenerTimeoutInMs);
|
||||
this.DebugTelemetryItems(actual);
|
||||
|
||||
// Expect 1 item1.
|
||||
Assert.Equal(1, actual.Count());
|
||||
|
||||
ValidateMessage(actual[0], new string[] { "error"});
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestIloggerDefaultsCanBeOverridenByUserForSpecificCategory()
|
||||
{
|
||||
|
||||
#if NETCOREAPP2_0
|
||||
void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
// ARRANGE
|
||||
// AddFilter to capture Trace or above for user category. This is expected to override default behavior.
|
||||
services.AddLogging(builder => builder.AddFilter<Microsoft.Extensions.Logging.ApplicationInsights.ApplicationInsightsLoggerProvider>("WebApi20.FunctionalTests.Controllers", LogLevel.Trace));
|
||||
}
|
||||
|
||||
using (var server = new InProcessServer(assemblyName, this.output, null, ConfigureServices))
|
||||
{
|
||||
// Make request to this path, which sents one log of each severity Error, Warning, Information, Trace
|
||||
this.ExecuteRequest(server.BaseHost + "/api/values/5");
|
||||
|
||||
// AI is now expected to capture Warning or above for all categories (default behavior), except 'WebApi20.FunctionalTests.Controllers' category where Trace of above
|
||||
// is captured. (overridden behavior)
|
||||
var actual = server.Listener.ReceiveItemsOfType<TelemetryItem<MessageData>>(4, TestListenerTimeoutInMs);
|
||||
this.DebugTelemetryItems(actual);
|
||||
|
||||
// Expect 4 items.
|
||||
Assert.Equal(4, actual.Count());
|
||||
|
||||
ValidateMessage(actual[0], new string[] { "error" });
|
||||
ValidateMessage(actual[1], new string[] { "warning" });
|
||||
ValidateMessage(actual[2], new string[] { "information" });
|
||||
ValidateMessage(actual[3], new string[] { "trace" });
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
private bool ValidateMessage(Envelope item, string[] expectedMessages)
|
||||
{
|
||||
if (!(item is TelemetryItem<MessageData> trace))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var actualMessage = trace.data.baseData.message;
|
||||
|
||||
bool foundMessage = false;
|
||||
foreach (var msg in expectedMessages)
|
||||
{
|
||||
if(actualMessage.Contains(msg))
|
||||
{
|
||||
foundMessage = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return foundMessage;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
while (Activity.Current != null)
|
||||
{
|
||||
Activity.Current.Stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -35,7 +35,7 @@
|
|||
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.0.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.WebApiCompatShim" Version="2.0.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.1.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Diagnostics" Version="2.0.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Server.Kestrel" Version="2.0.0" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.7.0" />
|
||||
|
|
Загрузка…
Ссылка в новой задаче