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.pswp.cn/pingmian/89813.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/89813.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

分布在内侧内嗅皮层(MEC)的带状细胞对NLP中的深层语义分析有什么积极的影响和启示

带状细胞&#xff08;Band Cells&#xff09;作为内侧内嗅皮层&#xff08;Medial Entorhinal Cortex, MEC&#xff09;层Ⅱ/Ⅲ的核心空间编码单元&#xff08;如网格细胞、头方向细胞等&#xff09;&#xff0c;其独特的神经计算机制为自然语言处理&#xff08;NLP&#xff09…

Django Ninja

Django Ninja 是一个用于 Django 框架的快速、现代化的 API 开发库&#xff0c;旨在简化构建高性能、类型安全的 RESTful API。它受到 FastAPI 的启发&#xff0c;结合了 Django 的强大功能和 FastAPI 的简洁与现代化设计&#xff0c;特别适合需要快速开发、易于维护且具有强类…

iic时序

数据和应答信号都规定在SCL在高电平期间&#xff0c;SDA电平稳定&#xff1b;SCL在低电平期间&#xff0c;SDA电平才可以变化。要不然容易被误认为起始或停止信号。应答信号&#xff1a;1. 第九个SCL之前的低电平期间将SDA拉低2. 确保在SCL为高电平时&#xff0c;SDA为稳定的低…

GitHub+Git新手使用说明

Git Git是一个在本地用于随时保存和查看历史版本的软件Git的三个概念&#xff1a;提交commit、仓库repository、分支branch Git安装 在电脑里面按winR&#xff0c;输入cmd进入终端后输入git --version&#xff0c;然后再次输入where git&#xff0c;查看git所在位置 Git常用语句…

前端图像视频实时检测

需求&#xff1a;在目标检测时&#xff0c;我们要求前端能够将后端检测的结果实时渲染在图片或者视频上。图片是静态的&#xff0c;只需要渲染一次&#xff1b;而视频是动态的&#xff0c;播放时需要根据帧数来实时渲染标注框&#xff0c;可以想象视频就是由一张张图片播放的效…

如何解决pip安装报错ModuleNotFoundError: No module named ‘sqlalchemy’问题

【Python系列Bug修复PyCharm控制台pip install报错】如何解决pip安装报错ModuleNotFoundError: No module named ‘sqlalchemy’问题 摘要 在使用 PyCharm 控制台执行 pip install sqlalchemy 后&#xff0c;仍然在代码中提示 ModuleNotFoundError: No module named sqlalche…

第4.3节 iOS App生成追溯关系

iOS生成追溯关系的逻辑和Android端从用户角度来说是一致的&#xff0c;就是需要通过开始和结束关联用例&#xff0c;将用例信息与覆盖率信息建立关系&#xff0c;然后再解析覆盖率数据。 4.3.1 添加关联用例弹层 关联用例弹层和Android类似&#xff0c;只要你能设计出相应的样…

STM32 USB键盘实现指南

概述 在STM32上实现键盘功能可以通过USB HID(人机接口设备)协议来实现,使STM32设备能被计算机识别为标准键盘。以下是完整的实现方案: 硬件准备 STM32开发板(支持USB,如STM32F103、STM32F4系列) USB接口(Micro USB或Type-C) 按键矩阵或单个按键 必要的电阻和连接…

继电器基础知识

继电器是一种电控制器件,它具有隔离功能的自动开关元件,广泛应用于遥控、遥测、通讯、自动控制、机电一体化及电力电子设备中,是最重要的控制元件之一。 继继电器的核心功能是通过小电流来控制大电流的通断。它通常包含一个线圈和一组或多组触点。当给继电器的线圈施加一定…

MYSQL:库的操作

文章目录MYSQL&#xff1a;库的操作1. 本文简述2. 查看数据库2.1 语法3. 创建数据库3.1 语法3.2 示例3.2.1 创建一个简单的数据库3.2.2 使用 IF NOT EXISTS 防止重复创建3.2.3 再次运行&#xff0c;观察现象3.2.4 查看这个警告到底是什么3.2.5 创建数据库允许使用关键字4. 字符…

Xilinx FPGA XCKU115‑2FLVA1517I AMD KintexUltraScale

