Serilog 日志庫簡單實踐(二):控制臺與調(diào)試 Sinks(.net8)
〇、前言
前文已經(jīng)介紹過什么是 Serilog,以及其核心特點,詳見:http://www.rzrgm.cn/hnzhengfy/p/19167414/Serilog_basic。
本文繼續(xù)對各種類型的 Sink 進行簡單的實踐,主題是控制臺與調(diào)試 Sinks,供參考。
一、控制臺與調(diào)試 Sinks 用法
1.1 Serilog.Sinks.Console:將日志優(yōu)雅地輸出到控制臺
Serilog.Sinks.Console 不僅僅是一個簡單的控制臺輸出工具,它是一個功能強大且靈活的日志接收器。支持純文本(默認)、著色文本(區(qū)分日志級別)、JSON 格式(保留結(jié)構(gòu)化數(shù)據(jù))。
通過可配置的 outputTemplate,它能夠在保持可讀性的同時,完美保留日志的結(jié)構(gòu)化信息(通過 JSON 格式或內(nèi)聯(lián) JSON 屬性,保存事件 ID、自定義字段等)。這種“雙重能力”使得開發(fā)者可以在本地清晰地看到日志,而運維和監(jiān)控系統(tǒng)可以通過解析 JSON 部分,實現(xiàn)高效的日志搜索、分析和告警,極大地提升了日志的價值和可維護性。
另外,直接輸出到控制臺,無額外依賴,性能開銷低。
關(guān)鍵配置參數(shù):
outputTemplate:自定義日志輸出模板,支持占位符(如 {Timestamp}、{Level}、{Message} 等)。
theme:控制控制臺顏色主題,可選值:
- AnsiConsoleTheme.Literate(默認,帶顏色)
- AnsiConsoleTheme.None(無顏色)
- 自定義主題(如 AnsiConsoleTheme.Code)。
formatter:指定日志格式化器,默認使用文本格式化器,可替換為 JsonFormatter 輸出 JSON。
MinimumLevel:設(shè)置最小日志級別(如只輸出 Warning 及以上級別)。
1.1.1 創(chuàng)建項目并安裝依賴包
創(chuàng)建一個 .net8 版本的控制臺應(yīng)用程序或者 WebAPI 程序,然后安裝必要的動態(tài)庫。
dotnet add package Serilog.Sinks.Console
1.1.2 修改 Program.cs
using Serilog;
// 創(chuàng)建日志記錄器,演示三種不同的 Console Sinks 配置
// 1. 純文本格式(默認)
var plainTextLogger = new LoggerConfiguration()
.WriteTo.Console(outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3}] {Message:lj}{NewLine}{Exception}")
.CreateLogger();
// 2. 帶顏色的控制臺輸出
var coloredLogger = new LoggerConfiguration()
.WriteTo.Console(
outputTemplate: "[{Timestamp:HH:mm:ss} {Level:w3}] {Message:lj} {Properties:j}{NewLine}{Exception}",
theme: Serilog.Sinks.SystemConsole.Themes.SystemConsoleTheme.Literate)
.CreateLogger();
// 3. JSON 格式輸出(保留結(jié)構(gòu)化數(shù)據(jù))
var jsonLogger = new LoggerConfiguration()
.WriteTo.Console(formatter: new Serilog.Formatting.Json.JsonFormatter())
.CreateLogger();
// 設(shè)置全局日志器(可選)
Log.Logger = coloredLogger;
try
{
// 使用不同 logger 輸出示例日志
Console.WriteLine("=== 純文本格式 ===");
plainTextLogger.Information("應(yīng)用程序啟動。");
plainTextLogger.Warning("這是一個警告,用戶 ID: {UserId}, 操作: {Action}", 123, "Login");
Console.WriteLine("\n=== 彩色控制臺輸出 ===");
coloredLogger.Information("用戶 {User} 成功登錄,IP: {IP}", "alice", "192.168.1.10");
coloredLogger.Error(new InvalidOperationException("無效操作"), "處理請求時出錯");
Console.WriteLine("\n=== JSON 格式輸出 ===");
jsonLogger.Information("記錄結(jié)構(gòu)化事件,Url: {Url}, StatusCode: {StatusCode}", "/api/values", 200);
jsonLogger.Debug("調(diào)試信息:耗時 {DurationMs} ms", 45.7);
Console.WriteLine("\n=== 結(jié)構(gòu)化日志的優(yōu)勢演示 ===");
var user = new { Id = 456, Name = "Bob", Roles = new[] { "Admin", "User" } };
coloredLogger.Information("新用戶注冊:{@User}", user); // {@User} 表示對象結(jié)構(gòu)化輸出
Console.WriteLine("\n按任意鍵退出...");
Console.ReadKey();
}
catch (Exception ex)
{
Log.Fatal(ex, "應(yīng)用程序發(fā)生未處理異常");
}
finally
{
Log.CloseAndFlush(); // 確保日志寫入完成
}
1.1.3 查看效果
如下圖,可見不同類型的值,會有不同的顏色,查看 json 字符串的值也比較清晰:

