Serilog 日志庫簡單實踐(jian)(二(er)):控制臺與調(diao)試 Sinks(.net8)
〇、前言
前文已經介紹過什么是 Serilog,以及其核心特點,詳見://www.lnzwny.com/hnzhengfy/p/19167414/Serilog_basic。
本文繼續(xu)對各種類型的 Sink 進行簡單的實踐,主題是(shi)控(kong)制臺(tai)與調試 Sink,供參考。
一、控制臺與調試 Sinks 用法
1.1 Serilog.Sinks.Console:將日志優雅地輸出到控制臺
Serilog.Sinks.Console 不僅僅是一個簡單的控制臺輸出工具,它是一個功能強大且靈活的日志接收器。支持純文本(默認)、著色文本(區分日志級別)、JSON 格式(保留結構化數據)。
通過可配置的 outputTemplate,它能夠在保持可讀性的同時,完美保留日志的結構化信息(通過 JSON 格式或內聯 JSON 屬性,保存事件 ID、自定義字段等)。這種“雙重能力”使得開發者可以在本地清晰地看到日志,而運維和(he)(he)監控系統可以通過解(jie)析(xi)(xi) JSON 部(bu)分(fen),實(shi)現高效的日志(zhi)搜索、分(fen)析(xi)(xi)和(he)(he)告警,極大地提(ti)升(sheng)了日志(zhi)的價值(zhi)和(he)(he)可維護(hu)性。
另外,直接輸出到控制臺,無額外依賴,性能開銷低。
關鍵配置參數:
outputTemplate:自定義日志輸出模板,支持占(zhan)位符(如 {Timestamp}、{Level}、{Message} 等(deng))。
theme:控(kong)制控(kong)制臺顏色(se)主(zhu)題,可選(xuan)值:
- AnsiConsoleTheme.Literate(默認,帶顏色)
- AnsiConsoleTheme.None(無顏色)
- 自定義主題(如 AnsiConsoleTheme.Code)。
formatter:指(zhi)定日志格式(shi)化器(qi),默認使(shi)用文本格式(shi)化器(qi),可(ke)替換為(wei) JsonFormatter 輸出 JSON。
MinimumLevel:設置最小日志級別(如(ru)只輸出 Warning 及以上級別)。
1.1.1 創建項目并安裝依賴包
創建一(yi)個 .net8 版本的控制臺應用程序或者 WebAPI 程序,然后安裝必要的動態庫。
dotnet add package Serilog.Sinks.Console
1.1.2 修改 Program.cs
using Serilog;
// 創建日志記錄器,演示三種不同的 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 格式輸出(保留結構化數據)
var jsonLogger = new LoggerConfiguration()
.WriteTo.Console(formatter: new Serilog.Formatting.Json.JsonFormatter())
.CreateLogger();
// 設置全局日志器(可選)
Log.Logger = coloredLogger;
try
{
// 使用不同 logger 輸出示例日志
Console.WriteLine("=== 純文本格式 ===");
plainTextLogger.Information("應用程序啟動。");
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("記錄結構化事件,Url: {Url}, StatusCode: {StatusCode}", "/api/values", 200);
jsonLogger.Debug("調試信息:耗時 {DurationMs} ms", 45.7);
Console.WriteLine("\n=== 結構化日志的優勢演示 ===");
var user = new { Id = 456, Name = "Bob", Roles = new[] { "Admin", "User" } };
coloredLogger.Information("新用戶注冊:{@User}", user); // {@User} 表示對象結構化輸出
Console.WriteLine("\n按任意鍵退出...");
Console.ReadKey();
}
catch (Exception ex)
{
Log.Fatal(ex, "應用程序發生未處理異常");
}
finally
{
Log.CloseAndFlush(); // 確保日志寫入完成
}
1.1.3 查看效果
如(ru)下圖,可(ke)見不同類型的(de)值,會(hui)有不同的(de)顏色,查看 json 字符串的(de)值也比較清晰:

