Skip to content

Commit e878335

Browse files
authored
Merge pull request #343 from serilog/dev
7.0.0 Release
2 parents 20333a2 + d7e0dbd commit e878335

File tree

79 files changed

+5015
-3620
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

79 files changed

+5015
-3620
lines changed

Diff for: .editorconfig

+2
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,5 @@ end_of_line = lf
1515

1616
[*.{cmd, bat}]
1717
end_of_line = crlf
18+
19+
csharp_style_namespace_declarations = file_scoped:suggestion

Diff for: .gitignore

+1-4
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ publish/
132132
# Publish Web Output
133133
*.[Pp]ublish.xml
134134
*.azurePubxml
135-
# TODO: Comment the next line if you want to checkin your web deploy settings
135+
# TODO: Comment the next line if you want to checkin your web deploy settings
136136
# but database connection strings (with potential passwords) will be unencrypted
137137
*.pubxml
138138
*.publishproj
@@ -200,7 +200,4 @@ FakesAssemblies/
200200

201201
project.lock.json
202202

203-
#Test files
204-
*.txt
205-
206203
artifacts/

Diff for: Build.ps1

+18-40
Original file line numberDiff line numberDiff line change
@@ -1,60 +1,38 @@
1-
echo "build: Build started"
1+
Write-Output "build: Build started"
22

33
Push-Location $PSScriptRoot
44

55
if(Test-Path .\artifacts) {
6-
echo "build: Cleaning .\artifacts"
7-
Remove-Item .\artifacts -Force -Recurse
6+
Write-Output "build: Cleaning .\artifacts"
7+
Remove-Item .\artifacts -Force -Recurse
88
}
99

10-
& dotnet restore --no-cache
11-
1210
$branch = @{ $true = $env:APPVEYOR_REPO_BRANCH; $false = $(git symbolic-ref --short -q HEAD) }[$env:APPVEYOR_REPO_BRANCH -ne $NULL];
1311
$revision = @{ $true = "{0:00000}" -f [convert]::ToInt32("0" + $env:APPVEYOR_BUILD_NUMBER, 10); $false = "local" }[$env:APPVEYOR_BUILD_NUMBER -ne $NULL];
1412
$suffix = @{ $true = ""; $false = "$($branch.Substring(0, [math]::Min(10,$branch.Length)))-$revision"}[$branch -eq "main" -and $revision -ne "local"]
1513
$commitHash = $(git rev-parse --short HEAD)
1614
$buildSuffix = @{ $true = "$($suffix)-$($commitHash)"; $false = "$($branch)-$($commitHash)" }[$suffix -ne ""]
1715

