Skip to content

Commit fc0969f

Browse files
authored
Merge pull request #171 from serilog/dev
3.1.0 Release
2 parents 008a61e + 2fc93f5 commit fc0969f

28 files changed

+812
-297
lines changed

Diff for: README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Serilog.Settings.Configuration [![Build status](https://ci.appveyor.com/api/projects/status/r2bgfimd9ocr61px/branch/master?svg=true)](https://ci.appveyor.com/project/serilog/serilog-settings-configuration/branch/master)
1+
# Serilog.Settings.Configuration [![Build status](https://ci.appveyor.com/api/projects/status/r2bgfimd9ocr61px/branch/master?svg=true)](https://ci.appveyor.com/project/serilog/serilog-settings-configuration/branch/master) [![NuGet Version](http://img.shields.io/nuget/v/Serilog.Settings.Configuration.svg?style=flat)](https://www.nuget.org/packages/Serilog.Settings.Configuration/)
22

33
A Serilog settings provider that reads from _Microsoft.Extensions.Configuration_, .NET Core's `appsettings.json` file.
44

Diff for: appveyor.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ artifacts:
1010
deploy:
1111
- provider: NuGet
1212
api_key:
13-
secure: bd9z4P73oltOXudAjPehwp9iDKsPtC+HbgshOrSgoyQKr5xVK+bxJQngrDJkHdY8
13+
secure: N59tiJECUYpip6tEn0xvdmDAEiP9SIzyLEFLpwiigm/8WhJvBNs13QxzT1/3/JW/
1414
skip_symbols: true
1515
on:
1616
branch: /^(master|dev)$/

Diff for: sample/Sample/appsettings.json

+6-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
{
22
"Serilog": {
3-
"Using": ["Serilog.Sinks.Console"],
3+
"Using": [ "Serilog.Sinks.Console" ],
4+
"LevelSwitches": { "$controlSwitch": "Verbose" },
45
"MinimumLevel": {
56
"Default": "Debug",
67
"Override": {
@@ -12,6 +13,7 @@
1213
"Name": "Logger",
1314
"Args": {
1415
"configureLogger": {
16+
"MinimumLevel": "Verbose",
1517
"WriteTo": [
1618
{
1719
"Name": "Console",
@@ -22,7 +24,8 @@
2224
}
2325
]
2426
},
25-
"restrictedToMinimumLevel": "Debug"
27+
"restrictedToMinimumLevel": "Verbose",
28+
"levelSwitch": "$controlSwitch"
2629
}
2730
},
2831
"WriteTo:Async": {
@@ -39,7 +42,7 @@
3942
]
4043
}
4144
},
42-
"Enrich": ["FromLogContext", "WithMachineName", "WithThreadId"],
45+
"Enrich": [ "FromLogContext", "WithMachineName", "WithThreadId" ],
4346
"Properties": {
4447
"Application": "Sample"
4548
},

Diff for: src/Serilog.Settings.Configuration/ConfigurationLoggerConfigurationExtensions.cs

+63-22
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
using Microsoft.Extensions.DependencyModel;
1818
using Serilog.Configuration;
1919
using Serilog.Settings.Configuration;
20-
using System.Reflection;
20+
using Serilog.Settings.Configuration.Assemblies;
2121

2222
namespace Serilog
2323
{
@@ -32,28 +32,53 @@ public static class ConfigurationLoggerConfigurationExtensions
3232
public const string DefaultSectionName = "Serilog";
3333

3434
/// <summary>
35-
/// Reads logger settings from the provided configuration object using the default section name. Generally this
35+
/// Reads logger settings from the provided configuration object using the provided section name. Generally this
3636
/// is preferable over the other method that takes a configuration section. Only this version will populate
3737
/// IConfiguration parameters on target methods.
3838
/// </summary>
3939
/// <param name="settingConfiguration">Logger setting configuration.</param>
4040
/// <param name="configuration">A configuration object which contains a Serilog section.</param>
41+
/// <param name="sectionName">A section name for section which contains a Serilog section.</param>
4142
/// <param name="dependencyContext">The dependency context from which sink/enricher packages can be located. If not supplied, the platform
4243
/// default will be used.</param>
4344
/// <returns>An object allowing configuration to continue.</returns>
4445
public static LoggerConfiguration Configuration(
4546
this LoggerSettingsConfiguration settingConfiguration,
4647
IConfiguration configuration,
48+
string sectionName,
4749
DependencyContext dependencyContext = null)
4850
{
51+
if (settingConfiguration == null) throw new ArgumentNullException(nameof(settingConfiguration));
4952
if (configuration == null) throw new ArgumentNullException(nameof(configuration));
53+
if (sectionName == null) throw new ArgumentNullException(nameof(sectionName));
54+
55+
var assemblyFinder = dependencyContext == null
56+
? AssemblyFinder.Auto()
57+
: AssemblyFinder.ForDependencyContext(dependencyContext);
5058

5159
return settingConfiguration.Settings(
5260
new ConfigurationReader(
53-
configuration,
54-
dependencyContext ?? (Assembly.GetEntryAssembly() != null ? DependencyContext.Default : null)));
61+
configuration.GetSection(sectionName),
62+
assemblyFinder,
63+
configuration));
5564
}
5665

66+
/// <summary>
67+
/// Reads logger settings from the provided configuration object using the default section name. Generally this
68+
/// is preferable over the other method that takes a configuration section. Only this version will populate
69+
/// IConfiguration parameters on target methods.
70+
/// </summary>
71+
/// <param name="settingConfiguration">Logger setting configuration.</param>
72+
/// <param name="configuration">A configuration object which contains a Serilog section.</param>
73+
/// <param name="dependencyContext">The dependency context from which sink/enricher packages can be located. If not supplied, the platform
74+
/// default will be used.</param>
75+
/// <returns>An object allowing configuration to continue.</returns>
76+
public static LoggerConfiguration Configuration(
77+
this LoggerSettingsConfiguration settingConfiguration,
78+
IConfiguration configuration,
79+
DependencyContext dependencyContext = null)
80+
=> Configuration(settingConfiguration, configuration, DefaultSectionName, dependencyContext);
81+
5782
/// <summary>
5883
/// Reads logger settings from the provided configuration section. Generally it is preferable to use the other
5984
/// extension method that takes the full configuration object.
@@ -63,6 +88,7 @@ public static LoggerConfiguration Configuration(
6388
/// <param name="dependencyContext">The dependency context from which sink/enricher packages can be located. If not supplied, the platform
6489
/// default will be used.</param>
6590
/// <returns>An object allowing configuration to continue.</returns>
91+
[Obsolete("Use ReadFrom.Configuration(IConfiguration configuration, string sectionName, DependencyContext dependencyContext) instead.")]
6692
public static LoggerConfiguration ConfigurationSection(
6793
this LoggerSettingsConfiguration settingConfiguration,
6894
IConfigurationSection configSection,
@@ -71,38 +97,57 @@ public static LoggerConfiguration ConfigurationSection(
7197
if (settingConfiguration == null) throw new ArgumentNullException(nameof(settingConfiguration));
7298
if (configSection == null) throw new ArgumentNullException(nameof(configSection));
7399

100+
var assemblyFinder = dependencyContext == null
101+
? AssemblyFinder.Auto()
102+
: AssemblyFinder.ForDependencyContext(dependencyContext);
103+
74104
return settingConfiguration.Settings(
75105
new ConfigurationReader(
76106
configSection,
77-
dependencyContext ?? (Assembly.GetEntryAssembly() != null ? DependencyContext.Default : null)));
107+
assemblyFinder,
108+
configuration: null));
78109
}
79110

80111
/// <summary>
81-
/// Reads logger settings from the provided configuration object using the default section name. Generally this
112+
/// Reads logger settings from the provided configuration object using the provided section name. Generally this
82113
/// is preferable over the other method that takes a configuration section. Only this version will populate
83114
/// IConfiguration parameters on target methods.
84115
/// </summary>
85116
/// <param name="settingConfiguration">Logger setting configuration.</param>
86117
/// <param name="configuration">A configuration object which contains a Serilog section.</param>
118+
/// <param name="sectionName">A section name for section which contains a Serilog section.</param>
87119
/// <param name="configurationAssemblySource">Defines how the package identifies assemblies to scan for sinks and other Types.</param>
88120
/// <returns>An object allowing configuration to continue.</returns>
89121
public static LoggerConfiguration Configuration(
90122
this LoggerSettingsConfiguration settingConfiguration,
91123
IConfiguration configuration,
124+
string sectionName,
92125
ConfigurationAssemblySource configurationAssemblySource)
93126
{
127+
if (settingConfiguration == null) throw new ArgumentNullException(nameof(settingConfiguration));
94128
if (configuration == null) throw new ArgumentNullException(nameof(configuration));
129+
if (sectionName == null) throw new ArgumentNullException(nameof(sectionName));
130+
131+
var assemblyFinder = AssemblyFinder.ForSource(configurationAssemblySource);
95132

96-
if(configurationAssemblySource == ConfigurationAssemblySource.UseLoadedAssemblies)
97-
{
98-
return Configuration(settingConfiguration, configuration);
99-
}
100-
else
101-
{
102-
return settingConfiguration.Settings(new ConfigurationReader(configuration, null));
103-
}
133+
return settingConfiguration.Settings(new ConfigurationReader(configuration.GetSection(sectionName), assemblyFinder, configuration));
104134
}
105135

136+
/// <summary>
137+
/// Reads logger settings from the provided configuration object using the default section name. Generally this
138+
/// is preferable over the other method that takes a configuration section. Only this version will populate
139+
/// IConfiguration parameters on target methods.
140+
/// </summary>
141+
/// <param name="settingConfiguration">Logger setting configuration.</param>
142+
/// <param name="configuration">A configuration object which contains a Serilog section.</param>
143+
/// <param name="configurationAssemblySource">Defines how the package identifies assemblies to scan for sinks and other Types.</param>
144+
/// <returns>An object allowing configuration to continue.</returns>
145+
public static LoggerConfiguration Configuration(
146+
this LoggerSettingsConfiguration settingConfiguration,
147+
IConfiguration configuration,
148+
ConfigurationAssemblySource configurationAssemblySource)
149+
=> Configuration(settingConfiguration, configuration, DefaultSectionName, configurationAssemblySource);
150+
106151
/// <summary>
107152
/// Reads logger settings from the provided configuration section. Generally it is preferable to use the other
108153
/// extension method that takes the full configuration object.
@@ -111,6 +156,7 @@ public static LoggerConfiguration Configuration(
111156
/// <param name="configSection">The Serilog configuration section</param>
112157
/// <param name="configurationAssemblySource">Defines how the package identifies assemblies to scan for sinks and other Types.</param>
113158
/// <returns>An object allowing configuration to continue.</returns>
159+
[Obsolete("Use ReadFrom.Configuration(IConfiguration configuration, string sectionName, ConfigurationAssemblySource configurationAssemblySource) instead.")]
114160
public static LoggerConfiguration ConfigurationSection(
115161
this LoggerSettingsConfiguration settingConfiguration,
116162
IConfigurationSection configSection,
@@ -119,14 +165,9 @@ public static LoggerConfiguration ConfigurationSection(
119165
if (settingConfiguration == null) throw new ArgumentNullException(nameof(settingConfiguration));
120166
if (configSection == null) throw new ArgumentNullException(nameof(configSection));
121167

122-
if (configurationAssemblySource == ConfigurationAssemblySource.UseLoadedAssemblies)
123-
{
124-
return Configuration(settingConfiguration, configSection);
125-
}
126-
else
127-
{
128-
return settingConfiguration.Settings(new ConfigurationReader(configSection, null));
129-
}
168+
var assemblyFinder = AssemblyFinder.ForSource(configurationAssemblySource);
169+
170+
return settingConfiguration.Settings(new ConfigurationReader(configSection, assemblyFinder, configuration: null));
130171
}
131172
}
132173
}

Diff for: src/Serilog.Settings.Configuration/Serilog.Settings.Configuration.csproj

+6-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
<PropertyGroup>
44
<Description>Microsoft.Extensions.Configuration (appsettings.json) support for Serilog.</Description>
5-
<VersionPrefix>3.0.1</VersionPrefix>
5+
<VersionPrefix>3.1.0</VersionPrefix>
66
<Authors>Serilog Contributors</Authors>
77
<TargetFrameworks>netstandard2.0;net451;net461</TargetFrameworks>
88
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
@@ -15,12 +15,16 @@
1515
<PackageTags>serilog;json</PackageTags>
1616
<PackageIconUrl>https://serilog.net/images/serilog-configuration-nuget.png</PackageIconUrl>
1717
<PackageProjectUrl>https://github.com/serilog/serilog-settings-configuration</PackageProjectUrl>
18-
<PackageLicenseUrl>https://www.apache.org/licenses/LICENSE-2.0</PackageLicenseUrl>
18+
<PackageLicenseExpression>Apache-2.0</PackageLicenseExpression>
1919
<RepositoryUrl>https://github.com/serilog/serilog-settings-configuration</RepositoryUrl>
2020
<RepositoryType>git</RepositoryType>
2121
<RootNamespace>Serilog</RootNamespace>
2222
</PropertyGroup>
2323

24+
<PropertyGroup Condition="('$(TargetFramework)' == 'net451') Or ('$(TargetFramework)' == 'net461')">
25+
<DefineConstants>$(DefineConstants);PRIVATE_BIN</DefineConstants>
26+
</PropertyGroup>
27+
2428
<ItemGroup>
2529
<PackageReference Include="Microsoft.Extensions.DependencyModel" Version="2.0.4" />
2630
<PackageReference Include="Serilog" Version="2.6.0" />
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Reflection;
4+
using Microsoft.Extensions.DependencyModel;
5+
6+
namespace Serilog.Settings.Configuration.Assemblies
7+
{
8+
abstract class AssemblyFinder
9+
{
10+
public abstract IReadOnlyList<AssemblyName> FindAssembliesContainingName(string nameToFind);
11+
12+
protected static bool IsCaseInsensitiveMatch(string text, string textToFind)
13+
{
14+
return text != null && text.ToLowerInvariant().Contains(textToFind.ToLowerInvariant());
15+
}
16+
17+
public static AssemblyFinder Auto()
18+
{
19+
// Need to check `Assembly.GetEntryAssembly()` first because
20+
// `DependencyContext.Default` throws an exception when `Assembly.GetEntryAssembly()` returns null
21+
if (Assembly.GetEntryAssembly() != null && DependencyContext.Default != null)
22+
{
23+
return new DependencyContextAssemblyFinder(DependencyContext.Default);
24+
}
25+
return new DllScanningAssemblyFinder();
26+
}
27+
28+
public static AssemblyFinder ForSource(ConfigurationAssemblySource configurationAssemblySource)
29+
{
30+
switch (configurationAssemblySource)
31+
{
32+
case ConfigurationAssemblySource.UseLoadedAssemblies:
33+
return Auto();
34+
case ConfigurationAssemblySource.AlwaysScanDllFiles:
35+
return new DllScanningAssemblyFinder();
36+
default:
37+
throw new ArgumentOutOfRangeException(nameof(configurationAssemblySource), configurationAssemblySource, null);
38+
}
39+
}
40+
41+
public static AssemblyFinder ForDependencyContext(DependencyContext dependencyContext)
42+
{
43+
return new DependencyContextAssemblyFinder(dependencyContext);
44+
}
45+
}
46+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Reflection;
5+
using Microsoft.Extensions.DependencyModel;
6+
7+
namespace Serilog.Settings.Configuration.Assemblies
8+
{
9+
sealed class DependencyContextAssemblyFinder : AssemblyFinder
10+
{
11+
readonly DependencyContext _dependencyContext;
12+
13+
public DependencyContextAssemblyFinder(DependencyContext dependencyContext)
14+
{
15+
_dependencyContext = dependencyContext ?? throw new ArgumentNullException(nameof(dependencyContext));
16+
}
17+
18+
public override IReadOnlyList<AssemblyName> FindAssembliesContainingName(string nameToFind)
19+
{
20+
var query = from library in _dependencyContext.RuntimeLibraries
21+
from assemblyName in library.GetDefaultAssemblyNames(_dependencyContext)
22+
where IsCaseInsensitiveMatch(assemblyName.Name, nameToFind)
23+
select assemblyName;
24+
25+
return query.ToList().AsReadOnly();
26+
}
27+
}
28+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.IO;
4+
using System.Linq;
5+
using System.Reflection;
6+
7+
namespace Serilog.Settings.Configuration.Assemblies
8+
{
9+
sealed class DllScanningAssemblyFinder : AssemblyFinder
10+
{
11+
public override IReadOnlyList<AssemblyName> FindAssembliesContainingName(string nameToFind)
12+
{
13+
var probeDirs = new List<string>();
14+
15+
if (!string.IsNullOrEmpty(AppDomain.CurrentDomain.BaseDirectory))
16+
{
17+
probeDirs.Add(AppDomain.CurrentDomain.BaseDirectory);
18+
19+
#if PRIVATE_BIN
20+
var privateBinPath = AppDomain.CurrentDomain.SetupInformation.PrivateBinPath;
21+
if (!string.IsNullOrEmpty(privateBinPath))
22+
{
23+
foreach (var path in privateBinPath.Split(';'))
24+
{
25+
if (Path.IsPathRooted(path))
26+
{
27+
probeDirs.Add(path);
28+
}
29+
else
30+
{
31+
probeDirs.Add(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, path));
32+
}
33+
}
34+
}
35+
#endif
36+
}
37+
else
38+
{
39+
probeDirs.Add(Path.GetDirectoryName(typeof(AssemblyFinder).Assembly.Location));
40+
}
41+
42+
var query = from probeDir in probeDirs
43+
where Directory.Exists(probeDir)
44+
from outputAssemblyPath in Directory.GetFiles(probeDir, "*.dll")
45+
let assemblyFileName = Path.GetFileNameWithoutExtension(outputAssemblyPath)
46+
where IsCaseInsensitiveMatch(assemblyFileName, nameToFind)
47+
let assemblyName = TryGetAssemblyNameFrom(outputAssemblyPath)
48+
where assemblyName != null
49+
select assemblyName;
50+
51+
return query.ToList().AsReadOnly();
52+
53+
AssemblyName TryGetAssemblyNameFrom(string path)
54+
{
55+
try
56+
{
57+
return AssemblyName.GetAssemblyName(path);
58+
}
59+
catch (BadImageFormatException)
60+
{
61+
return null;
62+
}
63+
}
64+
}
65+
}
66+
}

0 commit comments

Comments
 (0)