1.2 通過 Serilog.Sinks.Console 加自定義 json 格式化工具類輸出易讀格式
注意性能影響,美化 JSON(尤其是 Formatting.Indented)會增加 CPU 開銷,不建議在生產(chǎn)環(huán)境高頻率日志中使用,適合開發(fā)/調(diào)試環(huán)境。
依賴 Newtonsoft.Json,雖然 .NET Core 有 System.Text.Json,但 JObject.ToString(Formatting.Indented) 更方便。
每條日志都需要是一個獨立 JSON 對象,而非整個文件是 JSON 數(shù)組。
下面是一個簡單實現(xiàn):
先定義一個 json 格式化工具類 BeautifiedJsonFormatter.cs:
using Newtonsoft.Json;
using Serilog.Events;
using Serilog.Formatting;
using Serilog.Formatting.Compact;
using System.Text;
namespace Test.WebAPI.Serilog.WriteToFile
{
public class BeautifiedJsonFormatter : ITextFormatter
{
private readonly RenderedCompactJsonFormatter _innerFormatter = new RenderedCompactJsonFormatter();
public void Format(LogEvent logEvent, TextWriter output)
{
// 先用 CompactJsonFormatter 寫入 StringBuilder
var sb = new StringBuilder();
var stringWriter = new StringWriter(sb);
_innerFormatter.Format(logEvent, stringWriter);
// 解析為 JObject 并重新格式化為美化 JSON
var json = sb.ToString().Trim(); // 去掉空白
if (string.IsNullOrEmpty(json))
return;
var obj = Newtonsoft.Json.Linq.JObject.Parse(json);
var prettyJson = obj.ToString(Formatting.Indented); // 美化輸出(帶縮進)
output.WriteLine(prettyJson); // 寫入輸出流并換行
}
}
}
測試一下:
using Serilog;
using System.Text;
using Test.WebAPI.Serilog.WriteToFile;
// 創(chuàng)建一個自定義的 TextWriter,用于在寫入控制臺前美化 JSON
var writer = new StreamWriter(Console.OpenStandardOutput())
{
AutoFlush = true,
//Encoding = Encoding.UTF8
};
// 配置 Serilog
Log.Logger = new LoggerConfiguration()
.WriteTo.Console(
formatter: new BeautifiedJsonFormatter(), // 使用自定義美化格式化器
standardErrorFromLevel: null) // 所有級別都輸出到 stdout
.CreateLogger();
// 示例日志
Log.Information("Hello {Name}! Today is {Date:yyyy-MM-dd}.", "Alice", DateTime.Now);
Log.Warning("Something went wrong with user {@User}", new { Id = 123, Name = "Bob" });
Log.Error(new InvalidOperationException("Test exception"), "An error occurred");
Log.CloseAndFlush();
輸出的格式化 json 如下圖:

1.3 Serilog.Sinks.Debug:將日志寫入到 Visual Studio 的“輸出”窗口,主要用于開發(fā)和調(diào)試
Serilog.Sinks.Debug 是 Serilog 的一個官方接收器(Sink),它將日志事件寫入到 Visual Studio 的“輸出”窗口(Output Window)中。這個功能主要用于開發(fā)和調(diào)試階段,為開發(fā)者提供了一種高效、便捷的日志查看方式。
核心特點:
開發(fā)調(diào)試友好:無需額外配置或打開其他日志查看工具。日志實時顯示在 VS 的"輸出"窗口中,無需中斷程序執(zhí)行。
環(huán)境隔離:僅在開發(fā)環(huán)境中啟用,不會影響生產(chǎn)環(huán)境的性能。可以輕松地在配置中啟用/禁用,無需修改代碼。
結(jié)構(gòu)化日志:保持 Serilog 的結(jié)構(gòu)化日志優(yōu)勢。以可讀的格式顯示日志,包含時間戳、日志級別、消息和屬性。
與 Serilog 生態(tài)無縫集成:與其他 Serilog 接收器(如控制臺、文件)可以同時使用。保持 Serilog 統(tǒng)一的 API 和配置風(fēng)格。
在日常開發(fā)中,Serilog.Sinks.Debug 可以做到避免干擾,與 Console.WriteLine 不同,Serilog.Sinks.Debug 不會干擾控制臺輸出,不會使控制臺輸出混亂。
還可以方便日志級別控制,可以設(shè)置不同的日志級別(如 Debug、Information、Warning),只顯示需要的調(diào)試信息。
還能方便的查看上下文信息,保留 Serilog 的結(jié)構(gòu)化日志特性,包括參數(shù)化消息和上下文屬性。
更主要的是可以專業(yè)調(diào)試,比簡單的 Debug.WriteLine 更強大、更靈活,是專業(yè)開發(fā)的首選。
下邊是一個簡單的示例。
安裝必要的包:
dotnet add package Serilog.Sinks.Debug
修改 Program.cs:
using Serilog;
using System;
namespace SerilogDebugExample
{
class Program
{
static void Main(string[] args)
{
// 配置 Serilog,將日志寫入到 Visual Studio 的輸出窗口
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Debug() // 設(shè)置最小日志級別為 Debug
.WriteTo.Debug() // 關(guān)鍵:將日志寫入到 VS 輸出窗口
.CreateLogger();
try
{
Log.Information("應(yīng)用程序啟動");
// 模擬一些操作
Log.Debug("正在處理用戶請求");
Log.Warning("庫存不足,商品 {ProductId}", 12345);
Log.Error(new Exception("模擬的異常"), "處理訂單時發(fā)生錯誤,訂單ID: {OrderId}", "ORD12345");
Log.Information("應(yīng)用程序正常關(guān)閉");
}
finally
{
Log.CloseAndFlush(); // 確保所有日志已寫入
}
}
}
}
然后,打開輸出窗口(視圖-->輸出,快捷方式 Alt+2)。
然后運行項目,查看輸出窗口:

本文來自博客園,作者:橙子家,歡迎微信掃碼關(guān)注博主【橙子家czzj】,有任何疑問歡迎溝通,共同成長!
轉(zhuǎn)載本文請注明原文鏈接:http://www.rzrgm.cn/hnzhengfy/p/19144142/SerilogSink_ConsoleDebug

浙公網(wǎng)安備 33010602011771號