Skip to content

Commit

Permalink
ConsoleTarget - Flush Console.Out on explict flush or close. Added Au…
Browse files Browse the repository at this point in the history
…toFlush to enable flush after each Console.WriteLine
  • Loading branch information
snakefoot committed Apr 5, 2019
1 parent 6d3be02 commit 43f63ba
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 3 deletions.
43 changes: 41 additions & 2 deletions src/NLog/Targets/ColoredConsoleTarget.cs
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,15 @@ public Encoding Encoding
[DefaultValue(false)]
public bool DetectConsoleAvailable { get; set; }

/// <summary>
/// Gets or sets a value indicating whether to auto-flush after <see cref="Console.WriteLine()"/>
/// </summary>
/// <remarks>
/// Normally the standard Console.Out will have <see cref="StreamWriter.AutoFlush"/> = false, but not when piped
/// </remarks>
[DefaultValue(false)]
public bool AutoFlush { get; set; }

/// <summary>
/// Enables output using ANSI Color Codes
/// </summary>
Expand Down Expand Up @@ -251,10 +260,33 @@ protected override void CloseTarget()
LogEventInfo lei = LogEventInfo.CreateNullEvent();
WriteToOutput(lei, RenderLogEvent(Footer, lei));
}

ExplicitConsoleFlush();
base.CloseTarget();
}

/// <inheritdoc />
protected override void FlushAsync(AsyncContinuation asyncContinuation)
{
try
{
ExplicitConsoleFlush();
base.FlushAsync(asyncContinuation);
}
catch (Exception ex)
{
asyncContinuation(ex);
}
}

private void ExplicitConsoleFlush()
{
if (!_pauseLogging && !AutoFlush)
{
var output = GetOutput();
output.Flush();
}
}

/// <summary>
/// Writes the specified log event to the console highlighting entries
/// and words based on a set of defined rules.
Expand Down Expand Up @@ -306,7 +338,7 @@ private void WriteToOutputWithColor(LogEventInfo logEvent, string message)
ConsoleColor? newForegroundColor = matchingRule.ForegroundColor != ConsoleOutputColor.NoChange ? (ConsoleColor)matchingRule.ForegroundColor : default(ConsoleColor?);
ConsoleColor? newBackgroundColor = matchingRule.BackgroundColor != ConsoleOutputColor.NoChange ? (ConsoleColor)matchingRule.BackgroundColor : default(ConsoleColor?);

var consoleStream = ErrorStream ? Console.Error : Console.Out;
var consoleStream = GetOutput();
if (ReferenceEquals(colorMessage, message) && !newForegroundColor.HasValue && !newBackgroundColor.HasValue)
{
consoleStream.WriteLine(message);
Expand All @@ -316,6 +348,8 @@ private void WriteToOutputWithColor(LogEventInfo logEvent, string message)
bool wordHighlighting = !ReferenceEquals(colorMessage, message) || message.IndexOf('\n') >= 0;
WriteToOutputWithPrinter(consoleStream, colorMessage, newForegroundColor, newBackgroundColor, wordHighlighting);
}
if (AutoFlush)
consoleStream.Flush();
}

private void WriteToOutputWithPrinter(TextWriter consoleStream, string colorMessage, ConsoleColor? newForegroundColor, ConsoleColor? newBackgroundColor, bool wordHighlighting)
Expand Down Expand Up @@ -549,6 +583,11 @@ private string GenerateColorEscapeSequences(string message)
consolePrinter.WriteSubString(consoleWriter, message, p0, message.Length);
}
}

private TextWriter GetOutput()
{
return ErrorStream ? Console.Error : Console.Out;
}
}
}

Expand Down
36 changes: 35 additions & 1 deletion src/NLog/Targets/ConsoleTarget.cs
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,15 @@ public Encoding Encoding
[DefaultValue(false)]
public bool DetectConsoleAvailable { get; set; }

