From 834eae6ed67cb8ab1933b23ed6530cc4a93c6e2e Mon Sep 17 00:00:00 2001 From: Nicholas Blumhardt Date: Mon, 30 May 2016 12:12:24 +1000 Subject: [PATCH 1/3] WIP --- src/Serilog/Debugging/SelfLog.cs | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/src/Serilog/Debugging/SelfLog.cs b/src/Serilog/Debugging/SelfLog.cs index 86b7d775e..8580b5d16 100644 --- a/src/Serilog/Debugging/SelfLog.cs +++ b/src/Serilog/Debugging/SelfLog.cs @@ -23,6 +23,8 @@ namespace Serilog.Debugging /// public static class SelfLog { + static readonly Action _output; + /// /// The output mechanism for self-log events. /// @@ -30,7 +32,29 @@ public static class SelfLog /// SelfLog.Out = Console.Error; /// // ReSharper disable once MemberCanBePrivate.Global, UnusedAutoPropertyAccessor.Global - public static TextWriter Out { get; set; } + [Obsolete("Use SetOutput() instead")] + public static TextWriter Out + { + set + { + if (value == null) + { + SetOutput(null); + } + else + { + SetOutput(m => + { + value.WriteLine(DateTime.UtcNow.ToString("o") + " " + m); + value.Flush(); + }); + } + } + } + + public static void SetOutput(Action output) + { + } /// /// Write a message to the self-log. @@ -41,11 +65,10 @@ public static class SelfLog /// Third argument, if supplied. public static void WriteLine(string format, object arg0 = null, object arg1 = null, object arg2 = null) { - var o = Out; + var o = _output; if (o != null) { - o.WriteLine(DateTime.Now.ToString("s") + " " + format, arg0, arg1, arg2); - o.Flush(); + o(string.Format(format, arg0, arg1, arg2)); } } } From 58b9064fc5b020b8cc1193d43d4d39714c182e9a Mon Sep 17 00:00:00 2001 From: Nicholas Blumhardt Date: Mon, 30 May 2016 12:36:07 +1000 Subject: [PATCH 2/3] Fixes #731 - evented SelfLog --- src/Serilog/Debugging/SelfLog.cs | 63 ++++++++++++++------ test/Serilog.Tests/Debugging/SelfLogTests.cs | 35 +++++++++++ 2 files changed, 80 insertions(+), 18 deletions(-) create mode 100644 test/Serilog.Tests/Debugging/SelfLogTests.cs diff --git a/src/Serilog/Debugging/SelfLog.cs b/src/Serilog/Debugging/SelfLog.cs index 8580b5d16..424ff0916 100644 --- a/src/Serilog/Debugging/SelfLog.cs +++ b/src/Serilog/Debugging/SelfLog.cs @@ -23,7 +23,7 @@ namespace Serilog.Debugging /// public static class SelfLog { - static readonly Action _output; + static Action _output; /// /// The output mechanism for self-log events. @@ -32,28 +32,53 @@ public static class SelfLog /// SelfLog.Out = Console.Error; /// // ReSharper disable once MemberCanBePrivate.Global, UnusedAutoPropertyAccessor.Global - [Obsolete("Use SetOutput() instead")] + [Obsolete("Use SelfLog.Enable(value) and SelfLog.Disable() instead")] public static TextWriter Out { set { - if (value == null) - { - SetOutput(null); - } + if (value != null) + Enable(value); else - { - SetOutput(m => - { - value.WriteLine(DateTime.UtcNow.ToString("o") + " " + m); - value.Flush(); - }); - } + Disable(); } } - public static void SetOutput(Action output) + /// + /// Set the output mechanism for self-log events. + /// + /// A synchronized to which + /// self-log events will be written. + // ReSharper disable once MemberCanBePrivate.Global + public static void Enable(TextWriter output) + { + if (output == null) throw new ArgumentNullException(nameof(output)); + + Enable(m => + { + output.WriteLine(m); + output.Flush(); + }); + } + + /// + /// Set the output mechanism for self-log events. + /// + /// An action to invoke with self-log messages. + /// // ReSharper disable once MemberCanBePrivate.Global + public static void Enable(Action output) { + if (output == null) throw new ArgumentNullException(nameof(output)); + _output = output; + } + + /// + /// Clear the output mechanism and disable self-log events. + /// + /// // ReSharper disable once MemberCanBePrivate.Global + public static void Disable() + { + _output = null; } /// @@ -63,13 +88,15 @@ public static void SetOutput(Action output) /// First argument, if supplied. /// Second argument, if supplied. /// Third argument, if supplied. + /// + /// The name is historical; because this is used from third-party sink packages, removing the "Line" + /// suffix as would seem sensible isn't worth the breakage. + /// public static void WriteLine(string format, object arg0 = null, object arg1 = null, object arg2 = null) { var o = _output; - if (o != null) - { - o(string.Format(format, arg0, arg1, arg2)); - } + + o?.Invoke(string.Format(DateTime.UtcNow.ToString("o") + " " + format, arg0, arg1, arg2)); } } } diff --git a/test/Serilog.Tests/Debugging/SelfLogTests.cs b/test/Serilog.Tests/Debugging/SelfLogTests.cs new file mode 100644 index 000000000..08722065b --- /dev/null +++ b/test/Serilog.Tests/Debugging/SelfLogTests.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Serilog.Debugging; +using Xunit; + +namespace Serilog.Tests.Debugging +{ + public class SelfLogTests + { + [ThreadStatic] + static List Messages; + + [Fact] + public void MessagesAreWrittenWhenOutputIsSet() + { + Messages = new List(); + SelfLog.Enable(m => + { + Messages = Messages ?? new List(); + Messages.Add(m); + }); + + SelfLog.WriteLine("Hello {0} {1} {2}", 0, 1, 2); + Assert.True(Messages.Any(m => m.EndsWith("Hello 0 1 2"))); + + // Better to do this here than in another test, since at this point + // we've confirmed there's actually something to disable. + var count = Messages.Count; + SelfLog.Disable(); + SelfLog.WriteLine("Unwritten"); + Assert.Equal(Messages.Count, count); + } + } +} From 28e87c8bcb48a53b6d342aa1bed49f4c0e15c4a4 Mon Sep 17 00:00:00 2001 From: Nicholas Blumhardt Date: Mon, 30 May 2016 13:49:40 +1000 Subject: [PATCH 3/3] Use 'messages' consistently to describe entries written to SelfLog --- src/Serilog/Debugging/SelfLog.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Serilog/Debugging/SelfLog.cs b/src/Serilog/Debugging/SelfLog.cs index 424ff0916..c9423519a 100644 --- a/src/Serilog/Debugging/SelfLog.cs +++ b/src/Serilog/Debugging/SelfLog.cs @@ -26,7 +26,7 @@ public static class SelfLog static Action _output; /// - /// The output mechanism for self-log events. + /// The output mechanism for self-log messages. /// /// /// SelfLog.Out = Console.Error; @@ -45,10 +45,10 @@ public static TextWriter Out } /// - /// Set the output mechanism for self-log events. + /// Set the output mechanism for self-log messages. /// /// A synchronized to which - /// self-log events will be written. + /// self-log messages will be written. // ReSharper disable once MemberCanBePrivate.Global public static void Enable(TextWriter output) { @@ -62,7 +62,7 @@ public static void Enable(TextWriter output) } /// - /// Set the output mechanism for self-log events. + /// Set the output mechanism for self-log messages. /// /// An action to invoke with self-log messages. /// // ReSharper disable once MemberCanBePrivate.Global