Skip to content

Commit

Permalink
chore: Add DebugLogLevelEnabled property to default logger implementa…
Browse files Browse the repository at this point in the history
…tion (#928)
  • Loading branch information
HofmeisterAn committed Jun 21, 2023
1 parent f867967 commit 1c92dcf
Show file tree
Hide file tree
Showing 8 changed files with 95 additions and 58 deletions.
6 changes: 0 additions & 6 deletions src/Testcontainers/Builders/ContainerBuilder`3.cs
Original file line number Diff line number Diff line change
Expand Up @@ -255,12 +255,6 @@ public TBuilderEntity WithTmpfsMount(string destination, AccessMode accessMode)
return WithMount(new TmpfsMount(destination, accessMode));
}

/// <inheritdoc />
public TBuilderEntity WithNetwork(string id, string name)
{
return WithNetwork(name);
}

/// <inheritdoc />
public TBuilderEntity WithNetwork(string name)
{
Expand Down
4 changes: 2 additions & 2 deletions src/Testcontainers/Clients/DockerContainerOperations.cs
Original file line number Diff line number Diff line change
Expand Up @@ -102,13 +102,13 @@ public Task RemoveAsync(string id, CancellationToken ct = default)

public Task ExtractArchiveToContainerAsync(string id, string path, Stream tarStream, CancellationToken ct = default)
{
_logger.ExtractArchiveToDockerContainer(id, path);
_logger.CopyArchiveToDockerContainer(id, path);
return Docker.Containers.ExtractArchiveToContainerAsync(id, new ContainerPathStatParameters { Path = path, AllowOverwriteDirWithFile = false }, tarStream, ct);
}

public async Task<Stream> GetArchiveFromContainerAsync(string id, string path, CancellationToken ct = default)
{
_logger.GetArchiveFromDockerContainer(id, path);
_logger.ReadArchiveFromDockerContainer(id, path);

var tarResponse = await Docker.Containers.GetArchiveFromContainerAsync(id, new GetArchiveFromContainerParameters { Path = path }, false, ct)
.ConfigureAwait(false);
Expand Down
6 changes: 3 additions & 3 deletions src/Testcontainers/Clients/TraceProgress.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,17 @@ public void Report(JSONMessage value)

if (!string.IsNullOrWhiteSpace(value.Status))
{
_logger.LogTrace(value.Status);
_logger.LogDebug(value.Status);
}

if (!string.IsNullOrWhiteSpace(value.Stream))
{
_logger.LogTrace(value.Stream);
_logger.LogDebug(value.Stream);
}

if (!string.IsNullOrWhiteSpace(value.ProgressMessage))
{
_logger.LogTrace(value.ProgressMessage);
_logger.LogDebug(value.ProgressMessage);
}

if (!string.IsNullOrWhiteSpace(value.ErrorMessage))
Expand Down
13 changes: 9 additions & 4 deletions src/Testcontainers/Configurations/TestcontainersSettings.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
namespace DotNet.Testcontainers.Configurations
{
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Runtime.InteropServices;
Expand Down Expand Up @@ -167,7 +168,7 @@ static TestcontainersSettings()
/// </summary>
[NotNull]
public static ILogger Logger { get; set; }
= new Logger();
= ConsoleLogger.Instance;

/// <summary>
/// Gets or sets the host operating system.
Expand All @@ -184,12 +185,16 @@ public static WaitHandle SettingsInitialized
=> ManualResetEvent.WaitHandle;

/// <inheritdoc cref="PortForwardingContainer.ExposeHostPortsAsync" />
public static async Task ExposeHostPortsAsync(params ushort[] ports)
public static Task ExposeHostPortsAsync(ushort port, CancellationToken ct = default)
=> ExposeHostPortsAsync(new[] { port }, ct);

/// <inheritdoc cref="PortForwardingContainer.ExposeHostPortsAsync" />
public static async Task ExposeHostPortsAsync(IEnumerable<ushort> ports, CancellationToken ct = default)
{
await PortForwardingContainer.Instance.StartAsync()
await PortForwardingContainer.Instance.StartAsync(ct)
.ConfigureAwait(false);

await PortForwardingContainer.Instance.ExposeHostPortsAsync(ports)
await PortForwardingContainer.Instance.ExposeHostPortsAsync(ports, ct)
.ConfigureAwait(false);
}
}
Expand Down
4 changes: 4 additions & 0 deletions src/Testcontainers/Containers/DockerContainer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -440,12 +440,16 @@ await WaitStrategy.WaitUntilAsync(CheckPortBindingsAsync, TimeSpan.FromSeconds(1
await _configuration.StartupCallback(this, ct)
.ConfigureAwait(false);

Logger.StartReadinessCheck(_container.ID);

foreach (var waitStrategy in _configuration.WaitStrategies)
{
await WaitStrategy.WaitUntilAsync(() => CheckWaitStrategyAsync(waitStrategy), TimeSpan.FromSeconds(1), Timeout.InfiniteTimeSpan, ct)
.ConfigureAwait(false);
}

Logger.CompleteReadinessCheck(_container.ID);

Started?.Invoke(this, EventArgs.Empty);
}

Expand Down
5 changes: 4 additions & 1 deletion src/Testcontainers/Containers/PortForwarding.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
namespace DotNet.Testcontainers.Containers
{
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
using Docker.DotNet.Models;
using DotNet.Testcontainers.Builders;
Expand Down Expand Up @@ -41,8 +43,9 @@ private PortForwardingContainer(PortForwardingConfiguration configuration, ILogg
/// Exposes the host ports using SSH port forwarding.
/// </summary>
/// <param name="ports">The host ports to forward.</param>
/// <param name="ct">Cancellation token.</param>
/// <returns>A task that completes when the host ports are forwarded.</returns>
public Task ExposeHostPortsAsync(params ushort[] ports)
public Task ExposeHostPortsAsync(IEnumerable<ushort> ports, CancellationToken ct = default)
{
var sshClient = new SshClient(Hostname, GetMappedPublicPort(PortForwardingBuilder.SshdPort), _configuration.Username, _configuration.Password);
sshClient.Connect();
Expand Down
62 changes: 36 additions & 26 deletions src/Testcontainers/Logger.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@ namespace DotNet.Testcontainers
{
using System;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Runtime.InteropServices;
using JetBrains.Annotations;
using Microsoft.Extensions.Logging;

/// <summary>
Expand Down Expand Up @@ -55,54 +54,65 @@ namespace DotNet.Testcontainers
/// }
/// </code>
/// </example>
internal sealed class Logger : ILogger, IDisposable
[PublicAPI]
public sealed class ConsoleLogger : ILogger, IDisposable
{
private readonly Stopwatch _stopwatch = Stopwatch.StartNew();

public Logger()
private LogLevel _minLogLevel = LogLevel.Information;

private ConsoleLogger()
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && !Console.IsOutputRedirected && !Console.IsErrorRedirected)
{
Console.BufferWidth = short.MaxValue - 1;
}
}

/// <summary>
/// Gets the <see cref="ConsoleLogger" /> instance.
/// </summary>
public static ConsoleLogger Instance { get; }
= new ConsoleLogger();

/// <summary>
/// Gets a value indicating whether the debug log level is enabled or not.
/// </summary>
public bool DebugLogLevelEnabled
{
get
{
return LogLevel.Debug.Equals(_minLogLevel);
}

set
{
_minLogLevel = value ? LogLevel.Debug : LogLevel.Information;
}
}

/// <inheritdoc />
public void Dispose()
{
// The default logger does not support scopes. We return itself as IDisposable implementation.
// The default console logger does not support scopes. We return itself as IDisposable implementation.
}

/// <inheritdoc />
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
{
TextWriter console;

switch (logLevel)
if (IsEnabled(logLevel))
{
case LogLevel.Information:
console = Console.Out;
break;
case LogLevel.Warning:
console = Console.Out;
break;
case LogLevel.Error:
console = Console.Error;
break;
case LogLevel.Critical:
console = Console.Error;
break;
default:
return;
Console.Out.WriteLine("[testcontainers.org {0:hh\\:mm\\:ss\\.ff}] {1}", _stopwatch.Elapsed, formatter.Invoke(state, exception));
}

var message = string.Format(CultureInfo.CurrentCulture, "[testcontainers.org {0:hh\\:mm\\:ss\\.ff}] {1}", _stopwatch.Elapsed, formatter.Invoke(state, exception));
console.WriteLine(message);
}

/// <inheritdoc />
public bool IsEnabled(LogLevel logLevel)
{
return true;
return logLevel >= _minLogLevel;
}

/// <inheritdoc />
public IDisposable BeginScope<TState>(TState state)
{
return this;
Expand Down
53 changes: 37 additions & 16 deletions src/Testcontainers/Logging.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,16 @@ private static readonly Action<ILogger, string, Exception> _StopDockerContainer
private static readonly Action<ILogger, string, Exception> _DeleteDockerContainer
= LoggerMessage.Define<string>(LogLevel.Information, default, "Delete Docker container {Id}");

private static readonly Action<ILogger, string, string, Exception> _ExtractArchiveToDockerContainer
= LoggerMessage.Define<string, string>(LogLevel.Information, default, "Copy tar archive to \"{Path}\" at Docker container {Id}");
private static readonly Action<ILogger, string, Exception> _StartReadinessCheck
= LoggerMessage.Define<string>(LogLevel.Information, default, "Wait for Docker container {Id} to complete readiness checks");

private static readonly Action<ILogger, string, string, Exception> _GetArchiveFromDockerContainer
private static readonly Action<ILogger, string, Exception> _CompleteReadinessCheck
= LoggerMessage.Define<string>(LogLevel.Information, default, "Docker container {Id} ready");

private static readonly Action<ILogger, string, string, Exception> _CopyArchiveToDockerContainer
= LoggerMessage.Define<string, string>(LogLevel.Information, default, "Copy tar archive to \"{Path}\" to Docker container {Id}");

private static readonly Action<ILogger, string, string, Exception> _ReadArchiveFromDockerContainer
= LoggerMessage.Define<string, string>(LogLevel.Information, default, "Read \"{Path}\" from Docker container {Id}");

private static readonly Action<ILogger, Type, string, Exception> _AttachToDockerContainer
Expand Down Expand Up @@ -91,47 +97,57 @@ public static void IgnorePatternAdded(this ILogger logger, Regex ignorePattern)

public static void DockerContainerCreated(this ILogger logger, string id)
{
_DockerContainerCreated(logger, id, null);
_DockerContainerCreated(logger, TruncId(id), null);
}

public static void StartDockerContainer(this ILogger logger, string id)
{
_StartDockerContainer(logger, id, null);
_StartDockerContainer(logger, TruncId(id), null);
}

public static void StopDockerContainer(this ILogger logger, string id)
{
_StopDockerContainer(logger, id, null);
_StopDockerContainer(logger, TruncId(id), null);
}

public static void DeleteDockerContainer(this ILogger logger, string id)
{
_DeleteDockerContainer(logger, id, null);
_DeleteDockerContainer(logger, TruncId(id), null);
}

public static void StartReadinessCheck(this ILogger logger, string id)
{
_StartReadinessCheck(logger, TruncId(id), null);
}

public static void ExtractArchiveToDockerContainer(this ILogger logger, string id, string path)
public static void CompleteReadinessCheck(this ILogger logger, string id)
{
_ExtractArchiveToDockerContainer(logger, path, id, null);
_CompleteReadinessCheck(logger, TruncId(id), null);
}

public static void GetArchiveFromDockerContainer(this ILogger logger, string id, string path)
public static void CopyArchiveToDockerContainer(this ILogger logger, string id, string path)
{
_GetArchiveFromDockerContainer(logger, path, id, null);
_CopyArchiveToDockerContainer(logger, path, TruncId(id), null);
}

public static void ReadArchiveFromDockerContainer(this ILogger logger, string id, string path)
{
_ReadArchiveFromDockerContainer(logger, path, TruncId(id), null);
}

public static void AttachToDockerContainer(this ILogger logger, string id, Type type)
{
_AttachToDockerContainer(logger, type, id, null);
_AttachToDockerContainer(logger, type, TruncId(id), null);
}

public static void ConnectToDockerNetwork(this ILogger logger, string networkId, string containerId)
{
_ConnectToDockerNetwork(logger, containerId, networkId, null);
_ConnectToDockerNetwork(logger, TruncId(containerId), TruncId(networkId), null);
}

public static void ExecuteCommandInDockerContainer(this ILogger logger, string id, IEnumerable<string> command)
{
_ExecuteCommandInDockerContainer(logger, string.Join(" ", command), id, null);
_ExecuteCommandInDockerContainer(logger, string.Join(" ", command), TruncId(id), null);
}

public static void DockerImageCreated(this ILogger logger, IImage image)
Expand All @@ -151,12 +167,12 @@ public static void DeleteDockerImage(this ILogger logger, IImage image)

public static void DockerNetworkCreated(this ILogger logger, string id)
{
_DockerNetworkCreated(logger, id, null);
_DockerNetworkCreated(logger, TruncId(id), null);
}

public static void DeleteDockerNetwork(this ILogger logger, string id)
{
_DeleteDockerNetwork(logger, id, null);
_DeleteDockerNetwork(logger, TruncId(id), null);
}

public static void DockerVolumeCreated(this ILogger logger, string name)
Expand Down Expand Up @@ -205,5 +221,10 @@ public static void DockerRegistryCredentialFound(this ILogger logger, string doc
{
_DockerRegistryCredentialFound(logger, dockerRegistry, null);
}

private static string TruncId(string id)
{
return id.Substring(0, Math.Min(12, id.Length));
}
}
}

0 comments on commit 1c92dcf

Please sign in to comment.