Skip to content

Commit a9eb2e1

Browse files
authored
Merge pull request #11 from serilog/dev
3.0.0 Release
2 parents 8a7037e + 6b932b4 commit a9eb2e1

18 files changed

+425
-87
lines changed

README.md

Lines changed: 8 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
# Serilog.Extensions.Hosting [![Build status](https://ci.appveyor.com/api/projects/status/ue4s7htjwj88fulh?svg=true)](https://ci.appveyor.com/project/serilog/serilog-extensions-hosting) [![NuGet Version](http://img.shields.io/nuget/v/Serilog.Extensions.Hosting.svg?style=flat)](https://www.nuget.org/packages/Serilog.Extensions.Hosting/)
22

3-
Serilog logging for Microsoft.Extensions.Hosting . This package routes Microsoft.Extensions.Hosting log messages through Serilog, so you can get information about the framework's internal operations logged to the same Serilog sinks as your application events.
3+
Serilog logging for _Microsoft.Extensions.Hosting_. This package routes framework log messages through Serilog, so you can get information about the framework's internal operations written to the same Serilog sinks as your application events.
4+
5+
**ASP.NET Core** applications should consider [using _Serilog.AspNetCore_ instead](https://github.com/serilog/serilog-aspnetcore), which bundles this package and includes other ASP.NET Core-specific features.
46

57
### Instructions
68

@@ -54,7 +56,7 @@ public class Program
5456
}
5557
```
5658

57-
**Finally**, clean up by removing the rema `"Logging"` section from _appsettings.json_ files (this can be replaced with [Serilog configuration](https://github.com/serilog/serilog-settings-configuration) as shown in [this example](https://github.com/serilog/serilog-hosting/blob/dev/samples/SimpleServiceSample/Program.cs), if required)
59+
**Finally**, clean up by removing the remaining `"Logging"` section from _appsettings.json_ files (this can be replaced with [Serilog configuration](https://github.com/serilog/serilog-settings-configuration) as shown in [this example](https://github.com/serilog/serilog-extensions-hosting/blob/dev/samples/SimpleServiceSample/Program.cs), if required)
5860

5961
That's it! You will see log output like:
6062

@@ -63,7 +65,7 @@ That's it! You will see log output like:
6365
[22:10:39 INF] The current time is: 12/05/2018 10:10:39 +00:00
6466
```
6567