XCKU115‑2FLVA1517I 隶属于 Xilinx &#xff08;AMD&#xff09;Kintex UltraScale 系列&#xff0c;基于领先的 20 nm FinFET 制程打造。该器件采用 1517‑ball FCBGA&#xff08;FLVA1517&#xff09;封装&#xff0c;速度等级 ‑2&#xff0c;可实现高达 725 MHz 的核心逻…

Linux Ubuntu安装教程|附安装文件➕安装教程

[软件名称]: Linux Ubuntu18.0 [软件大小]: 1.8GB [安装环境]: VMware [夸克网盘接] 链接&#xff1a;https://pan.quark.cn/s/971f685256ef &#xff08;建议用手机保存到网盘后&#xff0c;再用电脑下载&#xff09;更多免费软件见https://docs.qq.com/sheet/DRkdWVFFCWm9UeG…

深入解析Hadoop YARN:三层调度模型与资源管理机制

Hadoop YARN概述与产生背景从MapReduce到YARN的演进之路在Hadoop早期版本中&#xff0c;MapReduce框架采用JobTracker/TaskTracker架构&#xff0c;这种设计逐渐暴露出严重局限性。JobTracker需要同时处理资源管理和作业控制两大核心功能&#xff0c;随着集群规模扩大&#xff…

Pycaita二次开发基础代码解析:边线提取、路径追踪与曲线固定

本文将深入剖析CATIA二次开发中三个核心类方法&#xff1a;边线提取特征创建、元素结构路径查找和草图曲线固定技术。通过逐行解读代码实现&#xff0c;揭示其在工业设计中的专业应用价值和技术原理。一、边线提取技术&#xff1a;几何特征的精确捕获与复用1.1 方法功能全景ext…

Linux 任务调度在进程管理中的关系和运行机制

&#x1f4d6; 推荐阅读&#xff1a;《Yocto项目实战教程:高效定制嵌入式Linux系统》 &#x1f3a5; 更多学习视频请关注 B 站&#xff1a;嵌入式Jerry Linux 任务调度在进程管理中的关系和运行机制 Linux 内核中的“任务调度”是进程管理系统的核心部分&#xff0c;相互关联而…

JAVA后端开发—— JWT(JSON Web Token)实践

1. 什么是HTTP请求头 (Request Headers)&#xff1f;当你的浏览器或手机App向服务器发起一个HTTP请求时&#xff0c;这个请求并不仅仅包含你要访问的URL&#xff08;比如 /logout&#xff09;和可能的数据&#xff08;请求体&#xff09;&#xff0c;它还附带了一堆“元数据&am…

【SVM smote】MAP - Charting Student Math Misunderstandings

针对数据不平衡问题&#xff0c;用调整类别权重的方式来处理数据不平衡问题&#xff0c;同时使用支持向量机&#xff08;SVM&#xff09;模型进行训练。 我们通过使用 SMOTE&#xff08;Synthetic Minority Over-sampling Technique&#xff09;进行过采样&#xff0c;增加少数…

repmgr+pgbouncer实现对业务透明的高可用切换

本方案说明 PostgreSQL repmgr&#xff1a;实现主从自动故障检测与切换&#xff08;Failover&#xff09;。PgBouncer&#xff1a;作为连接池&#xff0c;屏蔽后端数据库变动&#xff0c;提供透明连接。动态配置更新&#xff1a;通过repmgr组件的promote_command阶段触发脚本…

查找服务器上存在线程泄露的进程

以下是一个改进的命令&#xff0c;可以列出所有线程数大于200的进程及其PID和线程数&#xff1a; find /proc -maxdepth 1 -type d -regex /proc/[0-9] -exec sh -c for pid_dir dopid$(basename "$pid_dir")if [ -f "$pid_dir/status" ]; thenthreads$(aw…

Facebook 开源多季节性时间序列数据预测工具:Prophet 饱和预测 Saturating Forecasts

文中内容仅限技术学习与代码实践参考&#xff0c;市场存在不确定性&#xff0c;技术分析需谨慎验证&#xff0c;不构成任何投资建议。 Prophet 是一种基于加法模型的时间序列数据预测程序&#xff0c;在该模型中&#xff0c;非线性趋势与年、周、日季节性以及节假日效应相匹配。…