当前位置: 首页 > news >正文

ABP VNext + Grafana Loki:集中式日志聚合

📝 ABP VNext + Grafana Loki:集中式日志聚合


📚 目录

  • 📝 ABP VNext + Grafana Loki:集中式日志聚合
    • 一、引言
      • ✨ TL;DR
    • 二、环境与依赖
      • 🛠️ 平台版本
      • 🔗 NuGet 包
      • ⚙️ 基础服务
    • 三、Serilog + Loki 集成
      • 3.1 安装与配置
      • 3.2 添加标签
    • 四、Loki 数据源与推送格式
      • 错误处理与重试机制
    • 五、Grafana 配置
      • 5.1 新建 Loki Data Source
      • 5.2 日志面板(Explore)
    • 六、仪表盘与告警
      • 6.1 自定义仪表盘
      • 6.2 告警规则
      • 告警通知配置
    • 七、多服务与多环境
      • 📦 统一标签策略
      • 🔄 Grafana Dashboard 复用
      • Grafana Provisioning
    • 八、性能与可靠性最佳实践
      • ⚙️ 批量/缓冲
      • 💾 Durable Sink 保障可靠性
      • 📊 Loki 索引策略
      • ⚡ Loki 高可用部署
    • 九、端到端示例
    • 日志流转流程


一、引言

✨ TL;DR

  • Serilog 将 ABP 应用日志推送到 Grafana Loki,实现结构化、标签化存储,便于查询和追踪。
  • Grafana 中配置日志面板、查询模板与告警规则,支持多服务多环境的统一日志聚合。
  • 实现高可用、可扩展的日志管理体系,轻松定位问题并提高运维效率。

📚 背景与动机
在 ABP 微服务架构下,日志分散在多个服务实例中,排查问题时需要登录多个实例查看日志,运维成本高且不便实时监控。Grafana Loki 通过仅索引日志的标签,结合 Grafana 原生支持,能够实现零运维的集中式日志解决方案,极大提升查询性能与可用性。本教程展示了如何在 ABP VNext 应用中,结合 Serilog 和 Grafana Loki 构建高效、可复现的日志管理系统。


二、环境与依赖

🛠️ 平台版本

  • .NET 6 + ABP VNext 6.x
  • Grafana ≥ 9.xLoki ≥ 2.x

🔗 NuGet 包

  • Serilog.AspNetCore
  • Serilog.Sinks.Grafana.Loki(支持 /loki/api/v1/push 接口)
  • Serilog.Formatting.Compact(结构化 JSON 格式)

