Skip to content

3.0.0 Release #11

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 25 commits into from
Aug 27, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
33f97d5
Bump the `dev` branch's version
nblumhardt Jul 19, 2018
8d116f9
Fix incorrect urls
andrewlock Aug 5, 2018
4148a0f
Merge pull request #4 from serilog/fix-broken-links
merbla Aug 5, 2018
efad033
fixing repository url
MaximRouiller Sep 21, 2018
ad3405b
Merge pull request #5 from MaximRouiller/repositoryurl
andrewlock Sep 21, 2018
a6610fa
only build packaging-related commits
MV10 Oct 1, 2018
8ff6998
include unit-tests per discussion in tracking issue
MV10 Oct 8, 2018
99aa3c7
Merge pull request #6 from MV10/appveyor_source_commits
andrewlock Nov 7, 2018
0dac1ce
Pull changes from https://github.com/serilog/serilog-aspnetcore/pull/…
nblumhardt Jun 23, 2019
1f401ac
Fix flipped conditional
nblumhardt Jun 23, 2019
ac4f4cd
Diagnostic context infra for downstream middleware
nblumhardt Jun 23, 2019
c396419
Register diagnostic services; includes ILogger now in registered serv…
nblumhardt Jun 23, 2019
414a009
Reapply some doc improvements
nblumhardt Jun 23, 2019
53999fd
Merge pull request #8 from nblumhardt/add-providers
nblumhardt Jun 24, 2019
83427fe
Merge pull request #9 from nblumhardt/diagnostic-context
nblumhardt Jun 24, 2019
d691f30
NuGet publishing key
nblumhardt Jun 24, 2019
3b88ae0
Fix commit filter so that appveyor.yml changes trigger a rebuild
nblumhardt Jun 24, 2019
cee6a1a
Make DiagnosticContextCollector thread-safe
nblumhardt Jun 26, 2019
3a5f079
`IDiagnosticContext.Add()` -> `IDiagnosticContext.Set()`; more small …
nblumhardt Jun 26, 2019
df57744
Probably not paranoid here to trade some actual performance for bette…
nblumhardt Jun 26, 2019
55bb2a5
README trivia
nblumhardt Jun 26, 2019
204fe13
Merge pull request #10 from nblumhardt/threadsafe-context
nblumhardt Jun 26, 2019
8a77959
Update to Serilog.Extensions.Logging 3.0; update other non-shipping d…
nblumhardt Aug 20, 2019
4632471
Play it safe, try to ensure the latest patch is installed
nblumhardt Aug 21, 2019
6b932b4
Merge pull request #13 from nblumhardt/rtm-deps
nblumhardt Aug 27, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 8 additions & 34 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# 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/)

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.
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.

**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.

### Instructions

