diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 69c0ca5..2158dac 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -28,11 +28,14 @@ jobs: - name: Setup uses: actions/setup-dotnet@v1 with: - dotnet-version: 7.0.x + dotnet-version: 8.0.x source-url: https://nuget.pkg.github.com/${{ github.repository_owner }}/index.json - name: Restore run: dotnet restore + + - name: Test + run: dotnet test --no-restore --verbosity normal - name: Pack run: dotnet pack --no-restore -c:Release diff --git a/.github/workflows/nuget.yml b/.github/workflows/nuget.yml index 58cd4d9..4ffbcb0 100644 --- a/.github/workflows/nuget.yml +++ b/.github/workflows/nuget.yml @@ -25,12 +25,15 @@ jobs: - name: Setup .NET uses: actions/setup-dotnet@v1 with: - dotnet-version: 7.0.x + dotnet-version: 8.0.x source-url: https://nuget.pkg.github.com/${{ github.repository_owner }}/index.json - name: Restore - run: dotnet restore + run: dotnet restore + - name: Test + run: dotnet test --no-restore --verbosity normal + - name: Pack run: dotnet pack --no-restore -c:Release diff --git a/README.md b/README.md index a6afa7e..8e38444 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,7 @@ [![Build](https://github.com/Jandini/serilog-enrichers-classname/actions/workflows/build.yml/badge.svg)](https://github.com/Jandini/serilog-enrichers-classname/actions/workflows/build.yml) [![NuGet](https://github.com/Jandini/serilog-enrichers-classname/actions/workflows/nuget.yml/badge.svg)](https://github.com/Jandini/serilog-enrichers-classname/actions/workflows/nuget.yml) +[![NuGet Version](http://img.shields.io/nuget/v/Serilog.Enrichers.ClassName?style=flat&label=Version)](https://www.nuget.org/packages/Serilog.Enrichers.ClassName/) Enrich Serilog logs with class name only. diff --git a/src/Serilog.Enrichers.ClassName.Demo/DemoClass.cs b/src/Serilog.Enrichers.ClassName.Demo/DemoClass.cs new file mode 100644 index 0000000..0012eba --- /dev/null +++ b/src/Serilog.Enrichers.ClassName.Demo/DemoClass.cs @@ -0,0 +1,14 @@ +using Serilog; + +namespace SerilogDemo +{ + internal class DemoClass + { + private static readonly ILogger Log = Serilog.Log.ForContext(); + + public void DoWork() + { + Log.Information("Doing some work..."); + } + } +} diff --git a/src/Serilog.Enrichers.ClassName.Demo/Program.cs b/src/Serilog.Enrichers.ClassName.Demo/Program.cs new file mode 100644 index 0000000..734dee1 --- /dev/null +++ b/src/Serilog.Enrichers.ClassName.Demo/Program.cs @@ -0,0 +1,28 @@ +// See https://aka.ms/new-console-template for more information +// Configure Serilog with SourceContext +using Serilog; +using Serilog.Enrichers.ClassName; +using SerilogDemo; + +namespace Demo; + +class MyProgram +{ + public static void Main(string[] args) + { + Log.Logger = new LoggerConfiguration() + .MinimumLevel.Debug() + .Enrich.WithClassName() + .WriteTo.Console(outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3}] [{ClassName}] [{SourceContext}] {Message:lj}{NewLine}{Exception}") + .CreateLogger(); + + Log.Information("Application starting..."); + + // Log from another class + var demoClass = new DemoClass(); + demoClass.DoWork(); + + Log.Information("Application ending..."); + Log.CloseAndFlush(); + } +} diff --git a/src/Serilog.Enrichers.ClassName.Demo/Serilog.Enrichers.ClassName.Demo.csproj b/src/Serilog.Enrichers.ClassName.Demo/Serilog.Enrichers.ClassName.Demo.csproj new file mode 100644 index 0000000..84467c9 --- /dev/null +++ b/src/Serilog.Enrichers.ClassName.Demo/Serilog.Enrichers.ClassName.Demo.csproj @@ -0,0 +1,19 @@ + + + + Exe + net8.0 + enable + enable + + + + + + + + + + + + diff --git a/src/Serilog.Enrichers.ClassName.Tests/ClassNameEnricherTests.cs b/src/Serilog.Enrichers.ClassName.Tests/ClassNameEnricherTests.cs new file mode 100644 index 0000000..d72697a --- /dev/null +++ b/src/Serilog.Enrichers.ClassName.Tests/ClassNameEnricherTests.cs @@ -0,0 +1,33 @@ +using Serilog.Sinks.TestCorrelator; + +namespace Serilog.Enrichers.ClassName.Tests +{ + public class ClassNameEnricherTests + { + [Fact] + public void ClassNameProperty_MustExistAndMatch() + { + // Arrange + const string expectedClassName = "ClassNameEnricher"; + var logger = new LoggerConfiguration() + .Enrich.With(new ClassNameEnricher()) + .WriteTo.TestCorrelator() + .CreateLogger() + .ForContext("SourceContext", typeof(ClassNameEnricher).FullName); + + using (TestCorrelator.CreateContext()) + { + // Act + logger.Information("Test log"); + + // Assert + var logEvent = TestCorrelator.GetLogEventsFromCurrentContext().Single(); + Assert.NotNull(logEvent); + + // Verify if the UserId property is added + Assert.True(logEvent.Properties.ContainsKey("ClassName")); + Assert.Equal(expectedClassName, logEvent.Properties["ClassName"].ToString().Trim('"')); + } + } + } +} \ No newline at end of file diff --git a/src/Serilog.Enrichers.ClassName.Tests/Serilog.Enrichers.ClassName.Tests.csproj b/src/Serilog.Enrichers.ClassName.Tests/Serilog.Enrichers.ClassName.Tests.csproj new file mode 100644 index 0000000..95d173f --- /dev/null +++ b/src/Serilog.Enrichers.ClassName.Tests/Serilog.Enrichers.ClassName.Tests.csproj @@ -0,0 +1,35 @@ + + + + net8.0 + enable + enable + + false + true + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + + + + diff --git a/src/Serilog.Enrichers.ClassName.sln b/src/Serilog.Enrichers.ClassName.sln index 4f0eb9f..f2eaf5a 100644 --- a/src/Serilog.Enrichers.ClassName.sln +++ b/src/Serilog.Enrichers.ClassName.sln @@ -3,7 +3,11 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.5.33516.290 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{D12BECA3-8DFB-48E5-9430-3C060D774BD6}") = "Serilog.Enrichers.ClassName", "Serilog.Enrichers.ClassName\Serilog.Enrichers.ClassName.csproj", "{C7AF6148-7DAC-41C4-8CC6-A2B68404BDE8}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Serilog.Enrichers.ClassName", "Serilog.Enrichers.ClassName\Serilog.Enrichers.ClassName.csproj", "{C7AF6148-7DAC-41C4-8CC6-A2B68404BDE8}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Serilog.Enrichers.ClassName.Tests", "Serilog.Enrichers.ClassName.Tests\Serilog.Enrichers.ClassName.Tests.csproj", "{1964BEA8-3030-4E02-AD97-87D65E16157A}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Serilog.Enrichers.ClassName.Demo", "Serilog.Enrichers.ClassName.Demo\Serilog.Enrichers.ClassName.Demo.csproj", "{B92B7663-6086-44DA-B1FE-ACEFF082D8CF}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -15,6 +19,14 @@ Global {C7AF6148-7DAC-41C4-8CC6-A2B68404BDE8}.Debug|Any CPU.Build.0 = Debug|Any CPU {C7AF6148-7DAC-41C4-8CC6-A2B68404BDE8}.Release|Any CPU.ActiveCfg = Release|Any CPU {C7AF6148-7DAC-41C4-8CC6-A2B68404BDE8}.Release|Any CPU.Build.0 = Release|Any CPU + {1964BEA8-3030-4E02-AD97-87D65E16157A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1964BEA8-3030-4E02-AD97-87D65E16157A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1964BEA8-3030-4E02-AD97-87D65E16157A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1964BEA8-3030-4E02-AD97-87D65E16157A}.Release|Any CPU.Build.0 = Release|Any CPU + {B92B7663-6086-44DA-B1FE-ACEFF082D8CF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B92B7663-6086-44DA-B1FE-ACEFF082D8CF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B92B7663-6086-44DA-B1FE-ACEFF082D8CF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B92B7663-6086-44DA-B1FE-ACEFF082D8CF}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/src/Serilog.Enrichers.ClassName/LoggingExtensions.cs b/src/Serilog.Enrichers.ClassName/LoggingExtensions.cs index ce8f21d..fdf36a9 100644 --- a/src/Serilog.Enrichers.ClassName/LoggingExtensions.cs +++ b/src/Serilog.Enrichers.ClassName/LoggingExtensions.cs @@ -1,13 +1,26 @@ using Serilog.Configuration; +using System.Diagnostics; namespace Serilog.Enrichers.ClassName { public static class LoggingExtensions - { + { + public static LoggerConfiguration WithClassName(this LoggerEnrichmentConfiguration enrich) where T : class + { + _ = enrich ?? throw new ArgumentNullException(nameof(enrich)); + + enrich.WithProperty("SourceContext", typeof(T).FullName); + return enrich.With(); + } + public static LoggerConfiguration WithClassName(this LoggerEnrichmentConfiguration enrich) { _ = enrich ?? throw new ArgumentNullException(nameof(enrich)); + var stackFrame = new StackTrace().GetFrame(1); + var declaringType = stackFrame?.GetMethod()?.DeclaringType; + + enrich.WithProperty("SourceContext", declaringType?.FullName ?? "Unknown"); return enrich.With(); } }