diff --git a/README.md b/README.md index b2f2def..179683c 100644 --- a/README.md +++ b/README.md @@ -16,17 +16,19 @@ You can get started quickly with this package, and later migrate to the full Ser **1.** Add [the NuGet package](https://nuget.org/packages/serilog.extensions.logging.file) as a dependency of your project either with the package manager or directly to the CSPROJ file: ```xml - + ``` -**2.** In your `Startup` class's `Configure()` method, call `AddFile()` on the provided `loggerFactory`. +**2.** In your `Program` class, configure logging on the web host builder, and call `AddFile()` on the provided `loggingBuilder`. ```csharp - public void Configure(IApplicationBuilder app, - IHostingEnvironment env, - ILoggerFactory loggerFactory) +WebHost.CreateDefaultBuilder(args) + .ConfigureLogging((hostingContext, builder) => { - loggerFactory.AddFile("Logs/myapp-{Date}.txt"); + builder.AddFile("Logs/myapp-{Date}.txt"); + }) + .UseStartup() + .Build(); ``` **Done!** The framework will inject `ILogger` instances into controllers and other classes: @@ -35,12 +37,12 @@ You can get started quickly with this package, and later migrate to the full Ser class HomeController : Controller { readonly ILogger _log; - + public HomeController(ILogger log) { _log = log; } - + public IActionResult Index() { _log.LogInformation("Hello, world!"); @@ -65,12 +67,12 @@ By default, the file will be written in plain text. The fields in the log file a | **Level** | The log level assigned to the event. | Three-character code in brackets | `[INF]` | | **Message** | The log message associated with the event. | Free text | `Hello, world!` | | **Event id** | Identifies messages generated from the same format string/message template. | 32-bit hexadecimal, in parentheses | `(f83bcf75)` | -| **Exception** | Exception associated with the event. | `Exception.ToString()` format (not shown) | `System.DivideByZeroException: Attempt to divide by zero\r\n\ at...` | +| **Exception** | Exception associated with the event. | `Exception.ToString()` format (not shown) | `System.DivideByZeroException: Attempt to divide by zero\r\n\ at...` | To record events in newline-separated JSON instead, specify `isJson: true` when configuring the logger: ```csharp - loggerFactory.AddFile("Logs/myapp-{Date}.txt", isJson: true); +loggingBuilder.AddFile("Logs/myapp-{Date}.txt", isJson: true); ``` This will produce a log file with lines like: @@ -113,12 +115,13 @@ The `AddFile()` method exposes some basic options for controlling the connection | Parameter | Description | Example value | | --------- | ----------- | ------------- | -| `pathFormat` | Filname to write. The filename may include `{Date}` to specify how the date portion of the filename is calculated. May include environment variables.| `Logs/log-{Date}.txt` | +| `pathFormat` | Filename to write. The filename may include `{Date}` to specify how the date portion of the filename is calculated. May include environment variables.| `Logs/log-{Date}.txt` | | `minimumLevel` | The level below which events will be suppressed (the default is `LogLevel.Information`). | `LogLevel.Debug` | | `levelOverrides` | A dictionary mapping logger name prefixes to minimum logging levels. | | | `isJson` | If true, the log file will be written in JSON format. | `true` | | `fileSizeLimitBytes` | The maximum size, in bytes, to which any single log file will be allowed to grow. For unrestricted growth, pass`null`. The default is 1 GiB. | `1024 * 1024 * 1024` | | `retainedFileCountLimit` | The maximum number of log files that will be retained, including the current log file. For unlimited retention, pass `null`. The default is `31`. | `31` | +| `outputTemplate` | The template used for formatting plain text log output. The default is `{Timestamp:o} {RequestId,13} [{Level:u3}] {Message} ({EventId:x8}){NewLine}{Exception}` | `{Timestamp:o} {RequestId,13} [{Level:u3}] {Message} {Properties:j} ({EventId:x8}){NewLine}{Exception}` | ### `appsettings.json` configuration @@ -141,7 +144,7 @@ In `appsettings.json` add a `"Logging"` property: And then pass the configuration section to the `AddFile()` method: ```csharp - loggerFactory.AddFile(Configuration.GetSection("Logging")); +loggingBuilder.AddFile(Configuration.GetSection("Logging")); ``` In addition to the properties shown above, the `"Logging"` configuration supports: @@ -151,10 +154,11 @@ In addition to the properties shown above, the `"Logging"` configuration support | `Json` | If `true`, the log file will be written in JSON format. | `true` | | `FileSizeLimitBytes` | The maximum size, in bytes, to which any single log file will be allowed to grow. For unrestricted growth, pass`null`. The default is 1 GiB. | `1024 * 1024 * 1024` | | `RetainedFileCountLimit` | The maximum number of log files that will be retained, including the current log file. For unlimited retention, pass `null`. The default is `31`. | `31` | +| `OutputTemplate` | The template used for formatting plain text log output. The default is `{Timestamp:o} {RequestId,13} [{Level:u3}] {Message} ({EventId:x8}){NewLine}{Exception}` | `{Timestamp:o} {RequestId,13} [{Level:u3}] {Message} {Properties:j} ({EventId:x8}){NewLine}{Exception}` | ### Using the full Serilog API -This package is opinionated, providing the most common/recommended options supported by Serilog. For more sophisticated configuration, using Serilog directly is recommened. See the instructions in [Serilog.Extensions.Logging](https://github.com/serilog/serilog-extensions-logging) to get started. +This package is opinionated, providing the most common/recommended options supported by Serilog. For more sophisticated configuration, using Serilog directly is recommened. See the instructions in [Serilog.AspNetCore](https://github.com/serilog/serilog-aspnetcore) to get started. The following packages are used to provide `AddFile()`: @@ -163,5 +167,5 @@ The following packages are used to provide `AddFile()`: * [Serilog.Formatting.Compact](https://github.com/serilog/serilog-formatting-compact) - JSON event formatting * [Serilog.Extensions.Logging](https://github.com/serilog/serilog-extensions-logging) - ASP.NET Core integration * [Serilog.Sinks.Async](https://github.com/serilog/serilog-sinks-async) - async wrapper to perform log writes on a background thread - + If you decide to switch to the full Serilog API and need help, please drop into the [Gitter channel](https://gitter.im/serilog/serilog) or post your question on [Stack Overflow](http://stackoverflow.com/questions/tagged/serilog). diff --git a/appveyor.yml b/appveyor.yml index 7df8c2f..e040539 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -10,7 +10,7 @@ artifacts: deploy: - provider: NuGet api_key: - secure: nvZ/z+pMS91b3kG4DgfES5AcmwwGoBYQxr9kp4XiJHj25SAlgdIxFx++1N0lFH2x + secure: T+8ZvBlF6teDbEuPRHVWMkuaU84MAygeuveqR4TqHbcBrW7bBOhtljzUNfiLYjfr skip_symbols: true on: branch: /^(master|dev)$/ diff --git a/example/WebApplication/Controllers/HomeController.cs b/example/WebApplication/Controllers/HomeController.cs index ec9e824..a27c21d 100644 --- a/example/WebApplication/Controllers/HomeController.cs +++ b/example/WebApplication/Controllers/HomeController.cs @@ -1,15 +1,17 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; +using WebApplication.Models; using Microsoft.Extensions.Logging; namespace WebApplication.Controllers { public class HomeController : Controller { - readonly ILogger _log; + private readonly ILogger _log; public HomeController(ILogger log) { @@ -39,7 +41,7 @@ public IActionResult Contact() public IActionResult Error() { - return View(); + return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier }); } } } diff --git a/example/WebApplication/Logs/log-20170630.txt b/example/WebApplication/Logs/log-20170630.txt deleted file mode 100644 index 8afed0e..0000000 --- a/example/WebApplication/Logs/log-20170630.txt +++ /dev/null @@ -1,6 +0,0 @@ -2017-06-30T09:38:55.6849437+10:00 0HL5V900UR4A8 [INF] Request starting HTTP/1.1 DEBUG http://localhost:58951/ 0 (e5be5b71) -2017-06-30T09:38:55.6849437+10:00 0HL5V900UR4A9 [INF] Request starting HTTP/1.1 GET http://localhost:58951/ (e5be5b71) -2017-06-30T09:38:55.8539458+10:00 0HL5V900UR4A8 [INF] Request finished in 184.2573ms 200 (15c52c40) -2017-06-30T09:38:56.3379450+10:00 0HL5V900UR4A9 [INF] Executing action method "WebApplication.Controllers.HomeController.Index (WebApplication)" with arguments (null) - ModelState is Valid (ba7f4ac2) -2017-06-30T09:38:56.3499453+10:00 0HL5V900UR4A9 [INF] Hello, world! (f83bcf75) -2017-06-30T09:38:58.9934553+10:00 0HL5V900UR4A9 [INF] Executing ViewResult, running view at path "/Views/Home/Index.cshtml". (9707eebe) diff --git a/example/WebApplication/Logs/log-20170904.txt b/example/WebApplication/Logs/log-20170904.txt new file mode 100644 index 0000000..0a1b971 --- /dev/null +++ b/example/WebApplication/Logs/log-20170904.txt @@ -0,0 +1,6 @@ +2017-09-04T12:23:39.9205194+02:00 0HL7JFS1C6IAQ:00000001 [INF] Request starting HTTP/1.1 GET http://localhost:52126/ (ca22a1cb) +2017-09-04T12:23:39.9685124+02:00 0HL7JFS1C6IAQ:00000001 [INF] Executing action method "WebApplication.Controllers.HomeController.Index (WebApplication)" with arguments (null) - ModelState is Valid (ba7f4ac2) +2017-09-04T12:23:39.9689269+02:00 0HL7JFS1C6IAQ:00000001 [INF] Hello, world! (f83bcf75) +2017-09-04T12:23:41.5391807+02:00 0HL7JFS1C6IAQ:00000001 [INF] Executing ViewResult, running view at path "/Views/Home/Index.cshtml". (9707eebe) +2017-09-04T12:23:41.7710750+02:00 0HL7JFS1C6IAQ:00000001 [INF] Executed action "WebApplication.Controllers.HomeController.Index (WebApplication)" in 1807.3437ms (afa2e885) +2017-09-04T12:23:41.7735962+02:00 0HL7JFS1C6IAQ:00000001 [INF] Request finished in 1854.3777ms 200 text/html; charset=utf-8 (791a596a) diff --git a/example/WebApplication/Models/ErrorViewModel.cs b/example/WebApplication/Models/ErrorViewModel.cs new file mode 100644 index 0000000..81a8d29 --- /dev/null +++ b/example/WebApplication/Models/ErrorViewModel.cs @@ -0,0 +1,11 @@ +using System; + +namespace WebApplication.Models +{ + public class ErrorViewModel + { + public string RequestId { get; set; } + + public bool ShowRequestId => !string.IsNullOrEmpty(RequestId); + } +} \ No newline at end of file diff --git a/example/WebApplication/Program.cs b/example/WebApplication/Program.cs index 1b2e6d1..b63b019 100644 --- a/example/WebApplication/Program.cs +++ b/example/WebApplication/Program.cs @@ -3,7 +3,10 @@ using System.IO; using System.Linq; using System.Threading.Tasks; +using Microsoft.AspNetCore; using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Logging; namespace WebApplication { @@ -11,14 +14,17 @@ public class Program { public static void Main(string[] args) { - var host = new WebHostBuilder() - .UseKestrel() - .UseContentRoot(Directory.GetCurrentDirectory()) - .UseIISIntegration() + BuildWebHost(args).Run(); + } + + public static IWebHost BuildWebHost(string[] args) => + WebHost.CreateDefaultBuilder(args) + .ConfigureLogging((hostingContext, builder) => + { + var configuration = hostingContext.Configuration.GetSection("Logging"); + builder.AddFile(configuration); + }) .UseStartup() .Build(); - - host.Run(); - } } } diff --git a/example/WebApplication/Project_Readme.html b/example/WebApplication/Project_Readme.html deleted file mode 100644 index 1a0f5b5..0000000 --- a/example/WebApplication/Project_Readme.html +++ /dev/null @@ -1,187 +0,0 @@ - - - - - Welcome to ASP.NET Core - - - - - - - - - - diff --git a/example/WebApplication/Properties/launchSettings.json b/example/WebApplication/Properties/launchSettings.json index 67921e6..b85cf64 100644 --- a/example/WebApplication/Properties/launchSettings.json +++ b/example/WebApplication/Properties/launchSettings.json @@ -3,7 +3,7 @@ "windowsAuthentication": false, "anonymousAuthentication": true, "iisExpress": { - "applicationUrl": "http://localhost:58951/", + "applicationUrl": "http://localhost:52125/", "sslPort": 0 } }, @@ -18,10 +18,10 @@ "WebApplication": { "commandName": "Project", "launchBrowser": true, - "launchUrl": "http://localhost:5000", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" - } + }, + "applicationUrl": "http://localhost:52126/" } } } \ No newline at end of file diff --git a/example/WebApplication/Startup.cs b/example/WebApplication/Startup.cs index 09e198a..88141ff 100644 --- a/example/WebApplication/Startup.cs +++ b/example/WebApplication/Startup.cs @@ -6,43 +6,30 @@ using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Logging; namespace WebApplication { public class Startup { - public Startup(IHostingEnvironment env) + public Startup(IConfiguration configuration) { - var builder = new ConfigurationBuilder() - .SetBasePath(env.ContentRootPath) - .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) - .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true) - .AddEnvironmentVariables(); - Configuration = builder.Build(); + Configuration = configuration; } - public IConfigurationRoot Configuration { get; } + 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) { - // Add framework 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, ILoggerFactory loggerFactory) + public void Configure(IApplicationBuilder app, IHostingEnvironment env) { - // Add a file logger. - loggerFactory.AddFile(Configuration.GetSection("Logging")); - - loggerFactory.AddDebug(); - if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); - app.UseBrowserLink(); } else { diff --git a/example/WebApplication/Views/Home/About.cshtml b/example/WebApplication/Views/Home/About.cshtml index 50476d1..3674e37 100644 --- a/example/WebApplication/Views/Home/About.cshtml +++ b/example/WebApplication/Views/Home/About.cshtml @@ -1,7 +1,7 @@ @{ ViewData["Title"] = "About"; } -

@ViewData["Title"].

+

@ViewData["Title"]

@ViewData["Message"]

Use this area to provide additional information.

diff --git a/example/WebApplication/Views/Home/Contact.cshtml b/example/WebApplication/Views/Home/Contact.cshtml index 15c12c6..a11a186 100644 --- a/example/WebApplication/Views/Home/Contact.cshtml +++ b/example/WebApplication/Views/Home/Contact.cshtml @@ -1,7 +1,7 @@ @{ ViewData["Title"] = "Contact"; } -

@ViewData["Title"].

+

@ViewData["Title"]

@ViewData["Message"]

diff --git a/example/WebApplication/Views/Home/Index.cshtml b/example/WebApplication/Views/Home/Index.cshtml index 3cd243d..00afab6 100644 --- a/example/WebApplication/Views/Home/Index.cshtml +++ b/example/WebApplication/Views/Home/Index.cshtml @@ -15,7 +15,7 @@