# MiniLog **Repository Path**: netcasewqs/MiniLog ## Basic Information - **Project Name**: MiniLog - **Description**: 轻量级高性能 .NET 日志组件库 - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-08-13 - **Last Updated**: 2026-09-06 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # MiniLog > 轻量、高性能的 .NET 日志组件库,**零外部依赖**。API 形态借鉴 log4net / NLog 的派发模型(Logger → Appender → Layout),但在底层采用**结构体日志条目**、**零分配渲染**与**源生成器**,定位为「现代、低 GC 压力、可替代 MS Logging 的高性能日志框架」。 > > 核心技术亮点: > > - **零分配渲染** —— `LogEntry` 值语义结构体 + `ReusableDelegateWriter` + `ValueStringBuilder`(栈缓冲 / `ArrayPool`),热路径零 GC > > - **零装箱派发** —— 源生成器经 `ILogArgumentBag` 泛型参数袋把结构化参数穿过整条派发链,启用路径不装箱 > > - **ANSI 彩色分级控制台** —— 可选、`EnableColors` 默认关、跨平台、不依赖 `Console` 全局颜色状态 > > - **源生成器双后端** —— `[Log]`(注入 `ILog` 字段)+ `[LoggerMessage]`(强类型零装箱),一份声明通吃 MiniLog 与 Microsoft.Extensions.Logging > > - **8 种 Appender + 8 种过滤器 + 11×7 文件/目录滚动** > **版本**: 1.0.0(GA)| **目标框架**: .NET 8.0 / .NET 10.0 | **许可证**: MIT > > **状态**:首个正式稳定版(GA)。可从[源码构建](#二快速开始)或引用本地包使用;包名 `MiniLog` 经核查在 nuget.org 可用、无冲突。 > > 源码仓库: *** ## 🚀 快速导航 | 模块 | 说明 | | -------------------------------- | ---------------------------------- | | [特性一览](#一特性一览) | 核心功能与亮点 | | [快速开始](#二快速开始) | 安装与三种上手方式 | | [与其他日志库对比](#三与其他开源日志库对比) | 性能与设计差异 | | [配置](#四配置) | 三格式配置 / Fluent / 已知问题(详见手册) | | [布局模式校验器](#布局模式校验器编译期-llg-诊断) | 编译期校验 %token 拼写/格式(LLG0002–0006) | | [编译期诊断码总表](docs/DIAGNOSTICS.md) | LLG0001–LLG0015 目录 + 触发范围 + MEL 边界 | | [Appenders 速览](#五appenders-输出目标) | 8 种输出目标 | | [性能定位](#六性能定位) | 基准快照 | | [文档导航](#七文档导航) | 完整手册 / 配置 / 基准 | | [许可证](#八许可证) | MIT | *** ## 目录 - [开发背景](#开发背景) - [一、特性一览](#一特性一览) - [二、快速开始](#二快速开始) - [三、与其他开源日志库对比](#三与其他开源日志库对比) - [四、配置](#四配置) - [布局模式校验器(编译期 LLG 诊断)](#布局模式校验器编译期-llg-诊断) - [编译期诊断码总表(LLG0001–LLG0015)](docs/DIAGNOSTICS.md) - [五、Appenders 输出目标](#五appenders-输出目标) - [六、性能定位](#六性能定位) - [七、文档导航](#七文档导航) - [八、许可证](#八许可证) *** ## 一、特性一览 | 特性 | 说明 | | ------- | ---------------------------------------------------------------------------------- | | 零外部依赖 | 纯 .NET 实现,不引入任何第三方包 | | 多格式配置 | XML / JSON / INI 三种文件 + Fluent Builder;XML 带 XSD、JSON 带 JSON Schema,IDE 智能提示 | | 多输出目标 | Console / Debug / Trace / File / AsyncFile / Udp / AdoNet 共 8 种 Appender,任意组合 | | 完善的文件滚动 | 11 种文件滚动(大小 / 分 / 时 / 天 / 月 / 年及组合)× 7 种目录滚动,支持过期清理 | | 零分配渲染 | `LogEntry` 值语义结构体 + `ReusableDelegateWriter` + `ValueStringBuilder`,热路径零 GC | | 异步批处理 | 基于 `System.Threading.Channels` 的有界队列(`ProducerConsumerQueue`),Drop / Block 背压,优雅关闭 | | 级别模型 | `Trace / Debug / Info / Warn / Error / Fatal` 六级,含 `IsXxxEnabled` 前置短路 | | 彩色分级控制台 | `ConsoleAppender` 可选 ANSI 着色(默认关闭),跨平台、多线程不串色 | | 结构化日志 | 原生 `EventId` + `Scope`(`ILog.BeginScope`,`AsyncLocal`,`using` 嵌套 + `await` 流转) | | 源生成器 | `[Log]`(注入 `ILog` 字段)+ `[LoggerMessage]`(强类型零装箱),双后端通吃 MiniLog 与 MEL | | MEL 兼容 | `MiniLog.Extensions.Logging` 提供 `AddMiniLog()`,可作为 MS Logging 的 Provider 接入 | | 过滤器链 | 8 种 `FilterOptions`,三态判定 `Deny / Neutral / Accept` | *** ## 二、快速开始 ### 2.1 安装 MiniLog 已发布到 NuGet,直接引用包即可。**源生成器** **`MiniLog.Generators`(含** **`[Log]`** **/** **`[LoggerMessage]`** **生成与布局模式校验分析器)随包自动以 Analyzer 形式引入,无需单独安装。** ```bash # 核心库(.NET 8.0 / .NET 10.0 双目标框架) dotnet add package MiniLog # 可选:接入 ASP.NET Core / Microsoft.Extensions.Logging 时再装此包 dotnet add package MiniLog.Extensions.Logging ``` > 要求:.NET 8.0 或 .NET 10.0 SDK。 > 包 ID:`MiniLog`(核心库)、`MiniLog.Extensions.Logging`(MEL 适配器)。两者均为 MIT、零外部依赖。 尚未发布或本地开发 / 贡献时,可用源码引用或本地生成包: ```bash # 方式 A:项目引用(含源生成器,自动以 Analyzer 引入) dotnet add reference ../src/MiniLog/MiniLog.csproj # 方式 B:本地生成 NuGet 包后引用 dotnet pack src/MiniLog/MiniLog.csproj -c Release # 产物 bin/Release/MiniLog.1.0.0.nupkg ``` ### 2.2 静态门面(最简,5 行开始记录) ```csharp using MiniLog; // 程序启动时调用一次:默认查找 log.config.xml,缺失时按 xml→json→ini 自动探测同名配置, // 均无则回退到 Logs/Log.txt LogManager.Initialize(); var log = LogManager.GetLogger(); // Logger 名默认取类型简单名 "Program" log.Info("应用启动"); log.Warn("磁盘剩余空间偏低"); // 程序退出前调用一次,确保异步 Appender 缓冲落盘 LogManager.Shutdown(); ``` > 一个完整的控制台最小示例(`Program.cs`): ```csharp using MiniLog; LogManager.Initialize(); // 读取 log.config.xml(或同目录 xml/json/ini) try { var log = LogManager.GetLogger(); log.Info("应用启动"); log.Error("出错了", new Exception("演示异常")); } finally { LogManager.Shutdown(); // 优雅关闭,刷新异步文件缓冲 } ``` ### 2.3 源生成器 `[Log]`(Lombok 风格,推荐) ```csharp [Log] // 编译期注入:private static readonly ILog log; public partial class OrderService // 默认字段名 log;默认 Logger 名 = 简单类名 "OrderService" { public void Process(int id) => log.Info("处理订单 " + id); } // 覆盖注入的 Logger 名(默认用类的简单名,不含命名空间) [Log(Name = "MyApp.Order")] public partial class OrderService2 { /* ... */ } // 逐类覆盖默认字段名(库默认已是 log,此处演示可改) [Log(FieldName = "Logger")] public partial class OrderService3 { /* ... */ } ``` > 默认注入字段名为 `log`(库新建无历史包袱,已从 `Log` 改为小写);可用 `[Log(FieldName="...")]` 逐类覆盖。`[Log(Name="...")]` 可覆盖注入的 Logger 名,`[LoggerMessage]` 同样支持。 ### 2.4 源生成器 `[LoggerMessage]`(强类型、零装箱) `[LoggerMessage]` 标记 `partial` 方法,生成器为其补全实现:入口先判定级别 `IsXxxEnabled`,级别关闭时零分配直接返回;热路径参数经结构化参数袋零装箱直写,兼顾性能与强类型。 ```csharp [Log] // 注入 log 字段;本类 [LoggerMessage] 方法自动复用它 public partial class OrderService { // 字段模式:无 ILog 首参,生成的实现直接使用类的 log 字段 [LoggerMessage(LogLevel.Info, "处理订单 {Id} 金额 {Amount}")] public partial void LogOrderProcessed(int id, decimal amount); // 显式 ILog 首参模式:按传入的 ILog 派发(可用于 MEL 的 ILogger) [LoggerMessage(LogLevel.Error, "保存失败 {Id}")] public partial void LogSaveFailed(ILog log, int id); } // 调用处(与手写日志等价,但无装箱、带级别短路) var svc = new OrderService(); svc.LogOrderProcessed(1001, 29.9m); ``` > 级别可省略,由方法名推断(`LogInfo`/`LogWarn`/`LogError`…);也可 `[LoggerMessage(LogLevel.Warn, "...")]` 显式指定。`[LoggerMessage]` 既可单独使用(生成器自动注入 log 字段),也可与 `[Log]` 同用(复用已注入字段)。 ### 2.5 配置文件 + Fluent Builder ```csharp var mgr = LogManager.CreateLogManager(b => b .UseConsoleAppender() .UseFileAppender("file", new FileAppenderOptions { FileDirectory = "Logs", FileName = "app", Extension = ".log", RollingMode = FileRollingMode.DailyAndSize, ExpiredDays = 30, }) .UseRoot(LogLevel.Warn, "console") .UseLogger("MyApp.Data", LogLevel.Info, "console", "file")); LogManager.SetLogManager(mgr); ``` > 更多用法(ILog 接口速查、结构化日志、彩色控制台、MEL 集成、源生成器)见 [MiniLog 使用手册](docs/MiniLog使用手册.md)。 ### 2.6 从源码构建与测试 仓库**无** **`.sln`** **解决方案文件**,直接按项目构建(目标 .NET 8.0 / .NET 10.0 双 TFM): ```bash dotnet build src/MiniLog/MiniLog.csproj -c Release dotnet build src/MiniLog.Generators/MiniLog.Generators.csproj -c Release dotnet test test/MiniLog.Tests/MiniLog.Tests.csproj -c Release dotnet test test/MiniLog.Extensions.Logging.Tests/MiniLog.Extensions.Logging.Tests.csproj -c Release dotnet pack src/MiniLog/MiniLog.csproj -c Release # 产出 NuGet 包 ``` **双门禁(提交门槛)**:`MiniLog` / `MiniLog.Generators` 开启 `-warnaserror`,Debug 与 Release 下 net8.0 / net10.0 必须 **0 警告 0 错误**;两套测试全绿才算闭环。贡献前请本地跑齐上述命令。 *** ## 三、与其他开源日志库对比 MiniLog 与 log4net / NLog / Serilog / MS.Extensions.Logging 定位有本质差异:它保留传统派发模型(Logger → Appender → Layout),但在底层用零分配渲染与源生成器实现数量级性能领先。 ### 3.1 能力矩阵(主流 5 库) | 维度 | **MiniLog** | log4net | NLog | Serilog | MS.Extensions.Logging | | --------------- | -------------------------- | ------------------------ | ---------------- | ---------------------- | --------------------- | | 外部依赖 | **无** | 无 | 无 | 无 | 无(抽象层) | | 配置方式 | XML / JSON / INI / Builder | XML / 代码 | XML / JSON / 代码 | JSON / 代码 / C# | appsettings / 代码 | | Appender / 输出目标 | 8 种 | 20+ 种 | 80+ Targets | Sink 生态(数百) | 内置 + 第三方 Provider | | 零分配渲染 | **是(热路径)** | 否 | 部分 | 否 | 取决于 Provider | | 源生成器 | **内置(双后端)** | 无 | 无 | 无(用 MEL LoggerMessage) | **LoggerMessage(官方)** | | 结构化日志 | EventId + Scope(值语义) | 弱 | 支持(Layout) | **一等公民** | 一等公民 | | 彩色控制台 | ANSI(可选,默认关) | `ColoredConsoleAppender` | `ColoredConsole` | 控制台 Sink 主题 | 控制台 Provider 支持 | | 成熟度 / 生态 | 预览期 | **极高** | 高 | 高 | **官方标准** | ### 3.2 性能定位 ``` 固定消息:MiniLog(26.8µs) << MS(102µs) << Serilog(869µs) << NLog(16.5ms) ≈ log4net(17.6ms) 异步文件:MiniLog(98µs) << NLog(1.6ms) ≈ MS(1.8ms) << log4net(2.4ms) << Serilog(9.8ms) 级别关闭:MiniLog源生成(7.5µs/0B) < MS LoggerMessage(11.5µs/0B) << MS 原生(仍分配 640KB) ``` - **vs log4net / NLog**:传统派发模型但非文件模式快 600×+,零分配,现代 API。 - **vs Serilog**:Serilog 结构化日志与 Sink 生态最丰富;MiniLog 在性能与分配上显著占优。 - **vs MS.Extensions.Logging**:真实负载下更快且零分配语义打平;MiniLog 通过 `MiniLog.Extensions.Logging` 直接作为 MS Provider 接入,兼得两者。 > 完整能力矩阵、性能三段排名与选型建议见 [使用手册·对比章节](docs/MiniLog使用手册.md#十三与其他开源日志库对比)。 *** ## 四、配置 MiniLog 支持 **XML / JSON / INI** 三种格式 + **Fluent Builder**。默认查找 `AppDomain.CurrentDomain.BaseDirectory/log.config.xml`,缺失时按 xml→json→ini 优先级自动探测同目录同名配置,均无则回退到 `Logs/Log.txt`。 最简 XML 示例: ```xml file console ``` 常用占位符:`%timestamp`/`%thread`/`%level`/`%logger`/`%message`/`%exception`/`%newline`/`%appdomain`/`%username`/`%identity`/`%file`/`%line`/`%method`/`%location`/`%eventid`/`%scope`/`%property`/`%stacktrace`(共 22 个)。 > **完整配置参考**(加载机制、三格式选型、顶层选项、Appender 全属性、File / AdoNet 选项、Logger·Root、滚动模式、三格式完整示例、Fluent Builder、Schema 验证、已知问题)见 [MiniLog 使用手册·配置详解](docs/MiniLog使用手册.md#五配置详解) 与 [CONFIGURATION.md](CONFIGURATION.md)。 *** ## 五、Appenders 输出目标 共 8 种,均线程安全: | 类型 | 实现 | 说明 | | ----------- | ------------------- | ----------------------------------------- | | `None` | `NoneAppender` | 丢弃所有日志。用于显式关闭通道或零开销基准。 | | `Console` | `ConsoleAppender` | 输出到 `Console.Out`;可选 ANSI 彩色分级。 | | `Debug` | `DebugAppender` | 输出到 `System.Diagnostics.Debugger.Log`。 | | `Trace` | `TraceAppender` | 输出到 `System.Diagnostics.Trace.Listeners`。 | | `File` | `FileAppender` | 同步文件追加,内部 `lock` 保证写入与滚动安全。 | | `AsyncFile` | `AsyncFileAppender` | 基于 `Channels` 异步写入,调用方不阻塞;队列满可能丢弃(设计权衡)。 | | `Udp` | `UdpAppender` | 经 `UdpClient` 发送渲染文本到远程端点,超长消息截断。 | | `AdoNet` | `AdoNetAppender` | 参数化 SQL 写关系型数据库;支持零分配直传与异步批量。 | > 选型:低并发用 `File`,高并发用 `AsyncFile`。完整 8 种配置与 AdoNet 异步参数见 [使用手册·Appenders](docs/MiniLog使用手册.md#六appenders-输出目标)。 *** ## 六、性能定位 ### 6.1 基准快照(.NET 8.0,BenchmarkDotNet) **固定消息(10K 次循环总耗时):** | 库 | Mean | 分配 | | ------------------------------- | -----------: | ------: | | **MiniLog(无输出短路)** | **26.83 µs** | **0 B** | | MS Logging(未挂 Provider,纯 no-op) | 102.52 µs | 0 B | | Serilog | 868.70 µs | 1.6 MB | | NLog | 16,548.81 µs | 1.2 MB | | log4net | 17,561.30 µs | 2.0 MB | **异步文件(1K 条):** | 库 | Mean | 分配 | | --------------------- | -----------: | --------: | | **MiniLog-AsyncFile** | **97.52 µs** | **94 KB** | | NLog | 1,611.5 µs | 171 KB | | MS Logging | 1,781.8 µs | 241 KB | | log4net | 2,360.8 µs | 350 KB | | Serilog | 9,796.4 µs | 491 KB | **源生成器级别关闭(10K 次):** | 方式 | Mean | 分配 | | ------------------------------ | ----------: | ------: | | **MiniLog 源生成** | **7.49 µs** | **0 B** | | MS LoggerMessage | 11.53 µs | 0 B | | MiniLog 原生 API | 35.84 µs | 0 B | | MS 原生 `LogInformation(params)` | 232.93 µs | 640 KB | > 横向基准中 MS Logging 未挂载任何 Provider,`Log()` 在 `IsEnabled` 即短路为纯 no-op(102µs 是「什么都不做」的代价)。真实项目 MS 必挂 Provider,开销会上升。详细设计与并发/过滤基准见 [使用手册·性能设计](docs/MiniLog使用手册.md#十二性能设计) 与 [BENCHMARK\_REPORT.md](BENCHMARK_REPORT.md)。 ### 6.2 零分配黄金路径 要让日志调用达成热路径零堆分配(对应基准:固定消息 42µs/万条零分配、参数袋 Span 物化 8.8µs/零分配、UDP 新 26ns/零分配;并发 40 万消息 16/18 零 GC),遵循: 1. **用结构化 API 代替字符串插值**:`logger.Log(new LogEntry { ... })` 或源生成器 `Log`(编译期 `FormatTo` 零分配直写);避免 `logger.Info($"User {id}")`(每次分配插值字符串,基准 560KB/万条)。 2. **渲染物化走 Span 直写**:Appender 内部默认 `WriteToAndClear(TextWriter)` 直写(零分配);仅确需字符串时才调 `GetStringAndClear`(基准 96KB/千次)。 3. **结构化字段用** **`%property`**:经 `LogEntry.Properties["k"] = v` 设置,`%property{k}` 渲染;`PropertyCount == 0` 短路零开销。 4. **高吞吐降载用采样**:配置 `SamplingFilterOptions`,无锁零分配按比例丢弃。 完整四层基准(热方法 / 端到端 / 并发零分配 / 解析)与零回退论证见 [BENCHMARK\_REPORT.md](BENCHMARK_REPORT.md)。 *** ## 布局模式校验器(编译期 LLG 诊断) MiniLog 内置一个 Roslyn 分析器(`MiniLog.Generators`),在**编译期**校验赋值给 `AppenderOptions.Pattern` / `AdoNetParameter.Layout`(含 `WithPattern(...)` / `WithLayout(...)` 入参、常量折叠与插值字面段)的布局模式串,把 `%token` 拼写 / 格式错误拦在构建前,而非运行时解析失败。经 NuGet 包引入时分析器自动随包进入 `analyzers/dotnet/cs`,消费方编译期即得校验;配置文件(XML / JSON / INI)字面量则由 `ConfigurationBinder` 运行期探针以 `Trace` 警告兜底。 | 诊断 | 触发条件 | 示例 | | --------- | -------------------------------- | --------------------------- | | `LLG0002` | 未知占位符(附最近邻建议) | `%levl` → 是否指 `%level` | | `LLG0003` | 未闭合的 `{` | `%date{yyyy-MM-dd` | | `LLG0004` | 空选项 `{}` / `{ }` | `%property{}` | | `LLG0005` | 已知令牌带不应有的选项 | `%level{critical}` | | `LLG0006` | `%date` / `%timestamp` 选项保留字拼写错误 | `%date{ISO860}` → `ISO8601` | 保留字(`LLG0006` 建议集):`ISO8601` / `DATE` / `ABSOLUTE` / `COMPACT`;精确匹配或任意 .NET 格式(如 `yyyy-MM-dd`)合法、不触发。 ```csharp // 编译期即报错,而非运行时才发现布局串写错 new AppenderOptions { Pattern = "%levl %logger" }; // ⚠ LLG0002 未知 'levl'(是否指 'level'?) new AppenderOptions().WithPattern("%date{yyyy-MM-dd"); // ⚠ LLG0003 未闭合 new AppenderOptions { Pattern = "%property{}" }; // ⚠ LLG0004 空选项 new AppenderOptions { Pattern = "%level{x}" }; // ⚠ LLG0005 'level' 不接受选项 new AppenderOptions { Pattern = "%date{ISO860}" }; // ⚠ LLG0006 疑似 'ISO8601' // 配置文件(经 NuGet 分析的消费方亦生效,IDE 实时波浪线 + 构建警告) // ⚠ 未知占位符 'levl'(是否指 'level'?) ``` > 有意不做(编译期不可判定):非常量动态值(变量、含非 const 孔的插值)、`%date{非法格式}` 格式合法性、`%property{不存在的键}` 键存在性 —— 交由运行时解析兜底。 *** ## 七、文档导航 | 文档 | 内容 |
|
| | --------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | :----- | :----- | | [MiniLog 使用手册(中文)](docs/MiniLog使用手册.md) | 核心特性 / 安装 / 快速开始 / 核心概念 / **配置详解** / Appenders / 过滤器 / 彩色控制台 / 结构化日志 / 源生成器 / MEL 集成 / 性能设计 / **与其他开源库对比** / log4net 迁移 / 许可证 |
|
| | [配置参考](CONFIGURATION.md) | XML / JSON / INI 全部配置项、加载机制、Fluent API、Schema 验证、15 条已知问题 |
|
| | [MEL 集成指南](docs/MEL集成指南.md) | 与 Microsoft.Extensions.Logging 集成的权威深度文档:注册 API 全景 / 两种生命周期模型 / 级别·名称·结构化·Scope 映射 / IConfiguration 桥接原理 / 热重载 / 排错 |
|
| | [基准报告](BENCHMARK_REPORT.md) | BenchmarkDotNet 性能数据 |
|
| | [编译期诊断码总表](docs/DIAGNOSTICS.md) | LLG0001–LLG0015 目录 / 配置文件分析器触发范围 / MEL 路径边界 |
|
| | [变更日志](CHANGELOG.md) | 版本变更记录(1.0.0 GA 起,按需补充) |
|
| *** ## 八、许可证 MIT —— 详见 [LICENSE](LICENSE)(仓库根目录)。