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

goner/otel 在Gone框架接入OpenTelemetry

文章目录

    • 背景与意义
    • 快速上手:五步集成 OpenTelemetry
    • 运行效果展示
    • 代码详解与实践
      • 目录结构说明
      • 组件加载(module.load.go)
      • 业务组件示例(your_component.go)
      • 程序入口(main.go)
    • 进阶用法与最佳实践
      • 使用 goner/viper 读取配置
      • 使用OLTP/HTTP将链路追踪数据发送至 Jaeger
        • 启动 Jaeger
        • 上报至 Jaeger
        • 在Jaeger UI 查看链路数据
      • 常见问题解答(FAQ)
        • 1. 为什么集成 goner/otel 后没有看到任何追踪数据输出?
        • 2. Jaeger UI 没有显示任何链路数据怎么办?
        • 3. 如何自定义 Trace 的服务名?
        • 4. 控制台和 Jaeger 都没有数据,如何排查?
        • 5. 如何同时输出到控制台和 Jaeger?
        • 6. Jaeger 采集到的数据不全或丢失?
        • 7. 如何在业务代码中添加自定义事件或属性?
        • 8. goner/otel 支持哪些后端?
      • 参考资料与扩展阅读

背景与意义

OpenTelemetry 是当前云原生领域事实标准的可观测性框架,支持分布式追踪、指标和日志的采集与导出。它帮助开发者在微服务架构下快速定位问题、分析性能瓶颈。

Gone框架 是一个基于Go语言的依赖注入框架,专注于简化服务注册、依赖管理和组件解耦。goner 是Gone生态下的组件库,提供了日志、配置、数据库、缓存等常用能力。

将 OpenTelemetry 与 Gone 框架结合,可以让你的微服务天然具备分布式追踪能力,极大提升系统可观测性和运维效率。

本文将详细介绍如何通过 goner/otel 组件,在 Gone 框架中优雅集成 OpenTelemetry,并给出实用代码示例、常见问题解答及最佳实践。

快速上手:五步集成 OpenTelemetry

在这里插入图片描述

  1. 安装 gonectl 脚手架工具:
go install github.com/gone-io/gonectl@latest
  1. 创建基于 otel/tracer 模板的示例项目:
gonectl create -t otel/tracer/simple tracer-demo
cd tracer-demo
  1. 拉取依赖:
go mod tidy
  1. 运行示例:
go run .
  1. 查看控制台输出的追踪信息。

你也可以在已有 Gone 项目中直接安装 otel 组件:

gonectl install goner/otel/tracer

运行效果展示

执行后你将在控制台看到类似如下的追踪数据(已简化):

{"Name": "handle-request","SpanContext": {"TraceID": "...","SpanID": "..."},"Events": [{ "Name": "开始处理请求" }],"Resource": [{ "Key": "service.name", "Value": { "Value": "simple demo" } },{ "Key": "telemetry.sdk.language", "Value": { "Value": "go" } }]
}

你可以将数据导出到 Jaeger、Zipkin、Prometheus 等后端进行可视化分析。

代码详解与实践

目录结构说明

tracer-demo/
├── go.mod           # Go module 文件
├── go.sum           # 依赖校验
├── main.go          # 程序入口
├── module.load.go   # 组件加载入口(自动生成)
├── README_CN.md     # 中文说明
├── README.md        # 英文说明
└── your_component.go# 业务组件示例

组件加载(module.load.go)

该文件由 gonectl 自动生成,用于注册和加载 goner/otel/tracer 组件:

// Code generated by gonectl. DO NOT EDIT.
package main
import ("github.com/gone-io/gone/v2""github.com/gone-io/goner/g""github.com/gone-io/goner/otel/tracer"
)
var loaders = []gone.LoadFunc{tracer.Register,
}
func GoneModuleLoad(loader gone.Loader) error {var ops []*g.LoadOpfor _, f := range loaders {ops = append(ops, g.F(f))}return g.BuildOnceLoadFunc(ops...)(loader)
}

业务组件示例(your_component.go)

package main
import ("context""github.com/gone-io/gone/v2""go.opentelemetry.io/otel/trace"
)
type YourComponent struct {gone.Flagtracer trace.Tracer `gone:"*,otel-tracer"` // 注入 OpenTelemetry Tracer
}
func (c *YourComponent) HandleRequest(ctx context.Context) {tracer := c.tracerctx, span := tracer.Start(ctx, "handle-request")defer span.End()span.AddEvent("开始处理请求")// ...业务逻辑...
}

