在.NET项目中使用Serilog和Seq自定义日志级别是否可行?
Absolutely! You can totally create custom log levels in Serilog and use that clean, method-style syntax you're asking about. Here's a step-by-step breakdown to make it work:
1. Define Custom Level Extensions for ILogger
First, create a static class to hold extension methods for ILogger. This is where you'll define your custom log level method(s), mapping them to a custom LogEventLevel value (since Serilog's built-in LogEventLevel is an enum, you can use integer values beyond the default 0-5 range for new levels):
public static class CustomLoggerExtensions { // Define a custom log level (using an integer outside the default 0-5 range) private const LogEventLevel MyCustomLevel = (LogEventLevel)6; // Basic overload for messages without exceptions public static void MyCustomLogLevel(this ILogger logger, string messageTemplate, params object[] args) { logger.Write(MyCustomLevel, messageTemplate, args); } // Overload for messages with attached exceptions public static void MyCustomLogLevel(this ILogger logger, Exception exception, string messageTemplate, params object[] args) { logger.Write(MyCustomLevel, exception, messageTemplate, args); } }
2. Configure Serilog to Show Friendly Custom Level Names
By default, Serilog will display the integer value of your custom level in outputs. To make it show a human-readable name (like "MYCUSTOM" instead of "6"), add an enricher to map the level to a friendly label:
public class CustomLevelEnricher : ILogEventEnricher { public void Enrich(LogEvent logEvent, ILogEventPropertyFactory propertyFactory) { string levelName = logEvent.Level switch { (LogEventLevel)6 => "MYCUSTOM", // Add mappings for other custom levels if you need them _ => logEvent.Level.ToString() }; logEvent.AddPropertyIfAbsent(propertyFactory.CreateProperty("CustomLevel", levelName)); } }
Then update your Serilog configuration to use this enricher, and adjust your output templates to use {CustomLevel} instead of the default {Level}:
Log.Logger = new LoggerConfiguration() .MinimumLevel.Verbose() // Ensure your custom level is included in logging .Enrich.With<CustomLevelEnricher>() // Attach the custom level name enricher .WriteTo.Console( outputTemplate: "[{Timestamp:HH:mm:ss} {CustomLevel}] {Message:lj}{NewLine}{Exception}") .WriteTo.Seq("http://localhost:5341") // Seq will recognize the CustomLevel property automatically .CreateLogger();
3. Use Your Custom Log Level
Now you can use your custom method exactly how you wanted! Just make sure to include the namespace of your CustomLoggerExtensions class in your controller:
using YourAppNamespace.CustomLogging; public class MyController : Controller { private static readonly ILogger Logger = Log.ForContext<MyController>(); public IActionResult ProcessRequest() { // Call your custom log level method Logger.MyCustomLogLevel("Starting processing for request {RequestId}", HttpContext.TraceIdentifier); // Or with an exception try { // Perform a risky operation } catch (Exception ex) { Logger.MyCustomLogLevel(ex, "Failed to process request {RequestId}", HttpContext.TraceIdentifier); } return Ok(); } }
Quick Notes
- If you just need an alias for an existing level (e.g., renaming
WarningtoAlert), simplify the extension method to call the built-in level directly (e.g.,logger.Warning(messageTemplate, args)). - Seq will let you filter, search, and create alerts using your
CustomLevelproperty just like you would with built-in levels. - Double-check your minimum log level setting to ensure it's low enough to include your custom level (using
Verboseensures all levels are captured).
内容的提问来源于stack exchange,提问作者Régis NIOX

