Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[in-proc backport] Address unit test timing and setting Console.Out (#10808) #10892

Open
wants to merge 1 commit into
base: in-proc
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 20 additions & 4 deletions src/WebJobs.Script.WebHost/Diagnostics/BufferedConsoleWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Licensed under the MIT License. See License.txt in the project root for license information.

using System;
using System.IO;
using System.Text;
using System.Threading;
using System.Threading.Channels;
Expand Down Expand Up @@ -50,6 +51,8 @@ internal BufferedConsoleWriter(int bufferSize, Action<Exception> exceptionHandle
_exceptionhandler = exceptionHandler;
}

public TextWriter Writer { get; init; } = Console.Out;

public void WriteHandler(string evt)
{
_writeEvent(evt);
Expand All @@ -65,7 +68,7 @@ private void WriteToConsoleBuffer(string evt)
// If the wait failed, write to the console. Otherwise, try the writing again - if that fails, write to the console.
if (waitFailed || !_consoleBuffer.Writer.TryWrite(evt))
{
Console.WriteLine(evt);
Writer.WriteLine(evt);
}
}
}
Expand Down Expand Up @@ -108,12 +111,12 @@ private async Task ProcessConsoleBufferAsync()
}

_writeResetEvent.Set();
Console.Write(builder.ToString());
await Writer.WriteAsync(builder.ToString());
builder.Clear();
}
else
{
Console.WriteLine(line1);
await Writer.WriteLineAsync(line1);
}
}
}
Expand All @@ -126,7 +129,7 @@ private async Task ProcessConsoleBufferAsync()
finally
{
// if this has failed for any reason, fall everything back to console
_writeEvent = Console.WriteLine;
_writeEvent = Writer.WriteLine;
_consoleBuffer.Writer.TryComplete();
}
}
Expand All @@ -147,5 +150,18 @@ public void Dispose()

GC.SuppressFinalize(this);
}

/// <summary>
/// Primarily for testing. Do not call in production.
/// </summary>
/// <remarks>
/// Not called 'FlushAsync' because this does stop processing messages.
/// </remarks>
/// <returns>A task that completes when all buffered messages are drained.</returns>
internal Task CompleteAsync()
{
_consoleBuffer.Writer.TryComplete();
return _consoleBufferReadLoop;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@
// Licensed under the MIT License. See License.txt in the project root for license information.

using System;
using System.Threading.Tasks;
using Microsoft.Azure.WebJobs.Script.Config;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;

namespace Microsoft.Azure.WebJobs.Script.WebHost.Diagnostics
{
internal class LinuxContainerEventGenerator : LinuxEventGenerator, IDisposable
internal sealed class LinuxContainerEventGenerator : LinuxEventGenerator, IDisposable
{
private const int MaxDetailsLength = 10000;
private static readonly Lazy<LinuxContainerEventGenerator> _Lazy = new Lazy<LinuxContainerEventGenerator>(() => new LinuxContainerEventGenerator(SystemEnvironment.Instance, Console.WriteLine));
Expand All @@ -18,7 +19,6 @@ internal class LinuxContainerEventGenerator : LinuxEventGenerator, IDisposable
private string _containerName;
private string _stampName;
private string _tenantId;
private bool _disposed;

public LinuxContainerEventGenerator(IEnvironment environment, IOptions<ConsoleLoggingOptions> consoleLoggingOptions)
{
Expand All @@ -28,11 +28,15 @@ public LinuxContainerEventGenerator(IEnvironment environment, IOptions<ConsoleLo
}
else if (!consoleLoggingOptions.Value.BufferEnabled)
{
_writeEvent = Console.WriteLine;
_writeEvent = consoleLoggingOptions.Value.Writer.WriteLine;
}
else
{
_consoleWriter = new BufferedConsoleWriter(consoleLoggingOptions.Value.BufferSize, LogUnhandledException);
_consoleWriter = new BufferedConsoleWriter(consoleLoggingOptions.Value.BufferSize, LogUnhandledException)
{
Writer = consoleLoggingOptions.Value.Writer
};

_writeEvent = _consoleWriter.WriteHandler;
}

Expand Down Expand Up @@ -171,22 +175,21 @@ public static void LogEvent(string message, Exception e = null, LogLevel logLeve
eventTimestamp: DateTime.UtcNow);
}

protected virtual void Dispose(bool disposing)
public void Dispose()
{
if (!_disposed)
{
if (disposing)
{
_consoleWriter?.Dispose();
}
_disposed = true;
}
_consoleWriter?.Dispose();
}

public void Dispose()
/// <summary>
/// Primarily for testing. Do not call in production.
/// </summary>
/// <remarks>
/// Not called 'FlushAsync' because this does stop processing messages.
/// </remarks>
/// <returns>A task that completes when all buffered messages are drained.</returns>
internal Task CompleteAsync()
{
Dispose(disposing: true);
GC.SuppressFinalize(this);
return _consoleWriter is { } writer ? writer.CompleteAsync() : Task.CompletedTask;
}
}
}
20 changes: 11 additions & 9 deletions src/WebJobs.Script/Config/ConsoleLoggingOptions.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.

using System;
using System.IO;

namespace Microsoft.Azure.WebJobs.Script.Config
{
public class ConsoleLoggingOptions
Expand All @@ -10,18 +13,17 @@ public class ConsoleLoggingOptions
// So in the extreme case, this is about 1 second of buffer and should be less than 3MB
public const int DefaultBufferSize = 8000;

public ConsoleLoggingOptions()
{
LoggingDisabled = false;
BufferEnabled = true;
BufferSize = DefaultBufferSize;
}

public bool LoggingDisabled { get; set; }

// Use BufferSize = 0 to disable the buffer
public bool BufferEnabled { get; internal set; }
public bool BufferEnabled { get; set; } = true;

public int BufferSize { get; set; } = DefaultBufferSize;

public int BufferSize { get; set; }
/// <summary>
/// Gets or sets the <see cref="TextWriter"/> to write logs to.
/// IMPORTANT: this is primarily for unit tests to redirect logs to a different writer.
/// </summary>
internal TextWriter Writer { get; set; } = Console.Out;
}
}
Loading