|
1 |
| -# serilog-extensions-logging-file |
2 |
| -Add file logging to ASP.NET Core apps in one line of code. |
| 1 | +# Serilog.Extensions.Logging.File [](https://nuget.org/packages/Serilog.Extensions.Logging.File) [](https://gitter.im/serilog/serilog) [](https://ci.appveyor.com/project/serilog/serilog-extensions-logging-file) |
| 2 | + |
| 3 | +This package makes it a one-liner - `loggerFactory.AddFile()` - to configure top-quality file logging for ASP.NET Core apps. |
| 4 | + |
| 5 | + * Text or JSON file output |
| 6 | + * Files roll over on date; capped file size |
| 7 | + * Request ids and event ids included with each message |
| 8 | + * Writes are performed on a background thread |
| 9 | + * Files are periodically flushed to disk (required for Azure App Service log collection) |
| 10 | + * Fast, stable, battle-proven logging code courtesy of [Serilog](https://serilog.net) |
| 11 | + |
| 12 | +You can get started quickly with this package, and later migrate to the full Serilog API if you need more sophisticated log file configuration. |
| 13 | + |
| 14 | +### Getting started |
| 15 | + |
| 16 | +**1.** Add [the NuGet package](https://nuget.org/packages/serilog.extensions.logging.file) to the `"dependencies"` section of your `project.json` file: |
| 17 | + |
| 18 | +```json |
| 19 | + "dependencies": { |
| 20 | + "Serilog.Extensions.Logging.File": "1.0.0" |
| 21 | + } |
| 22 | +``` |
| 23 | + |
| 24 | +**2.** In your `Startup` class's `Configure()` method, call `AddFile()` on the provided `loggerFactory`. |
| 25 | + |
| 26 | +```csharp |
| 27 | + public void Configure(IApplicationBuilder app, |
| 28 | + IHostingEnvironment env, |
| 29 | + ILoggerFactory loggerFactory) |
| 30 | + { |
| 31 | + loggerFactory.AddFile("Logs/myapp-{Date}.txt"); |
| 32 | +``` |
| 33 | + |
| 34 | +**Done!** The framework will inject `ILogger` instances into controllers and other classes: |
| 35 | + |
| 36 | +```csharp |
| 37 | +class HomeController : Controller |
| 38 | +{ |
| 39 | + readonly ILogger<HomeController> _log; |
| 40 | + |
| 41 | + public HomeController(ILogger<HomeController> log) |
| 42 | + { |
| 43 | + _log = log; |
| 44 | + } |
| 45 | + |
| 46 | + public IActionResult Index() |
| 47 | + { |
| 48 | + _log.LogInformation("Hello, world!"); |
| 49 | + } |
| 50 | +} |
| 51 | +``` |
| 52 | + |
| 53 | +The events will appear in the log file: |
| 54 | + |
| 55 | +``` |
| 56 | +2016-10-18T11:14:11.0881912+10:00 0HKVMUG8EMJO9 [INF] Hello, world! (f83bcf75) |
| 57 | +``` |
| 58 | + |
| 59 | +### File format |
| 60 | + |
| 61 | +By default, the file will be written in plain text. The fields in the log file are: |
| 62 | + |
| 63 | +| Field | Description | Format | Example | |
| 64 | +| ----- | ----------- | ------ | ------- | |
| 65 | +| **Timestamp** | The time the event occurred. | ISO-8601 with offset | `2016-10-18T11:14:11.0881912+10:00` | |
| 66 | +| **Request id** | Uniquely identifies all messages raised during a single web request. | Alphanumeric | `0HKVMUG8EMJO9` | |
| 67 | +| **Level** | The log level assigned to the event. | Three-character code in brackets | `[INF]` | |
| 68 | +| **Message** | The log message associated with the event. | Free text | `Hello, world!` | |
| 69 | +| **Event id** | Identifies messages generated from the same format string/message template. | 32-bit hexadecimal, in parentheses | `(f83bcf75)` | |
| 70 | +| **Exception** | Exception associated with the event. | `Exception.ToString()` format (not shown) | `System.DivideByZeroException: Attempt to divide by zero\r\n\ at...` | |
| 71 | + |
| 72 | +To record events in newline-separated JSON instead, specify `isJson: true` when configuring the logger: |
| 73 | + |
| 74 | +```csharp |
| 75 | + loggerFactory.AddFile("Logs/myapp-{Date}.txt", isJson: true); |
| 76 | +``` |
| 77 | + |
| 78 | +This will produce a log file with lines like: |
| 79 | + |
| 80 | +```json |
| 81 | +{"@t":"2016-06-07T03:44:57.8532799Z","@m":"Hello, world!","@i":"f83bcf75","RequestId":"0HKVMUG8EMJO9"} |
| 82 | +``` |
| 83 | + |
| 84 | +The JSON document includes all properties associated with the event, not just those present in the message. This makes JSON formatted logs a better choice for offline analysis in many cases. |
| 85 | + |
| 86 | +### Rolling |
| 87 | + |
| 88 | +The filename provided to `AddFile()` should include the `{Date}` placeholder, which will be replaced with the date of the events contained in the file. Filenames use the `yyyyMMdd` date format so that files can be ordered using a lexicographic sort: |
| 89 | + |
| 90 | +``` |
| 91 | +log-20160631.txt |
| 92 | +log-20160701.txt |
| 93 | +log-20160702.txt |
| 94 | +``` |
| 95 | + |
| 96 | +To prevent outages due to disk space exhaustion, each file is capped to 1 GB in size. If the file size is exceeded, events will be dropped until the next roll point. |
| 97 | + |
| 98 | +### Message templates and event ids |
| 99 | + |
| 100 | +The provider supports the templated log messages used by _Microsoft.Extensions.Logging_. By writing events with format strings or [message templates](https://messagetemplates.org), the provider can infer which messages came from the same logging statement. |
| 101 | +
|
| 102 | +This means that although the text of two messages may be different, their **event id** fields will match, as shown by the two "view" logging statements below: |
| 103 | + |
| 104 | +``` |
| 105 | +2016-10-18T11:14:26.2544709+10:00 0HKVMUG8EMJO9 [INF] Running view at "/Views/Home/About.cshtml". (9707eebe) |
| 106 | +2016-10-18T11:14:11.0881912+10:00 0HKVMUG8EMJO9 [INF] Hello, world! (f83bcf75) |
| 107 | +2016-10-18T11:14:26.2544709+10:00 0HKVMUG8EMJO9 [INF] Running view at "/Views/Home/Index.cshtml". (9707eebe) |
| 108 | +``` |
| 109 | + |
| 110 | +Each log message describing view rendering is tagged with `(9707eebe)`, while the "hello" log message is given `(f83bcf75)`. This makes it easy to search the log for messages describing the same kind of event. |
| 111 | + |
| 112 | +### Additional configuration |
| 113 | + |
| 114 | +The `AddFile()` method exposes some basic options for controlling the connection and log volume. |
| 115 | + |
| 116 | +| Parameter | Description | Example value | |
| 117 | +| --------- | ----------- | ------------- | |
| 118 | +| `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` | |
| 119 | +| `minimumLevel` | The level below which events will be suppressed (the default is `LogLevel.Information`). | `LogLevel.Debug` | |
| 120 | +| `levelOverrides` | A dictionary mapping logger name prefixes to minimum logging levels. | | |
| 121 | +| `isJson` | If true, the log file will be written in JSON format. | `true` | |
| 122 | +| `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` | |
| 123 | +| `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` | |
| 124 | + |
| 125 | +### `appsettings.json` configuration |
| 126 | + |
| 127 | +The file path and other settings can be read from JSON configuration if desired. |
| 128 | + |
| 129 | +In `appsettings.json` add a `"Logging"` property: |
| 130 | + |
| 131 | +```json |
| 132 | +{ |
| 133 | + "Logging": { |
| 134 | + "PathFormat": "Logs/log-{Date}.txt", |
| 135 | + "LogLevel": { |
| 136 | + "Default": "Debug", |
| 137 | + "Microsoft": "Information" |
| 138 | + } |
| 139 | + } |
| 140 | +} |
| 141 | +``` |
| 142 | + |
| 143 | +And then pass the configuration section to the `AddFile()` method: |
| 144 | + |
| 145 | +```csharp |
| 146 | + loggerFactory.AddFile(Configuration.GetSection("Logging")); |
| 147 | +``` |
| 148 | + |
| 149 | +In addition to the properties shown above, the `"Logging"` configuration supports: |
| 150 | + |
| 151 | +| Property | Description | Example | |
| 152 | +| -------- | ----------- | ------- | |
| 153 | +| `Json` | If `true`, the log file will be written in JSON format. | `true` | |
| 154 | +| `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` | |
| 155 | +| `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` | |
| 156 | + |
| 157 | +### Using the full Serilog API |
| 158 | + |
| 159 | +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. |
| 160 | +
|
| 161 | +The following packages are used to provide `AddFile()`: |
| 162 | + |
| 163 | + * [Serilog](https://github.com/serilog/serilog) - the core logging pipeline |
| 164 | + * [Serilog.Sinks.RollingFile](https://github.com/serilog/serilog-sinks-rollingfile) - rolling file output |
| 165 | + * [Serilog.Formatting.Compact](https://github.com/serilog/serilog-formatting-compact) - JSON event formatting |
| 166 | + * [Serilog.Extensions.Logging](https://github.com/serilog/serilog-extensions-logging) - ASP.NET Core integration |
| 167 | + * [Serilog.Sinks.Async](https://github.com/serilog/serilog-sinks-async) - async wrapper to perform log writes on a background thread |
| 168 | + |
| 169 | +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). |
0 commit comments