/// <summary>
/// Gets or sets a value indicating whether to auto-flush after <see cref="Console.WriteLine()"/>
/// </summary>
/// <remarks>
/// Normally the standard Console.Out will have <see cref="StreamWriter.AutoFlush"/> = false, but not when piped
/// </remarks>
[DefaultValue(false)]
public bool AutoFlush { get; set; }

/// <summary>
/// Initializes a new instance of the <see cref="ConsoleTarget" /> class.
/// </summary>
Expand Down Expand Up @@ -178,10 +187,33 @@ protected override void CloseTarget()
{
WriteToOutput(RenderLogEvent(Footer, LogEventInfo.CreateNullEvent()));
}

ExplicitConsoleFlush();
base.CloseTarget();
}

/// <inheritdoc />
protected override void FlushAsync(AsyncContinuation asyncContinuation)
{
try
{
ExplicitConsoleFlush();
base.FlushAsync(asyncContinuation);
}
catch (Exception ex)
{
asyncContinuation(ex);
}
}

private void ExplicitConsoleFlush()
{
if (!_pauseLogging && !AutoFlush)
{
var output = GetOutput();
output.Flush();
}
}

/// <summary>
/// Writes the specified logging event to the Console.Out or
/// Console.Error depending on the value of the Error flag.
Expand Down Expand Up @@ -217,6 +249,8 @@ private void WriteToOutput(string textLine)
try
{
output.WriteLine(textLine);
if (AutoFlush)
output.Flush();
}
catch (IndexOutOfRangeException ex)
{
Expand Down
21 changes: 21 additions & 0 deletions tests/NLog.UnitTests/Targets/ColoredConsoleTargetTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,15 @@ public void DonRemoveIfRegexIsEmpty(bool compileRegex)
new string[] { "The Cat Sat At The Bar." });
}

[Fact]
public void ColortedConsoleAutoFlushOnWrite()
{
var target = new ColoredConsoleTarget { Layout = "${logger} ${message}", AutoFlush = true };
AssertOutput(target, "The Cat Sat At The Bar.",
new string[] { "The Cat Sat At The Bar." });

}

#if !NET3_5 && !MONO
[Fact]
public void ColoredConsoleRaceCondtionIgnoreTest()
Expand Down Expand Up @@ -277,6 +286,7 @@ private static void AssertOutput(Target target, string message, string[] expecte
var expected = Enumerable.Repeat(loggerName + expectedParts[0], 1).Concat(expectedParts.Skip(1));
Assert.Equal(expected, consoleOutWriter.Values);
Assert.True(consoleOutWriter.SingleWriteLine);
Assert.True(consoleOutWriter.SingleFlush);
}


Expand All @@ -289,12 +299,23 @@ public PartsWriter()

public List<string> Values { get; private set; }
public bool SingleWriteLine { get; private set; }
public bool SingleFlush { get; private set; }

public override void Write(string value)
{
Values.Add(value);
}

public override void Flush()
{
if (SingleFlush)
{
throw new InvalidOperationException("Single Flush only");
}
SingleFlush = true;
base.Flush();
}

public override void WriteLine(string value)
{
if (SingleWriteLine)
Expand Down
2 changes: 2 additions & 0 deletions tests/NLog.UnitTests/Targets/ConsoleTargetTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ public void ConsoleOutTest()
new LogEventInfo(LogLevel.Info, "Logger2", "message5").WithContinuation(exceptions.Add),
new LogEventInfo(LogLevel.Info, "Logger1", "message6").WithContinuation(exceptions.Add));
Assert.Equal(6, exceptions.Count);
target.Flush();
target.Close();
}
finally
Expand Down Expand Up @@ -116,6 +117,7 @@ public void ConsoleErrorTest()
new LogEventInfo(LogLevel.Info, "Logger2", "message5").WithContinuation(exceptions.Add),
new LogEventInfo(LogLevel.Info, "Logger1", "message6").WithContinuation(exceptions.Add));
Assert.Equal(6, exceptions.Count);
target.Flush();
target.Close();
}
finally
Expand Down

0 comments on commit 43f63ba

Please sign in to comment.