⚙️ 基础服务

  • Loki ▶ HTTP 接收器(<loki_host>:3100
  • Grafana ▶ 配置 Data Source 指向 Loki

三、Serilog + Loki 集成

3.1 安装与配置

首先在项目中安装必需的 NuGet 包:

dotnet add package Serilog.AspNetCore
dotnet add package Serilog.Sinks.Grafana.Loki
dotnet add package Serilog.Formatting.Compact

Program.cs 中进行 Serilog 配置:

using Serilog;
using Serilog.Formatting.Compact;Log.Logger = new LoggerConfiguration().Enrich.FromLogContext().Enrich.WithProperty("Application", "OrderService").Enrich.WithProperty("Environment", builder.Environment.EnvironmentName).Enrich.WithProperty("TraceId", Activity.Current?.TraceId.ToString() ?? "unknown").Enrich.WithProperty("TenantId", "Tenant123").WriteTo.Console(new RenderedCompactJsonFormatter()).WriteTo.GrafanaLoki("http://loki:3100", labels: new Dictionary<string, string>{{ "Application", "OrderService" },{ "Environment", builder.Environment.EnvironmentName }}).CreateLogger();builder.Host.UseSerilog();

3.2 添加标签

为了进一步增强日志的可查询性,可以在日志中加入更多的标签,如 TraceIdTenantId,使得日志查询更加精确。

Log.Logger = new LoggerConfiguration().Enrich.FromLogContext().Enrich.WithProperty("Application", "OrderService").Enrich.WithProperty("Environment", builder.Environment.EnvironmentName).Enrich.WithProperty("TraceId", Activity.Current?.TraceId.ToString() ?? "unknown").Enrich.WithProperty("TenantId", "Tenant123").WriteTo.Console(new RenderedCompactJsonFormatter()).WriteTo.GrafanaLoki("http://loki:3100", labels: new Dictionary<string, string>{{ "Application", "OrderService" },{ "Environment", builder.Environment.EnvironmentName }}).CreateLogger();

四、Loki 数据源与推送格式

Loki Push API 的日志数据格式要求如下:

{"streams": [{"stream": { "label1": "value1", "label2": "value2" },"values": [[ "1621373445000000000", "log line 1" ],[ "1621373446000000000", "log line 2" ]]}]
}

Serilog.Sinks.Grafana.Loki 会自动批量打包日志,并推送到 Loki。每条日志会自动包装成这种 JSON 格式,因此你不需要自己处理日志格式。

错误处理与重试机制

为了确保日志的可靠性,当 Loki 推送失败时,我们可以使用 Serilog Sink 的失败重试机制,或者将失败日志临时保存在本地文件中进行重试。以下是配置重试机制的示例:

.WriteTo.GrafanaLoki("http://loki:3100", labels: new Dictionary<string, string> {{"Application", "OrderService"}})
.WithAutomaticRetries(maxRetries: 5, delayBetweenRetries: TimeSpan.FromSeconds(5))

五、Grafana 配置

5.1 新建 Loki Data Source

在 Grafana 中创建 Loki 数据源:

  1. 在 Grafana 控制台选择 Data Sources,点击 Add Data Source
  2. 选择 Loki,输入 Loki 的地址 http://<loki_host>:3100,然后点击 Save & Test 验证连接是否成功。

5.2 日志面板(Explore)

示例查询

{Application="OrderService", Environment="Production"}|= "Error"|= "Exception"

使用模板变量 $app$env 来动态切换服务和环境:

{Application="$app", Environment="$env"} |= "Error"

六、仪表盘与告警

6.1 自定义仪表盘

每分钟日志量

count_over_time({Application="$app"}[1m])

错误级别趋势

rate({level="Error",Application="$app"}[5m])

请求延迟分布(假设记录了 Duration 字段):

histogram_quantile(0.95, sum(rate({Application="$app"} |= "Duration" [$__interval])) by (le))

推荐的布局包括概览、异常详情、容量监控。

6.2 告警规则

示例告警规则

  • Rule 1:5 分钟内 Error 日志 ≥ 50 ▶ 发送通知。
  • Rule 2:日志包含关键异常关键字(如 NullReferenceException)▶ 立即告警。

通知渠道:Email、Slack、Teams。

告警通知配置

Grafana 支持将告警通知集成到 Slack、Teams、Email 等渠道。在 Grafana 的 Alerting 设置中,可以创建通知渠道,并将其配置到特定告警规则中。


七、多服务与多环境

📦 统一标签策略

为了在不同环境和服务之间聚合日志,推荐使用统一的标签策略:ApplicationEnvironmentTenant 等。这样可以帮助开发者在查询日志时使用一致的命名方式。

🔄 Grafana Dashboard 复用

通过模板变量,如 $app$env,实现多实例监控,避免重复配置。你可以在一个 Grafana 仪表盘中查看多个服务和环境的数据,只需动态切换模板变量即可。

Grafana Provisioning

为了自动化管理多个 Grafana 实例的配置,可以使用 Provisioning 功能,将仪表盘和数据源配置文件化,从而实现批量部署和配置同步。


八、性能与可靠性最佳实践

⚙️ 批量/缓冲

调整 batchPostingLimitperiod 配置,以优化推送频率和批量大小。不同的日志 Sink 可能有不同的配置选项,请参考官方文档调整。

💾 Durable Sink 保障可靠性

为了确保日志的可靠性,建议配置带本地文件缓冲的 Durable Sink,例如:

.WriteTo.DurableHttpUsingFileSizeRolledBuffers("http://loki:3100", fileSizeLimitBytes: 50_000_000)

📊 Loki 索引策略

  • 避免标签的高基数(Cardinality),如每个日志条目的 UserIdSessionId
  • 只使用必要的标签,避免过多的字段导致存储和查询性能下降。

⚡ Loki 高可用部署

对于生产环境,建议将 Loki 部署为分布式系统,使用 DistributorIngesterQuerier 等组件来提升可用性和水平扩展能力。可以使用 Docker Compose 或 Kubernetes 配置 Loki 集群。


九、端到端示例

  1. 启动 Loki & Grafana Docker 容器
    使用以下 docker-compose.yml 启动 Loki 和 Grafana:

    version: '3.7'
    services:loki:image: grafana/loki:2.8.2command: -config.file=/etc/loki/local-config.yamlports:- "3100:3100"grafana:image: grafana/grafana:9.5.0ports:- "3000:3000"
    
  2. 配置 ABP 项目 Serilog
    在 ABP 项目的 Program.cs 中按照 3.1 配置 Serilog。

  3. 生成多级别日志
    在代码中添加不同级别的日志:Log.Information(), Log.Warning(), Log.Error()

  4. 在 Grafana Explore 中执行查询
    使用示例查询来可视化日志。

  5. 创建告警规则
    设置一个告警规则,并模拟触发 Error 日志来测试告警。


日志流转流程

ABP 应用
Serilog
Loki Push API
Distributor
Ingester
Querier
Loki
Grafana
日志查询与可视化
告警通知

http://www.dtcms.com/a/289335.html

相关文章:

  • 服装工厂生产管理软件最新核心排名是什么?
  • [simdjson] document_stream | iterate_many() | batch_size | 线程加速 | 轻量handle
  • Pycharm的Terminal打开后默认是python环境
  • 网工实验——路由器小项目
  • 每日面试题10:令牌桶
  • tidyverse-数据可视化 - 图形的分层语法
  • 论文分享(一)
  • C++ primer知识点总结
  • LVS-----TUN模式配置
  • Docker-compose-知识总结
  • 基于单片机倾角测量仪/角度测量/水平仪
  • 双8无碳小车“cad【17张】三维图+设计说名书
  • 【HarmonyOS】ArkUI - 自定义组件和结构重用
  • 【pandoc实践】如何将wordpress文章批量导出为Markdown格式
  • 神经网络:卷积层
  • 使用UV管理PyTorch项目
  • PyTorch常用的简单数学运算
  • Paimon INSERT OVERWRITE
  • 一维数组练题习~
  • PyTorch的基础概念和复杂模型的基本使用
  • 【软件测试】从软件测试到Bug评审:生命周期与管理技巧
  • ESXi6.7硬件传感器红色警示信息
  • ICT模拟零件测试方法--测量参数详解
  • ThinkPHP8极简上手指南:开启高效开发之旅
  • 基于机器视觉的迈克耳孙干涉环自动计数系统设计与实现
  • STM32CubeMX的一些操作步骤的作用
  • 拼写纠错模型Noisy Channel(下)
  • 机器学习理论基础 - 核心概念篇
  • 复杂度优先:基于推理链复杂性的提示工程新范式
  • Linux操作系统之线程(四):线程控制