如何配置ILogger实现单条消息单行、多行消息保留原格式?
实现自定义混合格式的日志输出
默认的SimpleConsoleFormatter没有提供直接配置项满足你的需求,但可以通过自定义日志格式化器来实现单条消息头与内容同行、多行消息保留原格式的效果,具体步骤如下:
1. 创建自定义格式化器类
继承ConsoleFormatter,复用原生SimpleConsoleFormatter的头部格式化逻辑,根据消息是否包含换行符切换输出模式:
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Console; using System.Text; public class SmartConsoleFormatter : ConsoleFormatter { private readonly SimpleConsoleFormatterOptions _options; private readonly SimpleConsoleFormatter _innerFormatter; public SmartConsoleFormatter(SimpleConsoleFormatterOptions options) : base("SmartConsole") { _options = options; _innerFormatter = new SimpleConsoleFormatter(options); } public override void Write<TState>(in LogEntry<TState> logEntry, IExternalScopeProvider scopeProvider, TextWriter textWriter) { var originalSingleLine = _options.SingleLine; var message = logEntry.Formatter(logEntry.State, logEntry.Exception); try { if (!message.Contains(Environment.NewLine)) { // 单条消息:强制SingleLine=true,让头与内容同行 _options.SingleLine = true; _innerFormatter.Write(logEntry, scopeProvider, textWriter); } else { // 多行消息:先输出头部,再完整输出消息内容 _options.SingleLine = true; using var headerWriter = new StringWriter(); _innerFormatter.Write(logEntry, scopeProvider, headerWriter); var fullHeader = headerWriter.ToString(); // 拆分出头部(去掉消息第一行) var firstLineEnd = fullHeader.IndexOf(message.Split(Environment.NewLine)[0], StringComparison.Ordinal); if (firstLineEnd != -1) { textWriter.Write(fullHeader.Substring(0, firstLineEnd)); textWriter.WriteLine(message); } else { // fallback到原生多行格式 _options.SingleLine = false; _innerFormatter.Write(logEntry, scopeProvider, textWriter); } } } finally { // 恢复原配置 _options.SingleLine = originalSingleLine; } } }
2. 注册自定义格式化器
在服务配置中替换默认的控制台格式化器:
services.AddLogging(options => { options.AddConsole(consoleOptions => { // 指定使用自定义格式化器 consoleOptions.FormatterName = "SmartConsole"; }); // 注册自定义格式化器及配置 options.AddConsoleFormatter<SmartConsoleFormatter, SimpleConsoleFormatterOptions>(formatterOptions => { // 可配置时间戳格式等原生选项 formatterOptions.TimestampFormat = "[yyyy-MM-ddTHH:mm:ss] "; // 其他配置如ColorBehavior等可按需设置 }); });
3. 验证效果
- 单条消息输出:
[2024-05-20T15:30:49] dbug: Lala.WebUI.Shared.DataManagerHub[0] SaveLanguages in 0s.
- 多行消息输出:
[2024-05-20T15:30:49] dbug: Microsoft.Extensions.Hosting.Internal.Host[4] Hosting stopped Unhandled exception. Xunit.Sdk.FailException: Assert.Fail(): An error occurred while saving the entity changes. SQLite Error 19: 'FOREIGN KEY constraint failed'. from MeasureAsync in /home/mist/Projekty/lala/app/Lala.WebUI.Shared/CommonPostDataWorkerBase.cs at line 45
补充说明
- 该实现复用原生格式化逻辑,避免重复编写日志头的级别、类别、时间戳等格式化代码,仅针对消息换行场景做适配。
- 若需调整多行消息的缩进或异常格式,可在
Write方法中进一步修改消息输出逻辑。
内容的提问来源于stack exchange,提问作者greenoldman
相关产品推荐
相关产品推荐

