.NET Core中如何配置Serilog将日志写入StringBuilder获取全量运行日志
Serilog写入StringBuilder的实现方案(.NET Core环境)
以下是两种生产环境常用的可行实现方式:
方案1:使用现成内存Sink包
可以直接用社区维护的Serilog.Sinks.InMemory包,不需要自己编写核心逻辑,适配性更强:
- 第一步安装NuGet包:
Install-Package Serilog.Sinks.InMemory - 第二步配置Serilog时添加Sink:
var inMemorySink = new InMemorySink(); Log.Logger = new LoggerConfiguration() .MinimumLevel.Information() .WriteTo.Sink(inMemorySink) // 原有其他Sink配置(写控制台、文件等)可正常保留 .WriteTo.Console() .CreateLogger();
- 第三步需要使用日志时直接提取即可:
// 仅提取日志消息内容 var simpleLogs = string.Join(Environment.NewLine, inMemorySink.LogEvents.Select(e => e.RenderMessage())); // 提取包含时间、级别、异常的完整格式化日志 var fullLogs = string.Join(Environment.NewLine, inMemorySink.LogEvents.Select(e => $"[{e.Timestamp:yyyy-MM-dd HH:mm:ss}] [{e.Level}] {e.RenderMessage()} {e.Exception?.ToString()}"));
注意:该Sink默认保留所有日志,若程序运行周期长、日志量大需注意内存占用,可定期清空日志列表避免内存溢出
方案2:自定义Sink绑定StringBuilder(无额外依赖)
如果不想引入第三方NuGet包,可以自己实现简单Sink,直接绑定到你声明的StringBuilder实例:
- 第一步实现自定义Sink类:
using Serilog.Core; using Serilog.Events; using System.Text; public class StringBuilderSink : ILogEventSink { private readonly StringBuilder _stringBuilder; private readonly IFormatProvider _formatProvider; private readonly object _lockObj = new object(); public StringBuilderSink(StringBuilder stringBuilder, IFormatProvider formatProvider = null) { _stringBuilder = stringBuilder ?? throw new ArgumentNullException(nameof(stringBuilder)); _formatProvider = formatProvider; } public void Emit(LogEvent logEvent) { // 加锁保证多线程场景下StringBuilder写入安全,单线程场景可去掉锁逻辑 lock (_lockObj) { var message = logEvent.RenderMessage(_formatProvider); _stringBuilder.AppendLine($"[{logEvent.Timestamp:yyyy-MM-dd HH:mm:ss}] [{logEvent.Level}] {message}"); if (logEvent.Exception != null) { _stringBuilder.AppendLine(logEvent.Exception.ToString()); } } } }
- 第二步配置Serilog时注册自定义Sink:
// 全局声明用于存储日志的StringBuilder实例 var logSb = new StringBuilder(); Log.Logger = new LoggerConfiguration() .MinimumLevel.Information() .WriteTo.Sink(new StringBuilderSink(logSb)) // 原有其他Sink配置正常保留 .CreateLogger();
- 第三步获取全量日志字符串:
string fullLogContent = logSb.ToString(); // 后续可直接用于邮件发送、接口上传、持久化存储等自定义操作
内容的提问来源于stack exchange,提问作者Lightsout
相关产品推荐
相关产品推荐

