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

从“黑盒”到“全景”:在.NET中拥抱OpenTelemetry与SigNoz的可观测工具

项目简介:本仓库是一个实战指南与示例集合,展示了如何在不同版本的 ABP 框架(从传统的 .NET Framework 4.6.2 到现代的 Volo.Abp)中集成 OpenTelemetry (OTel),并将可观测性数据(Tracing, Logs, Metrics)统一输出到开源观测平台 SigNoz

🚀 为什么需要可观测性?

作为开发者,你是否曾为这些问题困扰过?

  • 问题排查像“开盲盒”:用户报告接口慢,你只能埋头翻看分散的日志文件,试图从碎片信息中拼凑出一次请求的完整路径。
  • 监控数据“烟囱林立”:Metrics、Tracing、Logs 分散在不同的系统里,查看一个完整的问题上下文需要在多个标签页间反复横跳。
  • 技术栈绑定之痛:一旦选用了某个APM厂商的SDK,迁移成本高到让人望而却步。

如果你对以上任何一点深感共鸣,那么是时候了解 OpenTelemetry(简称OTel)​ 和 SigNoz​ 这个组合了。它们一个定义了开放标准,一个提供了开箱即用的实现。

OpenTelemetry:可观测性

想象一下,你的应用是一个由微服务、数据库、消息队列组成的复杂城市。过去,每个组件(或APM厂商)都说着自己的“方言”(私有协议),导致沟通成本极高。
OpenTelemetry (OTel) 就是为解决这个问题而生的。​ 它由CNCF孵化,目标是为可观测性数据(追踪、指标、日志)提供一套与供应商无关的、统一的采集和传输标准。你可以把它理解为可观测性领域的“普通话”或“USB-C接口”。
它的核心优势在于:

  • 供应商中立: 用一套SDK和API完成数据采集,通过简单的配置即可将数据发送到任何支持OTLP协议的后端(如kibana、Jaeger、zipkin、Tempo、SigNoz)。
  • 一次集成,多处可用: 避免了对特定APM厂商的锁定,未来切换后端成本极低。

演示架构

SigNoz:开箱即用的全景观测平台

Signoz 是一个基于 OpenTelemetry、ClickHouse、Go、TypeScript/React 等技术栈构建的开源可观测性平台,用于统一采集、分析和可视化日志、指标和链路追踪数据。
技术架构

SigNoz - 日志性能基准测试(与ElasticSearch、Loki比较)
ClickHouse vs. Elasticsearch:十亿行数据的较量

🛠️ 环境搭建:安装signoz

使用 Docker Compose 快速安装:
https://signoz.io/docs/install/docker/

git clone -b main https://github.com/SigNoz/signoz.git && cd signoz/deploy/
cd docker
docker compose up -d --remove-orphans


安装完成后,访问 http://127.0.0.1:8080 即可看到 SigNoz 的仪表盘。

📂 示例项目导航

本仓库包含针对不同 ABP 版本的集成方案,请根据你的项目背景选择:

项目名称 框架版本 说明 快速跳转
AbpFramework .NET Framework 4.6.2 适用于传统的 ABP (Legacy) 项目,集成 log4net 日志导出。 查看详情
AbpCore .NET Core 3.1+ 适用于标准的 ABP 框架(基于 .NET Core 版本)。 查看详情
VoloAbp .NET 6/8+ 适用于最新的 Volo.Abp (vNext) 框架集成。 查看详情

🏁 使用效果

集成通过AOP(面向切面编程)拦截器实现了应用内方法的自动追踪,并在以下监控维度中清晰地展现了效果:

Services(服务监控)


Logs(日志)


Traces(链路追踪)


被追踪的业务方法示例

以下是一个简单的服务类方法,其调用链将被追踪。方法内记录了日志,便于在Traces和Logs中关联观察。

public virtual void Test()
{Logger.LogInformation($"{nameof(BookAppService)}.{nameof(Test)}");TestPublic();TestPublicVirtual();TestPrivate();
}
public virtual void TestPublic()
{Logger.LogInformation($"{nameof(BookAppService)}.{nameof(TestPublic)}");
}
public virtual void TestPublicVirtual()
{Logger.LogInformation($"{nameof(BookAppService)}.{nameof(TestPublicVirtual)}");
}
private void TestPrivate()
{Logger.LogInformation($"{nameof(BookAppService)}.{nameof(TestPrivate)}");
}

通过AOP拦截器实现方法级追踪

VoloAbp中通过定义的OTelActivityInterceptor,它继承自Volo.Abp框架的AbpInterceptor。该拦截器负责在目标方法执行前后自动创建和停止OpenTelemetry的Activity,从而实现无侵入式的耗时追踪。AbpFramework OTelActivityInterceptor 与AbpCore OTelActivityInterceptor基本类似

