Skip to content

Commit 3038ad2

Browse files
Support custom timestamp format
Support customising the format of the timestamps. Resolves #311.
1 parent 2c68de7 commit 3038ad2

File tree

3 files changed

+26
-4
lines changed

3 files changed

+26
-4
lines changed

src/Logging.XUnit/XUnitLogger.cs

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ namespace MartinCostello.Logging.XUnit;
1313
/// </summary>
1414
public partial class XUnitLogger : ILogger
1515
{
16-
//// Based on https://github.com/aspnet/Logging/blob/master/src/Microsoft.Extensions.Logging.Console/ConsoleLogger.cs
16+
//// Based on https://github.com/dotnet/runtime/blob/65067052e433eda400c5e7cc9f7b21c84640f901/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLogger.cs#L41-L66
1717

1818
/// <summary>
1919
/// The padding to use for log levels.
@@ -36,6 +36,11 @@ public partial class XUnitLogger : ILogger
3636
[ThreadStatic]
3737
private static StringBuilder? _logBuilder;
3838

39+
/// <summary>
40+
/// The format string used to format the timestamp in log messages.
41+
/// </summary>
42+
private readonly string _timestampFormat;
43+
3944
/// <summary>
4045
/// Gets or sets the filter to use.
4146
/// </summary>
@@ -52,6 +57,7 @@ private XUnitLogger(string name, XUnitLoggerOptions? options)
5257

5358
_filter = options?.Filter ?? (static (_, _) => true);
5459
_messageSinkMessageFactory = options?.MessageSinkMessageFactory ?? (message => new DiagnosticMessage(message));
60+
_timestampFormat = options?.TimestampFormat ?? "u";
5561
IncludeScopes = options?.IncludeScopes ?? false;
5662
}
5763

@@ -156,7 +162,8 @@ public virtual void WriteMessage(LogLevel logLevel, int eventId, string? message
156162
logBuilder.Append(Name);
157163
logBuilder.Append('[');
158164
logBuilder.Append(eventId);
159-
logBuilder.AppendLine("]");
165+
logBuilder.Append(']');
166+
logBuilder.AppendLine();
160167

161168
if (IncludeScopes)
162169
{
@@ -184,11 +191,17 @@ public virtual void WriteMessage(LogLevel logLevel, int eventId, string? message
184191
logBuilder.Append(exception.ToString());
185192
}
186193

187-
string formatted = logBuilder.ToString();
194+
// Prefix the formatted message so it renders like this:
195+
// [{timestamp}] {logLevelString}{message}
196+
logBuilder.Insert(0, logLevelString);
197+
logBuilder.Insert(0, "] ");
198+
logBuilder.Insert(0, Clock().ToString(_timestampFormat, CultureInfo.CurrentCulture));
199+
logBuilder.Insert(0, '[');
200+
201+
string line = logBuilder.ToString();
188202

189203
try
190204
{
191-
var line = $"[{Clock():u}] {logLevelString}{formatted}";
192205
if (outputHelper != null)
193206
{
194207
outputHelper.WriteLine(line);

src/Logging.XUnit/XUnitLoggerOptions.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,12 @@ public XUnitLoggerOptions()
3333
/// Gets or sets a value indicating whether to include scopes.
3434
/// </summary>
3535
public bool IncludeScopes { get; set; }
36+
37+
/// <summary>
38+
/// Gets or sets format string used to format the timestamp in log messages. Defaults to <c>u</c>.
39+
/// </summary>
40+
#if NET7_0_OR_GREATER
41+
[StringSyntax(StringSyntaxAttribute.DateTimeFormat)]
42+
#endif
43+
public string? TimestampFormat { get; set; }
3644
}

tests/Logging.XUnit.Tests/IntegrationTests.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,7 @@ public static void Can_Configure_xunit_For_ILoggerFactory_With_Options_Factory()
177177
var options = new XUnitLoggerOptions()
178178
{
179179
Filter = (_, level) => level >= LogLevel.Error,
180+
TimestampFormat = "yyyy-MM-dd HH:mm:ss.fff",
180181
};
181182

182183
var logger = BootstrapFactory((builder) => builder.AddXUnit(mock.Object, () => options));

0 commit comments

Comments
 (0)