From 5d91b3ed7c32174a90ee42c9015bc5ac20d6f2c8 Mon Sep 17 00:00:00 2001 From: Rolf Kristensen Date: Wed, 24 Mar 2021 22:04:33 +0100 Subject: [PATCH] MicrosoftConsoleLayoutRenderer - For Hosting Lifetime Startup Messages (#490) --- .../MicrosoftConsoleLayoutRenderer.cs | 76 +++++++++++++++++++ .../MicrosoftConsoleLayoutRendererTest.cs | 28 +++++++ 2 files changed, 104 insertions(+) create mode 100644 src/NLog.Extensions.Logging/LayoutRenderers/MicrosoftConsoleLayoutRenderer.cs create mode 100644 test/NLog.Extensions.Logging.Tests/MicrosoftConsoleLayoutRendererTest.cs diff --git a/src/NLog.Extensions.Logging/LayoutRenderers/MicrosoftConsoleLayoutRenderer.cs b/src/NLog.Extensions.Logging/LayoutRenderers/MicrosoftConsoleLayoutRenderer.cs new file mode 100644 index 00000000..79b7edb7 --- /dev/null +++ b/src/NLog.Extensions.Logging/LayoutRenderers/MicrosoftConsoleLayoutRenderer.cs @@ -0,0 +1,76 @@ +using System.Linq; +using System.Text; +using NLog.Config; +using NLog.LayoutRenderers; + +namespace NLog.Extensions.Logging +{ + /// + /// Renders output that simulates simple Microsoft Console Logger. Useful for Hosting Lifetime Startup Messages. + /// + [LayoutRenderer("MicrosoftConsoleLayout")] + [ThreadSafe] + [ThreadAgnostic] + class MicrosoftConsoleLayoutRenderer : LayoutRenderer + { + private static readonly string[] EventIdMapper = Enumerable.Range(0, 50).Select(id => id.ToString()).ToArray(); + + /// + protected override void Append(StringBuilder builder, LogEventInfo logEvent) + { + var microsoftLogLevel = ConvertLogLevel(logEvent.Level); + builder.Append(microsoftLogLevel); + builder.Append(": "); + builder.Append(logEvent.LoggerName); + builder.Append("["); + int eventId = 0; + if (logEvent.HasProperties && logEvent.Properties.TryGetValue("EventId_Id", out var eventIdValue)) + { + if (eventIdValue is int) + eventId = (int)eventIdValue; + else if (!int.TryParse(eventIdValue?.ToString() ?? string.Empty, out eventId)) + eventId = 0; + } + else + { + eventId = 0; + } + builder.Append(ConvertEventId(eventId)); + builder.Append("]"); + builder.Append(System.Environment.NewLine); + builder.Append(" "); + builder.Append(logEvent.FormattedMessage); + if (logEvent.Exception != null) + { + builder.Append(System.Environment.NewLine); + builder.Append(logEvent.Exception.ToString()); + } + } + + static string ConvertEventId(int eventId) + { + if (eventId == 0) + return "0"; + else if (eventId > 0 || eventId < EventIdMapper.Length) + return EventIdMapper[eventId]; + else + return eventId.ToString(); + } + + string ConvertLogLevel(LogLevel logLevel) + { + if (logLevel == LogLevel.Trace) + return "trce"; + else if (logLevel == LogLevel.Debug) + return "dbug"; + else if (logLevel == LogLevel.Info) + return "info"; + else if (logLevel == LogLevel.Warn) + return "warn"; + else if (logLevel == LogLevel.Error) + return "fail"; + else + return "crit"; // Fatal + } + } +} diff --git a/test/NLog.Extensions.Logging.Tests/MicrosoftConsoleLayoutRendererTest.cs b/test/NLog.Extensions.Logging.Tests/MicrosoftConsoleLayoutRendererTest.cs new file mode 100644 index 00000000..fa56e033 --- /dev/null +++ b/test/NLog.Extensions.Logging.Tests/MicrosoftConsoleLayoutRendererTest.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Text; +using Xunit; + +namespace NLog.Extensions.Logging.Tests +{ + public class MicrosoftConsoleLayoutRendererTest + { + [Fact] + public void MicrosoftConsoleLayoutRenderer_NullEvent() + { + var layoutRenderer = new MicrosoftConsoleLayoutRenderer(); + var result = layoutRenderer.Render(LogEventInfo.CreateNullEvent()); + Assert.Contains("crit: [0]", result); + } + + [Fact] + public void MicrosoftConsoleLayoutRenderer_ExceptionEvent() + { + var layoutRenderer = new MicrosoftConsoleLayoutRenderer(); + var exception = new ArgumentException("Test"); + var eventId = 42; + var result = layoutRenderer.Render(new LogEventInfo(LogLevel.Error, "MyLogger", null, "Alert {EventId_Id}", new object[] { eventId }, exception)); + Assert.Equal($"fail: MyLogger[{eventId}]{Environment.NewLine} Alert 42{Environment.NewLine}{exception}", result); + } + } +}