跳到主要内容
版本:3.0.0

UMeta 结构化日志与 OpenTelemetry

解决什么问题

Aegis.UMeta.Logging 将 Aegis 应用的日志接入 UMetaOS OpenTelemetry SDK,实现:

  • 标准 ILogger 调用自动桥接到 OTel BizLogger,业务代码无需修改
  • 通过 BizLogger 直接输出带扩展字段的结构化日志
  • 审计日志自动采集(操作人、客户端、操作域、操作内容)
  • 请求级别的 RequestId 自动注入到所有日志条目

如何引入

NuGet 包Aegis.UMeta.Logging

注册方式:通过 Component.deps.json 自动注册,ComponentName 为 "UMeta.Logging"

Component.deps.json 中添加:

{
"Components": {
"Services": ["UMeta.Logging"],
"Middlewares": ["UMeta.Logging"]
}
}

依赖的 Aegis 包

  • Aegis.Component
  • Aegis.Context

配置

组件通过应用根目录的 otel-config.yaml 管理 OTel 相关参数,不使用 appsettings.json

otel-config.yaml 主要参数:

service_name: "your-service-name"
environment: "dev"
tracing:
enabled: true
sample_rate: 1.0
exporters:
otlp:
endpoint: "http://otel-collector:4317"
logging:
level: "INFO"
correlation: true
dev:
output:
type: "console"
audit:
output:
type: "console"

appsettings.json 中仅配置标准日志级别:

{
"Logging": {
"LogLevel": {
"Default": "Warning"
}
}
}

组件内置以下日志过滤规则(仅对 BizLoggerProvider 生效,可通过 Logging:BizLoggerProvider:LogLevel 覆盖):

命名空间前缀默认最低级别
MicrosoftWarning
HostWarning
System.Net.HttpWarning
WorkerWarning

使用示例

标准 ILogger(无侵入)

引入组件后,已有的 ILogger 调用自动桥接到 BizLogger,无需改动代码:

public class TestController : ControllerBase
{
private readonly ILogger<TestController> _logger;

public TestController(ILogger<TestController> logger)
{
_logger = logger;
}

[HttpGet]
public IActionResult Get()
{
_logger.LogInformation("处理请求");
return Ok();
}
}

BizLogger 直接调用

需要附加扩展字段时,通过 OtelSdk.GetBizLogger() 获取 BizLogger 实例:

using UMetaOS.OpenTelemetry.SDK;

var logger = OtelSdk.GetBizLogger();

// 基本用法
logger?.Info("创建订单");

// 带扩展字段
logger?.Info("创建订单", extend: new Dictionary<string, object?>
{
["uMetaVNA"] = new Dictionary<string, object?>
{
["user_id"] = "user-123",
["product_id"] = "prod-456",
["quantity"] = 2
}
});

审计日志

using UMetaOS.OpenTelemetry.SDK;
using UMetaOS.OpenTelemetry.SDK.Models;

OtelSdk.GetAuditBuilder()
.SetOperator(new OperatorInfo
{
Id = "user-001",
Name = "张三",
Role = Role.Admin
})
.SetClient(new ClientInfo
{
Ip = "192.168.1.100",
Device = "Chrome/120"
})
.SetOperateDomain(new OperateDomain
{
Domain = "order-service",
SubDomain = "order-management",
Node = "create-order"
})
.SetOperateContent(new OperateContent
{
Type = OperationType.创建.ToString(),
Topic = "创建订单",
ResourceId = "ORD-001",
Description = "用户创建订单"
})
.AddExtend("session_id", "sess-123")
.AuditLog();

RequestId 自动追踪

AegisOtelLogEnricher 中间件自动将 ActionContext.Current.RequestId 注入到当前请求的所有日志条目中。只要在 Component.deps.json 的 Middlewares 中声明了 "UMeta.Logging",这个行为就会自动生效,不需要额外配置。

扩展点

类型用途
BizLoggerProviderILoggerProvider 实现,将 ILogger 调用桥接到 OTel BizLogger
AegisOtelLogEnricherIMiddleware 实现,注入 RequestId scope 到请求日志

边界与限制

  • 组件依赖外部 umetaos-otel-csharp-sdk(版本 0.0.1),SDK 的更新不在 Aegis 框架控制范围内。
  • otel-config.yaml 文件需要手动放置在应用根目录,不通过 appsettings.json 管理。
  • 审计日志的输出配置(如 SM3/SHA256 哈希)在 otel-config.yaml 中设置。
  • ILogger 和 BizLogger 可以同时使用:ILogger 的输出会经过 BizLoggerProvider 桥接,直接调用 BizLogger 则跳过 ILogger 管道。