Skip to content

Commit f0e1dfe

Browse files
committed
fix: improve logging output
1 parent 2d62980 commit f0e1dfe

File tree

6 files changed

+39
-87
lines changed

6 files changed

+39
-87
lines changed

src/bunit.core/Extensions/WaitForHelpers/WaitForHelperLoggerExtensions.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,22 +5,22 @@ namespace Bunit.Extensions.WaitForHelpers;
55
internal static class WaitForHelperLoggerExtensions
66
{
77
private static readonly Action<ILogger, int, Exception?> CheckingWaitCondition
8-
= LoggerMessage.Define<int>(LogLevel.Debug, new EventId(1, "OnAfterRender"), "Checking the wait condition for component {Id}.");
8+
= LoggerMessage.Define<int>(LogLevel.Debug, new EventId(1, "CheckingWaitCondition"), "Checking the wait condition for component {Id}.");
99

1010
private static readonly Action<ILogger, int, Exception?> CheckCompleted
11-
= LoggerMessage.Define<int>(LogLevel.Debug, new EventId(2, "OnAfterRender"), "The check completed successfully for component {Id}.");
11+
= LoggerMessage.Define<int>(LogLevel.Debug, new EventId(2, "CheckCompleted"), "The check completed successfully for component {Id}.");
1212

1313
private static readonly Action<ILogger, int, Exception?> CheckFailed
14-
= LoggerMessage.Define<int>(LogLevel.Debug, new EventId(3, "OnAfterRender"), "The check failed for component {Id}.");
14+
= LoggerMessage.Define<int>(LogLevel.Debug, new EventId(3, "CheckFailed"), "The check failed for component {Id}.");
1515

1616
private static readonly Action<ILogger, int, Exception> CheckThrow
17-
= LoggerMessage.Define<int>(LogLevel.Debug, new EventId(4, "OnAfterRender"), "The checker for component {Id} throw an exception.");
17+
= LoggerMessage.Define<int>(LogLevel.Debug, new EventId(4, "CheckThrow"), "The checker for component {Id} throw an exception.");
1818

1919
private static readonly Action<ILogger, int, Exception?> WaiterTimedOut
20-
= LoggerMessage.Define<int>(LogLevel.Debug, new EventId(10, "OnTimeout"), "The waiter for component {Id} timed out.");
20+
= LoggerMessage.Define<int>(LogLevel.Debug, new EventId(10, "WaiterTimedOut"), "The waiter for component {Id} timed out.");
2121

2222
private static readonly Action<ILogger, int, Exception?> WaiterDisposed
23-
= LoggerMessage.Define<int>(LogLevel.Debug, new EventId(20, "OnTimeout"), "The waiter for component {Id} disposed.");
23+
= LoggerMessage.Define<int>(LogLevel.Debug, new EventId(20, "WaiterDisposed"), "The waiter for component {Id} disposed.");
2424

2525
internal static void LogCheckingWaitCondition<T>(this ILogger<WaitForHelper<T>> logger, int componentId)
2626
{

src/bunit.core/Rendering/TestRenderer.cs

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -233,32 +233,35 @@ protected override Task UpdateDisplayAsync(in RenderBatch renderBatch)
233233
{
234234
if (disposed)
235235
{
236-
logger.LogRenderCycleActiveAfterDispose();
237236
return Task.CompletedTask;
238237
}
239238

240239
var renderEvent = new RenderEvent();
241240

242-
for (var i = 0; i < renderBatch.DisposedComponentIDs.Count; i++)
243-
{
244-
var id = renderBatch.DisposedComponentIDs.Array[i];
245-
renderEvent.SetDisposed(id);
246-
}
241+
PrepareRenderEvent(renderBatch);
242+
InvokeApplyRenderEvent();
247243

248-
for (int i = 0; i < renderBatch.UpdatedComponents.Count; i++)
249-
{
250-
ref var update = ref renderBatch.UpdatedComponents.Array[i];
251-
renderEvent.SetUpdated(update.ComponentId, update.Edits.Count > 0);
252-
}
244+
return Task.CompletedTask;
253245

254-
foreach (var (key, rc) in renderedComponents)
246+
void PrepareRenderEvent(in RenderBatch renderBatch)
255247
{
256-
LoadChangesIntoRenderEvent(rc.ComponentId);
257-
}
248+
for (var i = 0; i < renderBatch.DisposedComponentIDs.Count; i++)
249+
{
250+
var id = renderBatch.DisposedComponentIDs.Array[i];
251+
renderEvent.SetDisposed(id);
252+
}
258253

259-
InvokeApplyRenderEvent();
254+
for (int i = 0; i < renderBatch.UpdatedComponents.Count; i++)
255+
{
256+
ref var update = ref renderBatch.UpdatedComponents.Array[i];
257+
renderEvent.SetUpdated(update.ComponentId, update.Edits.Count > 0);
258+
}
260259

261-
return Task.CompletedTask;
260+
foreach (var (key, rc) in renderedComponents)
261+
{
262+
LoadChangesIntoRenderEvent(rc.ComponentId);
263+
}
264+
}
262265

263266
void LoadChangesIntoRenderEvent(int componentId)
264267
{

src/bunit.core/Rendering/TestRendererLoggerExtensions.cs

Lines changed: 7 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -4,51 +4,27 @@ namespace Bunit.Rendering;
44

55
internal static class TestRendererLoggerExtensions
66
{
7-
private static readonly Action<ILogger, Exception?> ProcessingPendingRenders
8-
= LoggerMessage.Define(LogLevel.Debug, new EventId(1, "ProcessPendingRender"), "Processing pending renders.");
9-
10-
private static readonly Action<ILogger, Exception?> NewRenderBatchReceived
11-
= LoggerMessage.Define(LogLevel.Debug, new EventId(10, "UpdateDisplayAsync"), "New render batch received.");
12-
137
private static readonly Action<ILogger, int, Exception?> ComponentDisposed
14-
= LoggerMessage.Define<int>(LogLevel.Debug, new EventId(11, "UpdateDisplayAsync"), "Component {Id} has been disposed.");
8+
= LoggerMessage.Define<int>(LogLevel.Debug, new EventId(11, "ComponentDisposed"), "Component {Id} has been disposed.");
159

1610
private static readonly Action<ILogger, int, Exception?> ComponentRendered
17-
= LoggerMessage.Define<int>(LogLevel.Debug, new EventId(12, "UpdateDisplayAsync"), "Component {Id} has been rendered.");
18-
19-
private static readonly Action<ILogger, Exception?> ChangedComponentsMarkupUpdated
20-
= LoggerMessage.Define(LogLevel.Debug, new EventId(13, "UpdateDisplayAsync"), "Finished updating the markup of changed components.");
11+
= LoggerMessage.Define<int>(LogLevel.Debug, new EventId(12, "ComponentRendered"), "Component {Id} has been rendered.");
2112

2213
private static readonly Action<ILogger, int, int, Exception?> DisposedChildInRenderTreeFrame
23-
= LoggerMessage.Define<int, int>(LogLevel.Warning, new EventId(14, "UpdateDisplayAsync"), "A parent components {ParentComponentId} has a disposed component {ComponentId} as its child.");
14+
= LoggerMessage.Define<int, int>(LogLevel.Warning, new EventId(14, "DisposedChildInRenderTreeFrame"), "A parent components {ParentComponentId} has a disposed component {ComponentId} as its child.");
2415

2516
private static readonly Action<ILogger, Exception?> AsyncInitialRender
26-
= LoggerMessage.Define(LogLevel.Debug, new EventId(20, "Render"), "The initial render task did not complete immediately.");
17+
= LoggerMessage.Define(LogLevel.Debug, new EventId(20, "AsyncInitialRender"), "The initial render task did not complete immediately.");
2718

2819
private static readonly Action<ILogger, int, Exception?> InitialRenderCompleted
29-
= LoggerMessage.Define<int>(LogLevel.Debug, new EventId(21, "UpdateDisplayAsync"), "The initial render of component {Id} is completed.");
20+
= LoggerMessage.Define<int>(LogLevel.Debug, new EventId(21, "InitialRenderCompleted"), "The initial render of component {Id} is completed.");
3021

3122
private static readonly Action<ILogger, string, string, Exception> UnhandledException
32-
= LoggerMessage.Define<string, string>(LogLevel.Error, new EventId(30, "LogUnhandledException"), "An unhandled exception happened during rendering: {Message}" + Environment.NewLine + "{StackTrace}");
23+
= LoggerMessage.Define<string, string>(LogLevel.Error, new EventId(30, "UnhandledException"), "An unhandled exception happened during rendering: {Message}" + Environment.NewLine + "{StackTrace}");
3324

3425
private static readonly Action<ILogger, Exception?> RenderCycleActiveAfterDispose
35-
= LoggerMessage.Define(LogLevel.Warning, new EventId(31, "LogRenderCycleActiveAfterDispose"), "A component attempted to update the render tree after the renderer was disposed.");
36-
37-
internal static void LogProcessingPendingRenders(this ILogger<TestRenderer> logger)
38-
{
39-
if (logger.IsEnabled(LogLevel.Debug))
40-
{
41-
ProcessingPendingRenders(logger, null);
42-
}
43-
}
26+
= LoggerMessage.Define(LogLevel.Warning, new EventId(31, "RenderCycleActiveAfterDispose"), "A component attempted to update the render tree after the renderer was disposed.");
4427

45-
internal static void LogNewRenderBatchReceived(this ILogger<TestRenderer> logger)
46-
{
47-
if (logger.IsEnabled(LogLevel.Debug))
48-
{
49-
NewRenderBatchReceived(logger, null);
50-
}
51-
}
5228

5329
internal static void LogComponentDisposed(this ILogger<TestRenderer> logger, int componentId)
5430
{
@@ -66,14 +42,6 @@ internal static void LogComponentRendered(this ILogger<TestRenderer> logger, int
6642
}
6743
}
6844

69-
internal static void LogChangedComponentsMarkupUpdated(this ILogger<TestRenderer> logger)
70-
{
71-
if (logger.IsEnabled(LogLevel.Debug))
72-
{
73-
ChangedComponentsMarkupUpdated(logger, null);
74-
}
75-
}
76-
7745
internal static void LogAsyncInitialRender(this ILogger<TestRenderer> logger)
7846
{
7947
if (logger.IsEnabled(LogLevel.Debug))

src/bunit.web/TestDoubles/ErrorBoundary/BunitErrorBoundaryLogger.cs

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
11
#if NET6_0_OR_GREATER
2-
using System;
3-
using System.Threading.Tasks;
4-
using Microsoft.AspNetCore.Components.Web;
52
using Microsoft.Extensions.Logging;
63

74
namespace Bunit.TestDoubles;
@@ -12,10 +9,8 @@ namespace Bunit.TestDoubles;
129
/// </summary>
1310
internal class BunitErrorBoundaryLogger : IErrorBoundaryLogger
1411
{
15-
private static readonly Action<ILogger, string, Exception> ExceptionCaughtByErrorBoundary = LoggerMessage.Define<string>(
16-
LogLevel.Warning,
17-
100,
18-
"Unhandled exception rendering component: {Message}");
12+
private static readonly Action<ILogger, string, Exception> ExceptionCaughtByErrorBoundary
13+
= LoggerMessage.Define<string>(LogLevel.Warning, new EventId(100, "ExceptionCaughtByErrorBoundary"), "Unhandled exception rendering component: {Message}");
1914

2015
private readonly ILogger logger;
2116

Lines changed: 4 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,25 @@
1-
using System.Globalization;
21
using Microsoft.Extensions.Logging;
32
using Serilog;
4-
using Serilog.Core;
53
using Serilog.Events;
4+
using Serilog.Templates;
65
using Xunit.Abstractions;
76

87
namespace Xunit;
98

109
public static class ServiceCollectionLoggingExtensions
1110
{
12-
[SuppressMessage("Reliability", "CA2000:Dispose objects before losing scope", Justification = "Serilog should dispose of its logger itself")]
1311
public static IServiceCollection AddXunitLogger(this IServiceCollection services, ITestOutputHelper outputHelper)
1412
{
1513
var serilogLogger = new LoggerConfiguration()
1614
.MinimumLevel.Verbose()
17-
.Enrich.With(new ThreadIDEnricher())
1815
.WriteTo.TestOutput(
1916
testOutputHelper: outputHelper,
20-
restrictedToMinimumLevel: LogEventLevel.Verbose,
21-
outputTemplate: ThreadIDEnricher.DefaultConsoleOutputTemplate,
22-
formatProvider: CultureInfo.InvariantCulture)
17+
formatter: new ExpressionTemplate("[{UtcDateTime(@t):mm:ss.ffffff} | {@l:u3} | {Substring(SourceContext, LastIndexOf(SourceContext, '.') + 1)} | {Coalesce(EventId.Name, '<none>')}] {@m}\n{@x}"),
18+
restrictedToMinimumLevel: LogEventLevel.Verbose)
2319
.CreateLogger();
2420

25-
services.AddSingleton<ILoggerFactory>(new LoggerFactory().AddSerilog(serilogLogger, dispose: true));
21+
services.AddSingleton<ILoggerFactory>(_ => new LoggerFactory().AddSerilog(serilogLogger, dispose: true));
2622
services.AddSingleton(typeof(ILogger<>), typeof(Logger<>));
2723
return services;
2824
}
29-
30-
private sealed class ThreadIDEnricher : ILogEventEnricher
31-
{
32-
internal const string DefaultConsoleOutputTemplate = "{Timestamp:yyyy-MM-dd HH:mm:ss} ({ThreadID}) [{Level}] {Message}{NewLine}{Exception}";
33-
34-
public void Enrich(LogEvent logEvent, ILogEventPropertyFactory propertyFactory)
35-
{
36-
logEvent.AddPropertyIfAbsent(propertyFactory.CreateProperty(
37-
"ThreadID", Environment.CurrentManagedThreadId.ToString("D4", CultureInfo.InvariantCulture)));
38-
}
39-
}
4025
}

tests/bunit.testassets/bunit.testassets.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
<ItemGroup>
1616
<PackageReference Include="Serilog" Version="3.0.1" />
17+
<PackageReference Include="Serilog.Expressions" Version="3.4.1" />
1718
</ItemGroup>
1819

1920
<ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.1'">

0 commit comments

Comments
 (0)