mirror of
https://github.com/GeWuYou/GFramework.git
synced 2026-03-22 10:34:30 +08:00
- 移除 .claude 设置文件 - 重构枚举扩展生成器文档,更新 API 使用方式和配置选项 - 调整日志生成器文档,更新属性使用方式和配置参数 - 修改 Git 忽略规则添加 .claude/settings.json - 更新代码示例和最佳实践指南
338 lines
6.9 KiB
Markdown
338 lines
6.9 KiB
Markdown
# 日志生成器
|
||
|
||
> GFramework.SourceGenerators 自动生成日志代码,减少样板代码
|
||
|
||
## 概述
|
||
|
||
日志生成器是一个 Source Generator,它会自动为标记了 `[Log]` 特性的类生成 ILogger 字段。这消除了手动编写日志字段的需要,让开发者专注于业务逻辑。
|
||
|
||
## 基本用法
|
||
|
||
### 标记类
|
||
|
||
```csharp
|
||
using GFramework.SourceGenerators.Abstractions.logging;
|
||
|
||
[Log]
|
||
public partial class MyService
|
||
{
|
||
public void DoSomething()
|
||
{
|
||
// 自动生成的 Logger 字段可直接使用
|
||
Logger.Info("执行操作");
|
||
}
|
||
}
|
||
```
|
||
|
||
### 生成代码
|
||
|
||
上面的代码会被编译时转换为:
|
||
|
||
```csharp
|
||
// <auto-generated/>
|
||
public partial class MyService
|
||
{
|
||
private static readonly ILogger Logger =
|
||
LoggerFactoryResolver.Provider.CreateLogger("YourNamespace.MyService");
|
||
}
|
||
```
|
||
|
||
**注意**:生成器只生成 ILogger 字段,不生成日志方法。日志方法(Info、Debug、Error 等)来自 ILogger 接口本身。
|
||
|
||
## 日志级别
|
||
|
||
生成的 Logger 字段支持 ILogger 接口的所有方法:
|
||
|
||
```csharp
|
||
[Log]
|
||
public partial class MyClass
|
||
{
|
||
public void Example()
|
||
{
|
||
// 调试信息
|
||
Logger.Debug($"调试信息: {value}");
|
||
|
||
// 普通信息
|
||
Logger.Info("操作成功");
|
||
|
||
// 警告
|
||
Logger.Warning($"警告: {message}");
|
||
|
||
// 错误
|
||
Logger.Error($"错误: {ex.Message}");
|
||
|
||
// 严重错误
|
||
Logger.Critical("系统故障");
|
||
}
|
||
}
|
||
```
|
||
|
||
## 自定义日志类别
|
||
|
||
```csharp
|
||
[Log("Gameplay")]
|
||
public partial class GameplaySystem
|
||
{
|
||
// 日志会标记为 Gameplay 类别
|
||
public void Update()
|
||
{
|
||
Logger.Info("游戏逻辑更新");
|
||
}
|
||
}
|
||
```
|
||
|
||
## 配置选项
|
||
|
||
### 自定义字段名称
|
||
|
||
```csharp
|
||
[Log(FieldName = "_customLogger")]
|
||
public partial class MyClass
|
||
{
|
||
public void DoSomething()
|
||
{
|
||
// 使用自定义字段名
|
||
_customLogger.Info("使用自定义日志器");
|
||
}
|
||
}
|
||
```
|
||
|
||
### 非静态字段
|
||
|
||
```csharp
|
||
[Log(IsStatic = false)]
|
||
public partial class InstanceLogger
|
||
{
|
||
// 生成实例字段而非静态字段
|
||
public void LogMessage()
|
||
{
|
||
Logger.Info("实例日志");
|
||
}
|
||
}
|
||
```
|
||
|
||
### 访问修饰符
|
||
|
||
```csharp
|
||
[Log(AccessModifier = "protected")]
|
||
public partial class ProtectedLogger
|
||
{
|
||
// 生成 protected 字段
|
||
}
|
||
```
|
||
|
||
### 配置选项说明
|
||
|
||
| 参数 | 类型 | 默认值 | 说明 |
|
||
|----------------|---------|-----------|---------------------------------|
|
||
| Name | string? | null | 日志分类名称(默认使用类名) |
|
||
| FieldName | string | "Logger" | 生成的字段名称 |
|
||
| IsStatic | bool | true | 是否生成静态字段 |
|
||
| AccessModifier | string | "private" | 访问修饰符(private/protected/public) |
|
||
|
||
## 与其他模块集成
|
||
|
||
### 与 Godot 集成
|
||
|
||
```csharp
|
||
[Log]
|
||
[ContextAware]
|
||
public partial class GodotController : Node
|
||
{
|
||
public override void _Ready()
|
||
{
|
||
Logger.Info("控制器已准备就绪");
|
||
}
|
||
}
|
||
```
|
||
|
||
### 与架构集成
|
||
|
||
```csharp
|
||
[Log]
|
||
public partial class MySystem : AbstractSystem
|
||
{
|
||
protected override void OnInit()
|
||
{
|
||
Logger.Info("系统初始化");
|
||
}
|
||
}
|
||
```
|
||
|
||
## 实际应用示例
|
||
|
||
### 游戏控制器
|
||
|
||
```csharp
|
||
[Log]
|
||
[ContextAware]
|
||
public partial class PlayerController : IController
|
||
{
|
||
public void HandleInput(string action)
|
||
{
|
||
Logger.Debug($"处理输入: {action}");
|
||
|
||
switch (action)
|
||
{
|
||
case "jump":
|
||
Logger.Info("玩家跳跃");
|
||
Jump();
|
||
break;
|
||
case "attack":
|
||
Logger.Info("玩家攻击");
|
||
Attack();
|
||
break;
|
||
default:
|
||
Logger.Warning($"未知操作: {action}");
|
||
break;
|
||
}
|
||
}
|
||
|
||
private void Jump()
|
||
{
|
||
try
|
||
{
|
||
// 跳跃逻辑
|
||
Logger.Debug("跳跃执行成功");
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Logger.Error($"跳跃失败: {ex.Message}");
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
### 数据处理服务
|
||
|
||
```csharp
|
||
[Log("DataService")]
|
||
public partial class DataProcessor
|
||
{
|
||
public void ProcessData(string data)
|
||
{
|
||
Logger.Info($"开始处理数据,长度: {data.Length}");
|
||
|
||
if (string.IsNullOrEmpty(data))
|
||
{
|
||
Logger.Warning("数据为空,跳过处理");
|
||
return;
|
||
}
|
||
|
||
try
|
||
{
|
||
// 处理逻辑
|
||
Logger.Debug("数据处理中...");
|
||
// ...
|
||
Logger.Info("数据处理完成");
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Logger.Error($"数据处理失败: {ex.Message}");
|
||
throw;
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
## 最佳实践
|
||
|
||
### 1. 合理使用日志级别
|
||
|
||
```csharp
|
||
[Log]
|
||
public partial class BestPracticeExample
|
||
{
|
||
public void ProcessRequest()
|
||
{
|
||
// Debug: 详细的调试信息
|
||
Logger.Debug("开始处理请求");
|
||
|
||
// Info: 重要的业务流程信息
|
||
Logger.Info("请求处理成功");
|
||
|
||
// Warning: 可恢复的异常情况
|
||
Logger.Warning("缓存未命中,使用默认值");
|
||
|
||
// Error: 错误但不影响系统运行
|
||
Logger.Error("处理失败,将重试");
|
||
|
||
// Critical: 严重错误,可能导致系统崩溃
|
||
Logger.Critical("数据库连接失败");
|
||
}
|
||
}
|
||
```
|
||
|
||
### 2. 避免过度日志
|
||
|
||
```csharp
|
||
[Log]
|
||
public partial class PerformanceExample
|
||
{
|
||
private int _frameCount = 0;
|
||
|
||
public void Update()
|
||
{
|
||
// 好的做法:定期记录
|
||
if (_frameCount % 1000 == 0)
|
||
{
|
||
Logger.Debug($"已运行 {_frameCount} 帧");
|
||
}
|
||
_frameCount++;
|
||
|
||
// 避免:每帧都记录
|
||
// Logger.Debug($"帧 {_frameCount}"); // ❌ 太频繁
|
||
}
|
||
}
|
||
```
|
||
|
||
### 3. 结构化日志信息
|
||
|
||
```csharp
|
||
[Log]
|
||
public partial class StructuredLogging
|
||
{
|
||
public void ProcessUser(int userId, string action)
|
||
{
|
||
// 好的做法:包含上下文信息
|
||
Logger.Info($"用户操作 [UserId={userId}, Action={action}]");
|
||
|
||
// 避免:信息不完整
|
||
// Logger.Info("用户操作"); // ❌ 缺少上下文
|
||
}
|
||
}
|
||
```
|
||
|
||
## 常见问题
|
||
|
||
### Q: 为什么需要 partial 关键字?
|
||
|
||
**A**: 源代码生成器需要向现有类添加代码,`partial` 关键字允许一个类的定义分散在多个文件中。
|
||
|
||
### Q: 可以在静态类中使用吗?
|
||
|
||
**A**: 可以,生成器会自动生成静态字段:
|
||
|
||
```csharp
|
||
[Log]
|
||
public static partial class StaticHelper
|
||
{
|
||
public static void DoSomething()
|
||
{
|
||
Logger.Info("静态方法日志");
|
||
}
|
||
}
|
||
```
|
||
|
||
### Q: 如何自定义日志工厂?
|
||
|
||
**A**: 通过配置 `LoggerFactoryResolver.Provider` 来自定义日志工厂实现。
|
||
|
||
---
|
||
|
||
**相关文档**:
|
||
|
||
- [Source Generators 概述](./index)
|
||
- [枚举扩展生成器](./enum-generator)
|
||
- [ContextAware 生成器](./context-aware-generator)
|