Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<Project>
<PropertyGroup>
<VersionPrefix>1.1.3</VersionPrefix>
<VersionPrefix>1.1.4</VersionPrefix>
<!-- SPDX license identifier for MIT -->
<PackageLicenseExpression>MIT</PackageLicenseExpression>

Expand Down
45 changes: 27 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ Simplified, structured logging for modern .NET apps — overloads, conditionals,
- 🔧 **Easy Integration** - Drop-in replacement for standard ILogger calls
- 🎯 **Scope Management** - Comprehensive scope tracking with automatic disposal
- ⚡ **Performance Monitoring** - Built-in timing and performance tracking
- 🧪 **Testing Support** - Complete testing framework with assertions and mocking
- 📦 **Multi-Target** - Supports .NET 8.0, .NET 9.0, and .NET Standard 2.1
- 🧪 **Testing Support** - In-memory `TestLogger` with assertions and search helpers
- 📦 **Multi-Target** - Supports .NET 8.0, .NET 9.0, .NET 10.0, .NET Standard 2.1, and .NET Standard 2.0

## Installation

Expand Down Expand Up @@ -107,6 +107,12 @@ using (logger.BeginScopeWith(new { UserId = userId, SessionId = sessionId }))
// Session logic
}

// Caller-aware scopes (adds MemberName/FilePath/LineNumber)
using (logger.BeginCallerScope())
{
logger.Debug("Tracing caller details");
}

// Timed scopes for performance monitoring
using (logger.TimeOperation("DatabaseQuery"))
{
Expand Down Expand Up @@ -170,10 +176,10 @@ using (logger.TimeMethod())

## Testing Support

Comprehensive testing framework for verifying logging behavior:
`TestLogger` implements `ILogger` and captures entries in memory so you can assert against what was written. Extension methods help you inspect entries, check for the presence of messages, and perform simple assertions that throw `InvalidOperationException` when they fail.

```csharp
[Test]
[Fact]
public void Should_Log_User_Registration()
{
// Arrange
Expand All @@ -184,30 +190,26 @@ public void Should_Log_User_Registration()
userService.RegisterUser("[email protected]");

// Assert
testLogger.Should().HaveLoggedInformation()
.WithMessage("User registered successfully")
.WithProperty("Email", "[email protected]");

// Alternative assertion syntax
testLogger.AssertLogEntry(LogLevel.Information, "User registered");
testLogger.AssertLogCount(1);
testLogger.Should().HaveExactly(1).LogEntries();
testLogger.AssertLogEntry(LogLevel.Information, "User registered");

var entry = testLogger.GetLastLogEntry();
entry!.FormattedMessage.Should().Contain("[email protected]");
}

[Test]
[Fact]
public void Should_Handle_Registration_Errors()
{
// Arrange
var testLogger = new TestLogger();
var userService = new UserService(testLogger);

// Act & Assert
Assert.Throws<ValidationException>(() =>
Assert.Throws<ValidationException>(() =>
userService.RegisterUser("invalid-email"));

testLogger.Should().HaveLoggedError()
.WithException<ValidationException>()
.WithMessage("Invalid email format");
testLogger.AssertLogEntry(LogLevel.Error, "Invalid email format");
testLogger.HasLogEntryWithException<ValidationException>().Should().BeTrue();
}
```

Expand All @@ -216,20 +218,27 @@ public void Should_Handle_Registration_Errors()
```csharp
// Get specific log entries
var lastEntry = testLogger.GetLastLogEntry();
var secondEntry = testLogger.GetLogEntry(1);
var errorEntries = testLogger.GetLogEntries(LogLevel.Error);
var entriesWithException = testLogger.GetLogEntriesWithException<ArgumentException>();

// Search log entries
var userEntries = testLogger.GetLogEntriesContaining("user");
var hasError = testLogger.HasLogEntry(LogLevel.Error, "failed");
var hasArgumentError = testLogger.HasLogEntryWithException<ArgumentException>(LogLevel.Error);

// Assertions
testLogger.AssertLogEntry(LogLevel.Warning, "threshold");
testLogger.AssertLogEntryAt(0, LogLevel.Information, "started");
testLogger.AssertLogCount(5);
testLogger.AssertLogEntry(LogLevel.Information, "expected message");
testLogger.AssertNoLogEntries(LogLevel.Error);
testLogger.AssertLogCount(LogLevel.Error, 1);
testLogger.AssertNoLogEntries();

// Clear logs between tests
testLogger.Clear();

// Optional: only record entries at or above this level (defaults to Trace)
testLogger.MinimumLogLevel = LogLevel.Information;
```

## Advanced Usage
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="9.0.11" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net10.0'">
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="10.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="10.0.1" />
</ItemGroup>

<ItemGroup>
Expand Down
Loading
Loading