Skip to content

Commit 3c32997

Browse files
authored
Merge pull request #249 from sungam3r/tuple
Support for ITuple
2 parents 6fd2e72 + 504fc5c commit 3c32997

File tree

4 files changed

+70
-34
lines changed

4 files changed

+70
-34
lines changed

README.md

Lines changed: 39 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -28,41 +28,41 @@ using Serilog;
2828

2929
public class Startup
3030
{
31-
public Startup(IHostingEnvironment env)
32-
{
33-
Log.Logger = new LoggerConfiguration()
34-
.Enrich.FromLogContext()
35-
.WriteTo.Console()
36-
.CreateLogger();
37-
38-
// Other startup code
31+
public Startup(IHostingEnvironment env)
32+
{
33+
Log.Logger = new LoggerConfiguration()
34+
.Enrich.FromLogContext()
35+
.WriteTo.Console()
36+
.CreateLogger();
37+
38+
// Other startup code
3939
```
4040

4141
**Finally, for .NET Core 2.0+**, in your `Startup` class's `Configure()` method, remove the existing logger configuration entries and
4242
call `AddSerilog()` on the provided `loggingBuilder`.
4343

4444
```csharp
45-
public void ConfigureServices(IServiceCollection services)
46-
{
47-
services.AddLogging(loggingBuilder =>
48-
loggingBuilder.AddSerilog(dispose: true));
45+
public void ConfigureServices(IServiceCollection services)
46+
{
47+
services.AddLogging(loggingBuilder =>
48+
loggingBuilder.AddSerilog(dispose: true));
4949

50-
// Other services ...
51-
}
50+
// Other services ...
51+
}
5252
```
5353

5454
**For .NET Core 1.0 or 1.1**, in your `Startup` class's `Configure()` method, remove the existing logger configuration entries and call `AddSerilog()` on the provided `loggerFactory`.
5555

5656
```
57-
public void Configure(IApplicationBuilder app,
58-
IHostingEnvironment env,
59-
ILoggerFactory loggerfactory,
60-
IApplicationLifetime appLifetime)
61-
{
62-
loggerfactory.AddSerilog();
63-
64-
// Ensure any buffered events are sent at shutdown
65-
appLifetime.ApplicationStopped.Register(Log.CloseAndFlush);
57+
public void Configure(IApplicationBuilder app,
58+
IHostingEnvironment env,
59+
ILoggerFactory loggerfactory,
60+
IApplicationLifetime appLifetime)
61+
{
62+
loggerfactory.AddSerilog();
63+
64+
// Ensure any buffered events are sent at shutdown
65+
appLifetime.ApplicationStopped.Register(Log.CloseAndFlush);
6666
```
6767

6868
That's it! With the level bumped up a little you should see log output like:
@@ -87,10 +87,10 @@ _Serilog.Extensions.Logging_ captures the `ILogger`'s log category, but it's not
8787
8888
To include the log category in the final written messages, add the `{SourceContext}` named hole to a customised `outputTemplate` parameter value when configuring the relevant sink(s). For example:
8989
```csharp
90-
.WriteTo.Console(
91-
outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3}] {SourceContext}: {Message:lj}{NewLine}{Exception}")
92-
.WriteTo.File("log.txt",
93-
outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] {SourceContext}: {Message:lj}{NewLine}{Exception}")
90+
.WriteTo.Console(
91+
outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3}] {SourceContext}: {Message:lj}{NewLine}{Exception}")
92+
.WriteTo.File("log.txt",
93+
outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] {SourceContext}: {Message:lj}{NewLine}{Exception}")
9494
```
9595

9696
### Notes on Log Scopes
@@ -103,7 +103,8 @@ _Microsoft.Extensions.Logging_ provides the `BeginScope` API, which can be used
103103
Using the extension method will add a `Scope` property to your log events. This is most useful for adding simple "scope strings" to your events, as in the following code:
104104

105105
```csharp
106-
using (_logger.BeginScope("Transaction")) {
106+
using (_logger.BeginScope("Transaction"))
107+
{
107108
_logger.LogInformation("Beginning...");
108109
_logger.LogInformation("Completed in {DurationMs}ms...", 30);
109110
}
@@ -116,7 +117,8 @@ If you simply want to add a "bag" of additional properties to your log events, h
116117

117118
```csharp
118119
// WRONG! Prefer the dictionary or value tuple approach below instead
119-
using (_logger.BeginScope("TransactionId: {TransactionId}, ResponseJson: {ResponseJson}", 12345, jsonString)) {
120+
using (_logger.BeginScope("TransactionId: {TransactionId}, ResponseJson: {ResponseJson}", 12345, jsonString))
121+
{
120122
_logger.LogInformation("Completed in {DurationMs}ms...", 30);
121123
}
122124
// Example JSON output:
@@ -138,11 +140,13 @@ Moreover, the template string within `BeginScope` is rather arbitrary when all y
138140
A far better alternative is to use the `BeginScope<TState>(TState state)` method. If you provide any `IEnumerable<KeyValuePair<string, object>>` to this method, then Serilog will output the key/value pairs as structured properties _without_ the `Scope` property, as in this example:
139141

140142
```csharp
141-
var scopeProps = new Dictionary<string, object> {
143+
var scopeProps = new Dictionary<string, object>
144+
{
142145
{ "TransactionId", 12345 },
143146
{ "ResponseJson", jsonString },
144147
};
145-
using (_logger.BeginScope(scopeProps) {
148+
using (_logger.BeginScope(scopeProps)
149+
{
146150
_logger.LogInformation("Transaction completed in {DurationMs}ms...", 30);
147151
}
148152
// Example JSON output:
@@ -157,10 +161,12 @@ using (_logger.BeginScope(scopeProps) {
157161
// }
158162
```
159163

160-
Alternatively provide a `ValueTuple<string, object?>` to this method, where `Item1` is the property name and `Item2` is the property value. Note that `T2` _must_ be `object?`.
164+
Alternatively provide a `ValueTuple<string, object?>` to this method, where `Item1` is the property name and `Item2` is the property value.
165+
Note that `T2` _must_ be `object?` if your target platform is net462 or netstandard2.0.
161166

162167
```csharp
163-
using (_logger.BeginScope(("TransactionId", (object?)12345)) {
168+
using (_logger.BeginScope(("TransactionId", 12345))
169+
{
164170
_logger.LogInformation("Transaction completed in {DurationMs}ms...", 30);
165171
}
166172
// Example JSON output:

src/Serilog.Extensions.Logging/Extensions/Logging/SerilogLoggerScope.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,17 @@ void AddProperty(string key, object? value)
9999
AddProperty(stateProperty.Key, stateProperty.Value);
100100
}
101101
}
102+
#if FEATURE_ITUPLE
103+
else if (_state is System.Runtime.CompilerServices.ITuple tuple && tuple.Length == 2 && tuple[0] is string s)
104+
{
105+
scopeItem = null; // Unless it's `FormattedLogValues`, these are treated as property bags rather than scope items.
106+
107+
if (s == SerilogLoggerProvider.OriginalFormatPropertyName && tuple[1] is string)
108+
scopeItem = new ScalarValue(_state.ToString());
109+
else
110+
AddProperty(s, tuple[1]);
111+
}
112+
#else
102113
else if (_state is ValueTuple<string, object?> tuple)
103114
{
104115
scopeItem = null; // Unless it's `FormattedLogValues`, these are treated as property bags rather than scope items.
@@ -108,6 +119,7 @@ void AddProperty(string key, object? value)
108119
else
109120
AddProperty(tuple.Item1, tuple.Item2);
110121
}
122+
#endif
111123
else
112124
{
113125
scopeItem = propertyFactory.CreateProperty(NoName, _state).Value;

src/Serilog.Extensions.Logging/Serilog.Extensions.Logging.csproj

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,4 +35,19 @@
3535
<PackageReference Include="Nullable" Version="1.3.1" PrivateAssets="All" />
3636
</ItemGroup>
3737

38+
<PropertyGroup Condition=" '$(TargetFramework)' == 'netstandard2.1' ">
39+
<DefineConstants>$(DefineConstants);FEATURE_ITUPLE</DefineConstants>
40+
</PropertyGroup>
41+
42+
<PropertyGroup Condition=" '$(TargetFramework)' == 'net6.0' ">
43+
<DefineConstants>$(DefineConstants);FEATURE_ITUPLE</DefineConstants>
44+
</PropertyGroup>
45+
46+
<PropertyGroup Condition=" '$(TargetFramework)' == 'net7.0' ">
47+
<DefineConstants>$(DefineConstants);FEATURE_ITUPLE</DefineConstants>
48+
</PropertyGroup>
49+
50+
<PropertyGroup Condition=" '$(TargetFramework)' == 'net8.0' ">
51+
<DefineConstants>$(DefineConstants);FEATURE_ITUPLE</DefineConstants>
52+
</PropertyGroup>
3853
</Project>

test/Serilog.Extensions.Logging.Tests/SerilogLoggerScopeTests.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,11 @@ public void EnrichWithTupleStringObject()
8181

8282
var (loggerProvider, logEventPropertyFactory, logEvent) = SetUp();
8383

84-
84+
#if NET48
8585
var state = (propertyName, (object)expectedValue);
86+
#else
87+
var state = (propertyName, expectedValue);
88+
#endif
8689

8790
var loggerScope = new SerilogLoggerScope(loggerProvider, state);
8891

0 commit comments

Comments
 (0)