18-
echo "build: Package version suffix is $suffix"
19-
echo "build: Build version suffix is $buildSuffix"
20-
21-
foreach ($src in gci src/*) {
22-
Push-Location $src
23-
24-
echo "build: Packaging project in $src"
25-
26-
& dotnet build -c Release --version-suffix=$buildSuffix
27-
28-
if($suffix) {
29-
& dotnet pack -c Release --include-source --no-build -o ../../artifacts --version-suffix=$suffix -p:ContinuousIntegrationBuild=true
30-
} else {
31-
& dotnet pack -c Release --include-source --no-build -o ../../artifacts -p:ContinuousIntegrationBuild=true
32-
}
33-
if($LASTEXITCODE -ne 0) { exit 1 }
16+
Write-Output "build: Package version suffix is $suffix"
17+
Write-Output "build: Build version suffix is $buildSuffix"
3418

35-
Pop-Location
36-
}
37-
38-
foreach ($test in gci test/*.Tests) {
39-
Push-Location $test
40-
41-
echo "build: Testing project in $test"
19+
& dotnet build --configuration Release --version-suffix=$buildSuffix /p:ContinuousIntegrationBuild=true
4220

43-
& dotnet test -c Release
44-
if($LASTEXITCODE -ne 0) { exit 3 }
21+
if($LASTEXITCODE -ne 0) { throw 'build failed' }
4522

46-
Pop-Location
23+
if($suffix) {
24+
& dotnet pack src\Serilog.Settings.Configuration --configuration Release --no-build --no-restore -o artifacts --version-suffix=$suffix
25+
} else {
26+
& dotnet pack src\Serilog.Settings.Configuration --configuration Release --no-build --no-restore -o artifacts
4727
}
4828

49-
foreach ($test in gci test/*.PerformanceTests) {
50-
Push-Location $test
29+
if($LASTEXITCODE -ne 0) { throw 'pack failed' }
5130

52-
echo "build: Building performance test project in $test"
31+
Write-Output "build: Testing"
5332

54-
& dotnet build -c Release
55-
if($LASTEXITCODE -ne 0) { exit 2 }
56-
57-
Pop-Location
58-
}
33+
# Dotnet test doesn't run separate TargetFrameworks in parallel: https://github.com/dotnet/sdk/issues/19147
34+
# Workaround: use `dotnet test` on dlls directly in order to pass the `--parallel` option to vstest.
35+
# The _reported_ runtime is wrong but the _actual_ used runtime is correct, see https://github.com/microsoft/vstest/issues/2037#issuecomment-720549173
36+
& dotnet test test\Serilog.Settings.Configuration.Tests\bin\Release\*\Serilog.Settings.Configuration.Tests.dll --parallel
5937

60-
Pop-Location
38+
if($LASTEXITCODE -ne 0) { throw 'unit tests failed' }

Diff for: Directory.Build.props

+5-5
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22
<PropertyGroup>
33
<LangVersion>latest</LangVersion>
44
<TreatWarningsAsErrors>True</TreatWarningsAsErrors>
5-
<TreatSpecificWarningsAsErrors />
5+
<SignAssembly>true</SignAssembly>
6+
<AssemblyOriginatorKeyFile>$(MSBuildThisFileDirectory)assets/Serilog.snk</AssemblyOriginatorKeyFile>
7+
<ImplicitUsings>enable</ImplicitUsings>
8+
<CheckEolTargetFramework>false</CheckEolTargetFramework>
9+
<Nullable>enable</Nullable>
610
</PropertyGroup>
7-
8-
<ItemGroup Condition="'$(TargetFrameworkIdentifier)' == '.NETFramework'">
9-
<PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.2" PrivateAssets="all" />
10-
</ItemGroup>
1111
</Project>

Diff for: README.md

+60-17
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ For a more sophisticated example go to the [sample](sample/Sample) folder.
5656

5757
Root section name can be changed:
5858

59-
```json
59+
```yaml
6060
{
6161
"CustomSection": {
6262
...
@@ -65,16 +65,17 @@ Root section name can be changed:
6565
```
6666

6767
```csharp
68+
var options = new ConfigurationReaderOptions { SectionName = "CustomSection" };
6869
var logger = new LoggerConfiguration()
69-
.ReadFrom.Configuration(configuration, sectionName: "CustomSection")
70+
.ReadFrom.Configuration(configuration, options)
7071
.CreateLogger();
7172
```
7273

7374
### Using section and auto-discovery of configuration assemblies
7475

7576
`Using` section contains list of **assemblies** in which configuration methods (`WriteTo.File()`, `Enrich.WithThreadId()`) reside.
7677

77-
```json
78+
```yaml
7879
"Serilog": {
7980
"Using": [ "Serilog.Sinks.Console", "Serilog.Enrichers.Thread", /* ... */ ],
8081
// ...
@@ -83,7 +84,7 @@ var logger = new LoggerConfiguration()
8384

8485
For .NET Core projects build tools produce `.deps.json` files and this package implements a convention using `Microsoft.Extensions.DependencyModel` to find any package among dependencies with `Serilog` anywhere in the name and pulls configuration methods from it, so the `Using` section in example above can be omitted:
8586

