Skip to content

Commit d76a80f

Browse files
committed
v7.0 - pin to MEL v7, including matching target frameworks; update to Serilog v2.12 and apply annotations for nullable reference types
1 parent 9765013 commit d76a80f

18 files changed

+170
-173
lines changed

Directory.Build.props

+1-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
<AssemblyOriginatorKeyFile>$(MSBuildThisFileDirectory)assets/Serilog.snk</AssemblyOriginatorKeyFile>
88
<PublicSign Condition=" '$(OS)' != 'Windows_NT' ">true</PublicSign>
99
<Nullable>enable</Nullable>
10-
<ImplicitUsings>enable</ImplicitUsings>
1110
</PropertyGroup>
1211

13-
</Project>
12+
</Project>

README.md

+8-8
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Serilog.Extensions.Logging [![Build status](https://ci.appveyor.com/api/projects/status/865nohxfiq1rnby0/branch/master?svg=true)](https://ci.appveyor.com/project/serilog/serilog-framework-logging/history) [![NuGet Version](http://img.shields.io/nuget/v/Serilog.Extensions.Logging.svg?style=flat)](https://www.nuget.org/packages/Serilog.Extensions.Logging/)
1+
# Serilog.Extensions.Logging [![Build status](https://ci.appveyor.com/api/projects/status/865nohxfiq1rnby0/branch/master?svg=true)](https://ci.appveyor.com/project/serilog/serilog-framework-logging/history) [![NuGet Version](http://img.shields.io/nuget/v/Serilog.Extensions.Logging.svg?style=flat)](https://www.nuget.org/packages/Serilog.Extensions.Logging/)
22

33
A Serilog provider for [Microsoft.Extensions.Logging](https://www.nuget.org/packages/Microsoft.Extensions.Logging), the logging subsystem used by ASP.NET Core.
44

@@ -16,9 +16,9 @@ The package implements `AddSerilog()` on `ILoggingBuilder` and `ILoggerFactory`
1616

1717
**First**, install the _Serilog.Extensions.Logging_ [NuGet package](https://www.nuget.org/packages/Serilog.Extensions.Logging) into your web or console app. You will need a way to view the log messages - _Serilog.Sinks.Console_ writes these to the console.
1818

19-
```powershell
20-
Install-Package Serilog.Extensions.Logging -DependencyVersion Highest
21-
Install-Package Serilog.Sinks.Console
19+
```sh
20+
dotnet add package Serilog.Extensions.Logging
21+
dotnet add package Serilog.Sinks.Console
2222
```
2323

2424
**Next**, in your application's `Startup` method, configure Serilog first:
@@ -34,7 +34,7 @@ public class Startup
3434
.Enrich.FromLogContext()
3535
.WriteTo.Console()
3636
.CreateLogger();
37-
37+
3838
// Other startup code
3939
```
4040

@@ -46,7 +46,7 @@ call `AddSerilog()` on the provided `loggingBuilder`.
4646
{
4747
services.AddLogging(loggingBuilder =>
4848
loggingBuilder.AddSerilog(dispose: true));
49-
49+
5050
// Other services ...
5151
}
5252
```
@@ -60,7 +60,7 @@ call `AddSerilog()` on the provided `loggingBuilder`.
6060
IApplicationLifetime appLifetime)
6161
{
6262
loggerfactory.AddSerilog();
63-
63+
6464
// Ensure any buffered events are sent at shutdown
6565
appLifetime.ApplicationStopped.Register(Log.CloseAndFlush);
6666
```
@@ -69,7 +69,7 @@ That's it! With the level bumped up a little you should see log output like:
6969

7070
```
7171
[22:14:44.646 DBG] RouteCollection.RouteAsync
72-
Routes:
72+
Routes:
7373
Microsoft.AspNet.Mvc.Routing.AttributeRoute
7474
{controller=Home}/{action=Index}/{id?}
7575
Handled? True

appveyor.yml

+2-2
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,12 @@ deploy:
1414
secure: EN9f+XXE3fW+ebL4wxrIbafdtbNvRfddBN8UUixvctYh4qMBHzr1JdnM83QsM1zo
1515
skip_symbols: true
1616
on:
17-
branch: /^(master|dev)$/
17+
branch: /^(main|dev)$/
1818
- provider: GitHub
1919
auth_token:
2020
secure: p4LpVhBKxGS5WqucHxFQ5c7C8cP74kbNB0Z8k9Oxx/PMaDQ1+ibmoexNqVU5ZlmX
2121
artifact: /Serilog.*\.nupkg/
2222
tag: v$(appveyor_build_version)
2323
on:
24-
branch: master
24+
branch: main
2525

samples/Sample/Program.cs

+49-58
Original file line numberDiff line numberDiff line change
@@ -3,75 +3,66 @@
33
using Serilog;
44
using Serilog.Extensions.Logging;
55

6-
namespace Sample;
6+
// Creating a `LoggerProviderCollection` lets Serilog optionally write
7+
// events through other dynamically-added MEL ILoggerProviders.
8+
var providers = new LoggerProviderCollection();
79

8-
public class Program
9-
{
10-
public static void Main(string[] args)
11-
{
12-
// Creating a `LoggerProviderCollection` lets Serilog optionally write
13-
// events through other dynamically-added MEL ILoggerProviders.
14-
var providers = new LoggerProviderCollection();
15-
16-
Log.Logger = new LoggerConfiguration()
17-
.MinimumLevel.Debug()
18-
.WriteTo.Console()
19-
.WriteTo.Providers(providers)
20-
.CreateLogger();
10+
Log.Logger = new LoggerConfiguration()
11+
.MinimumLevel.Debug()
12+
.WriteTo.Console()
13+
.WriteTo.Providers(providers)
14+
.CreateLogger();
2115

22-
var services = new ServiceCollection();
16+
var services = new ServiceCollection();
2317

24-
services.AddSingleton(providers);
25-
services.AddSingleton<ILoggerFactory>(sc =>
26-
{
27-
var providerCollection = sc.GetService<LoggerProviderCollection>();
28-
var factory = new SerilogLoggerFactory(null, true, providerCollection);
18+
services.AddSingleton(providers);
19+
services.AddSingleton<ILoggerFactory>(sc =>
20+
{
21+
var providerCollection = sc.GetService<LoggerProviderCollection>();
22+
var factory = new SerilogLoggerFactory(null, true, providerCollection);
2923

30-
foreach (var provider in sc.GetServices<ILoggerProvider>())
31-
factory.AddProvider(provider);
24+
foreach (var provider in sc.GetServices<ILoggerProvider>())
25+
factory.AddProvider(provider);
3226

33-
return factory;
34-
});
27+
return factory;
28+
});
3529

36-
services.AddLogging(l => l.AddConsole());
30+
services.AddLogging(l => l.AddConsole());
3731

38-
var serviceProvider = services.BuildServiceProvider();
39-
var logger = serviceProvider.GetRequiredService<ILogger<Program>>();
32+
var serviceProvider = services.BuildServiceProvider();
33+
var logger = serviceProvider.GetRequiredService<ILogger<Program>>();
4034

41-
var startTime = DateTimeOffset.UtcNow;
42-
logger.LogInformation(1, "Started at {StartTime} and 0x{Hello:X} is hex of 42", startTime, 42);
35+
var startTime = DateTimeOffset.UtcNow;
36+
logger.LogInformation(1, "Started at {StartTime} and 0x{Hello:X} is hex of 42", startTime, 42);
4337

44-
try
45-
{
46-
throw new Exception("Boom!");
47-
}
48-
catch (Exception ex)
49-
{
50-
logger.LogCritical("Unexpected critical error starting application", ex);
51-
logger.Log(LogLevel.Critical, 0, "Unexpected critical error", ex, null!);
52-
// This write should not log anything
53-
logger.Log<object>(LogLevel.Critical, 0, null!, null, null!);
54-
logger.LogError("Unexpected error", ex);
55-
logger.LogWarning("Unexpected warning", ex);
56-
}
38+
try
39+
{
40+
throw new Exception("Boom!");
41+
}
42+
catch (Exception ex)
43+
{
44+
logger.LogCritical(ex, "Unexpected critical error starting application");
45+
logger.Log(LogLevel.Critical, 0, "Unexpected critical error", ex, null!);
46+
// This write should not log anything
47+
logger.Log<object>(LogLevel.Critical, 0, null!, null, null!);
48+
logger.LogError(ex, "Unexpected error");
49+
logger.LogWarning(ex, "Unexpected warning");
50+
}
5751

58-
using (logger.BeginScope("Main"))
59-
{
60-
logger.LogInformation("Waiting for user input");
61-
var key = Console.Read();
62-
logger.LogInformation("User pressed {@KeyInfo}", new { Key = key, KeyChar = (char)key });
63-
}
52+
using (logger.BeginScope("Main"))
53+
{
54+
logger.LogInformation("Waiting for user input");
55+
var key = Console.Read();
56+
logger.LogInformation("User pressed {@KeyInfo}", new { Key = key, KeyChar = (char)key });
57+
}
6458

65-
var endTime = DateTimeOffset.UtcNow;
66-
logger.LogInformation(2, "Stopping at {StopTime}", endTime);
59+
var endTime = DateTimeOffset.UtcNow;
60+
logger.LogInformation(2, "Stopping at {StopTime}", endTime);
6761

68-
logger.LogInformation("Stopping");
62+
logger.LogInformation("Stopping");
6963

70-
logger.LogInformation(Environment.NewLine);
71-
logger.LogInformation("{Result,-10:l}{StartTime,15:l}{EndTime,15:l}{Duration,15:l}", "RESULT", "START TIME", "END TIME", "DURATION(ms)");
72-
logger.LogInformation("{Result,-10:l}{StartTime,15:l}{EndTime,15:l}{Duration,15:l}", "------", "----- ----", "--- ----", "------------");
73-
logger.LogInformation("{Result,-10:l}{StartTime,15:mm:s tt}{EndTime,15:mm:s tt}{Duration,15}", "SUCCESS", startTime, endTime, (endTime - startTime).TotalMilliseconds);
64+
logger.LogInformation("{Result,-10:l}{StartTime,15:l}{EndTime,15:l}{Duration,15:l}", "RESULT", "START TIME", "END TIME", "DURATION(ms)");
65+
logger.LogInformation("{Result,-10:l}{StartTime,15:l}{EndTime,15:l}{Duration,15:l}", "------", "----- ----", "--- ----", "------------");
66+
logger.LogInformation("{Result,-10:l}{StartTime,15:mm:s tt}{EndTime,15:mm:s tt}{Duration,15}", "SUCCESS", startTime, endTime, (endTime - startTime).TotalMilliseconds);
7467

75-
serviceProvider.Dispose();
76-
}
77-
}
68+
serviceProvider.Dispose();

samples/Sample/Sample.csproj

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
4-
<TargetFramework>net7</TargetFramework>
4+
<TargetFramework>net7.0</TargetFramework>
55
<AssemblyName>Sample</AssemblyName>
66
<OutputType>Exe</OutputType>
7+
<ImplicitUsings>enable</ImplicitUsings>
78
</PropertyGroup>
89

910
<ItemGroup>
@@ -16,4 +17,4 @@
1617
<PackageReference Include="Serilog.Sinks.Console" Version="4.1.0" />
1718
</ItemGroup>
1819

19-
</Project>
20+
</Project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
2+
<s:Boolean x:Key="/Default/UserDictionary/Words/=stringified/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>

src/Serilog.Extensions.Logging/Extensions/Logging/CachingMessageTemplateParser.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ public MessageTemplate Parse(string messageTemplate)
3838

3939
// ReSharper disable once InconsistentlySynchronizedField
4040
// ignored warning because this is by design
41-
var result = (MessageTemplate)_templates[messageTemplate];
41+
var result = (MessageTemplate?)_templates[messageTemplate];
4242
if (result != null)
4343
return result;
4444

src/Serilog.Extensions.Logging/Extensions/Logging/LevelConvert.cs

+3-3
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,9 @@ public static class LevelConvert
2727
/// <summary>
2828
/// Convert <paramref name="logLevel"/> to the equivalent Serilog <see cref="LogEventLevel"/>.
2929
/// </summary>
30-
/// <param name="logLevel">A Microsoft.Extensions.Logging <see cref="LogLevel"/>.</param>
30+
/// <param name="logLevel">A Microsoft.Extensions.Logging <see cref="Microsoft.Extensions.Logging.LogLevel"/>.</param>
3131
/// <returns>The Serilog equivalent of <paramref name="logLevel"/>.</returns>
32-
/// <remarks>The <see cref="LogLevel.None"/> value has no Serilog equivalent. It is mapped to
32+
/// <remarks>The <see cref="Microsoft.Extensions.Logging.LogLevel.None"/> value has no Serilog equivalent. It is mapped to
3333
/// <see cref="LogEventLevel.Fatal"/> as the closest approximation, but this has entirely
3434
/// different semantics.</remarks>
3535
public static LogEventLevel ToSerilogLevel(LogLevel logLevel)
@@ -46,7 +46,7 @@ public static LogEventLevel ToSerilogLevel(LogLevel logLevel)
4646
}
4747

4848
/// <summary>
49-
/// Convert <paramref name="logEventLevel"/> to the equivalent Microsoft.Extensions.Logging <see cref="LogLevel"/>.
49+
/// Convert <paramref name="logEventLevel"/> to the equivalent Microsoft.Extensions.Logging <see cref="Microsoft.Extensions.Logging.LogLevel"/>.
5050
/// </summary>
5151
/// <param name="logEventLevel">A Serilog <see cref="LogEventLevel"/>.</param>
5252
/// <returns>The Microsoft.Extensions.Logging equivalent of <paramref name="logEventLevel"/>.</returns>

src/Serilog.Extensions.Logging/Extensions/Logging/SerilogLogValues.cs

+9-9
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,14 @@
1717

1818
namespace Serilog.Extensions.Logging;
1919

20-
readonly struct SerilogLogValues : IReadOnlyList<KeyValuePair<string, object>>
20+
readonly struct SerilogLogValues : IReadOnlyList<KeyValuePair<string, object?>>
2121
{
2222
// Note, this struct is only used in a very limited context internally, so we ignore
2323
// the possibility of fields being null via the default struct initialization.
2424

25-
private readonly MessageTemplate _messageTemplate;
26-
private readonly IReadOnlyDictionary<string, LogEventPropertyValue> _properties;
27-
private readonly KeyValuePair<string, object>[] _values;
25+
readonly MessageTemplate _messageTemplate;
26+
readonly IReadOnlyDictionary<string, LogEventPropertyValue> _properties;
27+
readonly KeyValuePair<string, object?>[] _values;
2828

2929
public SerilogLogValues(MessageTemplate messageTemplate, IReadOnlyDictionary<string, LogEventPropertyValue> properties)
3030
{
@@ -34,24 +34,24 @@ public SerilogLogValues(MessageTemplate messageTemplate, IReadOnlyDictionary<str
3434
_properties = properties ?? throw new ArgumentNullException(nameof(properties));
3535

3636
// The array is needed because the IReadOnlyList<T> interface expects indexed access
37-
_values = new KeyValuePair<string, object>[_properties.Count + 1];
37+
_values = new KeyValuePair<string, object?>[_properties.Count + 1];
3838
var i = 0;
3939
foreach (var p in properties)
4040
{
41-
_values[i] = new KeyValuePair<string, object>(p.Key, (p.Value is ScalarValue sv) ? sv.Value : p.Value);
41+
_values[i] = new KeyValuePair<string, object?>(p.Key, (p.Value is ScalarValue sv) ? sv.Value : p.Value);
4242
++i;
4343
}
44-
_values[i] = new KeyValuePair<string, object>("{OriginalFormat}", _messageTemplate.Text);
44+
_values[i] = new KeyValuePair<string, object?>("{OriginalFormat}", _messageTemplate.Text);
4545
}
4646

47-
public KeyValuePair<string, object> this[int index]
47+
public KeyValuePair<string, object?> this[int index]
4848
{
4949
get => _values[index];
5050
}
5151

5252
public int Count => _properties.Count + 1;
5353

54-
public IEnumerator<KeyValuePair<string, object>> GetEnumerator() => ((IEnumerable<KeyValuePair<string, object>>)_values).GetEnumerator();
54+
public IEnumerator<KeyValuePair<string, object?>> GetEnumerator() => ((IEnumerable<KeyValuePair<string, object?>>)_values).GetEnumerator();
5555

5656
public override string ToString() => _messageTemplate.Render(_properties);
5757

src/Serilog.Extensions.Logging/Extensions/Logging/SerilogLogger.cs

+12-11
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,9 @@ public SerilogLogger(
4141
string? name = null)
4242
{
4343
_provider = provider ?? throw new ArgumentNullException(nameof(provider));
44-
_logger = logger!;
4544

4645
// If a logger was passed, the provider has already added itself as an enricher
47-
_logger ??= Serilog.Log.Logger.ForContext(new[] { provider });
46+
_logger = logger ?? Serilog.Log.Logger.ForContext(new[] { provider });
4847

4948
if (name != null)
5049
{
@@ -57,12 +56,12 @@ public bool IsEnabled(LogLevel logLevel)
5756
return logLevel != LogLevel.None && _logger.IsEnabled(LevelConvert.ToSerilogLevel(logLevel));
5857
}
5958

60-
public IDisposable BeginScope<TState>(TState state)
59+
public IDisposable BeginScope<TState>(TState state) where TState : notnull
6160
{
6261
return _provider.BeginScope(state);
6362
}
6463

65-
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
64+
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception? exception, Func<TState, Exception?, string> formatter)
6665
{
6766
if (logLevel == LogLevel.None)
6867
{
@@ -81,15 +80,15 @@ public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Except
8180
}
8281
catch (Exception ex)
8382
{
84-
SelfLog.WriteLine($"Failed to write event through {typeof(SerilogLogger).Name}: {ex}");
83+
SelfLog.WriteLine($"Failed to write event through {nameof(SerilogLogger)}: {ex}");
8584
}
8685

8786
// Do not swallow exceptions from here because Serilog takes care of them in case of WriteTo and throws them back to the caller in case of AuditTo.
8887
if (evt != null)
8988
_logger.Write(evt);
9089
}
9190

92-
LogEvent PrepareWrite<TState>(LogEventLevel level, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
91+
LogEvent PrepareWrite<TState>(LogEventLevel level, EventId eventId, TState state, Exception? exception, Func<TState, Exception?, string> formatter)
9392
{
9493
string? messageTemplate = null;
9594

@@ -139,7 +138,9 @@ LogEvent PrepareWrite<TState>(LogEventLevel level, EventId eventId, TState state
139138
propertyName = "State";
140139
messageTemplate = "{State:l}";
141140
}
142-
else if (formatter != null)
141+
// `formatter` was originally accepted as nullable, so despite the new annotation, this check should still
142+
// be made.
143+
else if (formatter != null!)
143144
{
144145
propertyName = "Message";
145146
messageTemplate = "{Message:l}";
@@ -159,12 +160,12 @@ LogEvent PrepareWrite<TState>(LogEventLevel level, EventId eventId, TState state
159160
return new LogEvent(DateTimeOffset.Now, level, exception, parsedTemplate, properties);
160161
}
161162

162-
static object? AsLoggableValue<TState>(TState state, Func<TState, Exception, string> formatter)
163+
static object? AsLoggableValue<TState>(TState state, Func<TState, Exception?, string>? formatter)
163164
{
164-
object? sobj = state;
165+
object? stateObj = state;
165166
if (formatter != null)
166-
sobj = formatter(state, null!);
167-
return sobj;
167+
stateObj = formatter(state, null);
168+
return stateObj;
168169
}
169170

170171
internal static LogEventProperty CreateEventIdProperty(EventId eventId)

0 commit comments

Comments
 (0)