|
| 1 | +--- |
| 2 | +layout: post |
| 3 | +title: NLog 6.0 - List of major changes |
| 4 | +--- |
| 5 | + |
| 6 | +NLog 6.0 is a major version release that introduces breaking changes, including the splitting into multiple NuGet packages, and other improvements to support AOT builds. |
| 7 | + |
| 8 | +## Major changes |
| 9 | + |
| 10 | +### NLog supports AOT |
| 11 | + |
| 12 | +NLog has traditionally relied on reflection to dynamically discover requirements for target output. |
| 13 | +But reflection does not always work well with build trimming, and before NLog marked itself to have trimming disabled. |
| 14 | + |
| 15 | +NLog includes many features, each of these feature often introduce additional dependencies on the .NET library. |
| 16 | +This can lead to overhead for AOT builds, as it must include and compile all the relevant source code. |
| 17 | + |
| 18 | +NLog v6 attempts to reduce its footprint by extracting several features into separate nuget-packages: |
| 19 | + |
| 20 | +- NLog.RegEx - Depends on System.Text.RegularExpressions which is a huge dependency for a logging library. |
| 21 | +- NLog.Targets.ConcurrentFile - ConcurrentWrites using global mutex from operating system API. |
| 22 | +- NLog.Targets.AtomicFile - ConcurrentWrites using atomic file-append from operating system API. |
| 23 | +- NLog.Targets.Mail - Depends on System.Net.Mail.SmtpClient. |
| 24 | +- NLog.Targets.Network - Depends on TCP and UDP Network Socket. |
| 25 | +- NLog.Targets.Trace - Depends on System.Diagnostics.TraceListener. |
| 26 | +- NLog.Targets.WebService - Depends on System.Net.Http.HttpClient. |
| 27 | + |
| 28 | +NLog v6 also no longer supports automatic loading of `NLog.config`-file. This is because dynamic configuration |
| 29 | +loading, prevents build trimming of any NLog types, as the AOT-build cannot determine upfront what types |
| 30 | +will be used by the `NLog.config`-file. |
| 31 | + |
| 32 | +### NLog without automatic loading of NLog.config |
| 33 | + |
| 34 | +NLog will no longer automatically load the NLog LoggingConfiguration, when creating the first NLog Logger by calling `LogManger.GetCurrentClassLogger()` or `LogManger.GetLogger()`. |
| 35 | + |
| 36 | +Instead one must explicit load the `NLog.config` file at application-startup: |
| 37 | +```csharp |
| 38 | +var logger = NLog.LogManager.Setup().LoadConfigurationFromFile().GetCurrentClassLogger(); |
| 39 | +logger.Info("Hello World"); |
| 40 | +``` |
| 41 | + |
| 42 | +When using Microsoft HostBuilder with `UseNLog()`, then it will continue to automatically load the NLog LoggingConfiguration without having to make any changes. |
| 43 | + |
| 44 | +.NET Framework will continue to probe NLog LoggingConfiguration from the `app.config` / `web.config`, so one can consider doing this: |
| 45 | +```xml |
| 46 | +<?xml version="1.0" encoding="utf-8" ?> |
| 47 | +<configuration> |
| 48 | + <configSections> |
| 49 | + <section name="nlog" type="NLog.Config.ConfigSectionHandler, NLog"/> |
| 50 | + </configSections> |
| 51 | + <nlog include="NLog.config" /> |
| 52 | +</configuration> |
| 53 | +``` |
| 54 | + |
| 55 | +### NLog FileTarget without ConcurrentWrites |
| 56 | + |
| 57 | +NLog FileTarget no longer uses `File.Move` by default, but instead rolls to the next filename. |
| 58 | +This is to prevent file-locking issues with other background-applications, or if the log-file is |
| 59 | +held open by file-viewer. |
| 60 | + |
| 61 | +The new archive-logic: |
| 62 | + |
| 63 | +- LogFile.txt (Oldest file) |
| 64 | +- LogFile_1.txt |
| 65 | +- LogFile_2.txt (Newest file) |
| 66 | + |
| 67 | +The old archive-logic: |
| 68 | + |
| 69 | +- LogFile.txt (Newest file) |
| 70 | +- LogFile.1.txt (Oldest file) |
| 71 | +- LogFile.2.txt |
| 72 | + |
| 73 | +NLog FileTarget still support static archive logic with `File.Move`, but it must be explictly activated |
| 74 | +by specifying `ArchiveFileName`. |
| 75 | + |
| 76 | +NLog FileTarget no longer has the following options: |
| 77 | + |
| 78 | +- ConcurrentWrites - Removed because of dependency on global mutex and exotic file-locks. |
| 79 | +- EnableArchiveFileCompression - Removed because of dependency on compression-libraries. |
| 80 | +- CleanupFileName - Removed because it is now implicit. |
| 81 | +- FileNameKind - Removed because it is now implicit. |
| 82 | +- ArchiveFileKind - Removed because it is now implicit. |
| 83 | +- FileAttributes - Removed because of dependency on Windows-only API. |
| 84 | +- ForceManaged - Removed because of dependency on Windows-only API. |
| 85 | +- ConcurrentWriteAttempts - Removed together with ConcurrentWrites. |
| 86 | +- ConcurrentWriteAttemptDelay - Removed together with ConcurrentWrites. |
| 87 | +- ForceMutexConcurrentWrites - Removed together with ConcurrentWrites. |
| 88 | +- NetworkWrites - Replaced by KeepFileOpen. |
| 89 | +- ArchiveOldFileOnStartupAboveSize - Instead use ArchiveAboveSize / ArchiveOldFileOnStartup. |
| 90 | +- ArchiveDateFormat - Marked as obsolete. Instead use new ArchiveSuffixFormat |
| 91 | +- ArchiveNumbering - Marked as obsolete. Instead use new ArchiveSuffixFormat (Rolling is unsupported). |
| 92 | + |
| 93 | +If one still requires these options, then one can use the new NLog.Targets.ConcurrentFile-nuget-package. |
| 94 | + |
| 95 | +### NLog AtomicFileTarget without mutex |
| 96 | + |
| 97 | +New AtomicFileTarget has been introduced, that supports atomic file-append with help from the operating system, |
| 98 | +and supports both Windows and Linux (with help from Mono Posix) for NET8 (and newer). |
| 99 | + |
| 100 | +Extends the standard FileTarget and adds support for `ConcurrentWrites = true`, but without using global mutex. |
| 101 | + |
| 102 | +Linux users must use `dotnet publish` with `--configuration release --runtime linux-x64` to ensure |
| 103 | +correct publish of the `Mono.Posix.NETStandard`-nuget-package dependency. |
| 104 | + |
| 105 | +### NLog GZipFileTarget with GZipStream |
| 106 | + |
| 107 | +New GZipFileTarget has been introduced, that writes directly to a compressed log-file using GZipStream. |
| 108 | + |
| 109 | +Extends the standard FileTarget and adds support for `EnableArchiveFileCompression = true`, but only supports |
| 110 | +GZip file compression. |
| 111 | + |
| 112 | +The GZip File compression doesn't allow appending to existing GZip Archive without rewriting the entire GZip Archive. |
| 113 | +Therefore these options are set by default `KeepFileOpen = true` and `ArchiveOldFileOnStartup = true`. |
| 114 | + |
| 115 | +The GZip File compression has better handling of large log-files compared to the old `EnableArchiveFileCompression = true`, |
| 116 | +where the old ZIP compression would stall the file-logging until completed. |
| 117 | + |
| 118 | +### NLog LogFactory FlushAsync |
| 119 | + |
| 120 | +NLog LogFactory `Flush()` and `Shutdown()` are synchronous API methods, that schedules background worker-threads |
| 121 | +to execute NLog Target Flush. This doesn't work well on platforms that simulates worker-threads, |
| 122 | +by running everything on main thread. |
| 123 | + |
| 124 | +Instead NLog LogFactory `FlushAsync`-method has been introduced that will support multi-threaded flush. |
| 125 | + |
| 126 | +The NLog LogFactory now also implements `IDisposableAsync` which includes `FlushAsync` before closing. This allows the following: |
| 127 | +``` |
| 128 | +await using var logFactory = NLog.LogManager.Setup().LoadConfigurationFromFile().LogFactory; // Automatic Shutdown() |
| 129 | +``` |
| 130 | + |
| 131 | +The NLog LogFactory `Dispose()`-method has been changed to skip flush with help from worker-threads, |
| 132 | +but will only perform synchronous NLog Target Close. |
| 133 | + |
| 134 | +### NLog GelfTarget and GelfLayout |
| 135 | + |
| 136 | +The NLog.Targets.NetworkTarget nuget-package also includes support for the Graylog Extended Log Format (GELF). |
| 137 | + |
| 138 | +The `GelfTarget` extends the standard `NetworkTarget` with the new `GelfLayout`. |
| 139 | + |
| 140 | +It depends on the builtin NLog JSON serializer, but follows the 'standard' of prefixing all |
| 141 | +custom property-names with underscore `_`. |
| 142 | + |
| 143 | +## NLog SyslogTarget and SyslogLayout |
| 144 | + |
| 145 | +The NLog.Targets.NetworkTarget nuget-package also includes support for the Syslog Output Format. |
| 146 | + |
| 147 | +The `SyslogTarget` extends the standard `NetworkTarget` with the new `SyslogLayout`. |
| 148 | + |
| 149 | +The `SyslogLayout` supports both RFC-3164 (simple) + RFC-5424 (structured) logging output. |
| 150 | + |
| 151 | +### NLog NetworkTarget with NoDelay = true |
| 152 | + |
| 153 | +The NLog.Targets.NetworkTarget nuget-package includes support for configuring TCP_NODELAY. |
| 154 | +The `NetworkTarget` will by default use `NoDelay = true` to turn off delayed ACK, |
| 155 | +to avoid delays of 200ms because of nagle-algorithm. |
| 156 | + |
| 157 | +Believe most users will not notice the overhead of additional ACK-packages, but will notice |
| 158 | +a delay of 200ms. |
| 159 | + |
| 160 | +### NLog NetworkTarget with SendTimeoutSeconds = 100 |
| 161 | + |
| 162 | +The NLog.Targets.NetworkTarget nuget-package changes the default value of TCP SendTimeout |
| 163 | +from waiting forever to 100 secs. |
| 164 | + |
| 165 | +The `NetworkTarget` should now react to the network-cable being unplugged and the TCP send-window being filled. |
| 166 | + |
| 167 | +The `NetworkTarget` should now automatically attempt to reconnect when the endpoint suddenly becomes unresponsive. |
| 168 | + |
| 169 | +### NLog NetworkTarget with SslCertificateFile |
| 170 | + |
| 171 | +The NLog.Targets.NetworkTarget nuget-package introduces the ability to specify custom SSL certificate from file. |
| 172 | + |
| 173 | +The `NetworkTarget` now recognizes these new settings: |
| 174 | + - `Layout SslCertificateFile` |
| 175 | + - `Layout SslCertificatePassword` |
| 176 | + |
| 177 | +The `NetworkTarget` can now perform SSL handshake with custom SSL certificate from file, without needing to register the certificate in the global operating-system cache. |
| 178 | + |
| 179 | +## Breaking changes |
| 180 | + |
| 181 | +### NLog Structured Message formatting without quotes |
| 182 | + |
| 183 | +NLog v4.5 introduced support for message-templates, where it followed the Serilog approach by adding quotes around string-values: |
| 184 | +```csharp |
| 185 | +Logger.Info("Hello {World}", "Earth"); // Outputs Hello "Earth" with NLog v4.5 |
| 186 | +``` |
| 187 | + |
| 188 | +Microsoft Extension Logging decided not to implement that behavior, and now NLog also changes to not using quotes by default. Thus avoiding surprises when using NLog Logger directly instead as LoggingProvider for Microsoft Extension Logging. |
| 189 | + |
| 190 | +To apply string-quotes for a single value: |
| 191 | +```csharp |
| 192 | +Logger.Info("Hello {@World}", "Earth"); // Outputs Hello "Earth" with NLog v6 |
| 193 | +``` |
| 194 | + |
| 195 | +It is possible to globally revert to old behavior: |
| 196 | +```csharp |
| 197 | +LogManager.Setup().SetupSerialization(s => s.RegisterValueFormatterWithStringQuotes()); |
| 198 | +``` |
| 199 | + |
| 200 | +### NLog JsonLayout EscapeForwardSlash obsolete |
| 201 | + |
| 202 | +NLog v5 changed `JsonLayout` to have the default value `EscapeForwardSlash = false`, and now NLog v6 |
| 203 | +marks the NLog `JsonLayout` `EscapeForwardSlash` as completely obsolete and no longer having any effect. |
| 204 | + |
| 205 | +### NLog JsonLayout SuppressSpaces default true |
| 206 | + |
| 207 | +The `JsonLayout` has now have a new default value for `SuppressSpaces = true`, |
| 208 | +since log-file-size / network-traffic-usage doesn't benefit from the extra spaces. |
| 209 | + |
| 210 | +If the output from `JsonLayout` needs to be more human readable, then one can explictly assign |
| 211 | +`SuppressSpaces = false` or `IndentJson = true`. |
| 212 | + |
| 213 | +### NLog ColoredConsoleTarget with Errors in red |
| 214 | + |
| 215 | +NLog `ColoredConsoleTarget` used the color Yellow for Errors and Magenta for Warnings. |
| 216 | +This has now been changed to color Red for Errors and Yellow for Warnings. |
| 217 | + |
| 218 | +This is to align with the normal color standards that most other systems seems to be using. |
| 219 | + |
| 220 | +### NLog ColoredConsoleTarget without RegEx |
| 221 | + |
| 222 | +RegularExpressions (RegEx) is a huge API, and a big dependency for a logging library, |
| 223 | +so to reduce the footprint of NLog then RegEx support have been removed. |
| 224 | + |
| 225 | +This means word-highlighting rules no longer can scan for word-matches using RegEx. |
| 226 | +But logic has been implemented to continue support `IgnoreCase` and `WholeWords` |
| 227 | +for the string-matching logic. |
| 228 | + |
| 229 | +### NLog Replace LayoutRenderer without RegEx |
| 230 | + |
| 231 | +RegularExpressions (RegEx) is a huge API, and a big dependency for a logging library, |
| 232 | +so to reduce the footprint of NLog then RegEx support have been removed. |
| 233 | + |
| 234 | +Logic has been implemented to continue support `IgnoreCase` and `WholeWords` |
| 235 | +for the string-matching logic. |
| 236 | + |
| 237 | +This means the following has been removed for the `${replace}` LayoutRenderer: |
| 238 | +- `bool RegEx` |
| 239 | +- `bool CompileRegex` |
| 240 | +- `string ReplaceGroupName` |
| 241 | + |
| 242 | +If RegEx replace-logic is important then one can use the new nuget-package `NLog.RegEx`, which includes `${regex-replace}`. |
| 243 | + |
| 244 | +### NLog InternalLogger without LogToTrace |
| 245 | + |
| 246 | +NLog `InternalLogger.LogToTrace` has been remnoved. This reduces the NLog footprint by |
| 247 | +removing references to `System.Diagnostics.Trace` and `System.Diagnostics.TraceListener`. |
| 248 | + |
| 249 | +If it is important to redirect NLog InternalLogger output to `System.Diagnostics.Trace`, |
| 250 | +then one can use NLog `InternalLogger.LogWriter` to assign a custom `StringWriter` that performs the forwarding. |
| 251 | +Alternative one can setup custom subscriber to NLog `InternalLogger.InternalEventOccurred` event handler. |
| 252 | + |
| 253 | +### NLog XmlParser replaces XmlReader |
| 254 | + |
| 255 | +The .NET `System.Xml.XmlReader` is a heavy dependency that both loads XML using HttpClient, and support |
| 256 | +code generation to optimize serialization for types. To reduce dependencies and minimize AOT-build-filesize, |
| 257 | +then NLog now includes its own XML-parser. |
| 258 | + |
| 259 | +The NLog XML-parser only provides basic XML support, but it should be able to load any XML file that was |
| 260 | +working with NLog v5. |
| 261 | + |
| 262 | +### NLog EventLog with more Layout |
| 263 | +Use Layout for Log + MachineName + MaxMessageLength + MaxKilobytes |
| 264 | + |
| 265 | +### NLog SimpleLayout Immutable |
| 266 | +NLog `SimpleLayout` have removed the setter-method for its `Text`-property. |
| 267 | + |
| 268 | +This is to simpilfy the NLog `SimpleLayout` API, and to make it clear that NLog will optimize based on the initial layout. |
| 269 | + |
| 270 | +### Minimal Logger-API |
| 271 | +Not ready yet, and post-poned because major breaking change, which makes it harder to test first NLog v6-Preview. |
| 272 | + |
| 273 | +### Logger API with string interpolation |
| 274 | +Not ready yet, and post-poned because waiting for minimal Logger-API |
| 275 | + |
| 276 | +Idea is to skip string interpolation, when LogLevel is not enabled. |
| 277 | + |
| 278 | +### Logger API with ReadOnlySpan params |
| 279 | +Not ready yet, and post-poned because waiting for minimal Logger-API |
| 280 | + |
| 281 | +Idea is to skip params array-allocation, when LogLevel is not enabled. |
| 282 | + |
| 283 | +And if structured-logging then skip params allocation, but only rely on properties-dictionary. |
| 284 | + |
| 285 | +### NLog Nullable References |
| 286 | +Not ready yet, and post-poned because waiting for minimal Logger-API |
| 287 | + |
| 288 | +## Many other improvements |
| 289 | + |
| 290 | +For full list of all changes: [NLog 6.0 Pull Requests](https://github.com/NLog/NLog/pulls?q=is%3Apr+is%3Amerged+milestone:%226.0%22) |
| 291 | + |
| 292 | +- [Breaking Changes](https://github.com/NLog/NLog/pulls?q=is%3Apr+label%3A%22breaking%20change%22+is%3Amerged+milestone:%226.0%22) |
| 293 | +- [Breaking Behavior Changes](https://github.com/NLog/NLog/pulls?q=is%3Apr+label%3A%22breaking%20behavior%20change%22+is%3Amerged+milestone:%226.0%22) |
| 294 | +- [Features](https://github.com/NLog/NLog/pulls?q=is%3Apr+label%3A%22Feature%22+is%3Amerged+milestone:%226.0%22) |
| 295 | +- [Improvements](https://github.com/NLog/NLog/pulls?q=is%3Apr+label%3A%22Enhancement%22+is%3Amerged+milestone:%226.0%22) |
| 296 | +- [Performance](https://github.com/NLog/NLog/pulls?q=is%3Apr+label%3A%22Performance%22+is%3Amerged+milestone:%226.0%22) |
0 commit comments