Expand Down Expand Up @@ -54,7 +56,7 @@ public class Program
}
```

**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)
**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)

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

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

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).
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).

### Using the package

Expand All @@ -78,39 +80,11 @@ You can alternatively configure Serilog using a delegate as shown below:
```csharp
// dotnet add package Serilog.Settings.Configuration
.UseSerilog((hostingContext, loggerConfiguration) => loggerConfiguration
.ReadFrom.Configuration(hostingContext.Configuration)
.Enrich.FromLogContext()
.WriteTo.Console())
.ReadFrom.Configuration(hostingContext.Configuration)
.Enrich.FromLogContext()
.WriteTo.Console())
```

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.

If this method is used, `Log.Logger` is assigned implicitly, and closed when the app is shut down.

### Writing to the Azure Diagnostics Log Stream

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:

```powershell
Install-Package Serilog.Sinks.File
```

Then add a file sink to your `LoggerConfiguration`, taking care to set the `shared` and `flushToDiskInterval` parameters:

```csharp
public static int Main(string[] args)
{
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Debug()
.MinimumLevel.Override("Microsoft", LogEventLevel.Information)
.Enrich.FromLogContext()
.WriteTo.Console()
// Add this line:
.WriteTo.File(
@"D:\home\LogFiles\Application\myapp.txt",
fileSizeLimitBytes: 1_000_000,
rollOnFileSizeLimit: true,
shared: true,
flushToDiskInterval: TimeSpan.FromSeconds(1))
.CreateLogger();
```
5 changes: 4 additions & 1 deletion appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,13 @@ build_script:
- ps: ./Build.ps1
artifacts:
- path: artifacts/Serilog.*.nupkg
skip_commits:
files:
- README.md
deploy:
- provider: NuGet
api_key:
secure: bd9z4P73oltOXudAjPehwp9iDKsPtC+HbgshOrSgoyQKr5xVK+bxJQngrDJkHdY8
secure: JAnOxPQMZRp8ousbAW4vYnVtd936AOMp4gDGucCQ1RZrDZW3J+X5QmbLO7OJKtBr
skip_symbols: true
on:
branch: /^(master|dev)$/
Expand Down
2 changes: 1 addition & 1 deletion global.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"sdk": {
"version": "2.1.300-*"
"version": "2.2.105"
}
}
2 changes: 1 addition & 1 deletion samples/SimpleServiceSample/PrintTimeService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;

namespace SimpleWebSample
namespace SimpleServiceSample
{
public class PrintTimeService : IHostedService, IDisposable
{
Expand Down
6 changes: 3 additions & 3 deletions samples/SimpleServiceSample/Program.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
using System;
using System.IO;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Configuration;
using Serilog;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Serilog;

namespace SimpleWebSample
namespace SimpleServiceSample

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ahhh the cargo cult of redundant namespace for non public types ;)

{
public class Program
{
Expand Down
12 changes: 6 additions & 6 deletions samples/SimpleServiceSample/SimpleServiceSample.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="2.1.0-rc1-final" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="2.1.0-rc1-final" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="2.1.0-rc1-final" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.1.0-rc1-final" />
<PackageReference Include="Serilog.Sinks.Console" Version="3.0.1" />
<PackageReference Include="Serilog.Settings.Configuration" Version="2.4.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="2.2.4" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.2.0" />
<PackageReference Include="Serilog.Sinks.Console" Version="3.1.1" />
<PackageReference Include="Serilog.Settings.Configuration" Version="3.1.0" />
</ItemGroup>

</Project>
5 changes: 5 additions & 0 deletions serilog-extensions-hosting.sln.DotSettings
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<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">
<s:Boolean x:Key="/Default/UserDictionary/Words/=appsettings/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=benaadams/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=destructure/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Serilog/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// Copyright 2019 Serilog Contributors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

using System;
using System.Threading;

namespace Serilog.Extensions.Hosting
{
class AmbientDiagnosticContextCollector : IDisposable
{
static readonly AsyncLocal<AmbientDiagnosticContextCollector> AmbientCollector =
new AsyncLocal<AmbientDiagnosticContextCollector>();

// The indirection here ensures that completing collection cleans up the collector in all
// execution contexts. Via @benaadams' addition to `HttpContextAccessor` :-)
DiagnosticContextCollector _collector;

public static DiagnosticContextCollector Current => AmbientCollector.Value?._collector;

public static DiagnosticContextCollector Begin()
{
var value = new AmbientDiagnosticContextCollector();
value._collector = new DiagnosticContextCollector(value);
AmbientCollector.Value = value;
return value._collector;
}

public void Dispose()
{
_collector = null;
if (AmbientCollector.Value == this)
AmbientCollector.Value = null;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// Copyright 2019 Serilog Contributors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

using System;
using System.Threading;

namespace Serilog.Extensions.Hosting
{
/// <summary>
/// Implements an ambient diagnostic context using <see cref="AsyncLocal{T}"/>.
/// </summary>
/// <remarks>Consumers should use <see cref="IDiagnosticContext"/> to set context properties.</remarks>
public sealed class DiagnosticContext : IDiagnosticContext
{
readonly ILogger _logger;

/// <summary>
/// Construct a <see cref="DiagnosticContext"/>.
/// </summary>
/// <param name="logger">A logger for binding properties in the context, or <c>null</c> to use <see cref="Log.Logger"/>.</param>
public DiagnosticContext(ILogger logger)
{
_logger = logger;
}

/// <summary>
/// Start collecting properties to associate with the current diagnostic context. This will replace
/// the active collector, if any.
/// </summary>
/// <returns>A collector that will receive properties added in the current diagnostic context.</returns>
public DiagnosticContextCollector BeginCollection()
{
return AmbientDiagnosticContextCollector.Begin();
}

/// <inheritdoc cref="IDiagnosticContext.Set"/>
public void Set(string propertyName, object value, bool destructureObjects = false)
{
if (propertyName == null) throw new ArgumentNullException(nameof(propertyName));

var collector = AmbientDiagnosticContextCollector.Current;
if (collector != null &&
(_logger ?? Log.Logger).BindProperty(propertyName, value, destructureObjects, out var property))
{
collector.AddOrUpdate(property);
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
using System;
using System.Collections.Generic;
using Serilog.Events;

namespace Serilog.Extensions.Hosting
{
/// <summary>
/// A container that receives properties added to a diagnostic context.
/// </summary>
public sealed class DiagnosticContextCollector : IDisposable
{
readonly IDisposable _chainedDisposable;
readonly object _propertiesLock = new object();
Dictionary<string, LogEventProperty> _properties = new Dictionary<string, LogEventProperty>();

/// <summary>
/// Construct a <see cref="DiagnosticContextCollector"/>.
/// </summary>
/// <param name="chainedDisposable">An object that will be disposed to signal completion/disposal of
/// the collector.</param>
public DiagnosticContextCollector(IDisposable chainedDisposable)
{
_chainedDisposable = chainedDisposable ?? throw new ArgumentNullException(nameof(chainedDisposable));
}

/// <summary>
/// Add the property to the context.
/// </summary>
/// <param name="property">The property to add.</param>
public void AddOrUpdate(LogEventProperty property)
{
if (property == null) throw new ArgumentNullException(nameof(property));

lock (_propertiesLock)
{
if (_properties == null) return;
_properties[property.Name] = property;
}
}

/// <summary>
/// Complete the context and retrieve the properties added to it, if any. This will
/// stop collection and remove the collector from the original execution context and
/// any of its children.
/// </summary>
/// <param name="properties">The collected properties, or null if no collection is active.</param>
/// <returns>True if properties could be collected.</returns>
public bool TryComplete(out IEnumerable<LogEventProperty> properties)
{
lock (_propertiesLock)
{
properties = _properties?.Values;
_properties = null;
Dispose();
return properties != null;
}
}

/// <inheritdoc/>
public void Dispose()
{
_chainedDisposable.Dispose();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,25 @@
// See the License for the specific language governing permissions and
// limitations under the License.

using System;
using System.ComponentModel;
using Microsoft.Extensions.Logging;
using Serilog.Debugging;
using Serilog.Extensions.Logging;

// To line up with the convention used elsewhere in the *.Extensions libraries, this
// should have been Serilog.Extensions.Hosting.
// ReSharper disable once CheckNamespace
namespace Serilog.Hosting
{
/// <summary>
/// Implements <see cref="ILoggerFactory"/> so that we can inject Serilog Logger.
/// </summary>
[Obsolete("Replaced with Serilog.Extensions.Logging.SerilogLoggerFactory")]
[EditorBrowsable(EditorBrowsableState.Never)]
public class SerilogLoggerFactory : ILoggerFactory
{
private readonly SerilogLoggerProvider _provider;
readonly SerilogLoggerProvider _provider;

/// <summary>
/// Initializes a new instance of the <see cref="SerilogLoggerFactory"/> class.
Expand Down
32 changes: 32 additions & 0 deletions src/Serilog.Extensions.Hosting/IDiagnosticContext.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Copyright 2019 Serilog Contributors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

namespace Serilog
{
/// <summary>
/// Collects diagnostic information for packaging into wide events.
/// </summary>
public interface IDiagnosticContext
{
/// <summary>
/// Set the specified property on the current diagnostic context. The property will be collected
/// and attached to the event emitted at the completion of the context.
/// </summary>
/// <param name="propertyName">The name of the property. Must be non-empty.</param>
/// <param name="value">The property value.</param>
/// <param name="destructureObjects">If true, the value will be serialized as structured
/// data if possible; if false, the object will be recorded as a scalar or simple array.</param>
void Set(string propertyName, object value, bool destructureObjects = false);
}
}
Loading