为什么你的 C# 应用程序在“尖叫”,而你却听不见?
\n想象一下:你在午夜部署了一个新的 C# 微服务版本。起初的 10 分钟,一切运行完美……然后,砰!——用户开始抱怨卡顿,而你坐在一个 2GB 大小的日志文件前,试图大海捞针。熟悉吗?如果不熟悉——你要么是天才,要么从未真正做过监控。
\n在本文中,我们将探讨如何将混乱的日志转变为有序的系统。你将了解如何配置 C# 日志记录,以便在部署时不会抓狂,以及如何构建真正有用的 应用程序监控,而不仅仅是绘制漂亮的图表。
\n\n从何开始:正确日志记录的哲学
\n许多开发者认为:“用 Console.WriteLine 就行了。”剧透:不,不行。真正的 C# 日志记录是结构化日志。不要使用这样的字符串:
\nLog.Info("User " + userId + " bought item " + itemId);\n而应该这样写:
\nLog.Information("User {UserId} bought item {ItemId}", userId, itemId);\n区别巨大。在第二种情况下,你可以按 UserId 过滤日志,构建仪表板,并快速找到问题。这是生产环境中 C# 错误诊断 的基础。
选择库:Serilog vs NLog vs log4net
\n.NET 市场上有三个主要竞争者。让我们根据实际项目的重要标准进行比较:
\n- \n
- Serilog — 现代 .NET 的宠儿。非常适合结构化日志,易于配置,支持 sinks(输出到文件、数据库、Elasticsearch)。推荐用于新项目。 \n
- NLog — 老牌库,通过 XML/JSON 提供灵活配置。非常适合已经使用它的遗留系统。 \n
- log4net — 老古董,除非万不得已,最好别碰。支持不佳,结构化日志需要变通方法。 \n
对于现代应用程序中的 .NET 跟踪,Serilog 是第一选择。让我们在 5 分钟内完成配置。
\n\n在 C# 中配置 Serilog:分步指南
\n通过 NuGet 安装包:
\ndotnet add package Serilog\ndotnet add package Serilog.Sinks.Console\ndotnet add package Serilog.Sinks.File\ndotnet add package Serilog.Sinks.Seq\n现在,在 ASP.NET Core 的 Program.cs 中进行最小配置:
using Serilog;\n\nLog.Logger = new LoggerConfiguration()\n .MinimumLevel.Information()\n .WriteTo.Console()\n .WriteTo.File("logs/app-.log", rollingInterval: RollingInterval.Day)\n .WriteTo.Seq("http://localhost:5341") // 用于高级监控\n .CreateLogger();\n\ntry\n{\n Log.Information("Starting web application");\n var builder = WebApplication.CreateBuilder(args);\n builder.Host.UseSerilog(); // 与主机集成\n // ... 其余配置\n var app = builder.Build();\n app.Run();\n}\ncatch (Exception ex)\n{\n Log.Fatal(ex, "Application terminated unexpectedly");\n}\nfinally\n{\n Log.CloseAndFlush();\n}\n注意 rollingInterval —— 日志将每天轮换,而不是无限增长。这是生产环境中 异步日志记录 的基础。
结构化日志:如何最大化利用
\n假设我们有一个处理订单的方法。没有结构化,你可能会写:
\nlogger.LogInformation("Processing order {OrderId} for user {UserId}", order.Id, user.Id);\n使用 Serilog,这会被转换为可解析的 JSON 对象。如果通过 ILogger<T> 添加上下文:
public class OrderService\n{\n private readonly ILogger<OrderService> _logger;\n\n public OrderService(ILogger<OrderService> logger)\n {\n _logger = logge