diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..b84a08f --- /dev/null +++ b/.gitattributes @@ -0,0 +1,3 @@ +# Auto detect text files and perform LF normalization + +* text=auto diff --git a/Build.ps1 b/Build.ps1 new file mode 100644 index 0000000..41fbf5d --- /dev/null +++ b/Build.ps1 @@ -0,0 +1,56 @@ +echo "build: Build started" + +Push-Location $PSScriptRoot + +if(Test-Path .\artifacts) { + echo "build: Cleaning .\artifacts" + Remove-Item .\artifacts -Force -Recurse +} + +& dotnet restore --no-cache + +$branch = @{ $true = $env:APPVEYOR_REPO_BRANCH; $false = $(git symbolic-ref --short -q HEAD) }[$env:APPVEYOR_REPO_BRANCH -ne $NULL]; +$revision = @{ $true = "{0:00000}" -f [convert]::ToInt32("0" + $env:APPVEYOR_BUILD_NUMBER, 10); $false = "local" }[$env:APPVEYOR_BUILD_NUMBER -ne $NULL]; +$suffix = @{ $true = ""; $false = "$($branch.Substring(0, [math]::Min(10,$branch.Length)))-$revision"}[$branch -eq "master" -and $revision -ne "local"] + +echo "build: Version suffix is $suffix" + +foreach ($src in ls src/*) { + Push-Location $src + + echo "build: Packaging project in $src" + + if($suffix) { + & dotnet pack -c Release --include-source -o ..\..\artifacts --version-suffix=$suffix + } else { + & dotnet pack -c Release --include-source -o ..\..\artifacts + } + + if($LASTEXITCODE -ne 0) { exit 1 } + + Pop-Location +} + +foreach ($test in ls test/*.PerformanceTests) { + Push-Location $test + + echo "build: Building performance test project in $test" + + & dotnet build -c Release + if($LASTEXITCODE -ne 0) { exit 2 } + + Pop-Location +} + +foreach ($test in ls test/*.Tests) { + Push-Location $test + + echo "build: Testing project in $test" + + & dotnet test -c Release + if($LASTEXITCODE -ne 0) { exit 3 } + + Pop-Location +} + +Pop-Location diff --git a/CHANGES.md b/CHANGES.md new file mode 100644 index 0000000..be62715 --- /dev/null +++ b/CHANGES.md @@ -0,0 +1,4 @@ +2.0.0 + + * Initial version for ASP.NET Core 2. + diff --git a/README.md b/README.md index 09d256e..f14822a 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,88 @@ -# serilog-aspnetcore -Serilog integration for ASP.NET Core 2+ +# Serilog.AspNetCore [![Build status](https://ci.appveyor.com/api/projects/status/4rscdto23ik6vm2r?svg=true)](https://ci.appveyor.com/project/serilog/serilog-aspnetcore) [![NuGet Version](http://img.shields.io/nuget/v/Serilog.AspNetCore.svg?style=flat)](https://www.nuget.org/packages/Serilog.AspNetCore/) + + +Serilog logging for ASP.NET Core. This package routes ASP.NET Core log messages through Serilog, so you can get information about ASP.NET's internal operations logged to the same Serilog sinks as your application events. + +### Instructions + +**First**, install the _Serilog.AspNetCore_ [NuGet package](https://www.nuget.org/packages/Serilog.AspNetCore) into your app. You will need a way to view the log messages - _Serilog.Sinks.Console_ writes these to the console; there are [many more sinks available](https://www.nuget.org/packages?q=Tags%3A%22serilog%22) on NuGet. + +```powershell +Install-Package Serilog.AspNetCore -DependencyVersion Highest +Install-Package Serilog.Sinks.Console +``` + +**Next**, in your application's _Program.cs_ file, configure Serilog first: + +```csharp +public class Program +{ + public static int Main(string[] args) + { + Log.Logger = new LoggerConfiguration() + .MinimumLevel.Debug() + .MinimumLevel.Override("Microsoft", LogEventLevel.Information) + .Enrich.FromLogContext() + .WriteTo.Console() + .CreateLogger(); +``` + +Then, add `UseSerilog()` to the web host builder. A `try`/`catch` block will ensure any configuration issues are appropriately logged: + +```csharp + try + { + Log.Information("Starting web host"); + + var host = new WebHostBuilder() + .UseKestrel() + .UseContentRoot(Directory.GetCurrentDirectory()) + .UseIISIntegration() + .UseStartup() + .UseSerilog() // <-- Add this line + .Build(); + + host.Run(); + + return 0; + } + catch (Exception ex) + { + Log.Fatal(ex, "Host terminated unexpectedly"); + return 1; + } + finally + { + Log.CloseAndFlush(); + } + } +} +``` + +**Finally**, clean up by removing the remaining configuration for the default logger: + + * Remove calls to `AddLogging()` + * Remove the `"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-aspnetcore/blob/dev/samples/SimpleWebSample/Program.cs), if required) + * Remove `ILoggerFactory` parameters and any `Add*()` calls on the logger factory in _Startup.cs_ + * Remove `UseApplicationInsights()` (this can be replaced with the [Serilog AI sink](https://github.com/serilog/serilog-sinks-applicationinsights), if required) + +That's it! With the level bumped up a little you will see log output like: + +``` +[22:14:44.646 DBG] RouteCollection.RouteAsync + Routes: + Microsoft.AspNet.Mvc.Routing.AttributeRoute + {controller=Home}/{action=Index}/{id?} + Handled? True +[22:14:44.647 DBG] RouterMiddleware.Invoke + Handled? True +[22:14:45.706 DBG] /lib/jquery/jquery.js not modified +[22:14:45.706 DBG] /css/site.css not modified +[22:14:45.741 DBG] Handled. Status code: 304 File: /css/site.css +``` + +Tip: to see Serilog output in the Visual Studio output window when running under IIS, select _ASP.NET Core Web Server_ from the _Show output from_ drop-down list. + +### Using the package + +With _Serilog.AspNetCore_ installed and configured, you can write log messages directly through Serilog or any `ILogger` interface injected by ASP.NET. All loggers will use the same underlying implementation, levels, and destinations. diff --git a/appveyor.yml b/appveyor.yml new file mode 100644 index 0000000..c13bd52 --- /dev/null +++ b/appveyor.yml @@ -0,0 +1,29 @@ +version: '{build}' +skip_tags: true +image: Visual Studio 2017 Preview +configuration: Release +install: + - ps: mkdir -Force ".\build\" | Out-Null + #- ps: Invoke-WebRequest "https://raw.githubusercontent.com/dotnet/cli/release/2.0.0/scripts/obtain/dotnet-install.ps1" -OutFile ".\build\installcli.ps1" + #- ps: $env:DOTNET_INSTALL_DIR = "$pwd\.dotnetcli" + #- ps: '& .\build\installcli.ps1 -InstallDir "$env:DOTNET_INSTALL_DIR" -NoPath -Version 2.0.0-preview2-006497' + #- ps: $env:Path = "$env:DOTNET_INSTALL_DIR;$env:Path" +build_script: +- ps: ./Build.ps1 +test: off +artifacts: +- path: artifacts/Serilog.*.nupkg +deploy: +- provider: NuGet + api_key: + secure: nvZ/z+pMS91b3kG4DgfES5AcmwwGoBYQxr9kp4XiJHj25SAlgdIxFx++1N0lFH2x + skip_symbols: true + on: + branch: /^(master|dev)$/ +- provider: GitHub + auth_token: + secure: p4LpVhBKxGS5WqucHxFQ5c7C8cP74kbNB0Z8k9Oxx/PMaDQ1+ibmoexNqVU5ZlmX + artifact: /Serilog.*\.nupkg/ + tag: v$(appveyor_build_version) + on: + branch: master diff --git a/assets/Serilog.snk b/assets/Serilog.snk new file mode 100644 index 0000000..6d662e5 Binary files /dev/null and b/assets/Serilog.snk differ diff --git a/build.sh b/build.sh new file mode 100644 index 0000000..433a9b4 --- /dev/null +++ b/build.sh @@ -0,0 +1,11 @@ +#!/bin/bash +dotnet --info +dotnet restore + +for path in src/**/*.csproj; do + dotnet build -f netstandard2.0 -c Release ${path} +done + +for path in test/*.Tests/*.csproj; do + dotnet test -f netcoreapp2.0 -c Release ${path} +done diff --git a/global.json b/global.json new file mode 100644 index 0000000..110af60 --- /dev/null +++ b/global.json @@ -0,0 +1,5 @@ +{ + "sdk": { + "version": "2.0.0" + } +} diff --git a/samples/SimpleWebSample/Controllers/ScopesController.cs b/samples/SimpleWebSample/Controllers/ScopesController.cs new file mode 100644 index 0000000..66d6bbe --- /dev/null +++ b/samples/SimpleWebSample/Controllers/ScopesController.cs @@ -0,0 +1,37 @@ +using System.Collections.Generic; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Logging; + +namespace SimpleWebSample.Controllers +{ + [Route("api/[controller]")] + public class ScopesController : Controller + { + ILogger _logger; + + public ScopesController(ILogger logger) + { + _logger = logger; + } + + // GET api/scopes + [HttpGet] + public IEnumerable Get() + { + _logger.LogInformation("Before"); + + using (_logger.BeginScope("Some name")) + using (_logger.BeginScope(42)) + using (_logger.BeginScope("Formatted {WithValue}", 12345)) + using (_logger.BeginScope(new Dictionary { ["ViaDictionary"] = 100 })) + { + _logger.LogInformation("Hello from the Index!"); + _logger.LogDebug("Hello is done"); + } + + _logger.LogInformation("After"); + + return new string[] { "value1", "value2" }; + } + } +} diff --git a/samples/SimpleWebSample/Controllers/ValuesController.cs b/samples/SimpleWebSample/Controllers/ValuesController.cs new file mode 100644 index 0000000..f14dafc --- /dev/null +++ b/samples/SimpleWebSample/Controllers/ValuesController.cs @@ -0,0 +1,19 @@ +using System.Collections.Generic; +using Microsoft.AspNetCore.Mvc; +using Serilog; + +namespace SimpleWebSample.Controllers +{ + [Route("api/[controller]")] + public class ValuesController : Controller + { + // GET api/values + [HttpGet] + public IEnumerable Get() + { + // Directly through Serilog + Log.Information("This is a handler for {Path}", Request.Path); + return new string[] { "value1", "value2" }; + } + } +} diff --git a/samples/SimpleWebSample/Program.cs b/samples/SimpleWebSample/Program.cs new file mode 100644 index 0000000..e080844 --- /dev/null +++ b/samples/SimpleWebSample/Program.cs @@ -0,0 +1,53 @@ +using System; +using System.IO; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Configuration; +using Serilog; + +namespace SimpleWebSample +{ + public class Program + { + public static int Main(string[] args) + { + var configuration = new ConfigurationBuilder() + .SetBasePath(Directory.GetCurrentDirectory()) + .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true) + .AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Production"}.json", optional: true) + .Build(); + + Log.Logger = new LoggerConfiguration() + .ReadFrom.Configuration(configuration) + .Enrich.FromLogContext() + .WriteTo.Console() + .CreateLogger(); + + try + { + Log.Information("Getting the motors running..."); + + var host = new WebHostBuilder() + .UseKestrel() + .UseContentRoot(Directory.GetCurrentDirectory()) + .UseIISIntegration() + .UseStartup() + .UseConfiguration(configuration) + .UseSerilog() + .Build(); + + host.Run(); + + return 0; + } + catch (Exception ex) + { + Log.Fatal(ex, "Host terminated unexpectedly"); + return 1; + } + finally + { + Log.CloseAndFlush(); + } + } + } +} diff --git a/samples/SimpleWebSample/SimpleWebSample.csproj b/samples/SimpleWebSample/SimpleWebSample.csproj new file mode 100644 index 0000000..9977d79 --- /dev/null +++ b/samples/SimpleWebSample/SimpleWebSample.csproj @@ -0,0 +1,20 @@ + + + netcoreapp2.0 + + + + + + + + + + + + + + + + + diff --git a/samples/SimpleWebSample/Startup.cs b/samples/SimpleWebSample/Startup.cs new file mode 100644 index 0000000..84b2abc --- /dev/null +++ b/samples/SimpleWebSample/Startup.cs @@ -0,0 +1,40 @@ +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; + +namespace SimpleWebSample +{ + public class Startup + { + public Startup(IConfiguration configuration) + { + Configuration = configuration; + } + + public IConfiguration Configuration { get; } + + // This method gets called by the runtime. Use this method to add services to the container. + public void ConfigureServices(IServiceCollection services) + { + services.AddMvc(); + } + + // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. + public void Configure(IApplicationBuilder app, IHostingEnvironment env) + { + if (env.IsDevelopment()) + { + app.UseDeveloperExceptionPage(); + } + + app.UseMvc(); + + app.Run(async (context) => + { + await context.Response.WriteAsync("Hello World!"); + }); + } + } +} diff --git a/samples/SimpleWebSample/appsettings.Development.json b/samples/SimpleWebSample/appsettings.Development.json new file mode 100644 index 0000000..a96c927 --- /dev/null +++ b/samples/SimpleWebSample/appsettings.Development.json @@ -0,0 +1,7 @@ +{ + "Serilog": { + "MinimumLevel": { + "Default": "Debug" + } + } +} diff --git a/samples/SimpleWebSample/appsettings.json b/samples/SimpleWebSample/appsettings.json new file mode 100644 index 0000000..4478f5c --- /dev/null +++ b/samples/SimpleWebSample/appsettings.json @@ -0,0 +1,11 @@ +{ + "Serilog": { + "MinimumLevel": { + "Default": "Debug", + "Override": { + "Microsoft": "Warning", + "System": "Warning" + } + } + } +} diff --git a/serilog-aspnetcore.sln b/serilog-aspnetcore.sln new file mode 100644 index 0000000..3957472 --- /dev/null +++ b/serilog-aspnetcore.sln @@ -0,0 +1,57 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.26730.10 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{A1893BD1-333D-4DFE-A0F0-DDBB2FE526E0}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{E30F638E-BBBE-4AD1-93CE-48CC69CFEFE1}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{F2407211-6043-439C-8E06-3641634332E7}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "assets", "assets", "{9C21B9DF-AEDD-4AA6-BEA4-912DEF3E5B8E}" + ProjectSection(SolutionItems) = preProject + appveyor.yml = appveyor.yml + Build.ps1 = Build.ps1 + global.json = global.json + README.md = README.md + assets\Serilog.snk = assets\Serilog.snk + EndProjectSection +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SimpleWebSample", "samples\SimpleWebSample\SimpleWebSample.csproj", "{69F9A0ED-7910-4F33-8919-28BB05376FBC}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Serilog.AspNetCore", "src\Serilog.AspNetCore\Serilog.AspNetCore.csproj", "{0549D23F-986B-4FB2-BACE-16FD7A7BC9EF}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Serilog.AspNetCore.Tests", "test\Serilog.AspNetCore.Tests\Serilog.AspNetCore.Tests.csproj", "{AD51759B-CD58-473F-9620-0B0E56A123A1}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {69F9A0ED-7910-4F33-8919-28BB05376FBC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {69F9A0ED-7910-4F33-8919-28BB05376FBC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {69F9A0ED-7910-4F33-8919-28BB05376FBC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {69F9A0ED-7910-4F33-8919-28BB05376FBC}.Release|Any CPU.Build.0 = Release|Any CPU + {0549D23F-986B-4FB2-BACE-16FD7A7BC9EF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0549D23F-986B-4FB2-BACE-16FD7A7BC9EF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0549D23F-986B-4FB2-BACE-16FD7A7BC9EF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0549D23F-986B-4FB2-BACE-16FD7A7BC9EF}.Release|Any CPU.Build.0 = Release|Any CPU + {AD51759B-CD58-473F-9620-0B0E56A123A1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AD51759B-CD58-473F-9620-0B0E56A123A1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AD51759B-CD58-473F-9620-0B0E56A123A1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AD51759B-CD58-473F-9620-0B0E56A123A1}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {69F9A0ED-7910-4F33-8919-28BB05376FBC} = {F2407211-6043-439C-8E06-3641634332E7} + {0549D23F-986B-4FB2-BACE-16FD7A7BC9EF} = {A1893BD1-333D-4DFE-A0F0-DDBB2FE526E0} + {AD51759B-CD58-473F-9620-0B0E56A123A1} = {E30F638E-BBBE-4AD1-93CE-48CC69CFEFE1} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {811E61C5-3871-4633-AFAE-B35B619C8A10} + EndGlobalSection +EndGlobal diff --git a/src/Serilog.AspNetCore/AspNetCore/SerilogLoggerFactory.cs b/src/Serilog.AspNetCore/AspNetCore/SerilogLoggerFactory.cs new file mode 100644 index 0000000..ad5af8c --- /dev/null +++ b/src/Serilog.AspNetCore/AspNetCore/SerilogLoggerFactory.cs @@ -0,0 +1,45 @@ +// Copyright 2017 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 Microsoft.Extensions.Logging; +using Serilog.Debugging; +using Serilog.Extensions.Logging; + +namespace Serilog.AspNetCore +{ + class SerilogLoggerFactory : ILoggerFactory + { + readonly SerilogLoggerProvider _provider; + + public SerilogLoggerFactory(Serilog.ILogger logger = null, bool dispose = false) + { + _provider = new SerilogLoggerProvider(logger, dispose); + } + + public void Dispose() + { + _provider.Dispose(); + } + + public Microsoft.Extensions.Logging.ILogger CreateLogger(string categoryName) + { + return _provider.CreateLogger(categoryName); + } + + public void AddProvider(ILoggerProvider provider) + { + SelfLog.WriteLine("Ignoring added logger provider {0}", provider); + } + } +} diff --git a/src/Serilog.AspNetCore/Properties/AssemblyInfo.cs b/src/Serilog.AspNetCore/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..9e85a56 --- /dev/null +++ b/src/Serilog.AspNetCore/Properties/AssemblyInfo.cs @@ -0,0 +1,11 @@ +using System.Reflection; +using System.Runtime.CompilerServices; + +[assembly: AssemblyVersion("2.0.0.0")] + +[assembly: InternalsVisibleTo("Serilog.AspNetCore.Tests, PublicKey=" + + "0024000004800000940000000602000000240000525341310004000001000100fb8d13fd344a1c" + + "6fe0fe83ef33c1080bf30690765bc6eb0df26ebfdf8f21670c64265b30db09f73a0dea5b3db4c9" + + "d18dbf6d5a25af5ce9016f281014d79dc3b4201ac646c451830fc7e61a2dfd633d34c39f87b818" + + "94191652df5ac63cc40c77f3542f702bda692e6e8a9158353df189007a49da0f3cfd55eb250066" + + "b19485ec")] diff --git a/src/Serilog.AspNetCore/Serilog.AspNetCore.csproj b/src/Serilog.AspNetCore/Serilog.AspNetCore.csproj new file mode 100644 index 0000000..f029249 --- /dev/null +++ b/src/Serilog.AspNetCore/Serilog.AspNetCore.csproj @@ -0,0 +1,31 @@ + + + + Serilog support for ASP.NET Core logging + 2.0.0 + Microsoft;Serilog Contributors + netstandard2.0 + true + true + Serilog.AspNetCore + ../../assets/Serilog.snk + true + true + Serilog.AspNetCore + serilog;aspnet;aspnetcore + http://serilog.net/images/serilog-extension-nuget.png + https://github.com/serilog/serilog-aspnetcore + http://www.apache.org/licenses/LICENSE-2.0 + false + Serilog + + + + + + + + + + + diff --git a/src/Serilog.AspNetCore/SerilogWebHostBuilderExtensions.cs b/src/Serilog.AspNetCore/SerilogWebHostBuilderExtensions.cs new file mode 100644 index 0000000..c7a1df1 --- /dev/null +++ b/src/Serilog.AspNetCore/SerilogWebHostBuilderExtensions.cs @@ -0,0 +1,45 @@ +// Copyright 2017 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.AspNetCore.Hosting; +using Microsoft.Extensions.Logging; +using Serilog.AspNetCore; +using Microsoft.Extensions.DependencyInjection; + +namespace Serilog +{ + /// + /// Extends with Serilog configuration methods. + /// + public static class SerilogWebHostBuilderExtensions + { + /// + /// Sets Serilog as the logging provider. + /// + /// The web host builder to configure. + /// The Serilog logger; if not supplied, the static will be used. + /// When true, dispose when the framework disposes the provider. If the + /// logger is not specified but is true, the method will be + /// called on the static class instead. + /// The web host builder. + public static IWebHostBuilder UseSerilog(this IWebHostBuilder builder, Serilog.ILogger logger = null, bool dispose = false) + { + if (builder == null) throw new ArgumentNullException(nameof(builder)); + builder.ConfigureServices(collection => + collection.AddSingleton(new SerilogLoggerFactory(logger, dispose))); + return builder; + } + } +} diff --git a/test/Serilog.AspNetCore.Tests/Serilog.AspNetCore.Tests.csproj b/test/Serilog.AspNetCore.Tests/Serilog.AspNetCore.Tests.csproj new file mode 100644 index 0000000..71b2335 --- /dev/null +++ b/test/Serilog.AspNetCore.Tests/Serilog.AspNetCore.Tests.csproj @@ -0,0 +1,22 @@ + + + + netcoreapp2.0 + Serilog.AspNetCore.Tests + ../../assets/Serilog.snk + true + true + true + + + + + + + + + + + + + diff --git a/test/Serilog.AspNetCore.Tests/SerilogWebHostBuilderExtensionsTests.cs b/test/Serilog.AspNetCore.Tests/SerilogWebHostBuilderExtensionsTests.cs new file mode 100644 index 0000000..6aa9b1f --- /dev/null +++ b/test/Serilog.AspNetCore.Tests/SerilogWebHostBuilderExtensionsTests.cs @@ -0,0 +1,16 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using Xunit; + +namespace Serilog.AspNetCore.Tests +{ + public class SerilogWebHostBuilderExtensionsTests + { + [Fact] + public void Todo() + { + + } + } +} \ No newline at end of file diff --git a/test/Serilog.AspNetCore.Tests/Support/DisposeTrackingLogger.cs b/test/Serilog.AspNetCore.Tests/Support/DisposeTrackingLogger.cs new file mode 100644 index 0000000..70d3ef0 --- /dev/null +++ b/test/Serilog.AspNetCore.Tests/Support/DisposeTrackingLogger.cs @@ -0,0 +1,354 @@ +using System; +using System.Collections.Generic; +using Serilog.Core; +using Serilog.Events; + +namespace Serilog.AspNetCore.Tests.Support +{ + public class DisposeTrackingLogger : ILogger, IDisposable + { + public bool IsDisposed { get; set; } + + public ILogger ForContext(ILogEventEnricher enricher) + { + return new LoggerConfiguration().CreateLogger(); + } + + public ILogger ForContext(IEnumerable enrichers) + { + return new LoggerConfiguration().CreateLogger(); + } + + public ILogger ForContext(string propertyName, object value, bool destructureObjects = false) + { + return new LoggerConfiguration().CreateLogger(); + } + + public ILogger ForContext() + { + return new LoggerConfiguration().CreateLogger(); + } + + public ILogger ForContext(Type source) + { + return new LoggerConfiguration().CreateLogger(); + } + + public void Write(LogEvent logEvent) + { + } + + public void Write(LogEventLevel level, string messageTemplate) + { + } + + public void Write(LogEventLevel level, string messageTemplate, T propertyValue) + { + } + + public void Write(LogEventLevel level, string messageTemplate, T0 propertyValue0, T1 propertyValue1) + { + } + + public void Write(LogEventLevel level, string messageTemplate, T0 propertyValue0, T1 propertyValue1, + T2 propertyValue2) + { + } + + public void Write(LogEventLevel level, string messageTemplate, params object[] propertyValues) + { + } + + public void Write(LogEventLevel level, Exception exception, string messageTemplate) + { + } + + public void Write(LogEventLevel level, Exception exception, string messageTemplate, T propertyValue) + { + } + + public void Write(LogEventLevel level, Exception exception, string messageTemplate, T0 propertyValue0, + T1 propertyValue1) + { + } + + public void Write(LogEventLevel level, Exception exception, string messageTemplate, T0 propertyValue0, + T1 propertyValue1, T2 propertyValue2) + { + } + + public void Write(LogEventLevel level, Exception exception, string messageTemplate, params object[] propertyValues) + { + } + + public bool IsEnabled(LogEventLevel level) + { + return false; + } + + public void Verbose(string messageTemplate) + { + } + + public void Verbose(string messageTemplate, T propertyValue) + { + } + + public void Verbose(string messageTemplate, T0 propertyValue0, T1 propertyValue1) + { + } + + public void Verbose(string messageTemplate, T0 propertyValue0, T1 propertyValue1, T2 propertyValue2) + { + } + + public void Verbose(string messageTemplate, params object[] propertyValues) + { + } + + public void Verbose(Exception exception, string messageTemplate) + { + } + + public void Verbose(Exception exception, string messageTemplate, T propertyValue) + { + } + + public void Verbose(Exception exception, string messageTemplate, T0 propertyValue0, T1 propertyValue1) + { + } + + public void Verbose(Exception exception, string messageTemplate, T0 propertyValue0, T1 propertyValue1, + T2 propertyValue2) + { + } + + public void Verbose(Exception exception, string messageTemplate, params object[] propertyValues) + { + } + + public void Debug(string messageTemplate) + { + } + + public void Debug(string messageTemplate, T propertyValue) + { + } + + public void Debug(string messageTemplate, T0 propertyValue0, T1 propertyValue1) + { + } + + public void Debug(string messageTemplate, T0 propertyValue0, T1 propertyValue1, T2 propertyValue2) + { + } + + public void Debug(string messageTemplate, params object[] propertyValues) + { + } + + public void Debug(Exception exception, string messageTemplate) + { + } + + public void Debug(Exception exception, string messageTemplate, T propertyValue) + { + } + + public void Debug(Exception exception, string messageTemplate, T0 propertyValue0, T1 propertyValue1) + { + } + + public void Debug(Exception exception, string messageTemplate, T0 propertyValue0, T1 propertyValue1, + T2 propertyValue2) + { + } + + public void Debug(Exception exception, string messageTemplate, params object[] propertyValues) + { + } + + public void Information(string messageTemplate) + { + } + + public void Information(string messageTemplate, T propertyValue) + { + } + + public void Information(string messageTemplate, T0 propertyValue0, T1 propertyValue1) + { + } + + public void Information(string messageTemplate, T0 propertyValue0, T1 propertyValue1, T2 propertyValue2) + { + } + + public void Information(string messageTemplate, params object[] propertyValues) + { + } + + public void Information(Exception exception, string messageTemplate) + { + } + + public void Information(Exception exception, string messageTemplate, T propertyValue) + { + } + + public void Information(Exception exception, string messageTemplate, T0 propertyValue0, T1 propertyValue1) + { + } + + public void Information(Exception exception, string messageTemplate, T0 propertyValue0, T1 propertyValue1, + T2 propertyValue2) + { + } + + public void Information(Exception exception, string messageTemplate, params object[] propertyValues) + { + } + + public void Warning(string messageTemplate) + { + } + + public void Warning(string messageTemplate, T propertyValue) + { + } + + public void Warning(string messageTemplate, T0 propertyValue0, T1 propertyValue1) + { + } + + public void Warning(string messageTemplate, T0 propertyValue0, T1 propertyValue1, T2 propertyValue2) + { + } + + public void Warning(string messageTemplate, params object[] propertyValues) + { + } + + public void Warning(Exception exception, string messageTemplate) + { + } + + public void Warning(Exception exception, string messageTemplate, T propertyValue) + { + } + + public void Warning(Exception exception, string messageTemplate, T0 propertyValue0, T1 propertyValue1) + { + } + + public void Warning(Exception exception, string messageTemplate, T0 propertyValue0, T1 propertyValue1, + T2 propertyValue2) + { + } + + public void Warning(Exception exception, string messageTemplate, params object[] propertyValues) + { + } + + public void Error(string messageTemplate) + { + } + + public void Error(string messageTemplate, T propertyValue) + { + } + + public void Error(string messageTemplate, T0 propertyValue0, T1 propertyValue1) + { + } + + public void Error(string messageTemplate, T0 propertyValue0, T1 propertyValue1, T2 propertyValue2) + { + } + + public void Error(string messageTemplate, params object[] propertyValues) + { + } + + public void Error(Exception exception, string messageTemplate) + { + } + + public void Error(Exception exception, string messageTemplate, T propertyValue) + { + } + + public void Error(Exception exception, string messageTemplate, T0 propertyValue0, T1 propertyValue1) + { + } + + public void Error(Exception exception, string messageTemplate, T0 propertyValue0, T1 propertyValue1, + T2 propertyValue2) + { + } + + public void Error(Exception exception, string messageTemplate, params object[] propertyValues) + { + } + + public void Fatal(string messageTemplate) + { + } + + public void Fatal(string messageTemplate, T propertyValue) + { + } + + public void Fatal(string messageTemplate, T0 propertyValue0, T1 propertyValue1) + { + } + + public void Fatal(string messageTemplate, T0 propertyValue0, T1 propertyValue1, T2 propertyValue2) + { + } + + public void Fatal(string messageTemplate, params object[] propertyValues) + { + } + + public void Fatal(Exception exception, string messageTemplate) + { + } + + public void Fatal(Exception exception, string messageTemplate, T propertyValue) + { + } + + public void Fatal(Exception exception, string messageTemplate, T0 propertyValue0, T1 propertyValue1) + { + } + + public void Fatal(Exception exception, string messageTemplate, T0 propertyValue0, T1 propertyValue1, + T2 propertyValue2) + { + } + + public void Fatal(Exception exception, string messageTemplate, params object[] propertyValues) + { + } + + public bool BindMessageTemplate(string messageTemplate, object[] propertyValues, out MessageTemplate parsedTemplate, + out IEnumerable boundProperties) + { + parsedTemplate = null; + boundProperties = null; + return false; + } + + public bool BindProperty(string propertyName, object value, bool destructureObjects, out LogEventProperty property) + { + property = null; + return false; + } + + public void Dispose() + { + IsDisposed = true; + } + } +} diff --git a/test/Serilog.AspNetCore.Tests/Support/SerilogSink.cs b/test/Serilog.AspNetCore.Tests/Support/SerilogSink.cs new file mode 100644 index 0000000..5af3d36 --- /dev/null +++ b/test/Serilog.AspNetCore.Tests/Support/SerilogSink.cs @@ -0,0 +1,19 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Collections.Generic; +using Serilog.Core; +using Serilog.Events; + +namespace Serilog.AspNetCore.Tests.Support +{ + public class SerilogSink : ILogEventSink + { + public List Writes { get; set; } = new List(); + + public void Emit(LogEvent logEvent) + { + Writes.Add(logEvent); + } + } +} \ No newline at end of file