C Sharp 异常记录
外观
C#异常记录[编辑 | 编辑源代码]
异常记录是C#异常处理中至关重要的实践,它指在捕获异常时将错误信息持久化存储(如日志文件、数据库或监控系统),以便后续分析和调试。良好的异常记录能帮助开发者快速定位问题根源,并改进系统稳定性。
核心概念[编辑 | 编辑源代码]
在C#中,异常记录通常通过以下方式实现:
- 使用
try-catch
块捕获异常 - 记录异常的详细信息(消息、堆栈跟踪、上下文数据)
- 将记录写入持久化存储
基本语法示例[编辑 | 编辑源代码]
try
{
// 可能抛出异常的代码
int result = 10 / int.Parse("0");
}
catch (Exception ex)
{
// 基础异常记录
Console.WriteLine($"发生异常: {ex.Message}");
File.AppendAllText("error.log", $"[{DateTime.Now}] 异常: {ex}\n");
}
输出示例:
发生异常: Attempted to divide by zero.
详细实现方法[编辑 | 编辑源代码]
1. 结构化日志记录[编辑 | 编辑源代码]
推荐使用 ILogger
接口(Microsoft.Extensions.Logging)实现结构化记录:
using Microsoft.Extensions.Logging;
class Program
{
static void Main()
{
ILoggerFactory factory = LoggerFactory.Create(builder =>
builder.AddFile("app.log"));
ILogger logger = factory.CreateLogger<Program>();
try
{
File.ReadAllText("nonexistent.txt");
}
catch (FileNotFoundException ex)
{
logger.LogError(ex, "文件未找到: {FileName}", "nonexistent.txt");
}
}
}
日志文件内容示例:
2023-11-20 14:30:45 [Error] 文件未找到: nonexistent.txt System.IO.FileNotFoundException: Could not find file '...' at System.IO.File.ReadAllText(String path)
2. 异常上下文增强[编辑 | 编辑源代码]
通过 Exception.Data
属性添加上下文信息:
try
{
var user = GetUserById("invalid_id");
}
catch (Exception ex)
{
ex.Data["UserId"] = "invalid_id";
ex.Data["RequestTime"] = DateTime.UtcNow;
logger.LogError(ex, "用户查询失败");
}
最佳实践[编辑 | 编辑源代码]
记录层级建议[编辑 | 编辑源代码]
数学表示[编辑 | 编辑源代码]
异常记录的信息量可表示为: 其中:
- = 信息类型权重
- = 信息值
实际案例[编辑 | 编辑源代码]
案例:Web API异常处理[编辑 | 编辑源代码]
// ASP.NET Core 示例
public class UsersController : ControllerBase
{
private readonly ILogger<UsersController> _logger;
[HttpGet("{id}")]
public IActionResult GetUser(string id)
{
try
{
var user = _userService.GetUser(id);
return Ok(user);
}
catch (UserNotFoundException ex)
{
_logger.LogWarning(ex, "用户未找到: {UserId}", id);
return NotFound();
}
catch (Exception ex)
{
_logger.LogError(ex, "获取用户时发生错误");
return StatusCode(500);
}
}
}
异常记录系统架构[编辑 | 编辑源代码]
高级主题[编辑 | 编辑源代码]
性能考量[编辑 | 编辑源代码]
- 异步记录:使用
LogAsync
方法避免阻塞 - 批量写入:对于高频异常,采用缓冲写入策略
- 敏感信息过滤:避免记录密码等敏感数据
自定义异常记录器[编辑 | 编辑源代码]
实现自定义 ILoggerProvider
:
public class DatabaseLoggerProvider : ILoggerProvider
{
public ILogger CreateLogger(string categoryName)
{
return new DatabaseLogger();
}
public void Dispose() { }
}
public class DatabaseLogger : ILogger
{
public void Log<TState>(LogLevel logLevel, EventId eventId,
TState state, Exception exception, Func<TState, Exception, string> formatter)
{
// 实现数据库写入逻辑
}
}
总结[编辑 | 编辑源代码]
- 异常记录是诊断系统问题的关键工具
- 应记录足够的上下文信息(但避免敏感数据)
- 根据异常严重程度选择适当的日志级别
- 考虑使用成熟的日志框架(如Serilog/NLog)而非直接写文件