程序入口(main.go)

package main
import ("context""github.com/gone-io/gone/v2""os"
)
func main() {_ = os.Setenv("GONE_OTEL_SERVICE_NAME", "simple demo") // 设置服务名称gone.Loads(GoneModuleLoad).Load(&YourComponent{}).Run(func(c *YourComponent) {c.HandleRequest(context.Background())})
}

进阶用法与最佳实践

使用 goner/viper 读取配置

  • 安装 goner/viper 组件:
gonectl install goner/viper
  • 增加配置文件: config/default.yaml
    配置文件内容:
otel:service:name: simple demo
  • 去掉main.go中设置服务名称的代码:
//...
func main() {
//   _ = os.Setenv("GONE_OTEL_SERVICE_NAME", "simple demo") // 设置服务名称
// ...
}

使用OLTP/HTTP将链路追踪数据发送至 Jaeger

如果觉着控制台看的 span 不够直观,可以选择将链路追踪的数据发送至 Jaeger,通过 Jaeger UI 查看。

启动 Jaeger

Jaeger 官方提供的 all-in-one 是为快速本地测试而设计的可执行文件。它包括 Jaeger UI、jaeger-collector、jaeger-query 和 jaeger-agent,以及一个内存存储组件。

启动 all-in-one 的最简单方法是使用发布到 DockerHub 的预置镜像(只需一条命令行)。

docker run --rm --name jaeger \-e COLLECTOR_ZIPKIN_HOST_PORT=:9411 \-p 6831:6831/udp \-p 6832:6832/udp \-p 5778:5778 \-p 16686:16686 \-p 4317:4317 \-p 4318:4318 \-p 14250:14250 \-p 14268:14268 \-p 14269:14269 \-p 9411:9411 \jaegertracing/all-in-one:1.55

然后你可以使用浏览器打开 http://localhost:16686 访问Jaeger UI。

容器公开以下端口:

端口协议组件功能说明
6831UDPagent接收 jaeger.thrift(Thrift-compact,主流 SDK 使用)
6832UDPagent接收 jaeger.thrift(Thrift-binary,Node.js SDK 使用)
5775UDPagent(已废弃)接收 zipkin.thrift(Thrift-compact,旧版客户端)
5778HTTPagent提供配置(采样等)
16686HTTPquery提供前端 UI
4317HTTPcollector接收 OTLP(gRPC 协议)
4318HTTPcollector接收 OTLP(HTTP 协议)
14268HTTPcollector直接接收 jaeger.thrift 客户端数据
14250HTTPcollector接收 model.proto
9411HTTPcollectorZipkin 兼容端点(可选)

我们这里使用 HTTP 协议的4318 端口上报链路追踪数据。

上报至 Jaeger
  1. 安装goner/otel/tracer/http 组件:
gonectl install goner/otel/tracer/http
  1. 在配置文件中添加tracer的配置内容:
otel:service:name: simple demo# 新增以下配置tracer:http:endpoint: localhost:4318insecure: true
  1. 移除goner/otel/tracer组件,执行gonectl install goner/otel/tracer命令,去掉goner/otel/tracer的勾选:
    在这里插入图片描述

  2. 运行demo项目:go run .,这次链路信息没有打印到控制台,而是被发送到了Jaeger,所以看到程序直接退出了。

在Jaeger UI 查看链路数据

