React to logging DI changes (#56)
This commit is contained in:
parent
4e30141f30
commit
894a3d9d7a
|
|
@ -79,13 +79,9 @@ namespace IISSample
|
|||
.Build();
|
||||
|
||||
var host = new WebHostBuilder()
|
||||
.ConfigureLogging((hostingContext, factory) =>
|
||||
.ConfigureLogging((hostingContext, builder) =>
|
||||
{
|
||||
if (hostingContext.Configuration["WIRE_LOGGING_CONFIGURATION"]?.ToLowerInvariant() != "false")
|
||||
{
|
||||
factory.UseConfiguration(hostingContext.Configuration.GetSection("Logging"));
|
||||
}
|
||||
factory.AddConsole();
|
||||
builder.AddConsole();
|
||||
})
|
||||
.UseKestrel()
|
||||
.UseStartup<Startup>()
|
||||
|
|
|
|||
|
|
@ -1,72 +0,0 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Microsoft.AspNetCore.ApplicationInsights.HostingStartup
|
||||
{
|
||||
internal class ApplicationInsightsLoggerConfiguration
|
||||
{
|
||||
private const string ApplicationInsightsLoggerFactory = "Microsoft.ApplicationInsights.AspNetCore.Logging.ApplicationInsightsLoggerProvider";
|
||||
private const string ApplicationInsightsLoggerLevelSection = "Logging:" + ApplicationInsightsLoggerFactory + ":LogLevel";
|
||||
private const string ApplicationInsightsSettingsFile = "ApplicationInsights.settings.json";
|
||||
|
||||
private static readonly KeyValuePair<string, LogLevel>[] _defaultLoggingLevels = {
|
||||
new KeyValuePair<string, LogLevel>("Microsoft", LogLevel.Warning),
|
||||
new KeyValuePair<string, LogLevel>("System", LogLevel.Warning),
|
||||
new KeyValuePair<string, LogLevel>(null, LogLevel.Information)
|
||||
};
|
||||
|
||||
public static void ConfigureLogging(IConfigurationBuilder configurationBuilder)
|
||||
{
|
||||
// Skip adding default rules when debugger is attached
|
||||
// we want to send all events to VS
|
||||
if (!Debugger.IsAttached)
|
||||
{
|
||||
configurationBuilder.AddInMemoryCollection(GetDefaultLoggingSettings());
|
||||
}
|
||||
|
||||
var home = Environment.GetEnvironmentVariable("HOME");
|
||||
if (!string.IsNullOrEmpty(home))
|
||||
{
|
||||
var settingsFile = Path.Combine(home, "site", "diagnostics", ApplicationInsightsSettingsFile);
|
||||
configurationBuilder.AddJsonFile(settingsFile, optional: true);
|
||||
}
|
||||
}
|
||||
|
||||
public static bool ApplyDefaultFilter(string name, LogLevel level)
|
||||
{
|
||||
foreach (var pair in _defaultLoggingLevels)
|
||||
{
|
||||
// Default is null
|
||||
if (pair.Key == null || name.StartsWith(pair.Key, StringComparison.Ordinal))
|
||||
{
|
||||
return level >= pair.Value;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool HasLoggingConfigured(IConfiguration configuration)
|
||||
{
|
||||
return configuration?.GetSection(ApplicationInsightsLoggerLevelSection) != null;
|
||||
}
|
||||
|
||||
private static KeyValuePair<string, string>[] GetDefaultLoggingSettings()
|
||||
{
|
||||
return _defaultLoggingLevels.Select(pair =>
|
||||
{
|
||||
var key = pair.Key ?? "Default";
|
||||
var optionsKey = $"{ApplicationInsightsLoggerLevelSection}:{key}";
|
||||
return new KeyValuePair<string, string>(optionsKey, pair.Value.ToString());
|
||||
}).ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -21,25 +21,12 @@ namespace Microsoft.AspNetCore.ApplicationInsights.HostingStartup
|
|||
var loggerEnabled = true;
|
||||
Action disableCallback = () => loggerEnabled = false;
|
||||
|
||||
if (loggerFactory is LoggerFactory stronglyTypedLoggerFactory &&
|
||||
ApplicationInsightsLoggerConfiguration.HasLoggingConfigured(stronglyTypedLoggerFactory.Configuration))
|
||||
{
|
||||
// We detected that logger settings got to LoggerFactory configuration and
|
||||
// defaults would be applied
|
||||
loggerFactory.AddApplicationInsights(
|
||||
builder.ApplicationServices,
|
||||
(s, level) => loggerEnabled,
|
||||
disableCallback);
|
||||
}
|
||||
else
|
||||
{
|
||||
// It's not AspNetCore LoggerFactory or configuration was not wired
|
||||
// just add a logger with default settings
|
||||
loggerFactory.AddApplicationInsights(
|
||||
builder.ApplicationServices,
|
||||
(s, level) => loggerEnabled && ApplicationInsightsLoggerConfiguration.ApplyDefaultFilter(s, level),
|
||||
disableCallback);
|
||||
}
|
||||
// We detected that logger settings got to LoggerFactory configuration and
|
||||
// defaults would be applied
|
||||
loggerFactory.AddApplicationInsights(
|
||||
builder.ApplicationServices,
|
||||
(s, level) => loggerEnabled,
|
||||
disableCallback);
|
||||
|
||||
next(builder);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,9 +1,17 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Razor.TagHelpers;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
[assembly: HostingStartup(typeof(Microsoft.AspNetCore.ApplicationInsights.HostingStartup.ApplicationInsightsHostingStartup))]
|
||||
|
||||
|
|
@ -17,6 +25,7 @@ namespace Microsoft.AspNetCore.ApplicationInsights.HostingStartup
|
|||
/// </summary>
|
||||
public class ApplicationInsightsHostingStartup : IHostingStartup
|
||||
{
|
||||
private const string ApplicationInsightsSettingsFile = "ApplicationInsights.settings.json";
|
||||
|
||||
/// <summary>
|
||||
/// Calls UseApplicationInsights
|
||||
|
|
@ -24,7 +33,6 @@ namespace Microsoft.AspNetCore.ApplicationInsights.HostingStartup
|
|||
/// <param name="builder"></param>
|
||||
public void Configure(IWebHostBuilder builder)
|
||||
{
|
||||
builder.ConfigureAppConfiguration((context, configurationBuilder) => ApplicationInsightsLoggerConfiguration.ConfigureLogging(configurationBuilder));
|
||||
builder.UseApplicationInsights();
|
||||
|
||||
builder.ConfigureServices(InitializeServices);
|
||||
|
|
@ -37,8 +45,42 @@ namespace Microsoft.AspNetCore.ApplicationInsights.HostingStartup
|
|||
/// <param name="services">The <see cref="IServiceCollection"/> associated with the application.</param>
|
||||
private void InitializeServices(IServiceCollection services)
|
||||
{
|
||||
services.AddSingleton<IConfigureOptions<LoggerFilterOptions>, DefaultApplicationInsightsLoggerFilters>();
|
||||
services.AddSingleton<IStartupFilter, ApplicationInsightsLoggerStartupFilter>();
|
||||
services.AddSingleton<ITagHelperComponent, JavaScriptSnippetTagHelperComponent>();
|
||||
|
||||
var home = Environment.GetEnvironmentVariable("HOME");
|
||||
if (!string.IsNullOrEmpty(home))
|
||||
{
|
||||
var settingsFile = Path.Combine(home, "site", "diagnostics", ApplicationInsightsSettingsFile);
|
||||
var configurationBuilder = new ConfigurationBuilder();
|
||||
configurationBuilder.AddJsonFile(settingsFile, optional: true);
|
||||
services.AddLogging(builder => builder.AddConfiguration(configurationBuilder.Build().GetSection("Logging"), replace: true));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal class DefaultApplicationInsightsLoggerFilters : IConfigureOptions<LoggerFilterOptions>
|
||||
{
|
||||
private const string ApplicationInsightsLoggerFactory = "Microsoft.ApplicationInsights.AspNetCore.Logging.ApplicationInsightsLoggerProvider";
|
||||
|
||||
private static readonly KeyValuePair<string, LogLevel>[] _defaultLoggingLevels = {
|
||||
new KeyValuePair<string, LogLevel>("Microsoft", LogLevel.Warning),
|
||||
new KeyValuePair<string, LogLevel>("System", LogLevel.Warning),
|
||||
new KeyValuePair<string, LogLevel>(null, LogLevel.Information)
|
||||
};
|
||||
|
||||
public void Configure(LoggerFilterOptions options)
|
||||
{
|
||||
foreach (var pair in _defaultLoggingLevels)
|
||||
{
|
||||
options.Rules.Add(new LoggerFilterRule(
|
||||
ApplicationInsightsLoggerFactory,
|
||||
pair.Key,
|
||||
null,
|
||||
(type, name, level) => Debugger.IsAttached || level >= pair.Value
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ namespace Microsoft.AspNetCore.Hosting
|
|||
throw new ArgumentNullException(nameof(hostBuilder));
|
||||
}
|
||||
#pragma warning disable 618
|
||||
hostBuilder.ConfigureLogging(loggerFactory => loggerFactory.AddAzureWebAppDiagnostics());
|
||||
hostBuilder.ConfigureLogging(builder => builder.AddAzureWebAppDiagnostics());
|
||||
#pragma warning restore 618
|
||||
return hostBuilder;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,25 +22,16 @@ namespace ApplicationInsightsJavaScriptSnippetTest
|
|||
[InlineData(ApplicationType.Standalone)]
|
||||
public async Task DefaultAILogFiltersApplied(ApplicationType applicationType)
|
||||
{
|
||||
var responseText = await RunRequest(applicationType, "DefaultLogging", true);
|
||||
var responseText = await RunRequest(applicationType, "DefaultLogging");
|
||||
AssertDefaultLogs(responseText);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(ApplicationType.Portable)]
|
||||
[InlineData(ApplicationType.Standalone)]
|
||||
public async Task DefaultAILogFiltersAppliedWithoutConfiguration(ApplicationType applicationType)
|
||||
{
|
||||
var responseText = await RunRequest(applicationType, "DefaultLogging", false);
|
||||
AssertDefaultNoConfigurationLogs(responseText);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(ApplicationType.Portable)]
|
||||
[InlineData(ApplicationType.Standalone)]
|
||||
public async Task CustomAILogFiltersApplied(ApplicationType applicationType)
|
||||
{
|
||||
var responseText = await RunRequest(applicationType, "CustomLogging", true);
|
||||
var responseText = await RunRequest(applicationType, "CustomLogging");
|
||||
AssertCustomLogs(responseText);
|
||||
}
|
||||
|
||||
|
|
@ -75,37 +66,6 @@ namespace ApplicationInsightsJavaScriptSnippetTest
|
|||
Assert.Contains("Specific trace log", responseText);
|
||||
}
|
||||
|
||||
private static void AssertDefaultNoConfigurationLogs(string responseText)
|
||||
{
|
||||
// Enabled by default
|
||||
Assert.Contains("System warning log", responseText);
|
||||
// Disabled by default
|
||||
Assert.DoesNotContain("System information log", responseText);
|
||||
// Disabled by default
|
||||
Assert.DoesNotContain("System trace log", responseText);
|
||||
|
||||
// Enabled by default
|
||||
Assert.Contains("Microsoft warning log", responseText);
|
||||
// Disabled by default
|
||||
Assert.DoesNotContain("Microsoft information log", responseText);
|
||||
// Disabled by default
|
||||
Assert.DoesNotContain("Microsoft trace log", responseText);
|
||||
|
||||
// Enabled by default
|
||||
Assert.Contains("Custom warning log", responseText);
|
||||
// Enabled by default
|
||||
Assert.Contains("Custom information log", responseText);
|
||||
// Disabled by default
|
||||
Assert.DoesNotContain("Custom trace log", responseText);
|
||||
|
||||
// Enabled by default
|
||||
Assert.Contains("Specific warning log", responseText);
|
||||
// Enabled by default
|
||||
Assert.Contains("Specific information log", responseText);
|
||||
// Disabled by default
|
||||
Assert.DoesNotContain("Specific trace log", responseText);
|
||||
}
|
||||
|
||||
private static void AssertCustomLogs(string responseText)
|
||||
{
|
||||
// Custom logger allows only namespaces with 'o' in the name
|
||||
|
|
@ -130,7 +90,7 @@ namespace ApplicationInsightsJavaScriptSnippetTest
|
|||
Assert.DoesNotContain("Specific trace log", responseText);
|
||||
}
|
||||
|
||||
private async Task<string> RunRequest(ApplicationType applicationType, string environment, bool wireConfiguration)
|
||||
private async Task<string> RunRequest(ApplicationType applicationType, string environment)
|
||||
{
|
||||
string responseText;
|
||||
var testName = $"ApplicationInsightsLoggingTest_{applicationType}";
|
||||
|
|
@ -153,10 +113,7 @@ namespace ApplicationInsightsJavaScriptSnippetTest
|
|||
"Microsoft.AspNetCore.ApplicationInsights.HostingStartup"),
|
||||
new KeyValuePair<string, string>(
|
||||
"HOME",
|
||||
Path.Combine(GetApplicationPath(), "home")),
|
||||
new KeyValuePair<string, string>(
|
||||
"ASPNETCORE_WIRE_LOGGING_CONFIGURATION",
|
||||
wireConfiguration.ToString()),
|
||||
Path.Combine(GetApplicationPath(), "home"))
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
|
|
@ -17,7 +18,7 @@ namespace Microsoft.AspNetCore.Hosting.Azure.AppServices.Tests
|
|||
|
||||
mock.Object.UseAzureAppServices();
|
||||
|
||||
mock.Verify(builder => builder.ConfigureLogging(It.IsNotNull<Action<WebHostBuilderContext, LoggerFactory>>()), Times.Once);
|
||||
mock.Verify(builder => builder.ConfigureServices(It.IsNotNull<Action<IServiceCollection>>()), Times.Once);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue