Merge remote-tracking branch 'origin/rel/2.0.0-preview1' into dev

This commit is contained in:
Pavel Krymets 2017-05-08 10:08:27 -07:00
commit 3bcf6eaa69
8 changed files with 245 additions and 127 deletions

View File

@ -2,7 +2,7 @@
<PropertyGroup>
<AspNetCoreVersion>2.0.0-*</AspNetCoreVersion>
<AspNetIntegrationTestingVersion>0.4.0-*</AspNetIntegrationTestingVersion>
<AppInsightsVersion>2.1.0-beta2</AppInsightsVersion>
<AppInsightsVersion>2.1.0-beta3</AppInsightsVersion>
<CoreFxVersion>4.3.0</CoreFxVersion>
<InternalAspNetCoreSdkVersion>2.1.0-*</InternalAspNetCoreSdkVersion>
<MoqVersion>4.7.1</MoqVersion>

View File

@ -22,13 +22,27 @@ namespace IISSample
services.AddMvc();
}
public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory, IServiceProvider serviceProvider)
public void ConfigureJavaScript(IApplicationBuilder app)
{
var logger = loggerFactory.CreateLogger("Requests");
app.UseMvcWithDefaultRoute();
}
public void ConfigureDefaultLogging(IApplicationBuilder app, ILoggerFactory loggerFactory)
{
ConfigureLoggingMiddleware(app, loggerFactory);
}
public void ConfigureCustomLogging(IApplicationBuilder app, ILoggerFactory loggerFactory, IServiceProvider serviceProvider)
{
loggerFactory.AddApplicationInsights(serviceProvider, (s, level) => s.Contains("o"));
ConfigureLoggingMiddleware(app, loggerFactory);
}
private static void ConfigureLoggingMiddleware(IApplicationBuilder app, ILoggerFactory loggerFactory)
{
app.Map("/log", logApp => logApp.Run(context =>
{
var oldChannel = TelemetryConfiguration.Active.TelemetryChannel;
TelemetryConfiguration.Active.TelemetryChannel = new CurrentResponseTelemetryChannel(context.Response);
var systemLogger = loggerFactory.CreateLogger("System.Namespace");
@ -51,53 +65,10 @@ namespace IISSample
specificLogger.LogInformation("Specific information log");
specificLogger.LogWarning("Specific warning log");
TelemetryConfiguration.Active.TelemetryChannel = null;
TelemetryConfiguration.Active.TelemetryChannel = oldChannel;
return Task.CompletedTask;
}));
app.Run(async (context) =>
{
logger.LogDebug("Received request: " + context.Request.Method + " " + context.Request.Path);
context.Response.ContentType = "text/plain";
await context.Response.WriteAsync("Hello World - " + DateTimeOffset.Now + Environment.NewLine);
await context.Response.WriteAsync(Environment.NewLine);
await context.Response.WriteAsync("Address:" + Environment.NewLine);
await context.Response.WriteAsync("Scheme: " + context.Request.Scheme + Environment.NewLine);
await context.Response.WriteAsync("Host: " + context.Request.Headers["Host"] + Environment.NewLine);
await context.Response.WriteAsync("PathBase: " + context.Request.PathBase.Value + Environment.NewLine);
await context.Response.WriteAsync("Path: " + context.Request.Path.Value + Environment.NewLine);
await context.Response.WriteAsync("Query: " + context.Request.QueryString.Value + Environment.NewLine);
await context.Response.WriteAsync(Environment.NewLine);
await context.Response.WriteAsync("Connection:" + Environment.NewLine);
await context.Response.WriteAsync("RemoteIp: " + context.Connection.RemoteIpAddress + Environment.NewLine);
await context.Response.WriteAsync("RemotePort: " + context.Connection.RemotePort + Environment.NewLine);
await context.Response.WriteAsync("LocalIp: " + context.Connection.LocalIpAddress + Environment.NewLine);
await context.Response.WriteAsync("LocalPort: " + context.Connection.LocalPort + Environment.NewLine);
await context.Response.WriteAsync("ClientCert: " + context.Connection.ClientCertificate + Environment.NewLine);
await context.Response.WriteAsync(Environment.NewLine);
await context.Response.WriteAsync("User: " + context.User.Identity.Name + Environment.NewLine);
await context.Response.WriteAsync(Environment.NewLine);
await context.Response.WriteAsync("Headers:" + Environment.NewLine);
foreach (var header in context.Request.Headers)
{
await context.Response.WriteAsync(header.Key + ": " + header.Value + Environment.NewLine);
}
await context.Response.WriteAsync(Environment.NewLine);
await context.Response.WriteAsync("Environment Variables:" + Environment.NewLine);
var vars = Environment.GetEnvironmentVariables();
foreach (var key in vars.Keys.Cast<string>().OrderBy(key => key, StringComparer.OrdinalIgnoreCase))
{
var value = vars[key];
await context.Response.WriteAsync(key + ": " + value + Environment.NewLine);
}
await context.Response.WriteAsync(Environment.NewLine);
});
}
public static void Main(string[] args)
@ -110,8 +81,11 @@ namespace IISSample
var host = new WebHostBuilder()
.ConfigureLogging((hostingContext, factory) =>
{
factory.UseConfiguration(hostingContext.Configuration.GetSection("Logging"))
.AddConsole();
if (hostingContext.Configuration["WIRE_LOGGING_CONFIGURATION"]?.ToLowerInvariant() != "false")
{
factory.UseConfiguration(hostingContext.Configuration.GetSection("Logging"));
}
factory.AddConsole();
})
.UseKestrel()
.UseStartup<Startup>()

