SerilogAnalyzer
repository·master·Indexed 43 days ago
https://github.com/suchiman/seriloganalyzerA Roslyn-based static analysis tool for C# projects using the Serilog logging library. It identifies common pitfalls such as incorrect exception handling, malformed message templates, property binding issues, and performance problems related to non-constant templates. Includes specific analyzers Serilog001 through Serilog008 and provides CodeFixes for several rules.
What's inside SerilogAnalyzer
- To debug the analyzer, set the default project to the VSIX project and start debugging. This will deploy the analyzer as a VSIX into a separate instance of Visual Studio, allowing you to observe its behavior in the IDE even if your ultimate goal is to distribute it via NuGet.
Package the SerilogAnalyzer as a NuGet package or VSIX extension
masterBuilding the project produces an analyzer
.dll. You can package this in two ways depending on your deployment needs:- NuGet package (
.nupkg): Adds the analyzer as a project-local analyzer that participates in builds. This is the standard way to distribute analyzers for use in CI/CD and local development. - VSIX extension (
.vsix): Applies the analyzer to all projects within the IDE. This is useful for IDE-only enforcement.
- NuGet package (
Test a local NuGet package installation
masterTo verify a
.nupkgfile locally, follow these steps:- Create a local NuGet feed (refer to NuGet documentation).
- Copy the generated
.nupkgfile into your local feed folder. - Open your target project in Visual Studio.
- Right-click the project in Solution Explorer and select Manage NuGet Packages.
- Select your local NuGet feed from the left-hand pane.
- Select the analyzer from the list and click Install.
Install SerilogAnalyzer
masterSerilogAnalyzer is a Roslyn-based analyzer that checks for common mistakes and usage problems when using the Serilog logging library. You can install it using one of the following methods:
- Visual Studio Extension: Download the VSIX from the releases list.
- Visual Studio Gallery: Install directly from the Visual Studio Marketplace.
- NuGet: Add the
SerilogAnalyzerNuGet package to your project.
dotnet add package SerilogAnalyzerAutomate NuGet package deployment to a local feed
masterYou can configure the project to automatically copy the
.nupkgfile to your local NuGet feed folder upon every build by modifying the project file:- Right-click the project in Solution Explorer and select Unload Project.
- Right-click the project again and select Edit.
- Locate the
<AfterBuild>target in the XML. - Within the
<Exec>task, update theCommandattribute. Change the path following the-OutputDirectoryflag to point to your local NuGet feed folder.
<!-- Example of the target to modify in the .csproj file --> <Target Name="AfterBuild"> <Exec Command="... -OutputDirectory C:\Your\Local\NuGet\Feed\Path" /> </Target>Refactor Fluent LoggerConfiguration to AppSettings
masterSerilogAnalyzer can perform static analysis on fluentLoggerConfigurationcalls to generate configuration suitable for use withserilog-settings-appsettingsorserilog-settings-configuration(e.g.,appSettings.json).Serilog003: Verify Property Binding
masterThe
Serilog003analysis ensures coherence between message template tokens and the supplied arguments. Every property named in the message template must correspond to exactly one argument.Incorrect usage:
Log.Information("Saving {File} to {Directory}", file);Correct usage:
Log.Information("Saving {File} to {Directory}", file, directory);Log.Information("Saving {File} to {Directory}", file, directory);Serilog007: Destructure Anonymous Objects
masterThe
Serilog007analysis checks that anonymous objects passed to the logger use the destructuring operator (@). Without this, the object is logged as a string rather than its properties.Incorrect usage:
Log.Information("Saving {File} to {Directory}", new { Name = name, Size = size }, directory);Correct usage:
Log.Information("Saving {@File} to {Directory}", new { Name = name, Size = size }, directory);A CodeFix is available to apply the destructuring hint (
@).Log.Information("Saving {@File} to {Directory}", new { Name = name, Size = size }, directory);Serilog001: Ensure exceptions are passed as the first argument
masterThe
Serilog001analysis checks that exceptions are passed to theexceptionargument rather than being treated as a normal property. Serilog provides special handling for exceptions when they are passed as the first argument of a log method call.Incorrect usage:
catch (Exception ex) { Log.Error("Could not save {File}: {Error}", file, ex); }Correct usage:
catch (Exception ex) { Log.Error(ex, "Could not save {File}", file); }A CodeFix is available to correct this usage.
Log.Error(ex, "Could not save {File}", file);Serilog008: Use Correct Contextual Logger Type
masterThe
Serilog008analysis ensures that contextual loggers are constructed using the correct type for the class they are in.Incorrect usage:
class A { private static readonly ILogger Logger = Logger.ForContext<B>(); } class B {}Correct usage:
class A { private static readonly ILogger Logger = Logger.ForContext<A>(); } class B {}A CodeFix is available to update the type in the
ForContext<T>call.private static readonly ILogger Logger = Logger.ForContext<A>();Serilog005: Ensure Unique Property Names
masterThe
Serilog005analysis checks that all property names within a single message template are unique. If names are duplicated, Serilog may only record one of them.Incorrect usage:
Log.Information("Saving {Path} to {Path}", file, directory);Correct usage:
Log.Information("Saving {File} to {Directory}", file, directory);Log.Information("Saving {File} to {Directory}", file, directory);Serilog006: Use PascalCased Property Names
masterThe
Serilog006analysis checks that all property names in a message template usePascalCase.Incorrect usage:
Log.Information("Saving {file} to {directory}", file, directory);Correct usage:
Log.Information("Saving {File} to {Directory}", file, directory);A CodeFix is available to automatically apply Pascal casing to property names.
Log.Information("Saving {File} to {Directory}", file, directory);