1. 日志框架的核心价值与设计哲学
在.NET生态中,日志记录系统如同应用程序的"黑匣子",它不仅是问题排查的利器,更是系统行为分析的显微镜。一个典型的日志框架需要解决三个核心问题:记录什么(日志内容)、如何记录(输出渠道)、记录给谁看(消费分析)。主流框架如NLog、Serilog等之所以能成为行业标准,正是因为它们在这三个维度上做到了高度可配置和可扩展。
日志框架的架构通常遵循"记录器(Logger)-过滤器(Filter)-输出器(Appender)"的三层模型。记录器负责收集日志信息,过滤器决定哪些信息需要被记录,输出器则处理日志的持久化方式。这种分层设计符合单一职责原则,使得每个组件都可以独立替换和扩展。
关键经验:在实际项目中,日志级别(Log Level)的设置往往被低估。合理的级别划分(如Debug用于开发、Information用于常规运行、Error用于可恢复异常、Critical用于系统级故障)能显著提升日志的有效性。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 手写日志框架的实战演练
2.1 基础架构搭建
我们先从最基础的日志接口定义开始:
csharp复制public interface ILogger
{
void Log(LogLevel level, string message, Exception exception = null);
bool IsEnabled(LogLevel level);
}
public enum LogLevel
{
Trace,
Debug,
Information,
Warning,
Error,
Critical
}
这个简单的接口定义了日志系统的核心契约。接下来实现一个控制台输出的基础版本:
csharp复制public class ConsoleLogger : ILogger
{
private readonly string _categoryName;
public ConsoleLogger(string categoryName)
{
_categoryName = categoryName;
}
public void Log(LogLevel level, string message, Exception exception = null)
{
if (!IsEnabled(level)) return;
var logEntry = $"[{DateTime.Now:O}] [{level}] {_categoryName}: {message}";
if (exception != null)
{
logEntry += Environment.NewLine + exception;
}
Console.WriteLine(logEntry);
}
public bool IsEnabled(LogLevel level) => level >= LogLevel.Information;
}
2.2 日志上下文增强
现代日志系统往往需要携带上下文信息。我们引入LogScope的概念:
csharp复制public class LogScope : IDisposable
{
private static readonly AsyncLocal<LogScope> _current = new();
public LogScope(string name)
{
Name = name;
Parent = _current.Value;
_current.Value = this;
}
public string Name { get; }
public LogScope Parent { get; }
public static LogScope Current => _current.Value;
public void Dispose() => _current.Value = Parent;
}
public class EnhancedLogger : ILogger
{
// ...其他代码同前...
public void Log(LogLevel level, string message, Exception exception = null)
{
var scope = LogScope.Current;
var scopePath = new List<string>();
while