View File

@ -0,0 +1,72 @@
// 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();
}
}
}

View File

@ -11,15 +11,36 @@ namespace Microsoft.AspNetCore.ApplicationInsights.HostingStartup
{
internal class ApplicationInsightsLoggerStartupFilter : IStartupFilter
{
private readonly Func<string, LogLevel, bool> _noFilter = (s, level) => true;
public Action<IApplicationBuilder> Configure(Action<IApplicationBuilder> next)
{
return builder =>
{
var loggerFactory = builder.ApplicationServices.GetService<ILoggerFactory>();
// We need to disable filtering on logger, filtering would be done by LoggerFactory
loggerFactory.AddApplicationInsights(builder.ApplicationServices, _noFilter);
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);
}
next(builder);
};
}

View File

@ -1,14 +1,8 @@
// 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;
[assembly: HostingStartup(typeof(Microsoft.AspNetCore.ApplicationInsights.HostingStartup.ApplicationInsightsHostingStartup))]
@ -23,14 +17,6 @@ namespace Microsoft.AspNetCore.ApplicationInsights.HostingStartup
/// </summary>
public class ApplicationInsightsHostingStartup : IHostingStartup
{
private const string ApplicationInsightsLoggerFactory = "Microsoft.ApplicationInsights.AspNetCore.Logging.ApplicationInsightsLoggerProvider";
private const string ApplicationInsightsSettingsFile = "ApplicationInsights.settings.json";
private static readonly KeyValuePair<string, string>[] _defaultLoggingLevels = {
new KeyValuePair<string, string>("Microsoft", "Warning"),
new KeyValuePair<string, string>("System", "Warning"),
new KeyValuePair<string, string>("Default", "Information")
};
/// <summary>
/// Calls UseApplicationInsights
@ -38,37 +24,12 @@ namespace Microsoft.AspNetCore.ApplicationInsights.HostingStartup
/// <param name="builder"></param>
public void Configure(IWebHostBuilder builder)
{
builder.ConfigureAppConfiguration((context, configurationBuilder) => ConfigureLogging(configurationBuilder));
builder.ConfigureAppConfiguration((context, configurationBuilder) => ApplicationInsightsLoggerConfiguration.ConfigureLogging(configurationBuilder));
builder.UseApplicationInsights();
builder.ConfigureServices(InitializeServices);
}
private 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);
}
}
private static KeyValuePair<string, string>[] GetDefaultLoggingSettings()
{
return _defaultLoggingLevels.Select(pair =>
{
var key = $"Logging:{ApplicationInsightsLoggerFactory}:LogLevel:{pair.Key}";
return new KeyValuePair<string, string>(key, pair.Value);
}).ToArray();
}
/// <summary>
/// Adds the Javascript <see cref="TagHelperComponent"/> to the <see cref="IServiceCollection"/>.

View File

