Skip to content

Commit c069f1e

Browse files
(#171) Get logs with predicate
1 parent 0b1316b commit c069f1e

File tree

5 files changed

+68
-13
lines changed

5 files changed

+68
-13
lines changed

src/Stravaig.Extensions.Logging.Diagnostics.Tests/TestCaptureLoggerOfTTests.cs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,21 @@ namespace Stravaig.Extensions.Logging.Diagnostics.Tests;
88
[TestFixture]
99
public class TestCaptureLoggerOfTTests
1010
{
11+
[Test]
12+
public void ConstructorWithNullLoggerThrows()
13+
{
14+
Should.Throw<ArgumentNullException>(() => new TestCaptureLogger<object>(null!))
15+
.ParamName.ShouldBe("logger");
16+
}
17+
18+
[Test]
19+
public void ConstructorCategoryMismatchThrows()
20+
{
21+
var underlyingLogger = new TestCaptureLogger("NotTheRightCategory");
22+
Should.Throw<InvalidOperationException>(() => new TestCaptureLogger<object>(underlyingLogger))
23+
.Message.ShouldBe("The category name does not match the type of this logger. Expected \"object\", got \"NotTheRightCategory\".");
24+
}
25+
1126
[Test]
1227
public void CategoryNameIsBasedOnType()
1328
{
@@ -52,4 +67,20 @@ public void GetLogsWithExceptionsWillFilterOutNonExceptionLogs()
5267
logger.GetLogEntriesWithExceptions().Count.ShouldBe(2);
5368
logger.GetLogs().Count.ShouldBe(4);
5469
}
70+
71+
[Test]
72+
public void GetLogsMatchingPredicateWillFilterOutUnwantedLogs()
73+
{
74+
var logger = new TestCaptureLogger<TestCaptureLoggerOfTTests>();
75+
logger.LogInformation("Hello");
76+
logger.LogWarning("Hello, {Location}!", "World");
77+
logger.LogInformation("This is a log.");
78+
logger.LogError(new Exception(), "This has an exception.");
79+
80+
logger.GetLogs(static l => l.LogLevel == LogLevel.Information).Count.ShouldBe(2);
81+
82+
logger.GetLogs(static l => l.PropertyDictionary.ContainsKey("Location") && (string)l.PropertyDictionary["Location"] == "World")
83+
.Count.ShouldBe(1);
84+
logger.GetLogs().Count.ShouldBe(4);
85+
}
5586
}

src/Stravaig.Extensions.Logging.Diagnostics/ITestCaptureLogger.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using System;
12
using System.Collections.Generic;
23
using Microsoft.Extensions.Logging;
34

@@ -20,6 +21,13 @@ public interface ITestCaptureLogger : ILogger
2021
/// called won't be available in the list, and it will have to be called again.</remarks>
2122
IReadOnlyList<LogEntry> GetLogs();
2223

24+
/// <summary>
25+
/// Gets a read-only list of logs that is a snapshot of this logger filtered by the predicate.
26+
/// </summary>
27+
/// <remarks>Any additional logs added to the logger after this is
28+
/// called won't be available in the list, and it will have to be called again.</remarks>
29+
IReadOnlyList<LogEntry> GetLogs(Func<LogEntry, bool> predicate);
30+
2331
/// <summary>
2432
/// Gets a read-only list of logs that have an exception attached in sequential order.
2533
/// </summary>

src/Stravaig.Extensions.Logging.Diagnostics/TestCaptureLogger(OfTCategoryType).cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ public TestCaptureLogger()
2828
/// </summary>
2929
public TestCaptureLogger(TestCaptureLogger logger)
3030
{
31+
ArgumentNullException.ThrowIfNull(logger, nameof(logger));
3132
var expectedCategoryName = TypeNameHelper.GetTypeDisplayName(typeof(TCategoryType));
3233
if (logger.CategoryName != expectedCategoryName)
3334
throw new InvalidOperationException(
@@ -66,6 +67,10 @@ public void Reset()
6667
public IReadOnlyList<LogEntry> GetLogs()
6768
=> _logger.GetLogs();
6869

70+
/// <inheritdoc />
71+
public IReadOnlyList<LogEntry> GetLogs(Func<LogEntry, bool> predicate)
72+
=> _logger.GetLogs(predicate);
73+
6974
/// <summary>
7075
/// Gets a read-only list of logs that have an exception attached in sequential order.
7176
/// </summary>

src/Stravaig.Extensions.Logging.Diagnostics/TestCaptureLogger.cs

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -49,21 +49,23 @@ public IReadOnlyList<LogEntry> GetLogs()
4949
}
5050
}
5151

52-
5352
/// <inheritdoc />
54-
public IReadOnlyList<LogEntry> GetLogEntriesWithExceptions()
53+
public IReadOnlyList<LogEntry> GetLogs(Func<LogEntry, bool> predicate)
5554
{
56-
List<LogEntry> result;
5755
lock (_syncRoot)
5856
{
59-
result = _logs
60-
.Where(l => l.Exception != null)
61-
.ToList();
57+
return _logs
58+
.Where(predicate)
59+
.OrderBy(static log => log)
60+
.ToArray();
6261
}
63-
result.Sort();
64-
return result;
6562
}
6663

64+
65+
/// <inheritdoc />
66+
public IReadOnlyList<LogEntry> GetLogEntriesWithExceptions()
67+
=> GetLogs(log => log.Exception != null);
68+
6769
/// <summary>
6870
/// Writes a log entry
6971
/// </summary>

src/Stravaig.Extensions.Logging.Diagnostics/TestCaptureLoggerProvider.cs

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -103,18 +103,27 @@ public IReadOnlyList<LogEntry> GetAllLogEntries()
103103
}
104104

105105
/// <summary>
106-
/// Gets all log entries with exceptions attached regardless of the
107-
/// Category they were logged as.
106+
/// Gets all log entries matching the predicate regardless of the Category
107+
/// they were logged as.
108108
/// </summary>
109-
/// <returns>A read only list of <see cref="LogEntry"/></returns>
110-
public IReadOnlyList<LogEntry> GetAllLogEntriesWithExceptions()
109+
/// <returns>A read only list of <see cref="LogEntry"/> objects.</returns>
110+
public IReadOnlyList<LogEntry> GetLogEntriesMatchingPredicate(Func<LogEntry, bool> predicate)
111111
{
112112
var loggers = _captures.Values;
113-
var allLogs = loggers.SelectMany(l => l.GetLogEntriesWithExceptions()).ToList();
113+
var allLogs = loggers.SelectMany(l => l.GetLogs(predicate)).ToList();
114114
allLogs.Sort();
115115
return allLogs;
116116
}
117117

118+
119+
/// <summary>
120+
/// Gets all log entries with exceptions attached regardless of the
121+
/// Category they were logged as.
122+
/// </summary>
123+
/// <returns>A read only list of <see cref="LogEntry"/> objects.</returns>
124+
public IReadOnlyList<LogEntry> GetAllLogEntriesWithExceptions()
125+
=> GetLogEntriesMatchingPredicate(static log => log.Exception != null);
126+
118127
/// <summary>
119128
/// Resets the captures to an empty state.
120129
/// </summary>

0 commit comments

Comments
 (0)