1. .NET日志框架核心原理剖析
日志系统是任何应用程序不可或缺的组成部分,它如同程序的"黑匣子",记录着运行时的重要信息。在.NET生态中,微软提供了强大的日志抽象框架,让我们先深入理解其架构设计。
1.1 日志系统分层架构
.NET日志系统采用典型的三层架构设计:
- 日志记录层(Logger):开发者直接调用的API接口
- 日志过滤层(Filter):根据配置决定哪些日志需要记录
- 日志输出层(Provider):将日志写入不同目标(控制台、文件等)
这种分层设计的关键在于ILogger接口,它是整个系统的核心契约。当我们在代码中调用LogInformation()等方法时,实际上是通过这个接口将日志消息传递到日志管道中。
1.2 日志记录流程详解
一个典型的日志记录过程会经历以下阶段:
- 日志类别确定:每个日志记录器都有关联的类别,通常使用
ILogger<T>时,T的类型全名就是类别 - 日志级别检查:系统首先检查当前日志级别是否满足配置要求
- 作用域处理:如果启用了作用域,会将作用域信息附加到日志消息
- 格式化和输出:最终将日志消息按照指定格式输出到各个Provider
重要提示:日志级别检查发生在日志记录的最早期,这可以避免不必要的字符串格式化和对象分配,对性能影响极小。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 手写日志框架实战
理解了原理后,我们尝试从零构建一个简易日志框架。这个练习将帮助我们深入理解.NET日志框架的内部机制。
2.1 基础接口定义
首先定义核心接口,这与微软的设计非常相似:
csharp复制public interface ILogger
{
void Log(LogLevel level, string message, Exception exception = null);
bool IsEnabled(LogLevel level);
IDisposable BeginScope<TState>(TState state);
}
public interface ILoggerProvider : IDisposable
{
ILogger CreateLogger(string categoryName);
}
public enum LogLevel
{
Trace,
Debug,
Information,
Warning,
Error,
Critical,
None
}
2.2 实现控制台日志Provider
创建一个将日志输出到控制台的简单实现:
csharp复制public class ConsoleLogger : ILogger
{
private readonly string _categoryName;
public ConsoleLogger(string categoryName)
{
_categoryName = categoryName;
}
public IDisposable BeginScope<TState>(TState state) => null;
public bool IsEnabled(LogLevel logLevel) => logLevel != LogLevel.None;
public void Log(LogLevel logLevel, string message, Exception exception = null)
{
if (!IsEnabled(logLevel)) return;
var color = logLevel switch
{
LogLevel.Critical => ConsoleColor.Red,
LogLevel.Error => ConsoleColor.DarkRed,
LogLevel.Warning => ConsoleColor.Yellow,
LogLevel.Information => ConsoleColor.White,
_ => ConsoleColor.Gray
};
Console.ForegroundColor = color;
Console.WriteLine($"[{DateTime.Now:HH:mm:ss} {logLevel}] {_categoryName}: {message}");
if (exception != null)
Console.WriteLine(exception);
Console.ResetColor();
}
}
2.3 日志工厂实现
创建一个简单的LoggerFactory来管理日志提供者:
csharp复制public class LoggerFactory : ILoggerFactory
{
private readonly
