Skip to content

Commit d4c7f7c

Browse files
committed
NullTarget - Avoid string-allocation upfront when FormatMessage = true
1 parent b98723f commit d4c7f7c

File tree

2 files changed

+33
-3
lines changed

2 files changed

+33
-3
lines changed

src/NLog/Targets/NullTarget.cs

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@
3333

3434
namespace NLog.Targets
3535
{
36+
using System.Text;
37+
3638
/// <summary>
3739
/// Discards log messages. Used mainly for debugging and benchmarking.
3840
/// </summary>
@@ -54,13 +56,36 @@ namespace NLog.Targets
5456
[Target("Null")]
5557
public sealed class NullTarget : TargetWithLayout
5658
{
59+
/// <summary>
60+
/// Gets the number of times this target has been called.
61+
/// </summary>
62+
/// <docgen category='Layout Options' order='10' />
63+
public int LogEventCounter => _logEventCounter;
64+
private int _logEventCounter;
65+
5766
/// <summary>
5867
/// Gets or sets a value indicating whether to perform layout calculation.
5968
/// </summary>
6069
/// <remarks>Default: <see langword="false"/></remarks>
6170
/// <docgen category='Layout Options' order='10' />
6271
public bool FormatMessage { get; set; }
6372

73+
/// <summary>
74+
/// Gets the last message rendered by this target.
75+
/// </summary>
76+
/// <remarks>Requires <see cref="FormatMessage"/> = <see langword="true"/></remarks>
77+
/// <docgen category='Layout Options' order='10' />
78+
public string LastMessage => _lastMesageBuilder?.ToString() ?? string.Empty;
79+
private StringBuilder? _lastMesageBuilder;
80+
81+
/// <summary>
82+
/// Gets the last LogEvent rendered by this target.
83+
/// </summary>
84+
/// <remarks>Requires <see cref="FormatMessage"/> = <see langword="true"/></remarks>
85+
/// <docgen category='Layout Options' order='10' />
86+
public LogEventInfo? LastLogEvent => _lastLogEvent;
87+
private LogEventInfo? _lastLogEvent;
88+
6489
/// <summary>
6590
/// Initializes a new instance of the <see cref="NullTarget" /> class.
6691
/// </summary>
@@ -84,9 +109,14 @@ public NullTarget(string name) : this()
84109
/// <param name="logEvent">The logging event.</param>
85110
protected override void Write(LogEventInfo logEvent)
86111
{
112+
_logEventCounter++;
113+
87114
if (FormatMessage)
88115
{
89-
RenderLogEvent(Layout, logEvent);
116+
_lastLogEvent = logEvent;
117+
var stringBuilder = _lastMesageBuilder ?? (_lastMesageBuilder = new StringBuilder(128));
118+
stringBuilder.Length = 0;
119+
Layout?.Render(logEvent, stringBuilder);
90120
}
91121
}
92122
}

tests/NLog.UnitTests/LayoutRenderers/AllEventPropertiesTests.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ public void IncludeScopeProperties()
120120

121121
var logFactory = new LogFactory().Setup().LoadConfiguration(builder =>
122122
{
123-
builder.ForLogger().WriteTo(new DebugTarget("debug") { Layout = testLayout }).WithAsync();
123+
builder.ForLogger().WriteTo(new NullTarget("debug") { Layout = testLayout, FormatMessage = true }).WithAsync();
124124
}).LogFactory;
125125

126126
var ev = new LogEventInfo(LogLevel.Info, null, null, "{pi:0}", new object[] { 3.14159265359 });
@@ -130,7 +130,7 @@ public void IncludeScopeProperties()
130130
logger.Debug(ev);
131131
}
132132

133-
var target = logFactory.Configuration.AllTargets.OfType<DebugTarget>().First();
133+
var target = logFactory.Configuration.AllTargets.OfType<NullTarget>().First();
134134
logFactory.Shutdown(); // Flush
135135

136136
var result = target.LastMessage;

0 commit comments

Comments
 (0)