From 7305a6ba20af601511c457ee178eca94ca09ac03 Mon Sep 17 00:00:00 2001 From: Pavel Krymets Date: Fri, 15 Sep 2017 17:02:36 -0700 Subject: [PATCH 1/4] Add a way to get configuration section for provider --- .../ILoggerProviderConfiguration.cs | 17 ++++ .../ILoggerProviderConfigurationOfT.cs | 18 ++++ .../LoggerProviderConfiguration.cs | 81 ++++++++++++++++ .../LoggerProviderOptionsChangeTokenSource.cs | 13 +++ .../LoggingBuilderExtensions.cs | 6 ++ .../LoggingConfiguration.cs | 14 +++ .../ConsoleLoggerFactoryExtensions.cs | 4 +- .../ConsoleLoggerOptions.cs | 2 + .../ConsoleLoggerOptionsSetup.cs | 13 +++ ...icrosoft.Extensions.Logging.Console.csproj | 1 + .../Microsoft.Extensions.Logging.csproj | 1 + .../ConsoleLoggerTest.cs | 18 ++++ .../LoggerProviderConfigurationTests.cs | 92 +++++++++++++++++++ 13 files changed, 279 insertions(+), 1 deletion(-) create mode 100644 src/Microsoft.Extensions.Logging.Configuration/ILoggerProviderConfiguration.cs create mode 100644 src/Microsoft.Extensions.Logging.Configuration/ILoggerProviderConfigurationOfT.cs create mode 100644 src/Microsoft.Extensions.Logging.Configuration/LoggerProviderConfiguration.cs create mode 100644 src/Microsoft.Extensions.Logging.Configuration/LoggerProviderOptionsChangeTokenSource.cs create mode 100644 src/Microsoft.Extensions.Logging.Configuration/LoggingConfiguration.cs create mode 100644 src/Microsoft.Extensions.Logging.Console/ConsoleLoggerOptionsSetup.cs create mode 100644 test/Microsoft.Extensions.Logging.Test/LoggerProviderConfigurationTests.cs diff --git a/src/Microsoft.Extensions.Logging.Configuration/ILoggerProviderConfiguration.cs b/src/Microsoft.Extensions.Logging.Configuration/ILoggerProviderConfiguration.cs new file mode 100644 index 00000000..d519e2d7 --- /dev/null +++ b/src/Microsoft.Extensions.Logging.Configuration/ILoggerProviderConfiguration.cs @@ -0,0 +1,17 @@ +using System.Text; +using Microsoft.Extensions.Configuration; + +namespace Microsoft.Extensions.Logging +{ + /// + /// + /// + /// + public interface ILoggerProviderConfiguration + { + /// + /// + /// + IConfiguration Configuration { get; } + } +} diff --git a/src/Microsoft.Extensions.Logging.Configuration/ILoggerProviderConfigurationOfT.cs b/src/Microsoft.Extensions.Logging.Configuration/ILoggerProviderConfigurationOfT.cs new file mode 100644 index 00000000..71ef2c33 --- /dev/null +++ b/src/Microsoft.Extensions.Logging.Configuration/ILoggerProviderConfigurationOfT.cs @@ -0,0 +1,18 @@ +using System; +using Microsoft.Extensions.Configuration; + +namespace Microsoft.Extensions.Logging +{ + /// + /// + /// + public interface ILoggerProviderConfiguration + { + /// + /// + /// + /// + /// + IConfiguration GetConfiguration(Type providerType); + } +} \ No newline at end of file diff --git a/src/Microsoft.Extensions.Logging.Configuration/LoggerProviderConfiguration.cs b/src/Microsoft.Extensions.Logging.Configuration/LoggerProviderConfiguration.cs new file mode 100644 index 00000000..a7595af5 --- /dev/null +++ b/src/Microsoft.Extensions.Logging.Configuration/LoggerProviderConfiguration.cs @@ -0,0 +1,81 @@ +using System; +using System.Collections.Generic; +using System.Reflection; +using Microsoft.Extensions.Configuration; + +namespace Microsoft.Extensions.Logging +{ + internal class LoggerProviderConfiguration : ILoggerProviderConfiguration + { + public LoggerProviderConfiguration(ILoggerProviderConfiguration providerConfiguration) + { + Configuration = providerConfiguration.GetConfiguration(typeof(T)); + } + + public IConfiguration Configuration { get; } + } + + internal class LoggerProviderConfiguration : ILoggerProviderConfiguration + { + private readonly IEnumerable _configurations; + + public LoggerProviderConfiguration(IEnumerable configurations) + { + _configurations = configurations; + } + + private const string AliasAttibuteTypeFullName = "Microsoft.Extensions.Logging.ProviderAliasAttribute"; + private const string AliasAttibuteAliasProperty = "Alias"; + + public IConfiguration GetConfiguration(Type providerType) + { + if (providerType == null) + { + throw new ArgumentNullException(nameof(providerType)); + } + + var fullName = providerType.FullName; + var alias = GetAlias(providerType); + var configurationBuilder = new ConfigurationBuilder(); + foreach (var configuration in _configurations) + { + var sectionFromFullName = configuration.Configuration.GetSection(fullName); + if (sectionFromFullName.Exists()) + { + configurationBuilder.AddConfiguration(sectionFromFullName); + } + + if (!string.IsNullOrWhiteSpace(alias)) + { + var sectionFromAlias = configuration.Configuration.GetSection(alias); + if (sectionFromAlias.Exists()) + { + configurationBuilder.AddConfiguration(sectionFromAlias); + } + } + } + return configurationBuilder.Build(); + } + + + private string GetAlias(Type providerType) + { + foreach (var attribute in providerType.GetTypeInfo().GetCustomAttributes(inherit: false)) + { + if (attribute.GetType().FullName == AliasAttibuteTypeFullName) + { + var valueProperty = attribute + .GetType() + .GetProperty(AliasAttibuteAliasProperty, BindingFlags.Public | BindingFlags.Instance); + + if (valueProperty != null) + { + return valueProperty.GetValue(attribute) as string; + } + } + } + + return null; + } + } +} \ No newline at end of file diff --git a/src/Microsoft.Extensions.Logging.Configuration/LoggerProviderOptionsChangeTokenSource.cs b/src/Microsoft.Extensions.Logging.Configuration/LoggerProviderOptionsChangeTokenSource.cs new file mode 100644 index 00000000..2438d8cf --- /dev/null +++ b/src/Microsoft.Extensions.Logging.Configuration/LoggerProviderOptionsChangeTokenSource.cs @@ -0,0 +1,13 @@ +using Microsoft.Extensions.Options; + +namespace Microsoft.Extensions.Logging +{ + /// + public class LoggerProviderOptionsChangeTokenSource : ConfigurationChangeTokenSource + { + /// + public LoggerProviderOptionsChangeTokenSource(ILoggerProviderConfiguration providerConfiguration) : base(providerConfiguration.Configuration) + { + } + } +} \ No newline at end of file diff --git a/src/Microsoft.Extensions.Logging.Configuration/LoggingBuilderExtensions.cs b/src/Microsoft.Extensions.Logging.Configuration/LoggingBuilderExtensions.cs index 9e853179..abf542a9 100644 --- a/src/Microsoft.Extensions.Logging.Configuration/LoggingBuilderExtensions.cs +++ b/src/Microsoft.Extensions.Logging.Configuration/LoggingBuilderExtensions.cs @@ -3,6 +3,7 @@ using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.Options; namespace Microsoft.Extensions.Logging @@ -20,9 +21,14 @@ public static class LoggingBuilderExtensions /// The builder. public static ILoggingBuilder AddConfiguration(this ILoggingBuilder builder, IConfiguration configuration) { + builder.Services.TryAddSingleton(); + builder.Services.TryAddSingleton(typeof(ILoggerProviderConfiguration<>), typeof(LoggerProviderConfiguration<>)); + builder.Services.AddSingleton>(new LoggerFilterConfigureOptions(configuration)); builder.Services.AddSingleton>(new ConfigurationChangeTokenSource(configuration)); + builder.Services.AddSingleton(new LoggingConfiguration(configuration)); + return builder; } } diff --git a/src/Microsoft.Extensions.Logging.Configuration/LoggingConfiguration.cs b/src/Microsoft.Extensions.Logging.Configuration/LoggingConfiguration.cs new file mode 100644 index 00000000..9faae66f --- /dev/null +++ b/src/Microsoft.Extensions.Logging.Configuration/LoggingConfiguration.cs @@ -0,0 +1,14 @@ +using Microsoft.Extensions.Configuration; + +namespace Microsoft.Extensions.Logging +{ + internal class LoggingConfiguration + { + public IConfiguration Configuration { get; } + + public LoggingConfiguration(IConfiguration configuration) + { + Configuration = configuration; + } + } +} \ No newline at end of file diff --git a/src/Microsoft.Extensions.Logging.Console/ConsoleLoggerFactoryExtensions.cs b/src/Microsoft.Extensions.Logging.Console/ConsoleLoggerFactoryExtensions.cs index c8e47da2..c3e99820 100644 --- a/src/Microsoft.Extensions.Logging.Console/ConsoleLoggerFactoryExtensions.cs +++ b/src/Microsoft.Extensions.Logging.Console/ConsoleLoggerFactoryExtensions.cs @@ -5,6 +5,7 @@ using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging.Console; +using Microsoft.Extensions.Options; namespace Microsoft.Extensions.Logging { @@ -17,7 +18,8 @@ public static class ConsoleLoggerExtensions public static ILoggingBuilder AddConsole(this ILoggingBuilder builder) { builder.Services.AddSingleton(); - + builder.Services.AddSingleton, ConsoleLoggerOptionsSetup>(); + builder.Services.AddSingleton, LoggerProviderOptionsChangeTokenSource>(); return builder; } diff --git a/src/Microsoft.Extensions.Logging.Console/ConsoleLoggerOptions.cs b/src/Microsoft.Extensions.Logging.Console/ConsoleLoggerOptions.cs index 4c687a82..e95b08d8 100644 --- a/src/Microsoft.Extensions.Logging.Console/ConsoleLoggerOptions.cs +++ b/src/Microsoft.Extensions.Logging.Console/ConsoleLoggerOptions.cs @@ -1,6 +1,8 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using System; + namespace Microsoft.Extensions.Logging.Console { public class ConsoleLoggerOptions diff --git a/src/Microsoft.Extensions.Logging.Console/ConsoleLoggerOptionsSetup.cs b/src/Microsoft.Extensions.Logging.Console/ConsoleLoggerOptionsSetup.cs new file mode 100644 index 00000000..c48a0c58 --- /dev/null +++ b/src/Microsoft.Extensions.Logging.Console/ConsoleLoggerOptionsSetup.cs @@ -0,0 +1,13 @@ +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Options; + +namespace Microsoft.Extensions.Logging.Console +{ + internal class ConsoleLoggerOptionsSetup : ConfigureOptions + { + public ConsoleLoggerOptionsSetup(ILoggerProviderConfiguration providerConfiguration) + : base(options => providerConfiguration.Configuration.Bind(options)) + { + } + } +} \ No newline at end of file diff --git a/src/Microsoft.Extensions.Logging.Console/Microsoft.Extensions.Logging.Console.csproj b/src/Microsoft.Extensions.Logging.Console/Microsoft.Extensions.Logging.Console.csproj index 46f194bd..5aa4b871 100644 --- a/src/Microsoft.Extensions.Logging.Console/Microsoft.Extensions.Logging.Console.csproj +++ b/src/Microsoft.Extensions.Logging.Console/Microsoft.Extensions.Logging.Console.csproj @@ -8,6 +8,7 @@ + diff --git a/src/Microsoft.Extensions.Logging/Microsoft.Extensions.Logging.csproj b/src/Microsoft.Extensions.Logging/Microsoft.Extensions.Logging.csproj index 96b113fc..44e18f95 100644 --- a/src/Microsoft.Extensions.Logging/Microsoft.Extensions.Logging.csproj +++ b/src/Microsoft.Extensions.Logging/Microsoft.Extensions.Logging.csproj @@ -13,6 +13,7 @@ + diff --git a/test/Microsoft.Extensions.Logging.Test/ConsoleLoggerTest.cs b/test/Microsoft.Extensions.Logging.Test/ConsoleLoggerTest.cs index 0faa1350..18092e23 100644 --- a/test/Microsoft.Extensions.Logging.Test/ConsoleLoggerTest.cs +++ b/test/Microsoft.Extensions.Logging.Test/ConsoleLoggerTest.cs @@ -6,6 +6,7 @@ using System.Linq; using System.Threading; using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging.Console; using Microsoft.Extensions.Logging.Console.Internal; using Microsoft.Extensions.Logging.Test.Console; @@ -913,6 +914,23 @@ public void ConsoleLoggerOptions_IncludeScopes_IsAppliedToLoggers() Assert.False(logger.IncludeScopes); } + [Fact] + public void ConsoleLoggerOptions_IncludeScopes_IsReadFromLoggingConfiguration() + { + var configuration = new ConfigurationBuilder().AddInMemoryCollection(new[] { new KeyValuePair("Console:IncludeScopes", "true") }).Build(); + + var loggerProvider = new ServiceCollection() + .AddLogging(builder => builder + .AddConfiguration(configuration) + .AddConsole()) + .BuildServiceProvider() + .GetRequiredService(); + + var consoleLoggerProvider = Assert.IsType(loggerProvider); + var logger = (ConsoleLogger)consoleLoggerProvider.CreateLogger("Category"); + Assert.True(logger.IncludeScopes); + } + public static TheoryData LevelsWithPrefixes => new TheoryData() { {LogLevel.Critical, "crit"}, diff --git a/test/Microsoft.Extensions.Logging.Test/LoggerProviderConfigurationTests.cs b/test/Microsoft.Extensions.Logging.Test/LoggerProviderConfigurationTests.cs new file mode 100644 index 00000000..1a1ff5f6 --- /dev/null +++ b/test/Microsoft.Extensions.Logging.Test/LoggerProviderConfigurationTests.cs @@ -0,0 +1,92 @@ +using System; +using System.Collections.Generic; +using System.Text; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Xunit; + +namespace Microsoft.Extensions.Logging.Test +{ + public class LoggerProviderConfigurationTests + { + [Fact] + public void ReturnsConfigurationSectionByFullName() + { + var serviceProvider = BuildServiceProvider(Pair("Microsoft.Extensions.Logging.Test.TestLoggerProvider:Key", "Value")); + + var providerConfiguration = serviceProvider.GetRequiredService(); + var configuration = providerConfiguration.GetConfiguration(typeof(TestLoggerProvider)); + + Assert.Equal("Value", configuration["Key"]); + } + + [Fact] + public void ReturnsConfigurationSectionByAlias() + { + var serviceProvider = BuildServiceProvider(Pair("TestLogger:Key", "Value")); + + var providerConfiguration = serviceProvider.GetRequiredService(); + var configuration = providerConfiguration.GetConfiguration(typeof(TestLoggerProvider)); + + Assert.Equal("Value", configuration["Key"]); + } + + + [Fact] + public void ReturnsConfigurationSectionByFullNameGeneric() + { + var serviceProvider = BuildServiceProvider(Pair("Microsoft.Extensions.Logging.Test.TestLoggerProvider:Key", "Value")); + + var providerConfiguration = serviceProvider.GetRequiredService>(); + + Assert.Equal("Value", providerConfiguration.Configuration["Key"]); + } + + [Fact] + public void ReturnsConfigurationSectionByAliasGeneric() + { + var serviceProvider = BuildServiceProvider(Pair("TestLogger:Key", "Value")); + + var providerConfiguration = serviceProvider.GetRequiredService>(); + + Assert.Equal("Value", providerConfiguration.Configuration["Key"]); + } + + + [Fact] + public void MergesSectionsPreferringAlias() + { + var serviceProvider = BuildServiceProvider(Pair("TestLogger:Key", "Value1"), Pair("Microsoft.Extensions.Logging.Test.TestLoggerProvider:Key", "Value2")); + + var providerConfiguration = serviceProvider.GetRequiredService>(); + + Assert.Equal("Value1", providerConfiguration.Configuration["Key"]); + } + + [Fact] + public void MergesConfigurationsInOrder() + { + var serviceProvider = new ServiceCollection() + .AddLogging( + builder => builder + .AddConfiguration(new ConfigurationBuilder().AddInMemoryCollection(new [] { Pair("TestLogger:Key", "Value1") }).Build()) + .AddConfiguration(new ConfigurationBuilder().AddInMemoryCollection(new [] { Pair("Microsoft.Extensions.Logging.Test.TestLoggerProvider:Key", "Value2") }).Build())) + .BuildServiceProvider(); + + var providerConfiguration = serviceProvider.GetRequiredService>(); + + Assert.Equal("Value2", providerConfiguration.Configuration["Key"]); + } + + private KeyValuePair Pair(string key, string value) => new KeyValuePair(key, value); + + private static ServiceProvider BuildServiceProvider(params KeyValuePair[] values) + { + return new ServiceCollection() + .AddLogging( + builder => builder.AddConfiguration( + new ConfigurationBuilder().AddInMemoryCollection(values).Build())) + .BuildServiceProvider(); + } + } +} From e99f3211ace88df3b6a33e5f339397ebcae49036 Mon Sep 17 00:00:00 2001 From: Pavel Krymets Date: Mon, 18 Sep 2017 11:00:26 -0700 Subject: [PATCH 2/4] Doc comments, deduplicate code --- .../ILoggerProviderConfiguration.cs | 10 ++- .../ILoggerProviderConfigurationFactory.cs | 20 +++++ .../ILoggerProviderConfigurationOfT.cs | 18 ----- .../LoggerProviderConfiguration.cs | 74 ++----------------- .../LoggerProviderConfigurationFactory.cs | 50 +++++++++++++ .../LoggerProviderOptionsChangeTokenSource.cs | 5 +- .../LoggingBuilderExtensions.cs | 2 +- .../LoggingConfiguration.cs | 3 + .../LoggerRuleSelector.cs | 25 +------ .../ProviderAliasUtilities.cs | 34 +++++++++ .../LoggerProviderConfigurationTests.cs | 11 ++- 11 files changed, 129 insertions(+), 123 deletions(-) create mode 100644 src/Microsoft.Extensions.Logging.Configuration/ILoggerProviderConfigurationFactory.cs delete mode 100644 src/Microsoft.Extensions.Logging.Configuration/ILoggerProviderConfigurationOfT.cs create mode 100644 src/Microsoft.Extensions.Logging.Configuration/LoggerProviderConfigurationFactory.cs create mode 100644 src/Microsoft.Extensions.Logging/ProviderAliasUtilities.cs diff --git a/src/Microsoft.Extensions.Logging.Configuration/ILoggerProviderConfiguration.cs b/src/Microsoft.Extensions.Logging.Configuration/ILoggerProviderConfiguration.cs index d519e2d7..036ed68e 100644 --- a/src/Microsoft.Extensions.Logging.Configuration/ILoggerProviderConfiguration.cs +++ b/src/Microsoft.Extensions.Logging.Configuration/ILoggerProviderConfiguration.cs @@ -1,16 +1,18 @@ -using System.Text; +// 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 Microsoft.Extensions.Configuration; namespace Microsoft.Extensions.Logging { /// - /// + /// Allows access to configuration section associated with logger provider /// - /// + /// Type of logger provider to get configuration for public interface ILoggerProviderConfiguration { /// - /// + /// Configuration section for requested logger provider /// IConfiguration Configuration { get; } } diff --git a/src/Microsoft.Extensions.Logging.Configuration/ILoggerProviderConfigurationFactory.cs b/src/Microsoft.Extensions.Logging.Configuration/ILoggerProviderConfigurationFactory.cs new file mode 100644 index 00000000..25517cac --- /dev/null +++ b/src/Microsoft.Extensions.Logging.Configuration/ILoggerProviderConfigurationFactory.cs @@ -0,0 +1,20 @@ +// 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 Microsoft.Extensions.Configuration; + +namespace Microsoft.Extensions.Logging +{ + /// + /// Allows access to configuration section associated with logger provider + /// + public interface ILoggerProviderConfigurationFactory + { + /// + /// Return configuration section associated with logger provider + /// + /// The logger provider type + IConfiguration GetConfiguration(Type providerType); + } +} \ No newline at end of file diff --git a/src/Microsoft.Extensions.Logging.Configuration/ILoggerProviderConfigurationOfT.cs b/src/Microsoft.Extensions.Logging.Configuration/ILoggerProviderConfigurationOfT.cs deleted file mode 100644 index 71ef2c33..00000000 --- a/src/Microsoft.Extensions.Logging.Configuration/ILoggerProviderConfigurationOfT.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System; -using Microsoft.Extensions.Configuration; - -namespace Microsoft.Extensions.Logging -{ - /// - /// - /// - public interface ILoggerProviderConfiguration - { - /// - /// - /// - /// - /// - IConfiguration GetConfiguration(Type providerType); - } -} \ No newline at end of file diff --git a/src/Microsoft.Extensions.Logging.Configuration/LoggerProviderConfiguration.cs b/src/Microsoft.Extensions.Logging.Configuration/LoggerProviderConfiguration.cs index a7595af5..2adf0612 100644 --- a/src/Microsoft.Extensions.Logging.Configuration/LoggerProviderConfiguration.cs +++ b/src/Microsoft.Extensions.Logging.Configuration/LoggerProviderConfiguration.cs @@ -1,81 +1,17 @@ -using System; -using System.Collections.Generic; -using System.Reflection; +// 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 Microsoft.Extensions.Configuration; namespace Microsoft.Extensions.Logging { internal class LoggerProviderConfiguration : ILoggerProviderConfiguration { - public LoggerProviderConfiguration(ILoggerProviderConfiguration providerConfiguration) + public LoggerProviderConfiguration(ILoggerProviderConfigurationFactory providerConfigurationFactory) { - Configuration = providerConfiguration.GetConfiguration(typeof(T)); + Configuration = providerConfigurationFactory.GetConfiguration(typeof(T)); } public IConfiguration Configuration { get; } } - - internal class LoggerProviderConfiguration : ILoggerProviderConfiguration - { - private readonly IEnumerable _configurations; - - public LoggerProviderConfiguration(IEnumerable configurations) - { - _configurations = configurations; - } - - private const string AliasAttibuteTypeFullName = "Microsoft.Extensions.Logging.ProviderAliasAttribute"; - private const string AliasAttibuteAliasProperty = "Alias"; - - public IConfiguration GetConfiguration(Type providerType) - { - if (providerType == null) - { - throw new ArgumentNullException(nameof(providerType)); - } - - var fullName = providerType.FullName; - var alias = GetAlias(providerType); - var configurationBuilder = new ConfigurationBuilder(); - foreach (var configuration in _configurations) - { - var sectionFromFullName = configuration.Configuration.GetSection(fullName); - if (sectionFromFullName.Exists()) - { - configurationBuilder.AddConfiguration(sectionFromFullName); - } - - if (!string.IsNullOrWhiteSpace(alias)) - { - var sectionFromAlias = configuration.Configuration.GetSection(alias); - if (sectionFromAlias.Exists()) - { - configurationBuilder.AddConfiguration(sectionFromAlias); - } - } - } - return configurationBuilder.Build(); - } - - - private string GetAlias(Type providerType) - { - foreach (var attribute in providerType.GetTypeInfo().GetCustomAttributes(inherit: false)) - { - if (attribute.GetType().FullName == AliasAttibuteTypeFullName) - { - var valueProperty = attribute - .GetType() - .GetProperty(AliasAttibuteAliasProperty, BindingFlags.Public | BindingFlags.Instance); - - if (valueProperty != null) - { - return valueProperty.GetValue(attribute) as string; - } - } - } - - return null; - } - } } \ No newline at end of file diff --git a/src/Microsoft.Extensions.Logging.Configuration/LoggerProviderConfigurationFactory.cs b/src/Microsoft.Extensions.Logging.Configuration/LoggerProviderConfigurationFactory.cs new file mode 100644 index 00000000..b7da5de6 --- /dev/null +++ b/src/Microsoft.Extensions.Logging.Configuration/LoggerProviderConfigurationFactory.cs @@ -0,0 +1,50 @@ +// 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.Reflection; +using Microsoft.Extensions.Configuration; + +namespace Microsoft.Extensions.Logging +{ + internal class LoggerProviderConfigurationFactory : ILoggerProviderConfigurationFactory + { + private readonly IEnumerable _configurations; + + public LoggerProviderConfigurationFactory(IEnumerable configurations) + { + _configurations = configurations; + } + + public IConfiguration GetConfiguration(Type providerType) + { + if (providerType == null) + { + throw new ArgumentNullException(nameof(providerType)); + } + + var fullName = providerType.FullName; + var alias = ProviderAliasUtilities.GetAlias(providerType); + var configurationBuilder = new ConfigurationBuilder(); + foreach (var configuration in _configurations) + { + var sectionFromFullName = configuration.Configuration.GetSection(fullName); + if (sectionFromFullName.Exists()) + { + configurationBuilder.AddConfiguration(sectionFromFullName); + } + + if (!string.IsNullOrWhiteSpace(alias)) + { + var sectionFromAlias = configuration.Configuration.GetSection(alias); + if (sectionFromAlias.Exists()) + { + configurationBuilder.AddConfiguration(sectionFromAlias); + } + } + } + return configurationBuilder.Build(); + } + } +} \ No newline at end of file diff --git a/src/Microsoft.Extensions.Logging.Configuration/LoggerProviderOptionsChangeTokenSource.cs b/src/Microsoft.Extensions.Logging.Configuration/LoggerProviderOptionsChangeTokenSource.cs index 2438d8cf..20be07c9 100644 --- a/src/Microsoft.Extensions.Logging.Configuration/LoggerProviderOptionsChangeTokenSource.cs +++ b/src/Microsoft.Extensions.Logging.Configuration/LoggerProviderOptionsChangeTokenSource.cs @@ -1,4 +1,7 @@ -using Microsoft.Extensions.Options; +// 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 Microsoft.Extensions.Options; namespace Microsoft.Extensions.Logging { diff --git a/src/Microsoft.Extensions.Logging.Configuration/LoggingBuilderExtensions.cs b/src/Microsoft.Extensions.Logging.Configuration/LoggingBuilderExtensions.cs index abf542a9..4310a138 100644 --- a/src/Microsoft.Extensions.Logging.Configuration/LoggingBuilderExtensions.cs +++ b/src/Microsoft.Extensions.Logging.Configuration/LoggingBuilderExtensions.cs @@ -21,7 +21,7 @@ public static class LoggingBuilderExtensions /// The builder. public static ILoggingBuilder AddConfiguration(this ILoggingBuilder builder, IConfiguration configuration) { - builder.Services.TryAddSingleton(); + builder.Services.TryAddSingleton(); builder.Services.TryAddSingleton(typeof(ILoggerProviderConfiguration<>), typeof(LoggerProviderConfiguration<>)); builder.Services.AddSingleton>(new LoggerFilterConfigureOptions(configuration)); diff --git a/src/Microsoft.Extensions.Logging.Configuration/LoggingConfiguration.cs b/src/Microsoft.Extensions.Logging.Configuration/LoggingConfiguration.cs index 9faae66f..86a83cf0 100644 --- a/src/Microsoft.Extensions.Logging.Configuration/LoggingConfiguration.cs +++ b/src/Microsoft.Extensions.Logging.Configuration/LoggingConfiguration.cs @@ -1,3 +1,6 @@ +// 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 Microsoft.Extensions.Configuration; namespace Microsoft.Extensions.Logging diff --git a/src/Microsoft.Extensions.Logging/LoggerRuleSelector.cs b/src/Microsoft.Extensions.Logging/LoggerRuleSelector.cs index 2a66f782..48d9b3c5 100644 --- a/src/Microsoft.Extensions.Logging/LoggerRuleSelector.cs +++ b/src/Microsoft.Extensions.Logging/LoggerRuleSelector.cs @@ -2,15 +2,11 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; -using System.Reflection; namespace Microsoft.Extensions.Logging { internal class LoggerRuleSelector { - private const string AliasAttibuteTypeFullName = "Microsoft.Extensions.Logging.ProviderAliasAttribute"; - private const string AliasAttibuteAliasProperty = "Alias"; - public void Select(LoggerFilterOptions options, Type providerType, string category, out LogLevel? minLevel, out Func filter) { filter = null; @@ -24,7 +20,7 @@ public void Select(LoggerFilterOptions options, Type providerType, string catego // 4. If there are multiple rules use last // 5. If there are no applicable rules use global minimal level - var providerAlias = GetAlias(providerType); + var providerAlias = ProviderAliasUtilities.GetAlias(providerType); LoggerFilterRule current = null; foreach (var rule in options.Rules) { @@ -42,25 +38,6 @@ public void Select(LoggerFilterOptions options, Type providerType, string catego } } - private string GetAlias(Type providerType) - { - foreach (var attribute in providerType.GetTypeInfo().GetCustomAttributes(inherit: false)) - { - if (attribute.GetType().FullName == AliasAttibuteTypeFullName) - { - var valueProperty = attribute - .GetType() - .GetProperty(AliasAttibuteAliasProperty, BindingFlags.Public | BindingFlags.Instance); - - if (valueProperty != null) - { - return valueProperty.GetValue(attribute) as string; - } - } - } - - return null; - } private static bool IsBetter(LoggerFilterRule rule, LoggerFilterRule current, string logger, string category) { diff --git a/src/Microsoft.Extensions.Logging/ProviderAliasUtilities.cs b/src/Microsoft.Extensions.Logging/ProviderAliasUtilities.cs new file mode 100644 index 00000000..20610774 --- /dev/null +++ b/src/Microsoft.Extensions.Logging/ProviderAliasUtilities.cs @@ -0,0 +1,34 @@ +// 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.Reflection; + +namespace Microsoft.Extensions.Logging +{ + internal class ProviderAliasUtilities + { + private const string AliasAttibuteTypeFullName = "Microsoft.Extensions.Logging.ProviderAliasAttribute"; + private const string AliasAttibuteAliasProperty = "Alias"; + + internal static string GetAlias(Type providerType) + { + foreach (var attribute in providerType.GetTypeInfo().GetCustomAttributes(inherit: false)) + { + if (attribute.GetType().FullName == AliasAttibuteTypeFullName) + { + var valueProperty = attribute + .GetType() + .GetProperty(AliasAttibuteAliasProperty, BindingFlags.Public | BindingFlags.Instance); + + if (valueProperty != null) + { + return valueProperty.GetValue(attribute) as string; + } + } + } + + return null; + } + } +} \ No newline at end of file diff --git a/test/Microsoft.Extensions.Logging.Test/LoggerProviderConfigurationTests.cs b/test/Microsoft.Extensions.Logging.Test/LoggerProviderConfigurationTests.cs index 1a1ff5f6..91c17ff2 100644 --- a/test/Microsoft.Extensions.Logging.Test/LoggerProviderConfigurationTests.cs +++ b/test/Microsoft.Extensions.Logging.Test/LoggerProviderConfigurationTests.cs @@ -1,6 +1,7 @@ -using System; +// 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.Collections.Generic; -using System.Text; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Xunit; @@ -14,7 +15,7 @@ public void ReturnsConfigurationSectionByFullName() { var serviceProvider = BuildServiceProvider(Pair("Microsoft.Extensions.Logging.Test.TestLoggerProvider:Key", "Value")); - var providerConfiguration = serviceProvider.GetRequiredService(); + var providerConfiguration = serviceProvider.GetRequiredService(); var configuration = providerConfiguration.GetConfiguration(typeof(TestLoggerProvider)); Assert.Equal("Value", configuration["Key"]); @@ -25,13 +26,12 @@ public void ReturnsConfigurationSectionByAlias() { var serviceProvider = BuildServiceProvider(Pair("TestLogger:Key", "Value")); - var providerConfiguration = serviceProvider.GetRequiredService(); + var providerConfiguration = serviceProvider.GetRequiredService(); var configuration = providerConfiguration.GetConfiguration(typeof(TestLoggerProvider)); Assert.Equal("Value", configuration["Key"]); } - [Fact] public void ReturnsConfigurationSectionByFullNameGeneric() { @@ -52,7 +52,6 @@ public void ReturnsConfigurationSectionByAliasGeneric() Assert.Equal("Value", providerConfiguration.Configuration["Key"]); } - [Fact] public void MergesSectionsPreferringAlias() { From 9e31a3558bd302e5b2ca40da176da258ee9e1b4f Mon Sep 17 00:00:00 2001 From: Pavel Krymets Date: Mon, 18 Sep 2017 14:24:25 -0700 Subject: [PATCH 3/4] Better things --- .../ILoggerProviderConfiguration.cs | 2 +- .../ILoggerProviderConfigurationFactory.cs | 2 +- .../LoggerProviderConfiguration.cs | 2 +- .../LoggerProviderConfigurationFactory.cs | 2 +- .../LoggerProviderOptionsChangeTokenSource.cs | 2 +- .../LoggingBuilderConfigurationExtensions.cs | 22 +++++++++++++++++++ .../LoggingBuilderExtensions.cs | 5 ++--- .../LoggingConfiguration.cs | 2 +- .../ConsoleLoggerFactoryExtensions.cs | 3 +++ .../ConsoleLoggerOptionsSetup.cs | 5 +++-- .../LoggerProviderConfigurationTests.cs | 1 + 11 files changed, 37 insertions(+), 11 deletions(-) create mode 100644 src/Microsoft.Extensions.Logging.Configuration/LoggingBuilderConfigurationExtensions.cs diff --git a/src/Microsoft.Extensions.Logging.Configuration/ILoggerProviderConfiguration.cs b/src/Microsoft.Extensions.Logging.Configuration/ILoggerProviderConfiguration.cs index 036ed68e..bb6b4aa0 100644 --- a/src/Microsoft.Extensions.Logging.Configuration/ILoggerProviderConfiguration.cs +++ b/src/Microsoft.Extensions.Logging.Configuration/ILoggerProviderConfiguration.cs @@ -3,7 +3,7 @@ using Microsoft.Extensions.Configuration; -namespace Microsoft.Extensions.Logging +namespace Microsoft.Extensions.Logging.Configuration { /// /// Allows access to configuration section associated with logger provider diff --git a/src/Microsoft.Extensions.Logging.Configuration/ILoggerProviderConfigurationFactory.cs b/src/Microsoft.Extensions.Logging.Configuration/ILoggerProviderConfigurationFactory.cs index 25517cac..1f343fa5 100644 --- a/src/Microsoft.Extensions.Logging.Configuration/ILoggerProviderConfigurationFactory.cs +++ b/src/Microsoft.Extensions.Logging.Configuration/ILoggerProviderConfigurationFactory.cs @@ -4,7 +4,7 @@ using System; using Microsoft.Extensions.Configuration; -namespace Microsoft.Extensions.Logging +namespace Microsoft.Extensions.Logging.Configuration { /// /// Allows access to configuration section associated with logger provider diff --git a/src/Microsoft.Extensions.Logging.Configuration/LoggerProviderConfiguration.cs b/src/Microsoft.Extensions.Logging.Configuration/LoggerProviderConfiguration.cs index 2adf0612..ef84fef5 100644 --- a/src/Microsoft.Extensions.Logging.Configuration/LoggerProviderConfiguration.cs +++ b/src/Microsoft.Extensions.Logging.Configuration/LoggerProviderConfiguration.cs @@ -3,7 +3,7 @@ using Microsoft.Extensions.Configuration; -namespace Microsoft.Extensions.Logging +namespace Microsoft.Extensions.Logging.Configuration { internal class LoggerProviderConfiguration : ILoggerProviderConfiguration { diff --git a/src/Microsoft.Extensions.Logging.Configuration/LoggerProviderConfigurationFactory.cs b/src/Microsoft.Extensions.Logging.Configuration/LoggerProviderConfigurationFactory.cs index b7da5de6..8c0135a7 100644 --- a/src/Microsoft.Extensions.Logging.Configuration/LoggerProviderConfigurationFactory.cs +++ b/src/Microsoft.Extensions.Logging.Configuration/LoggerProviderConfigurationFactory.cs @@ -6,7 +6,7 @@ using System.Reflection; using Microsoft.Extensions.Configuration; -namespace Microsoft.Extensions.Logging +namespace Microsoft.Extensions.Logging.Configuration { internal class LoggerProviderConfigurationFactory : ILoggerProviderConfigurationFactory { diff --git a/src/Microsoft.Extensions.Logging.Configuration/LoggerProviderOptionsChangeTokenSource.cs b/src/Microsoft.Extensions.Logging.Configuration/LoggerProviderOptionsChangeTokenSource.cs index 20be07c9..cc646692 100644 --- a/src/Microsoft.Extensions.Logging.Configuration/LoggerProviderOptionsChangeTokenSource.cs +++ b/src/Microsoft.Extensions.Logging.Configuration/LoggerProviderOptionsChangeTokenSource.cs @@ -3,7 +3,7 @@ using Microsoft.Extensions.Options; -namespace Microsoft.Extensions.Logging +namespace Microsoft.Extensions.Logging.Configuration { /// public class LoggerProviderOptionsChangeTokenSource : ConfigurationChangeTokenSource diff --git a/src/Microsoft.Extensions.Logging.Configuration/LoggingBuilderConfigurationExtensions.cs b/src/Microsoft.Extensions.Logging.Configuration/LoggingBuilderConfigurationExtensions.cs new file mode 100644 index 00000000..2b89c4e9 --- /dev/null +++ b/src/Microsoft.Extensions.Logging.Configuration/LoggingBuilderConfigurationExtensions.cs @@ -0,0 +1,22 @@ +// 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 Microsoft.Extensions.DependencyInjection.Extensions; + +namespace Microsoft.Extensions.Logging.Configuration +{ + /// + /// Extension methods for setting up logging services in an . + /// + public static class LoggingBuilderConfigurationExtensions + { + /// + /// Adds services required to consume or + /// + public static void AddConfiguration(this ILoggingBuilder builder) + { + builder.Services.TryAddSingleton(); + builder.Services.TryAddSingleton(typeof(ILoggerProviderConfiguration<>), typeof(LoggerProviderConfiguration<>)); + } + } +} \ No newline at end of file diff --git a/src/Microsoft.Extensions.Logging.Configuration/LoggingBuilderExtensions.cs b/src/Microsoft.Extensions.Logging.Configuration/LoggingBuilderExtensions.cs index 4310a138..51fa1178 100644 --- a/src/Microsoft.Extensions.Logging.Configuration/LoggingBuilderExtensions.cs +++ b/src/Microsoft.Extensions.Logging.Configuration/LoggingBuilderExtensions.cs @@ -3,7 +3,7 @@ using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.DependencyInjection.Extensions; +using Microsoft.Extensions.Logging.Configuration; using Microsoft.Extensions.Options; namespace Microsoft.Extensions.Logging @@ -21,8 +21,7 @@ public static class LoggingBuilderExtensions /// The builder. public static ILoggingBuilder AddConfiguration(this ILoggingBuilder builder, IConfiguration configuration) { - builder.Services.TryAddSingleton(); - builder.Services.TryAddSingleton(typeof(ILoggerProviderConfiguration<>), typeof(LoggerProviderConfiguration<>)); + builder.AddConfiguration(); builder.Services.AddSingleton>(new LoggerFilterConfigureOptions(configuration)); builder.Services.AddSingleton>(new ConfigurationChangeTokenSource(configuration)); diff --git a/src/Microsoft.Extensions.Logging.Configuration/LoggingConfiguration.cs b/src/Microsoft.Extensions.Logging.Configuration/LoggingConfiguration.cs index 86a83cf0..7d330cf5 100644 --- a/src/Microsoft.Extensions.Logging.Configuration/LoggingConfiguration.cs +++ b/src/Microsoft.Extensions.Logging.Configuration/LoggingConfiguration.cs @@ -3,7 +3,7 @@ using Microsoft.Extensions.Configuration; -namespace Microsoft.Extensions.Logging +namespace Microsoft.Extensions.Logging.Configuration { internal class LoggingConfiguration { diff --git a/src/Microsoft.Extensions.Logging.Console/ConsoleLoggerFactoryExtensions.cs b/src/Microsoft.Extensions.Logging.Console/ConsoleLoggerFactoryExtensions.cs index c3e99820..7e8e2ae6 100644 --- a/src/Microsoft.Extensions.Logging.Console/ConsoleLoggerFactoryExtensions.cs +++ b/src/Microsoft.Extensions.Logging.Console/ConsoleLoggerFactoryExtensions.cs @@ -4,6 +4,7 @@ using System; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging.Configuration; using Microsoft.Extensions.Logging.Console; using Microsoft.Extensions.Options; @@ -17,6 +18,8 @@ public static class ConsoleLoggerExtensions /// The to use. public static ILoggingBuilder AddConsole(this ILoggingBuilder builder) { + builder.AddConfiguration(); + builder.Services.AddSingleton(); builder.Services.AddSingleton, ConsoleLoggerOptionsSetup>(); builder.Services.AddSingleton, LoggerProviderOptionsChangeTokenSource>(); diff --git a/src/Microsoft.Extensions.Logging.Console/ConsoleLoggerOptionsSetup.cs b/src/Microsoft.Extensions.Logging.Console/ConsoleLoggerOptionsSetup.cs index c48a0c58..d027ad01 100644 --- a/src/Microsoft.Extensions.Logging.Console/ConsoleLoggerOptionsSetup.cs +++ b/src/Microsoft.Extensions.Logging.Console/ConsoleLoggerOptionsSetup.cs @@ -1,12 +1,13 @@ using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Logging.Configuration; using Microsoft.Extensions.Options; namespace Microsoft.Extensions.Logging.Console { - internal class ConsoleLoggerOptionsSetup : ConfigureOptions + internal class ConsoleLoggerOptionsSetup : ConfigureFromConfigurationOptions { public ConsoleLoggerOptionsSetup(ILoggerProviderConfiguration providerConfiguration) - : base(options => providerConfiguration.Configuration.Bind(options)) + : base(providerConfiguration.Configuration) { } } diff --git a/test/Microsoft.Extensions.Logging.Test/LoggerProviderConfigurationTests.cs b/test/Microsoft.Extensions.Logging.Test/LoggerProviderConfigurationTests.cs index 91c17ff2..c2fb6dc5 100644 --- a/test/Microsoft.Extensions.Logging.Test/LoggerProviderConfigurationTests.cs +++ b/test/Microsoft.Extensions.Logging.Test/LoggerProviderConfigurationTests.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging.Configuration; using Xunit; namespace Microsoft.Extensions.Logging.Test From 89d02eba0206a62fa87b8ba61f1ac8343b1740f7 Mon Sep 17 00:00:00 2001 From: Pavel Krymets Date: Mon, 18 Sep 2017 14:33:22 -0700 Subject: [PATCH 4/4] Properties file --- src/Microsoft.Extensions.Logging/Properties/AssemlyInfo.cs | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 src/Microsoft.Extensions.Logging/Properties/AssemlyInfo.cs diff --git a/src/Microsoft.Extensions.Logging/Properties/AssemlyInfo.cs b/src/Microsoft.Extensions.Logging/Properties/AssemlyInfo.cs new file mode 100644 index 00000000..a603dd08 --- /dev/null +++ b/src/Microsoft.Extensions.Logging/Properties/AssemlyInfo.cs @@ -0,0 +1,3 @@ +using System.Runtime.CompilerServices; + +[assembly: InternalsVisibleTo("Microsoft.Extensions.Logging.Configuration, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")] \ No newline at end of file