打开浏览器,访问 [Jaeger UI 查看链路数据
打开Jaeger UI 查看链路数据
打开浏览器,访问 http://localhost:16686:
在这里插入图片描述

在这里插入图片描述

常见问题解答(FAQ)

1. 为什么集成 goner/otel 后没有看到任何追踪数据输出?
  • 请确认已正确安装并加载 goner/otel/tracer 组件。
  • 检查 main.go 是否设置了服务名称(如通过环境变量 GONE_OTEL_SERVICE_NAME 或配置文件)。
  • 若使用 HTTP 上报至 Jaeger,需确保 Jaeger 服务已启动且 endpoint 配置正确。
2. Jaeger UI 没有显示任何链路数据怎么办?
  • 请确认 Jaeger 容器已启动且端口(如 4318、16686)未被占用。
  • 检查配置文件中的 otel.tracer.http.endpoint 是否为 Jaeger 的 HTTP 采集端口(通常为 localhost:4318)。
  • 若为远程 Jaeger,请确保网络连通。
3. 如何自定义 Trace 的服务名?
  • 推荐通过配置文件 otel.service.name 设置服务名,或设置环境变量 GONE_OTEL_SERVICE_NAME
  • 若两者都未设置,默认服务名可能为 unknown-service
4. 控制台和 Jaeger 都没有数据,如何排查?
  • 检查依赖是否拉取完整(go mod tidy)。
  • 查看是否有 panic 或初始化错误日志。
  • 可尝试将日志级别调高,观察详细输出。
5. 如何同时输出到控制台和 Jaeger?
  • 当前 goner/otel/tracer 支持单一导出目标,建议优先选择 Jaeger 进行链路分析。
  • 如需多目标导出,可参考 OpenTelemetry 官方文档自定义 exporter 和 goner/otel/tracer 文档。
6. Jaeger 采集到的数据不全或丢失?
  • 检查采样配置,默认通常为全采样。
  • 确认 Jaeger 容器资源充足,避免因内存不足丢失数据。
7. 如何在业务代码中添加自定义事件或属性?
  • 使用 span.AddEvent("事件名") 添加事件。
  • 使用 span.SetAttributes() 添加自定义属性。
8. goner/otel 支持哪些后端?
  • 支持控制台、Jaeger、Zipkin、Prometheus 等主流可观测性后端。
  • 具体支持情况请参考 goner/otel 官方文档。

参考资料与扩展阅读

  • OpenTelemetry 官方文档
  • Gone 框架 GitHub
  • goner 组件库
  • gonectl 脚手架
  • Jaeger 可观测性平台

通过上述实践,你可以在 Gone 框架下快速集成 OpenTelemetry,提升微服务的可观测性和诊断能力。如有疑问,欢迎在 GitHub 提 Issue 交流。

相关文章:

goner/otel 在Gone框架接入OpenTelemetry

文章目录 背景与意义快速上手:五步集成 OpenTelemetry运行效果展示代码详解与实践目录结构说明组件加载(module.load.go)业务组件示例(your_component.go)程序入口(main.go) 进阶用法与最佳实践…...

杨校老师项目之基于SSM与JSP的鲜花销售系统-【成品设计含文档】

基于SSMJSP鲜花商城系统 随着电子商务的快速发展,鲜花在线销售已成为一种重要的消费模式。本文设计并实现了一个基于JSP技术的鲜花销售管理系统,采用B/S架构,使用SSM框架进行开发,并结合Maven进行项目依赖管理。系统分为前台用户模…...

springboot集成langchain4j实现票务助手实战

前言 看此篇的前置知识为langchain4j整合springboot,以及springboot集成langchain4j记忆对话。 Function-Calls介绍 langchain4j 中的 Function Calls(函数调用)是一种让大语言模型(LLM)与外部工具(如 A…...

Feed流推送之订阅推送

分类 feed流分为TimeLine和智能排序,前者不对内容进行过滤,一般根据发布的时间来进行排序,一般用于好友动态或者推送关注的人的消息,而后者一般有着复杂的算法,可以根据算法智能地向目标用户推送内容,例如…...

wordpress自学笔记 第四节 商城菜单的添加和修改美化

wordpress自学笔记 摘自 超详细WordPress搭建独立站商城教程-第四节 商城菜单的添加和修改美化,2025 WordPress搭建独立站商城#WordPress建站教程https://www.bilibili.com/video/BV1UwwgeuEkK?spm_id_from333.788.videopod.sections&vd_sourcea0af3bbc6b6d…...

GPU L2 Cache一致性协议对科学计算的影响研究

点击 “AladdinEdu,同学们用得起的【H卡】算力平台”,H卡级别算力,按量计费,灵活弹性,顶级配置,学生专属优惠。 一、GPU缓存层级革命:从Volta到Hopper的演进图谱 1.1 架构级缓存策略对比 ‌Vo…...

C++中类中const知识应用详解

下面将从**const 成员**、const 成员函数、const 对象、mutable、constexpr 等方面,逐一详解 C 类中常见的 const 用法及注意事项,并配合示例。 一、const 数据成员 必须在初始化列表中初始化 class A {const int x; // const 成员 public:A(int v) :…...

【速写】KV-cache与解码的再探讨(以束搜索实现为例)

文章目录 1 Beam Search 解码算法实现2 实现带KV Cache的Beam Search解码3 关于在带kv-cache的情况下的use_cache参数 1 Beam Search 解码算法实现 下面是一个使用PyTorch实现的beam search解码算法: 几个小细节: 束搜索可以加入length_penalty&#…...

(网络)应用层协议-HTTPS

1.HTTPS是什么? HTTPS是应用层的一种协议,是在HTTP的基础上进行了加密层的处理。 HTTP协议的内容都是按照文本的形式进行传输的,所以呢就很容易被别人知道传输的是什么。 我们在了解了TCP/IP之后是知道我们的数据在传输的过程中是通过路由器进…...

vue3: pdf.js 3.4.120 using javascript

npm install pdfjs-dist3.4.120 项目结构&#xff1a; pdfjsViewer.vue <template><div><div v-if"loading" class"flex justify-center items-center py-8"><div class"animate-spin rounded-full h-12 w-12 border-b-2 borde…...

Spark目前支持的部署模式。

一、本地模式&#xff08;Local Mode&#xff09; 特点&#xff1a; 在单台机器上运行&#xff0c;无需集群。主要用于开发、测试和调试。所有组件&#xff08;Driver、Executor&#xff09;在同一个 JVM 中运行。 启动命令&#xff1a; bash spark-submit --master local[*]…...

想实现一个基于MCP的pptx生成系统架构图【初版实现】

技术栈:Python + MCP协议 + python-pptx + FastMCP 核心创新点:通过MCP协议实现PPTX元素的动态化生成与标准化模板管理 当前还是个半成品,后续持续更新。 主要先介绍一下思路。 一、MCP协议与系统设计原理 1.1 为什么选择MCP? 标准化工具调用:通过MCP将PPTX元素生成逻辑封…...

PyTorch Lightning实战 - 训练 MNIST 数据集

MNIST with PyTorch Lightning 利用 PyTorch Lightning 训练 MNIST 数据。验证梯度范数、学习率、优化器对训练的影响。 pip show lightning Version: 2.5.1.post0Fast dev run DATASET_DIR"/repos/datasets" python mnist_pl.py --output_grad_norm --fast_dev_run…...

力扣2094题解

记录&#xff1a; 2025.5.12 题目&#xff1a; 思路&#xff1a; 暴力遍历。 解题步骤&#xff1a; 1.统计数字出现次数&#xff1a;使用数组cnt来记录输入数组中每个数字的出现次数。 2.生成三位偶数&#xff1a;通过循环从100开始&#xff0c;每次递增2&#xff0c;生成…...

DHCP自动分配IP

DHCP自动分配IP 练习1 路由器 Router>en Router#conf t Router(config)#ip dhcp pool ip10 //创建DHCP地址池 Router(dhcp-config)#network 192.168.20.0 255.255.255.0 // 配置网络地址和子网掩码 Router(dhcp-config)#default-router 192.168.20.254 //配置默认网关 Rou…...

【CF】Day57——Codeforces Round 955 (Div. 2, with prizes from NEAR!) BCD

B. Collatz Conjecture 题目&#xff1a; 思路&#xff1a; 简单模拟 很简单的模拟&#xff0c;我们只需要快速的找到下一个离 x 最近的 y 的倍数即可&#xff08;要大于 x&#xff09; 这里我们可以这样写 add y - (x % y)&#xff0c;这样就知道如果 x 要变成 y 的倍数还要…...

(done) 补充:xv6 的一个用户程序 init 是怎么启动的 ?它如何启动第一个 bash ?

先看 main.c 从函数名来看&#xff0c;比较相关的就 userinit() 和 scheduler() #include "types.h" #include "param.h" #include "memlayout.h" #include "riscv.h" #include "defs.h"volatile static int started 0;//…...

Nginx部署前端项目深度解析

在部署Vue前端项目时&#xff0c;Nginx的高效配置直接影响用户体验和性能表现。以下从7个关键维度深度解析部署方案&#xff0c;并提供专业级配置策略&#xff1a; 一、项目构建与基础部署 生产构建 npm run build -- --modern # 现代模式构建生成dist/目录包含&#xff1a;…...

超详细讲解C语言转义字符\a \b \r \t \? \n等等

转义字符 C语言有一组字符很特殊&#xff0c;叫做转义字符&#xff0c;顾名思义&#xff0c;改变原来的意思的字符。 1 \? ??)是一个三字母词&#xff0c;在以前的编译器它会被编译为] (??会被编译为[ 因此在以前输入(are you ok ??)就会被编译为are you ok ] 解决这个…...

SpringBoot校园失物招领信息平台

SpringBoot校园失物招领信息平台 文章目录 SpringBoot校园失物招领信息平台1、技术栈2、项目说明2.1、登录注册2.2、管理员端截图2.3、用户端截图 3、核心代码实现3.1、前端首页3.2、前端招领广场3.3、后端业务处理 1、技术栈 本项目采用前后端分离的架构&#xff0c;前端和后…...

【Qt/C++】深入理解 Lambda 表达式与 `mutable` 关键字的使用

【Qt/C】深入理解 Lambda 表达式与 mutable 关键字的使用 在 Qt 开发中&#xff0c;我们常常会用到 lambda 表达式来编写简洁的槽函数。今天通过一个实际代码示例&#xff0c;详细讲解 lambda 的语法、变量捕获方式&#xff0c;特别是 mutable 的作用。 示例代码 QPushButto…...

扩展:React 项目执行 yarn eject 后的 package.json 变化详解及参数解析

扩展&#xff1a;React 项目执行 yarn eject 后的 package.json 变化详解及参数解析 什么是 yarn eject&#xff1f;React 项目执行 yarn eject 后的 package.json 变化详解1. 脚本部分 Scripts 被替换2. 新增构建依赖 dependencies&#xff08;部分&#xff09;3. 新增 Babel …...

slackel系统详解

Slackel 是一个基于 Slackware Linux 和 Salix OS&#xff08;另一个 Slackware 衍生版&#xff09;的轻量级 Linux 发行版&#xff0c;主要面向桌面用户。它由希腊开发者 Dimitris Tzemos 创建&#xff0c;目标是结合 Slackware 的稳定性与用户友好的工具&#xff0c;同时优化…...

rust 全栈应用框架dioxus server

接上一篇文章dioxus全栈应用框架的基本使用&#xff0c;支持web、desktop、mobile等平台。 可以先查看上一篇文章rust 全栈应用框架dioxus&#x1f448; 既然是全栈框架&#xff0c;那肯定是得有后端服务的&#xff0c;之前创建的服务没有包含后端服务包&#xff0c;我们修改…...

CSS Layer 详解

CSS Layer 详解 前言 最近在整理CSS知识体系时&#xff0c;发现Layer这个特性特别有意思。它就像是给样式规则提供了一个专属的「VIP通道」&#xff0c;让我们能更优雅地解决样式冲突问题。今天我就用最通俗的语言&#xff0c;带大家全面了解这个CSS新特性。 什么是CSS Laye…...

西安交大多校联训NOIP1模拟赛题解

西安交大多校联训NOIP1模拟赛题解 T1 秘境形式化题意思路代码&#xff08;丑陋&#xff09; T2 礼物形式化题意思路代码&#xff08;实现&#xff09; T3 小盒子的数论形式化题意思路代码&#xff08;分讨&#xff09; T4 猫猫贴贴(CF997E)形式化题意思路代码&#xff08;深奥&…...

数据结构(三)——栈和队列

一、栈和队列的定义和特点 栈&#xff1a;受约束的线性表&#xff0c;只允许栈顶元素入栈和出栈 对栈来说&#xff0c;表尾端称为栈顶&#xff0c;表头端称为栈底&#xff0c;不含元素的空表称为空栈 先进后出&#xff0c;后进先出 队列&#xff1a;受约束的线性表&#xff0…...

若依定制pdf生成实战

一、介绍 使用 Java Apache POI 将文字渲染到 Word 模板是一种常见的文档自动化技术&#xff0c;广泛应用于批量生成或定制 Word 文档的场景。使用aspose可以将word转成pdf从而达到定制化pdf的目的。 参考文档&#xff1a;java实现Word转Pdf&#xff08;Windows、Linux通用&a…...

RCE联系

过滤 绕过空格 ● 进制绕过 题目练习 数字rce 使用$0执行bash&#xff0c;<<<将后面的字符串传递给左边的命令。 例如&#xff1a; <?php highlight_file(__FILE__); function waf($cmd) { $whiteList [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, \\, \, $, <]; $cmd_ch…...

c++STL-vector的模拟实现

cSTL-vector的模拟实现 vector的模拟实现基本信息构造函数析构函数返回容量&#xff08;capacity&#xff09;返回元素个数&#xff08;size&#xff09;扩容&#xff08;reserve和resize&#xff09;访问&#xff08;[]&#xff09;迭代器&#xff08;**iterator**&#xff09…...