RandomSkunk.EasyLogger
1.0.0-rc1
See the version list below for details.
dotnet add package RandomSkunk.EasyLogger --version 1.0.0-rc1
NuGet\Install-Package RandomSkunk.EasyLogger -Version 1.0.0-rc1
<PackageReference Include="RandomSkunk.EasyLogger" Version="1.0.0-rc1" />
paket add RandomSkunk.EasyLogger --version 1.0.0-rc1
#r "nuget: RandomSkunk.EasyLogger, 1.0.0-rc1"
// Install RandomSkunk.EasyLogger as a Cake Addin #addin nuget:?package=RandomSkunk.EasyLogger&version=1.0.0-rc1&prerelease // Install RandomSkunk.EasyLogger as a Cake Tool #tool nuget:?package=RandomSkunk.EasyLogger&version=1.0.0-rc1&prerelease
RandomSkunk.EasyLogging
This library provides two simple logger base classes, EasyLogger
and EasyLogger<TCategoryName>
,
which implement ILogger
and ILogger<TCategoryName>
respectively.
What makes it an "easy" logger?
- Correctly implementing the
ILogger.BeginScope
method is difficult.EasyLogger
takes care of it for you.
- Implementing
ILogger.IsEnabled
isn't terribly difficult, but if you're not careful, you could end up writing logs at theNone
log level.EasyLogger
implements this method and doesn't accidentally writeNone
logs.
- Mocking the
ILogger.Log
in order to verify that a logging operation took place is difficult.- First, you need to deal with the generic type argument and the
state
parameter. It could be literally any type and any value. Where do you even begin? - What is the
formatter
parameter all about? - What about the logger's scope? What if you wanted to verify that the logger had a certain scope at the time of the log event? How would you mock that?
- Mocking the
EasyLogger.Write
method to verify that a logging operation took place is easy.
- First, you need to deal with the generic type argument and the
- The ease of mocking is tested and verified with Moq, FakeItEasy, and NSubstitute.
Mock Logger Setup and Verification
EasyLogger
is easy to mock regardless of the mocking library - just specify that its abstract
Write
method should be the target for setup or verification.
Note that the LogEntry
struct contains numerous methods for querying whether it is a match for a
setup or verification. Methods used below in the examples are IsInformation
, HasMessage
, and
HasAttribute
.
Moq
Mock<EasyLogger> mockLogger = new Mock<EasyLogger>();
EasyLogger logger = mockLogger.Object;
LogEntry? capturedLogEntry = null;
// Setup
mockLogger.Setup(m => m.Write(It.IsAny<LogEntry>()))
.Callback<LogEntry>(logEntry => capturedLogEntry = logEntry);
logger.LogInformation("Hello, {Who}!", "world");
// Verification
mockLogger.Verify(m => m.Write(It.Is<LogEntry>(log =>
log.IsInformation() && log.HasMessage("Hello, world!") && log.HasAttribute("Who", "world"))));
FakeItEasy
EasyLogger logger = A.Fake<EasyLogger>();
LogEntry? capturedLogEntry = null;
// Setup
A.CallTo(() => logger.Write(A<LogEntry>.Ignored))
.Invokes((LogEntry logEntry) => capturedLogEntry = logEntry);
logger.LogInformation("Hello, {Who}!", "world");
// Verification
A.CallTo(() => logger.Write(A<LogEntry>.That.Matches(log =>
log.IsInformation() && log.HasMessage("Hello, world!") && log.HasAttribute("Who", "world"))))
.MustHaveHappened();
NSubstitute
EasyLogger logger = Substitute.For<EasyLogger>();
LogEntry? capturedLogEntry = null;
// Setup
logger.When(m => m.Write(Arg.Any<LogEntry>()))
.Do(x => capturedLogEntry = x.Arg<LogEntry>());
logger.LogInformation("Hello, {Who}!", "world");
// Verification
logger.Received().Write(Arg.Is<LogEntry>(log =>
log.IsInformation() && log.HasMessage("Hello, world!") && log.HasAttribute("Who", "world")));
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. |
.NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
.NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
.NET Framework | net461 was computed. net462 is compatible. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
MonoAndroid | monoandroid was computed. |
MonoMac | monomac was computed. |
MonoTouch | monotouch was computed. |
Tizen | tizen40 was computed. tizen60 was computed. |
Xamarin.iOS | xamarinios was computed. |
Xamarin.Mac | xamarinmac was computed. |
Xamarin.TVOS | xamarintvos was computed. |
Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETFramework 4.6.2
- Microsoft.Extensions.Logging.Abstractions (>= 9.0.0)
- System.ValueTuple (>= 4.5.0)
-
.NETStandard 2.0
- Microsoft.Extensions.Logging.Abstractions (>= 9.0.0)
-
net8.0
- Microsoft.Extensions.Logging.Abstractions (>= 9.0.0)
-
net9.0
- Microsoft.Extensions.Logging.Abstractions (>= 9.0.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.