Microsoft.Extensions.Logging.RabbitMQ 1.2.1
Microsoft.Extensions.Logging.RabbitMQ
将 .NET 日志无缝集成到 RabbitMQ,实现日志的异步收集、集中分发与可扩展处理。支持客户端日志生产、服务端日志消费、可插拔消息处理器、多实例隔离、自动重连与性能优化,适用于分布式系统、微服务架构、容器与云原生场景下的集中日志方案。
核心特性
- 异步推送:应用线程将日志写入缓冲(Channel/队列),快速返回,降低 IO 阻塞。
- 集中消费:服务端通过实现
IRabbitMQMessageHandler自定义持久化(数据库 / 文件 / ES / 分析平台)。 - 自动重连:开启
AutomaticRecoveryEnabled后网络抖动或 Broker 重启可自动恢复连接与通道。 - 多实例与路由:支持多个 RouteKey / Exchange / VirtualHost 组合,区分不同业务线或环境。
- 过滤与分类:使用标准
ILogger分类与级别,兼容Microsoft.Extensions.Logging生态。 - 配置绑定:可从
appsettings.json/ 环境变量 / 配置中心动态加载参数。 - 可扩展处理器:只需实现接口即可插入自定义序列化、批处理、降级策略。
- 高性能 / 低侵入:保持最小依赖,轻量接入;可与 Console / Debug / 其他 Provider 并行。
- 可观测性支持:可在处理器里添加度量(如 Prometheus 计数),方便监控生产 / 丢弃 / 错误率。
安装
dotnet add package Microsoft.Extensions.Logging.RabbitMQ
快速开始
1. 客户端(日志生产者)
using Microsoft.Extensions.Logging;
using RabbitMQ.Client;
builder.Services.AddLogging(option =>
{
option.AddRabbitMQ(configure =>
{
configure.HostName = "localhost";
configure.Port = 5672;
configure.UserName = "guest";
configure.Password = "guest";
configure.RouteKey = "logs"; // 队列或路由键
configure.Application = "Logging.RabbitMQ";// 应用标识
configure.VirtualHost = "/";
configure.AutomaticRecoveryEnabled = true; // 自动重连
});
});
var logger = builder.Services.BuildServiceProvider()
.GetRequiredService<ILoggerFactory>()
.CreateLogger("Demo");
logger.LogInformation("应用启动: {Time}", DateTimeOffset.Now);
logger.LogWarning("示例警告: {Id}", Guid.NewGuid());
日志写入后被序列化并发布到指定队列/交换机,可被服务器端消费。
2. 服务端(日志消费者)
实现处理器:
using Microsoft.Extensions.Logging.RabbitMQ.Handler;
public class MyLogHandler : IRabbitMQMessageHandler
{
public Task HandleAsync(RabbitMQLoggerMessage message, CancellationToken cancellationToken = default)
{
// TODO: 写入数据库 / ES / 文件 / 第三方平台
Console.WriteLine($"[LOG] {message?.Level} {message?.Application} {message?.Message}");
return Task.CompletedTask;
}
}
注册:
builder.Services.AddLogging(option =>
{
option.AddRabbitMQ<MyLogHandler>(configure =>
{
configure.HostName = "localhost";
configure.Port = 5672;
configure.UserName = "guest";
configure.Password = "guest";
configure.RouteKey = "logs";
configure.Application = "Logging.RabbitMQ.Consumer";
configure.VirtualHost = "/";
configure.AutomaticRecoveryEnabled = true;
});
});
服务端与客户端可以共存,也可以分离部署实现集中采集。
3. 复用已有连接工厂
option.AddRabbitMQ(sp => sp.GetRequiredService<IConnectionFactory>(), routeKey: "logs");
适合已有统一 RabbitMQ 连接配置的场景(如多模块共享工厂)。
高级用法
自定义序列化
在实现 IRabbitMQMessageHandler 中对 RabbitMQLoggerMessage 进行二次转换或写入多目标。
多环境隔离
option.AddRabbitMQ(o =>
{
o.HostName = "mq.internal";
o.RouteKey = Environment.GetEnvironmentVariable("APP_ENV") == "Prod" ? "logs.prod" : "logs.dev";
});
从配置文件绑定
{
"Logging": {
"RabbitMQ": {
"HostName": "localhost",
"Port": 5672,
"UserName": "guest",
"Password": "guest",
"RouteKey": "logs",
"Application": "MyApp",
"VirtualHost": "/",
"AutomaticRecoveryEnabled": true
}
}
}
option.AddRabbitMQ(o => builder.Configuration.GetSection("Logging:RabbitMQ").Bind(o));
批处理 / 降级策略
可在自定义处理器中添加本地缓存,当下游不可用时写入备用文件:
public class FailoverLogHandler : IRabbitMQMessageHandler
{
public Task HandleAsync(RabbitMQLoggerMessage msg, CancellationToken ct = default)
{
try
{
// 正常处理
}
catch
{
File.AppendAllText("failover.log", JsonSerializer.Serialize(msg) + "\n");
}
return Task.CompletedTask;
}
}
监控建议
- 处理器中记录发布成功 / 失败计数。
- 使用
ILogger写入内部异常到本地或备用 Provider。 - 对队列的堆积长度进行告警(通过 RabbitMQ 管理 API)。
配置参数说明
| 参数 | 说明 | 示例 | 备注 |
|---|---|---|---|
| HostName | RabbitMQ 主机地址 | localhost | 支持域名 / IP |
| Port | 端口 | 5672 | 与集群配置一致 |
| UserName | 用户名 | guest | 生产禁用默认账户 |
| Password | 密码 | guest | 建议使用密钥管理服务 |
| VirtualHost | 虚拟主机 | / | 可隔离权限与资源 |
| RouteKey | 路由键 / 队列名 | logs | 可按环境区分 (logs.dev) |
| Application | 应用标识 | Logging.RabbitMQ | 便于日志来源筛选 |
| AutomaticRecoveryEnabled | 自动重连 | true | 开启连接/通道恢复 |
性能与可靠性
- 推荐与本地内存日志结合,避免高并发下阻塞。
- 网络异常情况下自动恢复,仍可能短暂丢失;需业务容忍或补偿机制。
- 可通过多个路由或分片队列减少单队列压力。
安全建议
- 禁止在源码中硬编码生产密码;使用 Secret Manager / Key Vault / 环境变量。
- 限制虚拟主机权限,只开放必要的队列访问。
- 使用 TLS (AMQPS) 与防火墙策略保障传输链路安全。
常见问题 (FAQ)
- 日志未写入队列?
- 检查连接参数 / 账号权限 / 队列是否存在。
- 消费处理器未触发?
- 确认服务端是否使用带处理器的重载
AddRabbitMQ<THandler>。
- 确认服务端是否使用带处理器的重载
- 需要自定义序列化格式?
- 在处理器中对
RabbitMQLoggerMessage转换后写入目标存储。
- 在处理器中对
- 是否支持 .NET 8 / .NET 10?
- 项目目标为 .NET 8,可在更高版本运行(向后兼容)。
版本兼容
- 运行时:.NET 8 及更高版本。
- 依赖:
RabbitMQ.Client最新稳定版(参见项目文件)。
许可证
版权所有 © netor.me
本项目遵循 MIT 协议。
联系方式
- 官网: http://netor.me
- 邮箱: support@netor.me
No packages depend on Microsoft.Extensions.Logging.RabbitMQ.
2025年11月22日
- 修复日志消息在高并发情况下可能丢失的问题,提升了日志传输的可靠性。
.NET 8.0
- Microsoft.Extensions.Configuration (>= 9.0.6)
- Microsoft.Extensions.Hosting.Abstractions (>= 9.0.6)
- Microsoft.Extensions.Logging.Abstractions (>= 9.0.6)
- Microsoft.Extensions.Logging.Configuration (>= 9.0.6)
- Netor.Extensions.JsonExtensions (>= 1.0.1)
- Netor.Extensions.StringExtensions (>= 6.1.1)
- RabbitMQ.Client (>= 7.1.0)