@ -19,9 +19,9 @@ namespace Microsoft.AspNetCore.Hosting
{
throw new ArgumentNullException(nameof(hostBuilder));
}
#pragma warning disable 618
hostBuilder.ConfigureLogging(loggerFactory => loggerFactory.AddAzureWebAppDiagnostics());
#pragma warning restore 618
return hostBuilder;
}
}

View File

@ -41,6 +41,7 @@ namespace ApplicationInsightsJavaScriptSnippetTest
TargetFramework = "netcoreapp2.0",
Configuration = GetCurrentBuildConfiguration(),
ApplicationType = applicationType,
EnvironmentName = "JavaScript",
EnvironmentVariables =
{
new KeyValuePair<string, string>(

View File

@ -20,19 +20,132 @@ namespace ApplicationInsightsJavaScriptSnippetTest
[Theory]
[InlineData(ApplicationType.Portable)]
[InlineData(ApplicationType.Standalone)]
public async Task ScriptInjected(ApplicationType applicationType)
public async Task DefaultAILogFiltersApplied(ApplicationType applicationType)
{
var responseText = await RunRequest(applicationType, "DefaultLogging", true);
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);
AssertCustomLogs(responseText);
}
private static void AssertDefaultLogs(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 but overridden by ApplicationInsights.settings.json
Assert.Contains("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 but overridden by ApplicationInsights.settings.json
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
Assert.DoesNotContain("System warning log", responseText);
Assert.DoesNotContain("System information log", responseText);
Assert.DoesNotContain("System trace log", responseText);
// Enabled by default
Assert.Contains("Microsoft warning log", responseText);
Assert.Contains("Microsoft information log", responseText);
Assert.DoesNotContain("Microsoft trace log", responseText);
// Enabled by default
Assert.Contains("Custom warning log", responseText);
Assert.Contains("Custom information log", responseText);
Assert.DoesNotContain("Custom trace log", responseText);
// Enabled by default
Assert.DoesNotContain("Specific warning log", responseText);
Assert.DoesNotContain("Specific information log", responseText);
Assert.DoesNotContain("Specific trace log", responseText);
}
private async Task<string> RunRequest(ApplicationType applicationType, string environment, bool wireConfiguration)
{
string responseText;
var testName = $"ApplicationInsightsLoggingTest_{applicationType}";
using (StartLog(out var loggerFactory, testName))
{
var logger = loggerFactory.CreateLogger(nameof(ApplicationInsightsJavaScriptSnippetTest));
var deploymentParameters = new DeploymentParameters(GetApplicationPath(), ServerType.Kestrel, RuntimeFlavor.CoreClr, RuntimeArchitecture.x64)
var deploymentParameters = new DeploymentParameters(GetApplicationPath(), ServerType.Kestrel,
RuntimeFlavor.CoreClr, RuntimeArchitecture.x64)
{
PublishApplicationBeforeDeployment = true,
PreservePublishedApplicationForDebugging = PreservePublishedApplicationForDebugging,
TargetFramework = "netcoreapp2.0",
Configuration = GetCurrentBuildConfiguration(),
ApplicationType = applicationType,
EnvironmentName = environment,
EnvironmentVariables =
{
new KeyValuePair<string, string>(
@ -41,6 +154,9 @@ namespace ApplicationInsightsJavaScriptSnippetTest
new KeyValuePair<string, string>(
"HOME",
Path.Combine(GetApplicationPath(), "home")),
new KeyValuePair<string, string>(
"ASPNETCORE_WIRE_LOGGING_CONFIGURATION",
wireConfiguration.ToString()),
},
};
@ -56,39 +172,12 @@ namespace ApplicationInsightsJavaScriptSnippetTest
logger: logger, cancellationToken: deploymentResult.HostShutdownToken);
Assert.False(response == null, "Response object is null because the client could not " +
"connect to the server after multiple retries");
"connect to the server after multiple retries");
var responseText = await response.Content.ReadAsStringAsync();
// 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 but overridden by ApplicationInsights.settings.json
Assert.Contains("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 but overridden by ApplicationInsights.settings.json
Assert.Contains("Specific trace log", responseText);
responseText = await response.Content.ReadAsStringAsync();
}
}
return responseText;
}
}
}