Skip to content

Adds SerilogServiceCollectionExtensions #19

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

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
52 changes: 9 additions & 43 deletions src/Serilog.Extensions.Hosting/SerilogHostBuilderExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.DependencyInjection;
using Serilog.Extensions.Hosting;
using Serilog.Extensions.Logging;

namespace Serilog
{

Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change

/// <summary>
/// Extends <see cref="IHostBuilder"/> with Serilog configuration methods.
/// </summary>
Expand All @@ -39,33 +39,17 @@ public static class SerilogHostBuilderExtensions
/// default, only Serilog sinks will receive events.</param>
/// <returns>The host builder.</returns>
public static IHostBuilder UseSerilog(
this IHostBuilder builder,
ILogger logger = null,
this IHostBuilder builder,
ILogger logger = null,
bool dispose = false,
LoggerProviderCollection providers = null)
{
if (builder == null) throw new ArgumentNullException(nameof(builder));

builder.ConfigureServices((_, collection) =>
{
if (providers != null)
{
collection.AddSingleton<ILoggerFactory>(services =>
{
var factory = new SerilogLoggerFactory(logger, dispose, providers);

foreach (var provider in services.GetServices<ILoggerProvider>())
factory.AddProvider(provider);

return factory;
});
}
else
{
collection.AddSingleton<ILoggerFactory>(services => new SerilogLoggerFactory(logger, dispose));
}

ConfigureServices(collection, logger);
collection.AddSerilogLoggerFactory(logger, dispose, providers);
collection.AddSerilogServices(logger);
});

return builder;
Expand All @@ -91,7 +75,7 @@ public static IHostBuilder UseSerilog(
{
if (builder == null) throw new ArgumentNullException(nameof(builder));
if (configureLogger == null) throw new ArgumentNullException(nameof(configureLogger));

builder.ConfigureServices((context, collection) =>
{
var loggerConfiguration = new LoggerConfiguration();
Expand All @@ -105,7 +89,7 @@ public static IHostBuilder UseSerilog(

configureLogger(context, loggerConfiguration);
var logger = loggerConfiguration.CreateLogger();

ILogger registeredLogger = null;
if (preserveStaticLogger)
{
Expand All @@ -131,29 +115,11 @@ public static IHostBuilder UseSerilog(
return factory;
});

ConfigureServices(collection, logger);
collection.AddSerilogServices(logger);
});
return builder;
}

static void ConfigureServices(IServiceCollection collection, ILogger logger)
{
if (collection == null) throw new ArgumentNullException(nameof(collection));

if (logger != null)
{
// This won't (and shouldn't) take ownership of the logger.
collection.AddSingleton(logger);
}

// Registered to provide two services...
var diagnosticContext = new DiagnosticContext(logger);

// Consumed by e.g. middleware
collection.AddSingleton(diagnosticContext);

// Consumed by user code
collection.AddSingleton<IDiagnosticContext>(diagnosticContext);
}

Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
// 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 Microsoft.Extensions.Logging;
using Microsoft.Extensions.DependencyInjection;
using Serilog.Extensions.Hosting;
using Serilog.Extensions.Logging;

namespace Serilog
{
/// <summary>
/// Extends <see cref="IServiceCollection"/> with Serilog configuration methods.
/// </summary>
public static class SerilogServiceCollectionExtensions
{
/// <summary>
/// Configures the <see cref="ILoggerFactory"/> to use the <see cref="SerilogLoggerFactory"/>
/// </summary>
/// <param name="collection">The service collection to configure.</param>
/// <param name="logger">The Serilog logger; if not supplied, the static <see cref="Serilog.Log"/> will be used.</param>
/// <param name="dispose">When <c>true</c>, dispose <paramref name="logger"/> when the framework disposes the provider. If the
/// logger is not specified but <paramref name="dispose"/> is <c>true</c>, the <see cref="Log.CloseAndFlush()"/> method will be
/// called on the static <see cref="Log"/> class instead.</param>
/// <param name="providers">A <see cref="LoggerProviderCollection"/> registered in the Serilog pipeline using the
/// <c>WriteTo.Providers()</c> configuration method, enabling other <see cref="ILoggerProvider"/>s to receive events. By
/// default, only Serilog sinks will receive events.</param>
/// <returns>The service collection.</returns>
public static IServiceCollection AddSerilogLoggerFactory(
this IServiceCollection collection,
ILogger logger,
bool dispose,
LoggerProviderCollection providers = null)
{
if (collection == null) throw new ArgumentNullException(nameof(collection));

if (providers != null)
{
collection.AddSingleton<ILoggerFactory>(services =>
Copy link
Contributor

Choose a reason for hiding this comment

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

@Shazwazza @nblumhardt do you mind renaming IServiceCollection collection to IServiceCollection services and services (IServiceProvider arg) to provider ? The current naming is confusing.

{
var factory = new SerilogLoggerFactory(logger, dispose, providers);

foreach (var provider in services.GetServices<ILoggerProvider>())
factory.AddProvider(provider);

return factory;
});
}
else
{
collection.AddSingleton<ILoggerFactory>(services => new SerilogLoggerFactory(logger, dispose));
}

return collection;
}

/// <summary>
/// Adds required Serilog services to the <see cref="IServiceCollection"/>
/// </summary>
/// <param name="collection"></param>
/// <param name="logger"></param>
/// <returns>The service collection.</returns>
public static IServiceCollection AddSerilogServices(this IServiceCollection collection, ILogger logger)
{
if (collection == null) throw new ArgumentNullException(nameof(collection));

if (logger != null)
{
// This won't (and shouldn't) take ownership of the logger.
collection.AddSingleton(logger);
}

// Registered to provide two services...
var diagnosticContext = new DiagnosticContext(logger);

// Consumed by e.g. middleware
collection.AddSingleton(diagnosticContext);

// Consumed by user code
collection.AddSingleton<IDiagnosticContext>(diagnosticContext);

return collection;
}
}
}