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)

  1. 日志未写入队列?
    • 检查连接参数 / 账号权限 / 队列是否存在。
  2. 消费处理器未触发?
    • 确认服务端是否使用带处理器的重载 AddRabbitMQ<THandler>
  3. 需要自定义序列化格式?
    • 在处理器中对 RabbitMQLoggerMessage 转换后写入目标存储。
  4. 是否支持 .NET 8 / .NET 10?
    • 项目目标为 .NET 8,可在更高版本运行(向后兼容)。

版本兼容

  • 运行时:.NET 8 及更高版本。
  • 依赖:RabbitMQ.Client 最新稳定版(参见项目文件)。

许可证

版权所有 © netor.me
本项目遵循 MIT 协议。


联系方式

No packages depend on Microsoft.Extensions.Logging.RabbitMQ.

2025年11月22日 - 修复日志消息在高并发情况下可能丢失的问题,提升了日志传输的可靠性。

Version Downloads Last updated
1.2.1 16 11/22/2025
1.2.0 2 11/22/2025
1.1.9 2 11/22/2025
1.1.8 23 09/03/2025
1.1.7 9 09/02/2025
1.1.6 7 09/02/2025
1.1.5 9 08/29/2025
1.1.4 22 08/18/2025
1.1.3 7 08/18/2025
1.1.2 12 08/18/2025
1.1.1 9 08/18/2025
1.1.0 8 08/18/2025
1.0.9 6 08/18/2025