Skip to content

Commit 87f58ec

Browse files
committed
Merge branch 'dev'
# Conflicts: # src/Serilog.Extensions.Logging/project.json
2 parents 163a204 + cdfa474 commit 87f58ec

File tree

10 files changed

+142
-73
lines changed

10 files changed

+142
-73
lines changed

README.md

Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# Serilog.Extensions.Logging
2-
[![Build status](https://ci.appveyor.com/api/projects/status/865nohxfiq1rnby0/branch/master?svg=true)](https://ci.appveyor.com/project/serilog/serilog-extensions-logging/branch/master) [![NuGet Version](http://img.shields.io/nuget/v/Serilog.Extensions.Logging.svg?style=flat)](https://www.nuget.org/packages/Serilog.Extensions.Logging/)
2+
[![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/)
33

44

55
A Serilog provider for [Microsoft.Extensions.Logging](https://www.nuget.org/packages/Microsoft.Extensions.Logging), the logging subsystem used by ASP.NET Core.
@@ -11,8 +11,8 @@ This package routes ASP.NET log messages through Serilog, so you can get informa
1111
**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.Literate_ writes these to the console.
1212

1313
```powershell
14-
Install-Package Serilog.Extensions.Logging
15-
Install-Package Serilog.Sinks.Literate
14+
Install-Package Serilog.Extensions.Logging -Pre -DependencyVersion Highest
15+
Install-Package Serilog.Sinks.Literate -Pre
1616
```
1717

1818
**Next**, in your application's `Startup` method, configure Serilog first:
@@ -25,13 +25,15 @@ public class Startup
2525
public Startup(IHostingEnvironment env)
2626
{
2727
Log.Logger = new LoggerConfiguration()
28+
.Enrich.FromLogContext()
2829
.WriteTo.LiterateConsole()
2930
.CreateLogger();
3031

3132
// Other startup code
3233
```
3334

34-
**Finally**, in your `Startup` class's `Configure()` method, call `AddSerilog()` on the provided `loggerFactory`.
35+
**Finally**, in your `Startup` class's `Configure()` method, remove the existing logger configuration entries and
36+
call `AddSerilog()` on the provided `loggerFactory`.
3537

3638
```csharp
3739
public void Configure(IApplicationBuilder app,
@@ -56,19 +58,6 @@ That's it! With the level bumped up a little you should see log output like:
5658
2015-05-15 22:14:45.741 +10:00 [DBG] Handled. Status code: 304 File: /css/site.css
5759
```
5860

59-
### Levels
60-
61-
If you want to get more information from the log you'll need to bump up the level.
62-
63-
Two things:
64-
65-
* You need to set `MinimumLevel` on **both** the Serilog `LoggerConfiguration` and the `ILoggerFactory`
66-
* Serilog and ASP.NET assign different priorities to the `Debug` and `Verbose` levels; Serilog's `Debug` is ASP.NET's `Verbose`, and vice-versa
67-
68-
### Building from source
69-
70-
To build the `dev` branch, which tracks the `dev` branch of _Microsoft.Extensions.Logging_, you must add https://www.myget.org/F/aspnetvnext/ to your package sources.
71-
7261
### Credits
7362

7463
This package evolved from an earlier package _Microsoft.Framework.Logging.Serilog_ [provided by the ASP.NET team](https://github.com/aspnet/Logging/pull/182).

appveyor.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@ image: Visual Studio 2015
33
configuration: Release
44
install:
55
- ps: mkdir -Force ".\build\" | Out-Null
6-
- ps: Invoke-WebRequest "https://raw.githubusercontent.com/dotnet/cli/rel/1.0.0/scripts/obtain/install.ps1" -OutFile ".\build\installcli.ps1"
6+
- ps: Invoke-WebRequest "https://raw.githubusercontent.com/dotnet/cli/rel/1.0.0/scripts/obtain/dotnet-install.ps1" -OutFile ".\build\installcli.ps1"
77
- ps: $env:DOTNET_INSTALL_DIR = "$pwd\.dotnetcli"
8-
- ps: '& .\build\installcli.ps1 -InstallDir "$env:DOTNET_INSTALL_DIR" -NoPath'
8+
- ps: '& .\build\installcli.ps1 -InstallDir "$env:DOTNET_INSTALL_DIR" -NoPath -Version 1.0.0-preview2-002823'
99
- ps: $env:Path = "$env:DOTNET_INSTALL_DIR;$env:Path"
1010
build_script:
1111
- ps: ./Build.ps1

samples/Sample/project.json

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,12 @@
55
},
66
"dependencies": {
77
"Serilog.Extensions.Logging": { "target": "project" },
8-
"Serilog.Sinks.Literate": "2.0.0-rc-25"
8+
"Serilog.Sinks.Literate": "2.0.0-rc-25",
9+
"Microsoft.Extensions.Logging": "1.0.0-rc2-final"
910
},
1011

1112
"frameworks": {
12-
"net4.6": {
13-
"frameworkAssemblies": {
14-
"System.Runtime": ""
15-
}
16-
},
13+
"net4.6": {},
1714
"netcoreapp1.0": {
1815
"define": [ "ASYNCLOCAL" ],
1916
"dependencies": {

samples/WebSample/Controllers/HomeController.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using System.Linq;
44
using System.Threading.Tasks;
55
using Microsoft.AspNetCore.Mvc;
6+
using Serilog;
67

78
namespace WebSample.Controllers
89
{
@@ -17,6 +18,8 @@ public IActionResult About()
1718
{
1819
ViewData["Message"] = "Your application description page.";
1920

21+
Log.Information("This is a Serilog-native event from the About action");
22+
2023
return View();
2124
}
2225

samples/WebSample/Startup.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ public Startup(IHostingEnvironment env)
2222
{
2323
Log.Logger = new LoggerConfiguration()
2424
.MinimumLevel.Debug()
25+
.Enrich.FromLogContext()
2526
.WriteTo.Seq("http://localhost:5341")
2627
.CreateLogger();
2728

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

Lines changed: 36 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
using Microsoft.Extensions.Logging;
55
using System;
66
using System.Collections.Generic;
7-
using System.Linq;
87
using Serilog.Core;
98
using Serilog.Events;
109
using FrameworkLogger = Microsoft.Extensions.Logging.ILogger;
@@ -16,7 +15,6 @@ namespace Serilog.Extensions.Logging
1615
class SerilogLogger : FrameworkLogger
1716
{
1817
readonly SerilogLoggerProvider _provider;
19-
readonly string _name;
2018
readonly ILogger _logger;
2119

2220
static readonly MessageTemplateParser _messageTemplateParser = new MessageTemplateParser();
@@ -28,13 +26,12 @@ public SerilogLogger(
2826
{
2927
if (provider == null) throw new ArgumentNullException(nameof(provider));
3028
_provider = provider;
31-
_name = name;
3229
_logger = logger;
3330

3431
// If a logger was passed, the provider has already added itself as an enricher
3532
_logger = _logger ?? Serilog.Log.Logger.ForContext(new[] { provider });
3633

37-
if (_name != null)
34+
if (name != null)
3835
{
3936
_logger = _logger.ForContext(Constants.SourceContextPropertyName, name);
4037
}
@@ -47,7 +44,7 @@ public bool IsEnabled(LogLevel logLevel)
4744

4845
public IDisposable BeginScope<TState>(TState state)
4946
{
50-
return _provider.BeginScope(_name, state);
47+
return _provider.BeginScope(state);
5148
}
5249

5350
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
@@ -61,6 +58,8 @@ public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Except
6158
var logger = _logger;
6259
string messageTemplate = null;
6360

61+
var properties = new List<LogEventProperty>();
62+
6463
var structure = state as IEnumerable<KeyValuePair<string, object>>;
6564
if (structure != null)
6665
{
@@ -72,11 +71,15 @@ public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Except
7271
}
7372
else if (property.Key.StartsWith("@"))
7473
{
75-
logger = logger.ForContext(property.Key.Substring(1), property.Value, destructureObjects: true);
74+
LogEventProperty destructured;
75+
if (logger.BindProperty(property.Key.Substring(1), property.Value, true, out destructured))
76+
properties.Add(destructured);
7677
}
7778
else
7879
{
79-
logger = logger.ForContext(property.Key, property.Value);
80+
LogEventProperty bound;
81+
if (logger.BindProperty(property.Key, property.Value, false, out bound))
82+
properties.Add(bound);
8083
}
8184
}
8285

@@ -86,24 +89,28 @@ public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Except
8689
if (messageTemplate == null && !stateTypeInfo.IsGenericType)
8790
{
8891
messageTemplate = "{" + stateType.Name + ":l}";
89-
logger = logger.ForContext(stateType.Name, AsLoggableValue(state, formatter));
92+
LogEventProperty stateTypeProperty;
93+
if (logger.BindProperty(stateType.Name, AsLoggableValue(state, formatter), false, out stateTypeProperty))
94+
properties.Add(stateTypeProperty);
9095
}
9196
}
9297

9398
if (messageTemplate == null && state != null)
9499
{
95100
messageTemplate = "{State:l}";
96-
logger = logger.ForContext("State", AsLoggableValue(state, formatter));
101+
LogEventProperty stateProperty;
102+
if (logger.BindProperty("State", AsLoggableValue(state, formatter), false, out stateProperty))
103+
properties.Add(stateProperty);
97104
}
98105

99106
if (string.IsNullOrEmpty(messageTemplate))
100107
return;
101108

102-
if (eventId.Id != 0)
103-
logger = logger.ForContext("EventId", eventId);
109+
if (eventId.Id != 0 || eventId.Name != null)
110+
properties.Add(CreateEventIdProperty(eventId));
104111

105112
var parsedTemplate = _messageTemplateParser.Parse(messageTemplate);
106-
var evt = new LogEvent(DateTimeOffset.Now, level, exception, parsedTemplate, Enumerable.Empty<LogEventProperty>());
113+
var evt = new LogEvent(DateTimeOffset.Now, level, exception, parsedTemplate, properties);
107114
logger.Write(evt);
108115
}
109116

@@ -135,5 +142,22 @@ static LogEventLevel ConvertLevel(LogLevel logLevel)
135142
return LogEventLevel.Verbose;
136143
}
137144
}
145+
146+
static LogEventProperty CreateEventIdProperty(EventId eventId)
147+
{
148+
var properties = new List<LogEventProperty>(2);
149+
150+
if (eventId.Id != 0)
151+
{
152+
properties.Add(new LogEventProperty("Id", new ScalarValue(eventId.Id)));
153+
}
154+
155+
if (eventId.Name != null)
156+
{
157+
properties.Add(new LogEventProperty("Name", new ScalarValue(eventId.Name)));
158+
}
159+
160+
return new LogEventProperty("EventId", new StructureValue(properties));
161+
}
138162
}
139163
}

src/Serilog.Extensions.Logging/Extensions/Logging/SerilogLoggerProvider.cs

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,12 @@
22
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
33

44
using System;
5-
using System.Collections.Generic;
5+
#if ASYNCLOCAL
66
using System.Threading;
7+
#else
8+
using System.Runtime.Remoting;
9+
using System.Runtime.Remoting.Messaging;
10+
#endif
711
using Microsoft.Extensions.Logging;
812
using Serilog.Core;
913
using Serilog.Events;
@@ -15,8 +19,6 @@ class SerilogLoggerProvider : ILoggerProvider, ILogEventEnricher
1519
{
1620
public const string OriginalFormatPropertyName = "{OriginalFormat}";
1721

18-
readonly AsyncLocal<SerilogLoggerScope> _value = new AsyncLocal<SerilogLoggerScope>();
19-
2022
// May be null; if it is, Log.Logger will be lazily used
2123
readonly ILogger _logger;
2224

@@ -31,30 +33,22 @@ public FrameworkLogger CreateLogger(string name)
3133
return new SerilogLogger(this, _logger, name);
3234
}
3335

34-
public IDisposable BeginScope<T>(string name, T state)
36+
public IDisposable BeginScope<T>(T state)
3537
{
36-
return new SerilogLoggerScope(this, name, state);
38+
return new SerilogLoggerScope(this, state);
3739
}
3840

3941
public void Enrich(LogEvent logEvent, ILogEventPropertyFactory propertyFactory)
4042
{
4143
for (var scope = CurrentScope; scope != null; scope = scope.Parent)
4244
{
43-
var stateStructure = scope.State as IEnumerable<KeyValuePair<string, object>>;
44-
if (stateStructure != null)
45-
{
46-
foreach (var keyValue in stateStructure)
47-
{
48-
if (keyValue.Key == OriginalFormatPropertyName && keyValue.Value is string)
49-
continue;
50-
51-
var property = propertyFactory.CreateProperty(keyValue.Key, keyValue.Value);
52-
logEvent.AddPropertyIfAbsent(property);
53-
}
54-
}
45+
scope.Enrich(logEvent, propertyFactory);
5546
}
5647
}
5748

49+
#if ASYNCLOCAL
50+
readonly AsyncLocal<SerilogLoggerScope> _value = new AsyncLocal<SerilogLoggerScope>();
51+
5852
public SerilogLoggerScope CurrentScope
5953
{
6054
get
@@ -66,6 +60,22 @@ public SerilogLoggerScope CurrentScope
6660
_value.Value = value;
6761
}
6862
}
63+
#else
64+
readonly string _currentScopeKey = nameof(SerilogLoggerScope) + "#" + Guid.NewGuid().ToString("n");
65+
66+
public SerilogLoggerScope CurrentScope
67+
{
68+
get
69+
{
70+
var objectHandle = CallContext.LogicalGetData(_currentScopeKey) as ObjectHandle;
71+
return objectHandle?.Unwrap() as SerilogLoggerScope;
72+
}
73+
set
74+
{
75+
CallContext.LogicalSetData(_currentScopeKey, new ObjectHandle(value));
76+
}
77+
}
78+
#endif
6979

7080
public void Dispose() { }
7181
}

0 commit comments

Comments
 (0)