public class OTelActivityInterceptor : AbpInterceptor, ITransientDependency
{private readonly ActivitySource _activitySource;//private readonly IJsonSerializer _jsonSerializer;private readonly ILogger<OTelActivityInterceptor> _logger;private readonly IConfiguration _configuration;private readonly OTelOptions _oTelOptions;public OTelActivityInterceptor(ActivitySource activitySource,//IJsonSerializer jsonSerializer, ILogger<OTelActivityInterceptor> logger,IConfiguration configuration,IOptionsSnapshot<OTelOptions> oTelOptions){_activitySource = activitySource;//_jsonSerializer = jsonSerializer;_logger = logger;_configuration = configuration;_oTelOptions = oTelOptions.Value;}public override async Task InterceptAsync(IAbpMethodInvocation invocation){_logger.LogDebug($"方法调用前:{invocation.Method.DeclaringType?.Name}.{invocation.Method.Name}");if (!_oTelOptions.Enabled){await invocation.ProceedAsync();return;}if (!OTelActivityHelper.IsOTelActivityMethod(invocation.Method, out var oTelActivityAttribute)){await invocation.ProceedAsync();return;}// https://opentelemetry.io/docs/languages/dotnet/traces/best-practices/Activity activity = null;try{activity = _activitySource.StartActivity(invocation.Method.DeclaringType?.Name + "." + invocation.Method.Name);//if (activity != null && activity.IsAllDataRequested == true)//{//    activity.SetTag("", "");//}}finally{await invocation.ProceedAsync();activity?.Stop();activity?.Dispose();}_logger.LogDebug($"方法调用后:{invocation.Method.DeclaringType?.Name}.{invocation.Method.Name}");}
}

📚 参考资料

  • OpenTelemetry 官方文档
  • SigNoz 官方文档
  • OpenTelemetry Logs using log4net
http://www.jsqmd.com/news/433139/

相关文章:

  • TS+VUE3
  • 深入解析Qt事件处理机制:从原理到实战,构建响应式GUI应用
  • LeetCode 378 有序矩阵中第 K 小的元素:python3 题解
  • LeetCode 88 合并两个有序数组:python3 题解
  • Python核心语法-文件操作、os模块和常用标注库 - 努力-
  • 零基础联通云部署实战:三维编辑器上云全记录
  • Last Meeting Theory(最后相遇理论)and Soulmate(灵魂伴侣)
  • 基于ssm的学生健康管理系统w4apa20f(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
  • 拆解百度智能运营平台:AI应用架构师能借鉴的4个架构设计理念
  • 从大模型推理边界看职业壁垒:为什么说接入云端大模型API只是人机协作的第一步?
  • YOLO11 改进 - SPPF模块 替代SPPF, Mona多认知视觉适配器(CVPR 2025):打破全参数微调的性能枷锁:即插即用的提点神器
  • 基于ssm家电售后服务管理系统d9x66u24(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
  • 解析大数据领域数据增强的应用场景
  • S001 【模板】从前缀函数到KMP应用 字符串匹配 字符串周期
  • YOLO11 改进 - Mamba _ 集成Mamba-YOLO(AAAI 2025),Mamba-YOLO11-L 替换骨干,破解全局依赖建模难题,实现高效实时检测
  • YOLO11 改进 - Mamba _ 集成Mamba-YOLO(AAAI 2025),Mamba-YOLO11-T 替换骨干,破解全局依赖建模难题,实现高效实时检测
  • 私有部署、安全可控:BeeWorks一体化视频会议解决方案赋能政企高效协同
  • YOLO11 改进 - Mamba _ 集成Mamba-YOLO(AAAI 2025),Mamba-YOLO11-B 替换骨干,破解全局依赖建模难题,实现高效实时检测
  • AWS中东数据中心遭不明物体撞击引发大规模服务中断
  • python核心语法-运算符-类型转换 - 努力-
  • 提示工程远程团队敏捷协作:5个工具让沟通更高效!
  • 问题解决:Oracle VirtualBox创建的虚拟主机不能ping通windows host主机虚拟网卡的ip
  • Qt 捕获应用程序未知异常的方法
  • 异常和自定义错误码使用时机
  • 解读大数据领域结构化数据的性能优化策略
  • YOLO11 改进 - C2PSA _ C2PSA融合Mask Attention掩码注意力,可学习掩码矩阵破解低分辨率特征提取难题 _ 2025 预印
  • 计算资源与AI模型性能提升的关系探讨
  • AI检测会对论文进行误判吗?
  • cf div2 1078 F1
  • 2026城固装修公司排名TOP5权威测评|城固哪家装修公司靠谱?性价比高口碑好首选金匠装饰 - 一个呆呆