C# 应用程序中的日志记录:实践中的最佳实践
日志记录不仅仅是向文件写入消息。它是任何 C# 生产应用程序进行监控、调试和审计的最重要工具。正确配置的日志记录可以让你快速找到故障原因,分析系统行为并预防事件。在本文中,我们将介绍 .NET 中日志记录的最佳实践,你可以立即应用到自己的项目中。
1. 选择库:Serilog vs NLog vs 内置 ILogger
在现代 .NET 中,有三种主要的日志记录方法。让我们看看它们的优势。
- 内置 ILogger (Microsoft.Extensions.Logging) — 基本的抽象接口。它内置于 ASP.NET Core 中,配置最少。适用于简单项目,但对于高级场景需要第三方提供程序。
- Serilog — 行业事实标准。开箱即用支持结构化日志记录,拥有丰富的 sinks(目标)生态系统,并且可以通过配置进行简单设置。
- NLog — 成熟的框架,具有灵活的路由和对遗留系统的支持。以高性能和详细的规则配置而著称。
建议: 对于新项目,使用 Serilog — 它最好地集成了现代实践(ELK、Application Insights)。对于性能至关重要的高负载系统,请考虑 NLog。
// Program.cs 中 Serilog 的最小配置示例using Serilog;
Log.Logger = new LoggerConfiguration() .MinimumLevel.Information() .WriteTo.Console() .WriteTo.File("logs/app-.log", rollingInterval: RollingInterval.Day) .CreateLogger();
try{ Log.Information("应用程序已启动"); // 你的代码}catch (Exception ex){ Log.Fatal(ex, "启动时发生严重错误");}finally{ Log.CloseAndFlush();}2. 日志级别:何时记录什么
错误选择日志级别是最常见的错误之一。让我们分析每个级别及其用途。
- Trace / Verbose — 仅用于开发人员调试。除非绝对必要,否则切勿在生产环境中启用。
- Debug — 用于开发的诊断信息。可以临时启用以查找问题。
- Information — 应用程序的正常运行:请求、成功操作、业务事件。生产环境中的主要级别。
- Warning — 潜在问题:磁盘空间不足、重试、过时的 API。
- Error — 应用程序已处理但用户注意到问题的异常和故障。
- Fatal / Critical — 需要管理员立即干预的不可恢复错误。
// 正确使用级别的示例public class OrderService{ private readonly ILogger<OrderService> _logger;
public OrderService(ILogger<OrderService> logger) { _logger = logger; }
public async Task<Order> CreateOrderAsync(CreateOrderRequest request) { _logger.LogInformation("正在为用户 {UserId} 创建订单", request.UserId);
try { var order = await _repository.SaveAsync(request); _logger.LogInformation("订单 {OrderId} 已成功创建", order.Id); return order; } catch (Exception ex) { _logger.LogError(ex, "为用户 {UserId} 创建订单时出错", request.UserId); throw; } }}3. 结构化日志记录:为什么它很重要
传统的文本日志记录(通