86-
```json
87+
```yaml
8788
{
8889
"Serilog": {
8990
"MinimumLevel": "Debug",
@@ -106,8 +107,9 @@ In case of [non-standard](#azure-functions-v2-v3) dependency management you can
106107
```csharp
107108
var functionDependencyContext = DependencyContext.Load(typeof(Startup).Assembly);
108109

110+
var options = new ConfigurationReaderOptions(functionDependencyContext) { SectionName = "AzureFunctionsJobHost:Serilog" };
109111
var logger = new LoggerConfiguration()
110-
.ReadFrom.Configuration(hostConfig, sectionName: "AzureFunctionsJobHost:Serilog", dependencyContext: functionDependencyContext)
112+
.ReadFrom.Configuration(hostConfig, options)
111113
.CreateLogger();
112114
```
113115

@@ -119,8 +121,9 @@ var configurationAssemblies = new[]
119121
typeof(ConsoleLoggerConfigurationExtensions).Assembly,
120122
typeof(FileLoggerConfigurationExtensions).Assembly,
121123
};
124+
var options = new ConfigurationReaderOptions(configurationAssemblies);
122125
var logger = new LoggerConfiguration()
123-
.ReadFrom.Configuration(configuration, configurationAssemblies)
126+
.ReadFrom.Configuration(configuration, options)
124127
.CreateLogger();
125128
```
126129

@@ -183,6 +186,22 @@ You can also declare `LoggingLevelSwitch`-es in custom section and reference the
183186

184187
Level updates to switches are also respected for a dynamic update.
185188

189+
Since version 7.0.0, both declared switches (i.e. `Serilog:LevelSwitches` section) and minimum level override switches (i.e. `Serilog:MinimumLevel:Override` section) are exposed through a callback on the reader options so that a reference can be kept:
190+
191+
```csharp
192+
var allSwitches = new Dictionary<string, LoggingLevelSwitch>();
193+
var options = new ConfigurationReaderOptions
194+
{
195+
OnLevelSwitchCreated = (switchName, levelSwitch) => allSwitches[switchName] = levelSwitch
196+
};
197+
198+
var logger = new LoggerConfiguration()
199+
.ReadFrom.Configuration(configuration, options)
200+
.CreateLogger();
201+
202+
LoggingLevelSwitch controlSwitch = allSwitches["$controlSwitch"];
203+
```
204+
186205
### WriteTo, Enrich, AuditTo, Destructure sections
187206

188207
These sections support simplified syntax, for example the following is valid if no arguments are needed by the sinks:
@@ -195,7 +214,7 @@ Or alternatively, the long-form (`"Name":` ...) syntax from the example above ca
195214

196215
By `Microsoft.Extensions.Configuration.Json` convention, array syntax implicitly defines index for each element in order to make unique paths for configuration keys. So the example above is equivalent to:
197216

198-
```json
217+
```yaml
199218
"WriteTo": {
200219
"0": "Console",
201220
"1": "DiagnosticTrace"
@@ -204,7 +223,7 @@ By `Microsoft.Extensions.Configuration.Json` convention, array syntax implicitly
204223

205224
And
206225

207-
```json
226+
```yaml
208227
"WriteTo:0": "Console",
209228
"WriteTo:1": "DiagnosticTrace"
210229
```
@@ -213,7 +232,7 @@ And
213232

214233
When overriding settings with [environment variables](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration/?view=aspnetcore-3.1#environment-variables) it becomes less convenient and fragile, so you can specify custom names:
215234

216-
```json
235+
```yaml
217236
"WriteTo": {
218237
"ConsoleSink": "Console",
219238
"DiagnosticTraceSink": { "Name": "DiagnosticTrace" }
@@ -226,9 +245,9 @@ This section defines a static list of key-value pairs that will enrich log event
226245

227246
### Filter section
228247

229-
This section defines filters that will be applied to log events. It is especially usefull in combination with _[Serilog.Expressions](https://github.com/serilog/serilog-expressions)_ (or legacy _[Serilog.Filters.Expressions](https://github.com/serilog/serilog-filters-expressions)_) package so you can write expression in text form:
248+
This section defines filters that will be applied to log events. It is especially useful in combination with _[Serilog.Expressions](https://github.com/serilog/serilog-expressions)_ (or legacy _[Serilog.Filters.Expressions](https://github.com/serilog/serilog-filters-expressions)_) package so you can write expression in text form:
230249

231-
```json
250+
```yaml
232251
"Filter": [{
233252
"Name": "ByIncludingOnly",
234253
"Args": {
@@ -239,7 +258,7 @@ This section defines filters that will be applied to log events. It is especiall
239258

240259
Using this package you can also declare `LoggingFilterSwitch`-es in custom section and reference them for filter parameters:
241260

242-
```json
261+
```yaml
243262
{
244263
"Serilog": {
245264
"FilterSwitches": { "filterSwitch": "Application = 'Sample'" },
@@ -256,11 +275,27 @@ Using this package you can also declare `LoggingFilterSwitch`-es in custom secti
256275

257276
Level updates to switches are also respected for a dynamic update.
258277

278+
Since version 7.0.0, filter switches are exposed through a callback on the reader options so that a reference can be kept:
279+
280+
```csharp
281+
var filterSwitches = new Dictionary<string, ILoggingFilterSwitch>();
282+
var options = new ConfigurationReaderOptions
283+
{
284+
OnFilterSwitchCreated = (switchName, filterSwitch) => filterSwitches[switchName] = filterSwitch
285+
};
286+
287+
var logger = new LoggerConfiguration()
288+
.ReadFrom.Configuration(configuration, options)
289+
.CreateLogger();
290+
291+
ILoggingFilterSwitch filterSwitch = filterSwitches["filterSwitch"];
292+
```
293+
259294
### Nested configuration sections
260295

261296
Some Serilog packages require a reference to a logger configuration object. The sample program in this project illustrates this with the following entry configuring the _[Serilog.Sinks.Async](https://github.com/serilog/serilog-sinks-async)_ package to wrap the _[Serilog.Sinks.File](https://github.com/serilog/serilog-sinks-file)_ package. The `configure` parameter references the File sink configuration:
262297

263-
```json
298+
```yaml
264299
"WriteTo:Async": {
265300
"Name": "Async",
266301
"Args": {
@@ -282,11 +317,13 @@ Some Serilog packages require a reference to a logger configuration object. The
282317

283318
When the configuration specifies a discrete value for a parameter (such as a string literal), the package will attempt to convert that value to the target method's declared CLR type of the parameter. Additional explicit handling is provided for parsing strings to `Uri`, `TimeSpan`, `enum`, arrays and custom collections.
284319

320+
Since version 7.0.0, conversion will use the invariant culture (`CultureInfo.InvariantCulture`) as long as the `ReadFrom.Configuration(IConfiguration configuration, ConfigurationReaderOptions options)` method is used. Obsolete methods use the current culture to preserve backward compatibility.
321+
285322
### Static member support
286323

287324
Static member access can be used for passing to the configuration argument via [special](https://github.com/serilog/serilog-settings-configuration/blob/dev/test/Serilog.Settings.Configuration.Tests/StringArgumentValueTests.cs#L35) syntax:
288325

289-
```json
326+
```yaml
290327
{
291328
"Args": {
292329
"encoding": "System.Text.Encoding::UTF8",
@@ -299,14 +336,15 @@ Static member access can be used for passing to the configuration argument via [
299336

300337
If the parameter value is not a discrete value, it will try to find a best matching public constructor for the argument:
301338

302-
```json
339+
```yaml
303340
{
304341
"Name": "Console",
305342
"Args": {
306343
"formatter": {
307344
// `type` (or $type) is optional, must be specified for abstract declared parameter types
308345
"type": "Serilog.Templates.ExpressionTemplate, Serilog.Expressions",
309346
"template": "[{@t:HH:mm:ss} {@l:u3} {Coalesce(SourceContext, '<none>')}] {@m}\n{@x}"
347+
}
310348
}
311349
}
312350
```
@@ -317,7 +355,7 @@ For other cases the package will use the configuration binding system provided b
317355

318356
If parameter type is an interface or an abstract class you need to specify the full type name that implements abstract type. The implementation type should have parameterless constructor.
319357

320-
```json
358+
```yaml
321359
"Destructure": [
322360
{ "Name": "With", "Args": { "policy": "Sample.CustomPolicy, Sample" } },
323361
...
@@ -377,8 +415,9 @@ public class Startup : FunctionsStartup
377415
var functionDependencyContext = DependencyContext.Load(typeof(Startup).Assembly);
378416

379417
var hostConfig = sp.GetRequiredService<IConfiguration>();
418+
var options = new ConfigurationReaderOptions(functionDependencyContext) { SectionName = "AzureFunctionsJobHost:Serilog" };
380419
var logger = new LoggerConfiguration()
381-
.ReadFrom.Configuration(hostConfig, sectionName: "AzureFunctionsJobHost:Serilog", dependencyContext: functionDependencyContext)
420+
.ReadFrom.Configuration(hostConfig, options)
382421
.CreateLogger();
383422

384423
return new SerilogLoggerProvider(logger, dispose: true);
@@ -405,3 +444,7 @@ In order to make auto-discovery of configuration assemblies work, modify Functio
405444

406445
</Project>
407446
```
447+
448+
### Versioning
449+
450+
This package tracks the versioning and target framework support of its [_Microsoft.Extensions.Configuration_](https://nuget.org/packages/Microsoft.Extensions.Configuration) dependency.

Diff for: appveyor.yml

+19-1
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,27 @@ skip_tags: true
55
image:
66
- Visual Studio 2022
77
- Ubuntu
8+
- macOS
89

910
build_script:
10-
- pwsh: ./Build.ps1
11+
- pwsh: |
12+
if ($isWindows) {
13+
Invoke-WebRequest "https://dot.net/v1/dotnet-install.ps1" -OutFile "./dotnet-install.ps1"
14+
./dotnet-install.ps1 -JSonFile global.json -Architecture x64 -InstallDir 'C:\Program Files\dotnet'
15+
./Build.ps1
16+
}
17+
if ($isLinux) {
18+
Invoke-WebRequest "https://dot.net/v1/dotnet-install.sh" -OutFile "./dotnet-install.sh"
19+
sudo chmod u+x dotnet-install.sh
20+
sudo ./dotnet-install.sh --jsonfile global.json --architecture x64 --install-dir '/usr/share/dotnet'
21+
./Build.ps1
22+
}
23+
if ($isMacOS) {
24+
Invoke-WebRequest "https://dot.net/v1/dotnet-install.sh" -OutFile "./dotnet-install.sh"
25+
sudo chmod u+x dotnet-install.sh
26+
sudo ./dotnet-install.sh --jsonfile global.json --architecture x64 --install-dir '/usr/local/share/dotnet'
27+
./Build.ps1
28+
}
1129
1230
test: off
1331

Diff for: global.json

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"sdk": {
3+
"version": "7.0.201",
4+
"allowPrerelease": false,
5+
"rollForward": "latestFeature"
6+
}
7+
}

Diff for: sample/Sample/CustomFilter.cs

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
using Serilog.Core;
2+
using Serilog.Events;
3+
4+
namespace Sample;
5+
6+
// The filter syntax in the sample configuration file is
7+
// processed by the Serilog.Filters.Expressions package.
8+
public class CustomFilter : ILogEventFilter
9+
{
10+
readonly LogEventLevel _levelFilter;
11+
12+
public CustomFilter(LogEventLevel levelFilter = LogEventLevel.Information)
13+
{
14+
_levelFilter = levelFilter;
15+
}
16+
17+
public bool IsEnabled(LogEvent logEvent)
18+
{
19+
return logEvent.Level >= _levelFilter;
20+
}
21+
}

0 commit comments

Comments
 (0)