From 890c75c1b3b83008a9c7b43bbe0f4784d5d82719 Mon Sep 17 00:00:00 2001 From: Gregory Jordan Date: Sat, 22 Jun 2024 21:00:09 -0500 Subject: [PATCH 1/2] Upgrade project and add tests This commit updates the `serilog-enrichers-memory` solution to support Visual Studio 2022 and introduces a new test project to enhance code quality and maintainability. Key changes include: - Upgraded the solution file to Visual Studio 2022 and added a new test project (`Serilog.Enrichers.Memory.Tests`) with a "tests" solution folder and a "Solution Items" folder for better organization. - Updated copyright year in `MemoryUsageEnricher.cs` to 2024 and refactored the file using the latest C# syntax, including file-scoped namespaces and target-typed `new` expressions. Improved documentation comments and aligned the namespace declaration with ReSharper's recommendations. - Introduced a new static class `ProcessLoggerConfigurationExtensions` providing an extension method `WithMemoryUsage` to enrich log events with memory usage information, leveraging the latest C# syntax for cleaner method chaining. - Updated the main project file to target .NET 8.0, upgraded the Serilog dependency to version 4.0.0, and updated the package version to 1.1.0 to reflect new features and improvements. - Added unit tests for `MemoryUsageEnricher` and `ProcessLoggerConfigurationExtensions` in new test files, ensuring correct functionality and error handling. - Created a new test project file targeting .NET 8.0 with modern project settings, including implicit usings and nullable reference types, and added necessary package references for xUnit, Moq, and Serilog testing. --- serilog-enrichers-memory.sln | 19 +++++- .../Enrichers/MemoryUsageEnricher.cs | 37 ++++++----- .../ProcessLoggerConfigurationExtensions.cs | 34 +++++----- .../Serilog.Enrichers.Memory.csproj | 11 ++-- .../MemoryUsageEnricherTests.cs | 66 +++++++++++++++++++ ...ocessLoggerConfigurationExtensionsTests.cs | 19 ++++++ .../Serilog.Enrichers.Memory.Tests.csproj | 29 ++++++++ 7 files changed, 170 insertions(+), 45 deletions(-) create mode 100644 tests/Serilog.Enrichers.Memory.Tests/MemoryUsageEnricherTests.cs create mode 100644 tests/Serilog.Enrichers.Memory.Tests/ProcessLoggerConfigurationExtensionsTests.cs create mode 100644 tests/Serilog.Enrichers.Memory.Tests/Serilog.Enrichers.Memory.Tests.csproj diff --git a/serilog-enrichers-memory.sln b/serilog-enrichers-memory.sln index 726ba78..ecd4b8f 100644 --- a/serilog-enrichers-memory.sln +++ b/serilog-enrichers-memory.sln @@ -1,20 +1,25 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.26430.15 +# Visual Studio Version 17 +VisualStudioVersion = 17.10.35013.160 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{037440DE-440B-4129-9F7A-09B42D00397E}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "assets", "assets", "{E9D1B5E1-DEB9-4A04-8BAB-24EC7240ADAF}" ProjectSection(SolutionItems) = preProject Build.ps1 = Build.ps1 - NuGet.Config = NuGet.Config README.md = README.md assets\SerilogMemory.snk = assets\SerilogMemory.snk EndProjectSection EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Serilog.Enrichers.Memory", "src\Serilog.Enrichers.Memory\Serilog.Enrichers.Memory.csproj", "{2312A998-5E53-4355-9CB6-6014252B3E88}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{F1A28E03-3590-4F6F-B0D7-7D3008BCDF23}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Serilog.Enrichers.Memory.Tests", "tests\Serilog.Enrichers.Memory.Tests\Serilog.Enrichers.Memory.Tests.csproj", "{CC27194E-C8D2-4B1D-ACC5-28F9BDF49546}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{5AD5AD8E-809B-4ADA-BEE6-45AF2CF23825}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -25,11 +30,19 @@ Global {2312A998-5E53-4355-9CB6-6014252B3E88}.Debug|Any CPU.Build.0 = Debug|Any CPU {2312A998-5E53-4355-9CB6-6014252B3E88}.Release|Any CPU.ActiveCfg = Release|Any CPU {2312A998-5E53-4355-9CB6-6014252B3E88}.Release|Any CPU.Build.0 = Release|Any CPU + {CC27194E-C8D2-4B1D-ACC5-28F9BDF49546}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CC27194E-C8D2-4B1D-ACC5-28F9BDF49546}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CC27194E-C8D2-4B1D-ACC5-28F9BDF49546}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CC27194E-C8D2-4B1D-ACC5-28F9BDF49546}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(NestedProjects) = preSolution {2312A998-5E53-4355-9CB6-6014252B3E88} = {037440DE-440B-4129-9F7A-09B42D00397E} + {CC27194E-C8D2-4B1D-ACC5-28F9BDF49546} = {F1A28E03-3590-4F6F-B0D7-7D3008BCDF23} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {CF4B9AB9-DF05-417C-A8DE-CEBD1695A26B} EndGlobalSection EndGlobal diff --git a/src/Serilog.Enrichers.Memory/Enrichers/MemoryUsageEnricher.cs b/src/Serilog.Enrichers.Memory/Enrichers/MemoryUsageEnricher.cs index 53598d1..f34eea9 100644 --- a/src/Serilog.Enrichers.Memory/Enrichers/MemoryUsageEnricher.cs +++ b/src/Serilog.Enrichers.Memory/Enrichers/MemoryUsageEnricher.cs @@ -1,4 +1,4 @@ -// Copyright 2017 Josh Schreuder +// Copyright 2017, 2024 Josh Schreuder // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -16,26 +16,27 @@ using Serilog.Core; using Serilog.Events; -namespace Serilog.Enrichers +// ReSharper disable CheckNamespace +namespace Serilog.Enrichers; +// ReSharper restore CheckNamespace + +/// +/// Enriches log events with a MemoryUsage property containing an estimation of the current process' memory usage in bytes. +/// +public class MemoryUsageEnricher : ILogEventEnricher { /// - /// Enriches log events with a MemoryUsage property containing an estimation of the current process' memory usage in bytes. + /// The property name added to enriched log events. /// - public class MemoryUsageEnricher : ILogEventEnricher - { - /// - /// The property name added to enriched log events. - /// - public const string MemoryUsagePropertyName = "MemoryUsage"; + public const string MemoryUsagePropertyName = "MemoryUsage"; - /// - /// Enrich the log event. - /// - /// The log event to enrich. - /// Factory for creating new properties to add to the event. - public void Enrich(LogEvent logEvent, ILogEventPropertyFactory propertyFactory) - { - logEvent.AddPropertyIfAbsent(propertyFactory.CreateProperty(MemoryUsagePropertyName, GC.GetTotalMemory(false))); - } + /// + /// Enrich the log event. + /// + /// The log event to enrich. + /// Factory for creating new properties to add to the event. + public void Enrich(LogEvent logEvent, ILogEventPropertyFactory propertyFactory) + { + logEvent.AddPropertyIfAbsent(propertyFactory.CreateProperty(MemoryUsagePropertyName, GC.GetTotalMemory(false))); } } \ No newline at end of file diff --git a/src/Serilog.Enrichers.Memory/ProcessLoggerConfigurationExtensions.cs b/src/Serilog.Enrichers.Memory/ProcessLoggerConfigurationExtensions.cs index 73525ee..72b00fd 100644 --- a/src/Serilog.Enrichers.Memory/ProcessLoggerConfigurationExtensions.cs +++ b/src/Serilog.Enrichers.Memory/ProcessLoggerConfigurationExtensions.cs @@ -17,24 +17,24 @@ using Serilog.Configuration; using Serilog.Enrichers; -namespace Serilog +// ReSharper disable CheckNamespace +namespace Serilog; +// ReSharper restore CheckNamespace + +/// +/// Extends to add enrichers related to memory. +/// capabilities. +/// +public static class ProcessLoggerConfigurationExtensions { /// - /// Extends to add enrichers related to memory. - /// capabilities. + /// Enrich log events with memory usage/>. /// - public static class ProcessLoggerConfigurationExtensions - { - /// - /// Enrich log events with memory usage/>. - /// - /// Logger enrichment configuration. - /// Configuration object allowing method chaining. - public static LoggerConfiguration WithMemoryUsage( - this LoggerEnrichmentConfiguration enrichmentConfiguration) - { - if (enrichmentConfiguration == null) throw new ArgumentNullException(nameof(enrichmentConfiguration)); - return enrichmentConfiguration.With(); - } - } + /// Logger enrichment configuration. + /// Configuration object allowing method chaining. + public static LoggerConfiguration WithMemoryUsage( + this LoggerEnrichmentConfiguration enrichmentConfiguration) => + enrichmentConfiguration == null + ? throw new ArgumentNullException(nameof(enrichmentConfiguration)) + : enrichmentConfiguration.With(); } \ No newline at end of file diff --git a/src/Serilog.Enrichers.Memory/Serilog.Enrichers.Memory.csproj b/src/Serilog.Enrichers.Memory/Serilog.Enrichers.Memory.csproj index 0c9ca4c..1191417 100644 --- a/src/Serilog.Enrichers.Memory/Serilog.Enrichers.Memory.csproj +++ b/src/Serilog.Enrichers.Memory/Serilog.Enrichers.Memory.csproj @@ -1,10 +1,9 @@  - The memory enricher for Serilog. 1.0.3 Josh Schreuder - net45;netstandard1.3;netcoreapp2.0;netstandard2.0 + net8.0 Serilog.Enrichers.Memory ../../assets/SerilogMemory.snk true @@ -15,15 +14,13 @@ https://github.com/JoshSchreuder/serilog-enrichers-memory http://www.apache.org/licenses/LICENSE-2.0 false - 1.0.4 + 1.1.0 - - + - - + \ No newline at end of file diff --git a/tests/Serilog.Enrichers.Memory.Tests/MemoryUsageEnricherTests.cs b/tests/Serilog.Enrichers.Memory.Tests/MemoryUsageEnricherTests.cs new file mode 100644 index 0000000..e13cd7b --- /dev/null +++ b/tests/Serilog.Enrichers.Memory.Tests/MemoryUsageEnricherTests.cs @@ -0,0 +1,66 @@ +using System.Diagnostics.CodeAnalysis; +using Moq; +using Serilog.Core; +using Serilog.Events; +using Serilog.Parsing; + +namespace Serilog.Enrichers.Memory.Tests; + +[ExcludeFromCodeCoverage] +public class MemoryUsageEnricherTests +{ + [Fact] + public void Enrich_ShouldAddMemoryUsageProperty() + { + // Arrange + var enricher = new MemoryUsageEnricher(); + var logEvent = new LogEvent(DateTimeOffset.Now, LogEventLevel.Information, null, new MessageTemplate(new List()), new List()); + var propertyFactoryMock = new Mock(); + propertyFactoryMock.Setup(x => x.CreateProperty(It.IsAny(), It.IsAny(), It.IsAny())) + .Returns((string name, object value, bool destructureObjects) => new LogEventProperty(name, new ScalarValue(value))); + + // Act + enricher.Enrich(logEvent, propertyFactoryMock.Object); + + // Assert + var memoryUsageProperty = logEvent.Properties.FirstOrDefault(p => p.Key == MemoryUsageEnricher.MemoryUsagePropertyName); + Assert.NotNull(memoryUsageProperty.Value); + } + + [Fact] + public void Enrich_ShouldAddMemoryUsageWithPositiveValue() + { + // Arrange + var enricher = new MemoryUsageEnricher(); + var logEvent = new LogEvent(DateTimeOffset.Now, LogEventLevel.Information, null, new MessageTemplate(new List()), new List()); + var propertyFactoryMock = new Mock(); + propertyFactoryMock.Setup(x => x.CreateProperty(It.IsAny(), It.IsAny(), It.IsAny())) + .Returns((string name, object value, bool destructureObjects) => new LogEventProperty(name, new ScalarValue(value))); + + // Act + enricher.Enrich(logEvent, propertyFactoryMock.Object); + + // Assert + var memoryUsageProperty = logEvent.Properties.FirstOrDefault(p => p.Key == MemoryUsageEnricher.MemoryUsagePropertyName); + Assert.True(memoryUsageProperty.Value is ScalarValue scalarValue && scalarValue.Value is long && (long)scalarValue.Value > 0); + } + + [Fact] + public void Enrich_ShouldNotAddMemoryUsagePropertyTwice() + { + // Arrange + var enricher = new MemoryUsageEnricher(); + var logEvent = new LogEvent(DateTimeOffset.Now, LogEventLevel.Information, null, new MessageTemplate(new List()), new List()); + var propertyFactoryMock = new Mock(); + propertyFactoryMock.Setup(x => x.CreateProperty(It.IsAny(), It.IsAny(), It.IsAny())) + .Returns((string name, object value, bool destructureObjects) => new LogEventProperty(name, new ScalarValue(value))); + + // Act + enricher.Enrich(logEvent, propertyFactoryMock.Object); + enricher.Enrich(logEvent, propertyFactoryMock.Object); // Enrich a second time + + // Assert + var memoryUsageProperties = logEvent.Properties.Where(p => p.Key == MemoryUsageEnricher.MemoryUsagePropertyName); + Assert.Single(memoryUsageProperties); + } +} \ No newline at end of file diff --git a/tests/Serilog.Enrichers.Memory.Tests/ProcessLoggerConfigurationExtensionsTests.cs b/tests/Serilog.Enrichers.Memory.Tests/ProcessLoggerConfigurationExtensionsTests.cs new file mode 100644 index 0000000..fe2b793 --- /dev/null +++ b/tests/Serilog.Enrichers.Memory.Tests/ProcessLoggerConfigurationExtensionsTests.cs @@ -0,0 +1,19 @@ +using System.Diagnostics.CodeAnalysis; +using Moq; +using Serilog.Configuration; + +namespace Serilog.Enrichers.Memory.Tests; + +[ExcludeFromCodeCoverage] +public class ProcessLoggerConfigurationExtensionsTests +{ + [Fact] + public void WithMemoryUsage_ThrowsArgumentNullException_WhenEnrichmentConfigurationIsNull() + { + // Arrange + LoggerEnrichmentConfiguration enrichmentConfiguration = null; + + // Act & Assert + Assert.Throws(() => ProcessLoggerConfigurationExtensions.WithMemoryUsage(enrichmentConfiguration)); + } +} \ No newline at end of file diff --git a/tests/Serilog.Enrichers.Memory.Tests/Serilog.Enrichers.Memory.Tests.csproj b/tests/Serilog.Enrichers.Memory.Tests/Serilog.Enrichers.Memory.Tests.csproj new file mode 100644 index 0000000..2d96071 --- /dev/null +++ b/tests/Serilog.Enrichers.Memory.Tests/Serilog.Enrichers.Memory.Tests.csproj @@ -0,0 +1,29 @@ + + + + net8.0 + enable + enable + + false + true + + + + + + + + + + + + + + + + + + + + From 97823a3dfb886c7aa8e8d82f62564da0b812977e Mon Sep 17 00:00:00 2001 From: Gregory Jordan Date: Sat, 22 Jun 2024 21:00:50 -0500 Subject: [PATCH 2/2] Remove "Solution Items" project Removed the "Solution Items" project from the solution to streamline project structure and focus on specific project-related files. --- serilog-enrichers-memory.sln | 2 -- 1 file changed, 2 deletions(-) diff --git a/serilog-enrichers-memory.sln b/serilog-enrichers-memory.sln index ecd4b8f..de88cf7 100644 --- a/serilog-enrichers-memory.sln +++ b/serilog-enrichers-memory.sln @@ -18,8 +18,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{F1A28E03 EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Serilog.Enrichers.Memory.Tests", "tests\Serilog.Enrichers.Memory.Tests\Serilog.Enrichers.Memory.Tests.csproj", "{CC27194E-C8D2-4B1D-ACC5-28F9BDF49546}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{5AD5AD8E-809B-4ADA-BEE6-45AF2CF23825}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU