将Feature/XP.Common和Feature/XP.Hardware分支合并至Develop/XP.forHardwareAndCommon,完善XPapp注册和相关硬件类库通用类库功能。
This commit is contained in:
@@ -0,0 +1,177 @@
|
||||
# 日志服务使用指南 | Logger Service Usage Guide
|
||||
|
||||
## 概述 | Overview
|
||||
|
||||
XplorePlane 使用 Serilog 作为底层日志框架,通过 `ILoggerService` 接口提供统一的日志服务。
|
||||
|
||||
## 基本用法 | Basic Usage
|
||||
|
||||
### 方式 1:自动类型推断(推荐)| Method 1: Auto Type Inference (Recommended)
|
||||
|
||||
使用泛型方法 `ForModule<T>()` 自动获取类型的完整名称(命名空间 + 类名):
|
||||
|
||||
```csharp
|
||||
public class PlcService
|
||||
{
|
||||
private readonly ILoggerService _logger;
|
||||
|
||||
public PlcService(ILoggerService logger)
|
||||
{
|
||||
// 自动使用 "XP.Hardware.Plc.Services.PlcService" 作为模块名
|
||||
// Automatically uses "XP.Hardware.Plc.Services.PlcService" as module name
|
||||
_logger = logger?.ForModule<PlcService>() ?? throw new ArgumentNullException(nameof(logger));
|
||||
}
|
||||
|
||||
public void DoSomething()
|
||||
{
|
||||
_logger.Info("执行操作 | Performing operation");
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 方式 2:手动指定模块名 | Method 2: Manual Module Name
|
||||
|
||||
如果需要自定义模块名,可以使用字符串参数:
|
||||
|
||||
```csharp
|
||||
public class PlcService
|
||||
{
|
||||
private readonly ILoggerService _logger;
|
||||
|
||||
public PlcService(ILoggerService logger)
|
||||
{
|
||||
// 手动指定简短的模块名
|
||||
// Manually specify a short module name
|
||||
_logger = logger?.ForModule("PlcService") ?? throw new ArgumentNullException(nameof(logger));
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 方式 3:使用 typeof 获取类型名 | Method 3: Using typeof for Type Name
|
||||
|
||||
在静态方法或无法使用泛型的场景:
|
||||
|
||||
```csharp
|
||||
public class PlcService
|
||||
{
|
||||
private readonly ILoggerService _logger;
|
||||
|
||||
public PlcService(ILoggerService logger)
|
||||
{
|
||||
// 使用 typeof 获取类型
|
||||
// Use typeof to get type
|
||||
_logger = logger?.ForModule<PlcService>() ?? throw new ArgumentNullException(nameof(logger));
|
||||
}
|
||||
|
||||
public static void StaticMethod(ILoggerService logger)
|
||||
{
|
||||
// 静态方法中也可以使用泛型
|
||||
// Can also use generics in static methods
|
||||
var log = logger.ForModule<PlcService>();
|
||||
log.Info("静态方法日志 | Static method log");
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 日志级别 | Log Levels
|
||||
|
||||
```csharp
|
||||
// 调试信息(开发环境)| Debug information (development environment)
|
||||
_logger.Debug("调试信息:变量值={Value} | Debug info: variable value={Value}", someValue);
|
||||
|
||||
// 一般信息 | General information
|
||||
_logger.Info("操作成功 | Operation successful");
|
||||
|
||||
// 警告信息 | Warning information
|
||||
_logger.Warn("连接不稳定 | Connection unstable");
|
||||
|
||||
// 错误信息(带异常)| Error information (with exception)
|
||||
_logger.Error(ex, "操作失败:{Message} | Operation failed: {Message}", ex.Message);
|
||||
|
||||
// 致命错误 | Fatal error
|
||||
_logger.Fatal(ex, "系统崩溃 | System crash");
|
||||
```
|
||||
|
||||
## 日志输出格式 | Log Output Format
|
||||
|
||||
使用 `ForModule<T>()` 后,日志会自动包含完整的类型信息:
|
||||
|
||||
```
|
||||
2026-03-12 10:30:15.123 [INF] [XP.Hardware.Plc.Services.PlcService] 正在初始化 PLC 连接... | Initializing PLC connection...
|
||||
2026-03-12 10:30:16.456 [INF] [XP.Hardware.Plc.Services.PlcService] PLC 连接成功 | PLC connection successful
|
||||
```
|
||||
|
||||
## 最佳实践 | Best Practices
|
||||
|
||||
### 1. 在构造函数中初始化日志器 | Initialize Logger in Constructor
|
||||
|
||||
```csharp
|
||||
public class MyService
|
||||
{
|
||||
private readonly ILoggerService _logger;
|
||||
|
||||
public MyService(ILoggerService logger)
|
||||
{
|
||||
_logger = logger?.ForModule<MyService>() ?? throw new ArgumentNullException(nameof(logger));
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 使用结构化日志 | Use Structured Logging
|
||||
|
||||
```csharp
|
||||
// 好的做法:使用占位符 | Good: use placeholders
|
||||
_logger.Info("用户 {UserId} 执行了操作 {Action} | User {UserId} performed action {Action}", userId, action);
|
||||
|
||||
// 不好的做法:字符串拼接 | Bad: string concatenation
|
||||
_logger.Info($"用户 {userId} 执行了操作 {action}");
|
||||
```
|
||||
|
||||
### 3. 异常日志包含上下文 | Exception Logs Include Context
|
||||
|
||||
```csharp
|
||||
try
|
||||
{
|
||||
await _plcClient.ConnectAsync(config);
|
||||
}
|
||||
catch (PlcException ex)
|
||||
{
|
||||
_logger.Error(ex, "PLC 连接失败:地址={Address}, 端口={Port} | PLC connection failed: address={Address}, port={Port}",
|
||||
config.Address, config.Port);
|
||||
throw;
|
||||
}
|
||||
```
|
||||
|
||||
## 对比:三种方式的输出 | Comparison: Output of Three Methods
|
||||
|
||||
```csharp
|
||||
// 方式 1:ForModule<T>() - 完整类型名
|
||||
// Method 1: ForModule<T>() - Full type name
|
||||
_logger = logger.ForModule<PlcService>();
|
||||
// 输出 | Output: [XP.Hardware.Plc.Services.PlcService]
|
||||
|
||||
// 方式 2:ForModule("PlcService") - 自定义名称
|
||||
// Method 2: ForModule("PlcService") - Custom name
|
||||
_logger = logger.ForModule("PlcService");
|
||||
// 输出 | Output: [PlcService]
|
||||
|
||||
// 方式 3:不调用 ForModule - 无模块标记
|
||||
// Method 3: Don't call ForModule - No module tag
|
||||
_logger = logger;
|
||||
// 输出 | Output: [] (空标记 | empty tag)
|
||||
```
|
||||
|
||||
## 配置 | Configuration
|
||||
|
||||
日志配置在 `App.config` 中设置,通过 `SerilogConfig` 加载:
|
||||
|
||||
```xml
|
||||
<appSettings>
|
||||
<add key="Serilog:LogPath" value="C:\Logs\XplorePlane" />
|
||||
<add key="Serilog:MinimumLevel" value="Information" />
|
||||
<add key="Serilog:EnableConsole" value="true" />
|
||||
<add key="Serilog:RollingInterval" value="Day" />
|
||||
<add key="Serilog:FileSizeLimitMB" value="100" />
|
||||
<add key="Serilog:RetainedFileCountLimit" value="30" />
|
||||
</appSettings>
|
||||
```
|
||||
Reference in New Issue
Block a user