引言:为什么日志记录是稳定应用的基石
任何开发者,尤其是初学者,迟早都会遇到应用崩溃却无法查明原因的情况。没有日志,你就如同盲人。日志记录不仅仅是向文件写入消息,更是监控、调试和分析程序行为的强大工具。在 C# (.NET) 生态系统中,有多个成熟的框架允许你灵活配置日志输出。在本文中,我们将为初学者解析日志记录的最佳实践:从库的选择到结构化数据输出。
1. 日志记录库的选择:NLog vs Serilog
对于 .NET 应用,主要有两个选择:NLog 和 Serilog。两者都是免费的,得到积极维护,并拥有数千种集成。如何选择?
NLog
- 通过 XML 或代码进行简单配置。
- 在高负载下性能出色。
- 内置支持文件轮转、发送邮件、写入数据库。
- 适合需要快速启动且无需额外依赖的项目。
Serilog
- 专注于结构化日志记录。
- 日志不以字符串形式存储,而是作为带有字段的对象存储——这简化了搜索和分析。
- 非常适合微服务和日志收集到 Elasticsearch 或 Grafana 的系统。
- 使用占位符语法
{Property}使代码更具可读性。
给初学者的建议:如果你计划使用现代监控工具,请从 Serilog 开始。如果项目较小且是本地项目,NLog 就足够了。
// 在 Program.cs (.NET 6+) 中配置 Serilog 的示例using Serilog;
Log.Logger = new LoggerConfiguration() .MinimumLevel.Information() .WriteTo.Console() .WriteTo.File("logs/app-.log", rollingInterval: RollingInterval.Day) .CreateLogger();
var builder = WebApplication.CreateBuilder(args);builder.Host.UseSerilog(); // 将 Serilog 连接到主机2. 日志级别:何时记录什么内容
初学者最常见的错误之一是在 Info 或 Error 级别记录所有内容。这会污染日志并使其变得无用。在 .NET 中,采用以下级别(按重要性递增):
- Trace — 最细微的细节:方法的进入/退出、循环迭代。仅在深度调试时使用。
- Debug — 供开发者使用的调试信息:变量值、对象状态。
- Information — 应用运行的关键事件:启动、停止、成功处理请求。
- Warning — 不影响运行的潜在问题:慢请求、过时的 API 版本。
- Error — 需要干预的异常和故障:数据库错误、超时。
- Fatal — 应用无法继续运行的严重错误。
// 使用不同级别的示例ILogger<MyService> _logger;
public async Task ProcessOrderAsync(int orderId){ _logger.LogInformation("开始处理订单 {OrderId}", orderId);
try { var result = await _repository.GetOrderAsync(orderId); if (result == null) { _logger.LogWarning("未找到订单 {OrderId}", orderId); return; } // ... 业务逻辑 } catch (Exception ex) { _logger.LogError(ex, "处理订单 {OrderId} 时出错", orderId); throw; // 如果无法恢复,则向上抛出 }}最佳实践