Skip to content

Commit

Permalink
Feature - clear logger providers except functions extension (#134)
Browse files Browse the repository at this point in the history
* Feature - clear logger providers except functions

* pr-sug: update docs w/ created project
  • Loading branch information
stijnmoreels authored Jul 8, 2020
1 parent 8594c34 commit 3eec37f
Show file tree
Hide file tree
Showing 9 changed files with 203 additions and 2 deletions.
4 changes: 2 additions & 2 deletions docs/preview/guidance/use-with-dotnet-and-functions.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,13 @@ Using Serilog with Azure Functions requires some guidance and we've made it a bi
Before we get started, install our NuGet package for Azure Functions:

```
PM > TODO @stijnmoreels
PM > Install-Package -Name Arcus.Observability.Telemetry.AzureFunctions
```

Once that is done, you can configure Serilog during startup as following:

```csharp
using Arcus.TODO.@stijnmoreels;
using Microsoft.Extensions.Logging;

[assembly: FunctionsStartup(typeof(Startup))]
namespace Arcus.Samples.AzureFunction
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>netstandard2.0;netcoreapp3.1</TargetFrameworks>
<Authors>Arcus</Authors>
<Company>Arcus</Company>
<Description>Provides capability to improve telemetry with Serilog in Azure Functions applications</Description>
<Copyright>Copyright (c) Arcus</Copyright>
<PackageLicenseUrl>https://github.com/arcus-azure/arcus.observability/blob/master/LICENSE</PackageLicenseUrl>
<PackageProjectUrl>https://github.com/arcus-azure/arcus.observability</PackageProjectUrl>
<PackageIconUrl>https://raw.githubusercontent.com/arcus-azure/arcus/master/media/arcus.png</PackageIconUrl>
<RepositoryUrl>https://github.com/arcus-azure/arcus.observability</RepositoryUrl>
<RepositoryType>Git</RepositoryType>
<PackageTags>Azure;Observability;Telemetry;Azure Functions</PackageTags>
<PackageId>Arcus.Observability.Telemetry.AzureFunctions</PackageId>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
</PropertyGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'netcoreapp3.1'">
<FrameworkReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>

<ItemGroup Condition="'$(TargetFramework)' != 'netcoreapp3.1'">
<PackageReference Include="Microsoft.Extensions.Logging" Version="2.2.0" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Guard.Net" Version="1.2.0" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
using GuardNet;
using Microsoft.Extensions.DependencyInjection;

// ReSharper disable once CheckNamespace
namespace Microsoft.Extensions.Logging
{
/// <summary>
/// <see cref="ILoggingBuilder"/> extensions related to Azure Functions projects.
/// </summary>
// ReSharper disable once InconsistentNaming
public static class ILoggingBuilderExtensions
{
/// <summary>
/// Clears the <see cref="ILoggerProvider"/> registrations from the given <paramref name="loggingBuilder"/>,
/// except the specific Azure Functions registrations.
/// </summary>
/// <param name="loggingBuilder">The builder containing the <see cref="ILoggerProvider"/> registrations.</param>
public static ILoggingBuilder ClearProvidersExceptFunctionProviders(this ILoggingBuilder loggingBuilder)
{
Guard.NotNull(loggingBuilder, nameof(loggingBuilder));

// Kudos to katrash: https://stackoverflow.com/questions/45986517/remove-console-and-debug-loggers-in-asp-net-core-2-0-when-in-production-mode
foreach (ServiceDescriptor serviceDescriptor in loggingBuilder.Services)
{
if (serviceDescriptor.ServiceType == typeof(ILoggerProvider))
{
if (serviceDescriptor.ImplementationType.FullName != "Microsoft.Azure.WebJobs.Script.Diagnostics.HostFileLoggerProvider"
&& serviceDescriptor.ImplementationType.FullName != "Microsoft.Azure.WebJobs.Script.Diagnostics.FunctionFileLoggerProvider")
{
loggingBuilder.Services.Remove(serviceDescriptor);
break;
}
}
}

return loggingBuilder;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
<ItemGroup>
<ProjectReference Include="..\Arcus.Observability.Correlation\Arcus.Observability.Correlation.csproj" />
<ProjectReference Include="..\Arcus.Observability.Telemetry.IoT\Arcus.Observability.Telemetry.IoT.csproj" />
<ProjectReference Include="..\Arcus.Observability.Telemetry.AzureFunctions\Arcus.Observability.Telemetry.AzureFunctions.csproj" />
<ProjectReference Include="..\Arcus.Observability.Telemetry.Serilog.Filters\Arcus.Observability.Telemetry.Serilog.Filters.csproj" />
<ProjectReference Include="..\Arcus.Observability.Telemetry.Serilog.Sinks.ApplicationInsights\Arcus.Observability.Telemetry.Serilog.Sinks.ApplicationInsights.csproj" />
<ProjectReference Include="..\Arcus.Observability.Telemetry.Serilog.Enrichers\Arcus.Observability.Telemetry.Serilog.Enrichers.csproj" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Extensions.Logging;

// ReSharper disable once CheckNamespace
namespace Microsoft.Azure.WebJobs.Script.Diagnostics
{
/// <summary>
/// <see cref="ILoggerProvider"/> to verify if the surrogate of the real provider doesn't get removed.
/// </summary>
public class FunctionFileLoggerProvider : ILoggerProvider
{
/// <summary>
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
/// </summary>
public void Dispose()
{
throw new NotImplementedException();
}

/// <summary>
/// Creates a new <see cref="T:Microsoft.Extensions.Logging.ILogger" /> instance.
/// </summary>
/// <param name="categoryName">The category name for messages produced by the logger.</param>
/// <returns>The instance of <see cref="T:Microsoft.Extensions.Logging.ILogger" /> that was created.</returns>
public ILogger CreateLogger(string categoryName)
{
throw new NotImplementedException();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using System;
using Microsoft.Extensions.Logging;

// ReSharper disable once CheckNamespace
namespace Microsoft.Azure.WebJobs.Script.Diagnostics
{
/// <summary>
/// <see cref="ILoggerProvider"/> to verify if the surrogate of the real provider doesn't get removed.
/// </summary>
public class HostFileLoggerProvider : ILoggerProvider
{
/// <summary>
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
/// </summary>
public void Dispose()
{
throw new NotImplementedException();
}

/// <summary>
/// Creates a new <see cref="T:Microsoft.Extensions.Logging.ILogger" /> instance.
/// </summary>
/// <param name="categoryName">The category name for messages produced by the logger.</param>
/// <returns>The instance of <see cref="T:Microsoft.Extensions.Logging.ILogger" /> that was created.</returns>
public ILogger CreateLogger(string categoryName)
{
throw new NotImplementedException();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Extensions.Logging;

namespace Arcus.Observability.Tests.Unit.Telemetry.AzureFunctions.Fixture
{
/// <summary>
/// <see cref="ILoggerProvider"/> implementation to verify if the provider gets removed during the <see cref="ILoggerBuilderExtensionsTests"/>.
/// </summary>
public class TestLoggerProvider : ILoggerProvider
{
/// <summary>Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.</summary>
public void Dispose()
{
throw new NotImplementedException();
}

/// <summary>
/// Creates a new <see cref="T:Microsoft.Extensions.Logging.ILogger" /> instance.
/// </summary>
/// <param name="categoryName">The category name for messages produced by the logger.</param>
/// <returns>The instance of <see cref="T:Microsoft.Extensions.Logging.ILogger" /> that was created.</returns>
public ILogger CreateLogger(string categoryName)
{
throw new NotImplementedException();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using Arcus.Observability.Tests.Unit.Telemetry.AzureFunctions.Fixture;
using Microsoft.Azure.WebJobs.Script.Diagnostics;
using Microsoft.Extensions.DependencyInjection;
using Moq;
using Microsoft.Extensions.Logging;
using Xunit;

namespace Arcus.Observability.Tests.Unit.Telemetry.AzureFunctions
{
public class ILoggerBuilderExtensionsTests
{
[Fact]
public void ClearProvidersExceptFunctions_WithLoggerBuilderContainingProviders_RemovesNonFunctionProviders()
{
// Arrange
var services = new ServiceCollection();
services.AddSingleton<ILoggerProvider, HostFileLoggerProvider>();
services.AddSingleton<ILoggerProvider, FunctionFileLoggerProvider>();
services.AddSingleton<ILoggerProvider, TestLoggerProvider>();
var builder = new Mock<ILoggingBuilder>();
builder.Setup(b => b.Services).Returns(services);

// Act
builder.Object.ClearProvidersExceptFunctionProviders();

// Assert
Assert.NotEmpty(services);
Assert.Equal(2, services.Count);
Assert.All(services, desc => Assert.NotEqual(typeof(TestLoggerProvider), desc.ImplementationType));
}
}
}
6 changes: 6 additions & 0 deletions src/Arcus.Observability.sln
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Arcus.Observability.Tests.C
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Arcus.Observability.Telemetry.IoT", "Arcus.Observability.Telemetry.IoT\Arcus.Observability.Telemetry.IoT.csproj", "{E4A6624B-C1A4-4956-9FC2-E77D6C634717}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Arcus.Observability.Telemetry.AzureFunctions", "Arcus.Observability.Telemetry.AzureFunctions\Arcus.Observability.Telemetry.AzureFunctions.csproj", "{C6C0ED5D-94B4-4CD2-B17A-E72432AC4883}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -65,6 +67,10 @@ Global
{E4A6624B-C1A4-4956-9FC2-E77D6C634717}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E4A6624B-C1A4-4956-9FC2-E77D6C634717}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E4A6624B-C1A4-4956-9FC2-E77D6C634717}.Release|Any CPU.Build.0 = Release|Any CPU
{C6C0ED5D-94B4-4CD2-B17A-E72432AC4883}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C6C0ED5D-94B4-4CD2-B17A-E72432AC4883}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C6C0ED5D-94B4-4CD2-B17A-E72432AC4883}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C6C0ED5D-94B4-4CD2-B17A-E72432AC4883}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down

0 comments on commit 3eec37f

Please sign in to comment.