diff --git a/src/Serilog.Settings.Configuration/ConfigurationLoggerConfigurationExtensions.cs b/src/Serilog.Settings.Configuration/ConfigurationLoggerConfigurationExtensions.cs
index 4e24eef..0453c83 100644
--- a/src/Serilog.Settings.Configuration/ConfigurationLoggerConfigurationExtensions.cs
+++ b/src/Serilog.Settings.Configuration/ConfigurationLoggerConfigurationExtensions.cs
@@ -47,6 +47,28 @@ public static LoggerConfiguration Configuration(
IConfiguration configuration,
string sectionName,
DependencyContext dependencyContext = null)
+ {
+ return Configuration(settingConfiguration, configuration, sectionName, out _, dependencyContext);
+ }
+
+ ///
+ /// Reads logger settings from the provided configuration object using the provided section name. Generally this
+ /// is preferable over the other method that takes a configuration section. Only this version will populate
+ /// IConfiguration parameters on target methods.
+ ///
+ /// Logger setting configuration.
+ /// A configuration object which contains a Serilog section.
+ /// A section name for section which contains a Serilog section.
+ /// Contains information about the loaded configuration upon return.
+ /// The dependency context from which sink/enricher packages can be located. If not supplied, the platform
+ /// default will be used.
+ /// An object allowing configuration to continue.
+ public static LoggerConfiguration Configuration(
+ this LoggerSettingsConfiguration settingConfiguration,
+ IConfiguration configuration,
+ string sectionName,
+ out LoadedConfiguration loadedConfiguration,
+ DependencyContext dependencyContext = null)
{
if (settingConfiguration == null) throw new ArgumentNullException(nameof(settingConfiguration));
if (configuration == null) throw new ArgumentNullException(nameof(configuration));
@@ -56,11 +78,10 @@ public static LoggerConfiguration Configuration(
? AssemblyFinder.Auto()
: AssemblyFinder.ForDependencyContext(dependencyContext);
- return settingConfiguration.Settings(
- new ConfigurationReader(
- configuration.GetSection(sectionName),
- assemblyFinder,
- configuration));
+ var configurationReader = new ConfigurationReader(configuration.GetSection(sectionName), assemblyFinder, configuration);
+ var loggerConfiguration = settingConfiguration.Settings(configurationReader);
+ loadedConfiguration = configurationReader.GetLoadedConfiguration();
+ return loggerConfiguration;
}
///
@@ -79,6 +100,24 @@ public static LoggerConfiguration Configuration(
DependencyContext dependencyContext = null)
=> Configuration(settingConfiguration, configuration, DefaultSectionName, dependencyContext);
+ ///
+ /// Reads logger settings from the provided configuration object using the default section name. Generally this
+ /// is preferable over the other method that takes a configuration section. Only this version will populate
+ /// IConfiguration parameters on target methods.
+ ///
+ /// Logger setting configuration.
+ /// A configuration object which contains a Serilog section.
+ /// Contains information about the loaded configuration upon return.
+ /// The dependency context from which sink/enricher packages can be located. If not supplied, the platform
+ /// default will be used.
+ /// An object allowing configuration to continue.
+ public static LoggerConfiguration Configuration(
+ this LoggerSettingsConfiguration settingConfiguration,
+ IConfiguration configuration,
+ out LoadedConfiguration loadedConfiguration,
+ DependencyContext dependencyContext = null)
+ => Configuration(settingConfiguration, configuration, DefaultSectionName, out loadedConfiguration, dependencyContext);
+
///
/// Reads logger settings from the provided configuration section. Generally it is preferable to use the other
/// extension method that takes the full configuration object.
@@ -123,6 +162,25 @@ public static LoggerConfiguration Configuration(
IConfiguration configuration,
string sectionName,
ConfigurationAssemblySource configurationAssemblySource)
+ => Configuration(settingConfiguration, configuration, sectionName, configurationAssemblySource, out _);
+
+ ///
+ /// Reads logger settings from the provided configuration object using the provided section name. Generally this
+ /// is preferable over the other method that takes a configuration section. Only this version will populate
+ /// IConfiguration parameters on target methods.
+ ///
+ /// Logger setting configuration.
+ /// A configuration object which contains a Serilog section.
+ /// A section name for section which contains a Serilog section.
+ /// Defines how the package identifies assemblies to scan for sinks and other types.
+ /// Contains information about the loaded configuration upon return.
+ /// An object allowing configuration to continue.
+ public static LoggerConfiguration Configuration(
+ this LoggerSettingsConfiguration settingConfiguration,
+ IConfiguration configuration,
+ string sectionName,
+ ConfigurationAssemblySource configurationAssemblySource,
+ out LoadedConfiguration loadedConfiguration)
{
if (settingConfiguration == null) throw new ArgumentNullException(nameof(settingConfiguration));
if (configuration == null) throw new ArgumentNullException(nameof(configuration));
@@ -130,7 +188,10 @@ public static LoggerConfiguration Configuration(
var assemblyFinder = AssemblyFinder.ForSource(configurationAssemblySource);
- return settingConfiguration.Settings(new ConfigurationReader(configuration.GetSection(sectionName), assemblyFinder, configuration));
+ var configurationReader = new ConfigurationReader(configuration.GetSection(sectionName), assemblyFinder, configuration);
+ var loggerConfiguration = settingConfiguration.Settings(configurationReader);
+ loadedConfiguration = configurationReader.GetLoadedConfiguration();
+ return loggerConfiguration;
}
///
@@ -183,12 +244,32 @@ public static LoggerConfiguration Configuration(
IConfiguration configuration,
string sectionName,
params Assembly[] assemblies)
+ => Configuration(settingConfiguration, configuration, sectionName, out _, assemblies);
+
+ ///
+ /// Reads logger settings from the provided configuration object using the provided section name.
+ ///
+ /// Logger setting configuration.
+ /// A configuration object which contains a Serilog section.
+ /// A section name for section which contains a Serilog section.
+ /// Contains information about the loaded configuration upon return.
+ /// A collection of assemblies that contains sinks and other types.
+ /// An object allowing configuration to continue.
+ public static LoggerConfiguration Configuration(
+ this LoggerSettingsConfiguration settingConfiguration,
+ IConfiguration configuration,
+ string sectionName,
+ out LoadedConfiguration loadedConfiguration,
+ params Assembly[] assemblies)
{
if (settingConfiguration == null) throw new ArgumentNullException(nameof(settingConfiguration));
if (configuration == null) throw new ArgumentNullException(nameof(configuration));
if (sectionName == null) throw new ArgumentNullException(nameof(sectionName));
- return settingConfiguration.Settings(new ConfigurationReader(configuration.GetSection(sectionName), assemblies, new ResolutionContext(configuration)));
+ var configurationReader = new ConfigurationReader(configuration.GetSection(sectionName), assemblies, new ResolutionContext(configuration));
+ var loggerConfiguration = settingConfiguration.Settings(configurationReader);
+ loadedConfiguration = configurationReader.GetLoadedConfiguration();
+ return loggerConfiguration;
}
///
diff --git a/src/Serilog.Settings.Configuration/Settings/Configuration/ConfigurationReader.cs b/src/Serilog.Settings.Configuration/Settings/Configuration/ConfigurationReader.cs
index 8b20544..6ec2406 100644
--- a/src/Serilog.Settings.Configuration/Settings/Configuration/ConfigurationReader.cs
+++ b/src/Serilog.Settings.Configuration/Settings/Configuration/ConfigurationReader.cs
@@ -58,6 +58,11 @@ public void Configure(LoggerConfiguration loggerConfiguration)
ApplyAuditSinks(loggerConfiguration);
}
+ public LoadedConfiguration GetLoadedConfiguration()
+ {
+ return new LoadedConfiguration(_resolutionContext.LogLevelSwitches);
+ }
+
void ProcessFilterSwitchDeclarations()
{
var filterSwitchesDirective = _section.GetSection("FilterSwitches");
diff --git a/src/Serilog.Settings.Configuration/Settings/Configuration/LoadedConfiguration.cs b/src/Serilog.Settings.Configuration/Settings/Configuration/LoadedConfiguration.cs
new file mode 100644
index 0000000..c1864a7
--- /dev/null
+++ b/src/Serilog.Settings.Configuration/Settings/Configuration/LoadedConfiguration.cs
@@ -0,0 +1,20 @@
+using Serilog.Core;
+
+namespace Serilog.Settings.Configuration;
+
+///
+/// Contains information about the loaded configuration.
+///
+public class LoadedConfiguration
+{
+ internal LoadedConfiguration(IReadOnlyDictionary logLevelSwitches)
+ {
+ LogLevelSwitches = logLevelSwitches;
+ }
+
+ ///
+ /// The log level switches that were loaded from the LevelSwitches section of the configuration.
+ ///
+ /// The keys of the dictionary are the names of the switches, including the leading $ character.
+ public IReadOnlyDictionary LogLevelSwitches { get; }
+}
diff --git a/src/Serilog.Settings.Configuration/Settings/Configuration/ResolutionContext.cs b/src/Serilog.Settings.Configuration/Settings/Configuration/ResolutionContext.cs
index 1db02a5..b520f38 100644
--- a/src/Serilog.Settings.Configuration/Settings/Configuration/ResolutionContext.cs
+++ b/src/Serilog.Settings.Configuration/Settings/Configuration/ResolutionContext.cs
@@ -9,8 +9,8 @@ namespace Serilog.Settings.Configuration;
///
sealed class ResolutionContext
{
- readonly IDictionary _declaredLevelSwitches;
- readonly IDictionary _declaredFilterSwitches;
+ readonly Dictionary _declaredLevelSwitches;
+ readonly Dictionary _declaredFilterSwitches;
readonly IConfiguration _appConfiguration;
public ResolutionContext(IConfiguration appConfiguration = null)
@@ -20,6 +20,8 @@ public ResolutionContext(IConfiguration appConfiguration = null)
_appConfiguration = appConfiguration;
}
+ public IReadOnlyDictionary LogLevelSwitches => _declaredLevelSwitches;
+
///
/// Looks up a switch in the declared LoggingLevelSwitches
///
diff --git a/test/Serilog.Settings.Configuration.Tests/ConfigurationSettingsTests.cs b/test/Serilog.Settings.Configuration.Tests/ConfigurationSettingsTests.cs
index 94e8ff9..b744665 100644
--- a/test/Serilog.Settings.Configuration.Tests/ConfigurationSettingsTests.cs
+++ b/test/Serilog.Settings.Configuration.Tests/ConfigurationSettingsTests.cs
@@ -1,4 +1,4 @@
-using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.Configuration;
using Serilog.Core;
using Serilog.Events;
using Serilog.Settings.Configuration.Tests.Support;
@@ -12,22 +12,27 @@ public class ConfigurationSettingsTests
{
static LoggerConfiguration ConfigFromJson(string jsonString, string secondJsonSource = null)
{
- return ConfigFromJson(jsonString, secondJsonSource, out _);
+ return ConfigFromJson(jsonString, secondJsonSource, out _, out _);
}
static LoggerConfiguration ConfigFromJson(string jsonString, out IConfiguration configuration)
{
- return ConfigFromJson(jsonString, null, out configuration);
+ return ConfigFromJson(jsonString, null, out configuration, out _);
}
- static LoggerConfiguration ConfigFromJson(string jsonString, string secondJsonSource, out IConfiguration configuration)
+ static LoggerConfiguration ConfigFromJson(string jsonString, out LoadedConfiguration loadedConfiguration)
+ {
+ return ConfigFromJson(jsonString, null, out _, out loadedConfiguration);
+ }
+
+ static LoggerConfiguration ConfigFromJson(string jsonString, string secondJsonSource, out IConfiguration configuration, out LoadedConfiguration loadedConfiguration)
{
var builder = new ConfigurationBuilder().AddJsonString(jsonString);
if (secondJsonSource != null)
builder.AddJsonString(secondJsonSource);
configuration = builder.Build();
return new LoggerConfiguration()
- .ReadFrom.Configuration(configuration);
+ .ReadFrom.Configuration(configuration, out loadedConfiguration);
}
[Fact]
@@ -384,10 +389,12 @@ public void LoggingLevelSwitchIsConfigured(string switchName)
}}";
LogEvent evt = null;
- var log = ConfigFromJson(json)
+ var log = ConfigFromJson(json, out LoadedConfiguration loadedConfiguration)
.WriteTo.Sink(new DelegatingSink(e => evt = e))
.CreateLogger();
+ Assert.Contains("$switch1", loadedConfiguration.LogLevelSwitches);
+ Assert.Equal(LogEventLevel.Warning, loadedConfiguration.LogLevelSwitches["$switch1"].MinimumLevel);
log.Write(Some.DebugEvent());
Assert.True(evt is null, "LoggingLevelSwitch initial level was Warning. It should not log Debug messages");
log.Write(Some.InformationEvent());
@@ -542,7 +549,7 @@ public void SinkWithIConfigurationArguments()
}";
DummyConfigurationSink.Reset();
- var log = ConfigFromJson(json, out var expectedConfig)
+ var log = ConfigFromJson(json, out IConfiguration expectedConfig)
.CreateLogger();
log.Write(Some.InformationEvent());
@@ -566,7 +573,7 @@ public void SinkWithOptionalIConfigurationArguments()
}";
DummyConfigurationSink.Reset();
- var log = ConfigFromJson(json, out var expectedConfig)
+ var log = ConfigFromJson(json, out IConfiguration expectedConfig)
.CreateLogger();
log.Write(Some.InformationEvent());
diff --git a/test/Serilog.Settings.Configuration.Tests/DynamicLevelChangeTests.cs b/test/Serilog.Settings.Configuration.Tests/DynamicLevelChangeTests.cs
index 1c3eb5a..87dd4a8 100644
--- a/test/Serilog.Settings.Configuration.Tests/DynamicLevelChangeTests.cs
+++ b/test/Serilog.Settings.Configuration.Tests/DynamicLevelChangeTests.cs
@@ -47,9 +47,11 @@ public void ShouldRespectDynamicLevelChanges()
{
using var logger = new LoggerConfiguration()
.ReadFrom
- .Configuration(new ConfigurationBuilder().Add(_configSource).Build())
+ .Configuration(new ConfigurationBuilder().Add(_configSource).Build(), out var loadedConfiguration)
.CreateLogger();
+ Assert.Equal(LogEventLevel.Information, loadedConfiguration.LogLevelSwitches["$mySwitch"].MinimumLevel);
+
DummyConsoleSink.Emitted.Clear();
logger.Write(Some.DebugEvent());
Assert.Empty(DummyConsoleSink.Emitted);
@@ -64,6 +66,7 @@ public void ShouldRespectDynamicLevelChanges()
logger.Write(Some.DebugEvent());
logger.ForContext(Constants.SourceContextPropertyName, "Root.Test").Write(Some.DebugEvent());
Assert.Single(DummyConsoleSink.Emitted);
+ Assert.Equal(LogEventLevel.Debug, loadedConfiguration.LogLevelSwitches["$mySwitch"].MinimumLevel);
DummyConsoleSink.Emitted.Clear();
UpdateConfig(overrideLevel: LogEventLevel.Debug);