66-
A more complete example, showing _appsettings.json_ configuration, can be found in [the sample project here](https://github.com/serilog/serilog-hostinh/tree/dev/samples/SimpleServiceSample).
68+
A more complete example, showing _appsettings.json_ configuration, can be found in [the sample project here](https://github.com/serilog/serilog-hosting/tree/dev/samples/SimpleServiceSample).
6769

6870
### Using the package
6971

@@ -78,39 +80,11 @@ You can alternatively configure Serilog using a delegate as shown below:
7880
```csharp
7981
// dotnet add package Serilog.Settings.Configuration
8082
.UseSerilog((hostingContext, loggerConfiguration) => loggerConfiguration
81-
.ReadFrom.Configuration(hostingContext.Configuration)
82-
.Enrich.FromLogContext()
83-
.WriteTo.Console())
83+
.ReadFrom.Configuration(hostingContext.Configuration)
84+
.Enrich.FromLogContext()
85+
.WriteTo.Console())
8486
```
8587

8688
This has the advantage of making the `hostingContext`'s `Configuration` object available for configuration of the logger, but at the expense of recording `Exception`s raised earlier in program startup.
8789

8890
If this method is used, `Log.Logger` is assigned implicitly, and closed when the app is shut down.
89-
90-
### Writing to the Azure Diagnostics Log Stream
91-
92-
The Azure Diagnostic Log Stream ships events from any files in the `D:\home\LogFiles\` folder. To enable this for your app, first install the _Serilog.Sinks.File_ package:
93-
94-
```powershell
95-
Install-Package Serilog.Sinks.File
96-
```
97-
98-
Then add a file sink to your `LoggerConfiguration`, taking care to set the `shared` and `flushToDiskInterval` parameters:
99-
100-
```csharp
101-
public static int Main(string[] args)
102-
{
103-
Log.Logger = new LoggerConfiguration()
104-
.MinimumLevel.Debug()
105-
.MinimumLevel.Override("Microsoft", LogEventLevel.Information)
106-
.Enrich.FromLogContext()
107-
.WriteTo.Console()
108-
// Add this line:
109-
.WriteTo.File(
110-
@"D:\home\LogFiles\Application\myapp.txt",
111-
fileSizeLimitBytes: 1_000_000,
112-
rollOnFileSizeLimit: true,
113-
shared: true,
114-
flushToDiskInterval: TimeSpan.FromSeconds(1))
115-
.CreateLogger();
116-
```

appveyor.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,13 @@ build_script:
77
- ps: ./Build.ps1
88
artifacts:
99
- path: artifacts/Serilog.*.nupkg
10+
skip_commits:
11+
files:
12+
- README.md
1013
deploy:
1114
- provider: NuGet
1215
api_key:
13-
secure: bd9z4P73oltOXudAjPehwp9iDKsPtC+HbgshOrSgoyQKr5xVK+bxJQngrDJkHdY8
16+
secure: JAnOxPQMZRp8ousbAW4vYnVtd936AOMp4gDGucCQ1RZrDZW3J+X5QmbLO7OJKtBr
1417
skip_symbols: true
1518
on:
1619
branch: /^(master|dev)$/

global.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
22
"sdk": {
3-
"version": "2.1.300-*"
3+
"version": "2.2.105"
44
}
55
}

samples/SimpleServiceSample/PrintTimeService.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
using Microsoft.Extensions.Hosting;
55
using Microsoft.Extensions.Logging;
66

7-
namespace SimpleWebSample
7+
namespace SimpleServiceSample
88
{
99
public class PrintTimeService : IHostedService, IDisposable
1010
{

samples/SimpleServiceSample/Program.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
using System;
22
using System.IO;
3-
using Microsoft.Extensions.Hosting;
43
using Microsoft.Extensions.Configuration;
5-
using Serilog;
64
using Microsoft.Extensions.DependencyInjection;
5+
using Microsoft.Extensions.Hosting;
6+
using Serilog;
77

8-
namespace SimpleWebSample
8+
namespace SimpleServiceSample
99
{
1010
public class Program
1111
{

samples/SimpleServiceSample/SimpleServiceSample.csproj

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,12 @@
1313
</ItemGroup>
1414

1515
<ItemGroup>
16-
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="2.1.0-rc1-final" />
17-
<PackageReference Include="Microsoft.Extensions.Hosting" Version="2.1.0-rc1-final" />
18-
<PackageReference Include="Microsoft.Extensions.Configuration" Version="2.1.0-rc1-final" />
19-
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.1.0-rc1-final" />
20-
<PackageReference Include="Serilog.Sinks.Console" Version="3.0.1" />
21-
<PackageReference Include="Serilog.Settings.Configuration" Version="2.4.0" />
16+
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="2.2.4" />
17+
<PackageReference Include="Microsoft.Extensions.Hosting" Version="2.2.0" />
18+
<PackageReference Include="Microsoft.Extensions.Configuration" Version="2.2.0" />
19+
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.2.0" />
20+
<PackageReference Include="Serilog.Sinks.Console" Version="3.1.1" />
21+
<PackageReference Include="Serilog.Settings.Configuration" Version="3.1.0" />
2222
</ItemGroup>
2323

2424
</Project>
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
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/=appsettings/@EntryIndexedValue">True</s:Boolean>
3+
<s:Boolean x:Key="/Default/UserDictionary/Words/=benaadams/@EntryIndexedValue">True</s:Boolean>
4+
<s:Boolean x:Key="/Default/UserDictionary/Words/=destructure/@EntryIndexedValue">True</s:Boolean>
5+
<s:Boolean x:Key="/Default/UserDictionary/Words/=Serilog/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// Copyright 2019 Serilog Contributors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
using System;
16+
using System.Threading;
17+
18+
namespace Serilog.Extensions.Hosting
19+
{
20+
class AmbientDiagnosticContextCollector : IDisposable
21+
{
22+
static readonly AsyncLocal<AmbientDiagnosticContextCollector> AmbientCollector =
23+
new AsyncLocal<AmbientDiagnosticContextCollector>();
24+
25+
// The indirection here ensures that completing collection cleans up the collector in all
26+
// execution contexts. Via @benaadams' addition to `HttpContextAccessor` :-)
27+
DiagnosticContextCollector _collector;
28+
29+
public static DiagnosticContextCollector Current => AmbientCollector.Value?._collector;
30+
31+
public static DiagnosticContextCollector Begin()
32+
{
33+
var value = new AmbientDiagnosticContextCollector();
34+
value._collector = new DiagnosticContextCollector(value);
35+
AmbientCollector.Value = value;
36+
return value._collector;
37+
}
38+
39+
public void Dispose()
40+
{
41+
_collector = null;
42+
if (AmbientCollector.Value == this)
43+
AmbientCollector.Value = null;
44+
}
45+
}
46+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
// Copyright 2019 Serilog Contributors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
using System;
16+
using System.Threading;
17+
18+
namespace Serilog.Extensions.Hosting
19+
{
20+
/// <summary>
21+
/// Implements an ambient diagnostic context using <see cref="AsyncLocal{T}"/>.
22+
/// </summary>
23+
/// <remarks>Consumers should use <see cref="IDiagnosticContext"/> to set context properties.</remarks>
24+
public sealed class DiagnosticContext : IDiagnosticContext
25+
{
26+
readonly ILogger _logger;
27+
28+
/// <summary>
29+
/// Construct a <see cref="DiagnosticContext"/>.
30+
/// </summary>
31+
/// <param name="logger">A logger for binding properties in the context, or <c>null</c> to use <see cref="Log.Logger"/>.</param>
32+
public DiagnosticContext(ILogger logger)
33+
{
34+
_logger = logger;
35+
}
36+
37+
/// <summary>
38+
/// Start collecting properties to associate with the current diagnostic context. This will replace
39+
/// the active collector, if any.
40+
/// </summary>
41+
/// <returns>A collector that will receive properties added in the current diagnostic context.</returns>
42+
public DiagnosticContextCollector BeginCollection()
43+
{
44+
return AmbientDiagnosticContextCollector.Begin();
45+
}
46+
47+
/// <inheritdoc cref="IDiagnosticContext.Set"/>
48+
public void Set(string propertyName, object value, bool destructureObjects = false)
49+
{
50+
if (propertyName == null) throw new ArgumentNullException(nameof(propertyName));
51+
52+
var collector = AmbientDiagnosticContextCollector.Current;
53+
if (collector != null &&
54+
(_logger ?? Log.Logger).BindProperty(propertyName, value, destructureObjects, out var property))
55+
{
56+
collector.AddOrUpdate(property);
57+
}
58+
}
59+
}
60+
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using Serilog.Events;
4+
5+
namespace Serilog.Extensions.Hosting
6+
{
7+
/// <summary>
8+
/// A container that receives properties added to a diagnostic context.
9+
/// </summary>
10+
public sealed class DiagnosticContextCollector : IDisposable
11+
{
12+
readonly IDisposable _chainedDisposable;
13+
readonly object _propertiesLock = new object();
14+
Dictionary<string, LogEventProperty> _properties = new Dictionary<string, LogEventProperty>();
15+
16+
/// <summary>
17+
/// Construct a <see cref="DiagnosticContextCollector"/>.
18+
/// </summary>
19+
/// <param name="chainedDisposable">An object that will be disposed to signal completion/disposal of
20+
/// the collector.</param>
21+
public DiagnosticContextCollector(IDisposable chainedDisposable)
22+
{
23+
_chainedDisposable = chainedDisposable ?? throw new ArgumentNullException(nameof(chainedDisposable));
24+
}
25+
26+
/// <summary>
27+
/// Add the property to the context.
28+
/// </summary>
29+
/// <param name="property">The property to add.</param>
30+
public void AddOrUpdate(LogEventProperty property)
31+
{
32+
if (property == null) throw new ArgumentNullException(nameof(property));
33+
34+
lock (_propertiesLock)
35+
{
36+
if (_properties == null) return;
37+
_properties[property.Name] = property;
38+
}
39+
}
40+
41+
/// <summary>
42+
/// Complete the context and retrieve the properties added to it, if any. This will
43+
/// stop collection and remove the collector from the original execution context and
44+
/// any of its children.
45+
/// </summary>
46+
/// <param name="properties">The collected properties, or null if no collection is active.</param>
47+
/// <returns>True if properties could be collected.</returns>
48+
public bool TryComplete(out IEnumerable<LogEventProperty> properties)
49+
{
50+
lock (_propertiesLock)
51+
{
52+
properties = _properties?.Values;
53+
_properties = null;
54+
Dispose();
55+
return properties != null;
56+
}
57+
}
58+
59+
/// <inheritdoc/>
60+
public void Dispose()
61+
{
62+
_chainedDisposable.Dispose();
63+
}
64+
}
65+
}

src/Serilog.Extensions.Hosting/Hosting/SerilogLoggerFactory.cs renamed to src/Serilog.Extensions.Hosting/Extensions/Hosting/SerilogLoggerFactory.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,18 +12,25 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15+
using System;
16+
using System.ComponentModel;
1517
using Microsoft.Extensions.Logging;
1618
using Serilog.Debugging;
1719
using Serilog.Extensions.Logging;
1820

21+
// To line up with the convention used elsewhere in the *.Extensions libraries, this
22+
// should have been Serilog.Extensions.Hosting.
23+
// ReSharper disable once CheckNamespace
1924
namespace Serilog.Hosting
2025
{
2126
/// <summary>
2227
/// Implements <see cref="ILoggerFactory"/> so that we can inject Serilog Logger.
2328
/// </summary>
29+
[Obsolete("Replaced with Serilog.Extensions.Logging.SerilogLoggerFactory")]
30+
[EditorBrowsable(EditorBrowsableState.Never)]
2431
public class SerilogLoggerFactory : ILoggerFactory
2532
{
26-
private readonly SerilogLoggerProvider _provider;
33+
readonly SerilogLoggerProvider _provider;
2734

2835
/// <summary>
2936
/// Initializes a new instance of the <see cref="SerilogLoggerFactory"/> class.
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// Copyright 2019 Serilog Contributors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
namespace Serilog
16+
{
17+
/// <summary>
18+
/// Collects diagnostic information for packaging into wide events.
19+
/// </summary>
20+
public interface IDiagnosticContext
21+
{
22+
/// <summary>
23+
/// Set the specified property on the current diagnostic context. The property will be collected
24+
/// and attached to the event emitted at the completion of the context.
25+
/// </summary>
26+
/// <param name="propertyName">The name of the property. Must be non-empty.</param>
27+
/// <param name="value">The property value.</param>
28+
/// <param name="destructureObjects">If true, the value will be serialized as structured
29+
/// data if possible; if false, the object will be recorded as a scalar or simple array.</param>
30+
void Set(string propertyName, object value, bool destructureObjects = false);
31+
}
32+
}

0 commit comments

Comments
 (0)