1.2 通過 Serilog.Sinks.Console 加自定義 json 格式化工具類輸出易讀格式
注意性能影響,美化 JSON(尤其是 Formatting.Indented)會增加 CPU 開銷,不建議在生產環境高(gao)頻率日志(zhi)中使用,適合開發(fa)/調(diao)試(shi)環境。
依賴 Newtonsoft.Json,雖然 .NET Core 有 System.Text.Json,但 JObject.ToString(Formatting.Indented) 更方便。
每條日志都需要是一個獨立 JSON 對象,而非整(zheng)個文件(jian)是 JSON 數組。
下面是一個簡(jian)單(dan)實現:
先(xian)定義(yi)一(yi)個 json 格式(shi)化工具類 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;
// 創建一個自定義的 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();
輸出的格(ge)式(shi)化 json 如下圖:

1.3 Serilog.Sinks.Debug:將日志寫入到 Visual Studio 的“輸出”窗口,主要用于開發和調試
Serilog.Sinks.Debug 是 Serilog 的一個官方接收器(Sink),它將日志事件寫入到 Visual Studio 的“輸出”窗口(Output Window)中。這個功能主要用于開發和調試階段,為開發者提供了一種高效、便捷的日志查看方式。
核心特點:
開發調試友好:無需額外配置或打開其他日志查看工具。日志實時顯示在 VS 的"輸出"窗口中,無需中斷程序執行。
環境隔離:僅在開發環境中啟用,不會影響生產環境的性能。可以輕松地在配置中啟用/禁用,無需修改代碼。
結構化日志:保持 Serilog 的結構化日志優勢。以可讀的格式顯示日志,包含時間戳、日志級別、消息和屬性。
與 Serilog 生態無縫集成:與其他 Serilog 接收器(如控(kong)制(zhi)臺、文件)可(ke)以同時使用。保(bao)持 Serilog 統一的 API 和配置風(feng)格。
在日常開發中,Serilog.Sinks.Debug 可以做到避免干擾,與 Console.WriteLine 不(bu)同,Serilog.Sinks.Debug 不(bu)會干擾控(kong)制(zhi)(zhi)臺輸出,不(bu)會使控(kong)制(zhi)(zhi)臺輸出混亂。
還可以方便日志級別控制,可(ke)以(yi)設置不同的(de)日(ri)志級別(如 Debug、Information、Warning),只(zhi)顯示需要的(de)調試信(xin)息。
還能方便的查看上下文信息,保留 Serilog 的結構(gou)化(hua)日志特性,包(bao)括參數化(hua)消息和(he)上(shang)下文屬性。
更主要的是可以專業調試,比(bi)簡單的 Debug.WriteLine 更(geng)(geng)強大、更(geng)(geng)靈活,是專業開(kai)發的首(shou)選。
下邊(bian)是(shi)一個簡(jian)單的示例(li)。
安裝必要的包:
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() // 設置最小日志級別為 Debug
.WriteTo.Debug() // 關鍵:將日志寫入到 VS 輸出窗口
.CreateLogger();
try
{
Log.Information("應用程序啟動");
// 模擬一些操作
Log.Debug("正在處理用戶請求");
Log.Warning("庫存不足,商品 {ProductId}", 12345);
Log.Error(new Exception("模擬的異常"), "處理訂單時發生錯誤,訂單ID: {OrderId}", "ORD12345");
Log.Information("應用程序正常關閉");
}
finally
{
Log.CloseAndFlush(); // 確保所有日志已寫入
}
}
}
}
然(ran)后,打開(kai)輸出窗口(視圖-->輸出,快(kuai)捷方(fang)式 Alt+2)。
然后(hou)運行項目,查看輸出(chu)窗口:

本文來自博客園,作者:橙子家,歡迎(ying)微信(xin)掃碼關注博主【橙(cheng)子家czzj】,有任何(he)疑問歡迎(ying)溝通,共(gong)同成(cheng)長!
