在不改动业务代码、不手动初始化 OpenTelemetry SDK 的情况下,为 Go 应用自动生成链路数据,并通过 OTLP 上报到观测平台。
为什么需要编译时插桩
为 Go 应用接入链路追踪,传统方式通常需要引入 OpenTelemetry SDK、创建 Provider、配置 Exporter,再为 HTTP、gRPC 或数据库客户端逐一添加 instrumentation。对于新项目,这套方式足够清晰;但在存量服务较多、技术栈复杂的环境中,接入和维护成本会逐渐显现。
一方面,可观测性代码会进入业务仓库,应用团队需要理解并维护 SDK 生命周期;另一方面,不同项目的接入方式、依赖版本和配置习惯也可能不一致。随着服务数量增加,这些差异会成为升级和治理的负担。
编译时插桩提供了另一种思路:把监控能力放到构建阶段统一处理,让业务代码继续关注业务本身。
OpenTelemetry Go Compile-Time Instrumentation 提供的 otelc 工具,能够在 Go 编译过程中识别目标组件并注入 Hook。应用仍然按照普通 Go 项目开发,但最终生成的二进制已经具备遥测能力。
Go 编译时插桩如何工作
otelc 与 Go 工具链配合,在源码进入编译器之前完成分析和修改:
-
分析应用及其依赖,识别
net/http、gRPC、数据库等支持的组件。 -
根据内置规则定位需要监控的函数和方法。
-
在目标函数入口和出口注入 OpenTelemetry Hook。
-
使用修改后的代码继续编译,生成带有自动插桩能力的二进制文件。
-
应用运行后,通过 OTLP 将遥测数据上报到 Collector 或 DataKit。
整个过程不会直接修改业务源码。插桩期间生成的构建计划、匹配规则和调试信息会保存在 .otelc-build 目录中。
Plain
Go 业务代码
|
| go tool otelc go build
v
插桩后的应用二进制
|
| OTLP/gRPC
v
DataKit / OpenTelemetry Collector
这种方式带来的价值主要体现在几个方面:

需要说明的是,"零代码接入"并不等于"零运行时开销"。最终二进制仍会包含 otelc 注入的 OpenTelemetry 运行时代码,只是应用开发者不需要在业务仓库中手动维护这些代码。
观测云
观测云是一站式一体化可观测性平台,可对接 OpenTelemetry 开源标准构建完整可观测体系。OpenTelemetry 提供多语言应用埋点能力,覆盖 Java、Go、Python、PHP、Node.js 等开发语言,统一采集调用链追踪、指标、日志、性能剖析等可观测数据,并通过 OTLP(gRPC/HTTP)协议对外发送。观测云通过 DataKit 组件接收 OpenTelemetry 上报的数据,DataKit 负责数据处理转换、补充环境标签,经由 HTTPS 安全传输将数据投递至观测云平台。平台对各类数据统一存储、解析与可视化,提供链路追踪、指标监控、日志分析、性能剖析等能力。两者分工清晰:观测云承担数据接收、存储与可视化分析的平台能力;OpenTelemetry 负责应用侧标准化埋点采集,不绑定后端,帮助企业低成本搭建云原生可观测方案。

实践
下面使用一个最小的 net/http 服务验证完整链路。示例采用 otelc v1.1.0,并将 Trace 通过 OTLP/gRPC 上报到本机 4317 端口。
开始前需要确认:
-
Go 版本不低于 1.25。
-
项目使用 Go Module 管理依赖。
-
本机
4317端口已经运行 DataKit 或 OpenTelemetry Collector。
创建 Demo
先创建项目并初始化 Go Module:
Bash
mkdir http-otelc-demo
cd http-otelc-demo
go mod init example.com/http-otelc-demo
创建 main.go:
Go
package main
import (
"log"
"net/http"
)
func main() {
http.HandleFunc("/ping", func(w http.ResponseWriter, _ *http.Request) {
_, _ = w.Write([]byte("pong\n"))
})
log.Println("HTTP server listening on :18080")
log.Fatal(http.ListenAndServe(":18080", nil))
}
这是一个完全普通的 Go HTTP 服务。代码中没有 OpenTelemetry SDK 初始化,也没有使用额外的 HTTP middleware。
引入 otelc
在项目目录中添加并固定 otelc v1.1.0:
Bash
go get -tool go.opentelemetry.io/otelc/tool/cmd/otelc@v1.1.0
go mod tidy
确认工具版本:
Bash
go tool otelc version
预期输出:
Plain
otelc version v1.1.0
工具依赖会记录在 go.mod 和 go.sum 中,不需要克隆源码,也不需要单独维护一个本地 otelc 二进制。这种方式也便于团队在不同环境中使用相同版本。
编译并启动应用
先配置服务名、OTLP 地址和需要启用的插桩:
Bash
export OTEL_SERVICE_NAME=http-otelc-demo
export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317
export OTEL_EXPORTER_OTLP_PROTOCOL=grpc
export OTEL_GO_ENABLED_INSTRUMENTATIONS=nethttp
执行插桩编译:
Bash
go tool otelc go build -o http-otelc-demo .
第一次构建需要下载并编译 OpenTelemetry 相关依赖,耗时会比普通 go build 更长。看到终端重新出现命令提示符,才表示编译已经完成。
编译完成后,在终端一启动应用:
Bash
./http-otelc-demo
终端一需要保持运行。当日志中出现以下内容时,应用已经开始监听 18080:
Plain
{"time":"2026-08-25T16:32:21.467216684+08:00","level":"INFO","msg":"trace provider initialized with auto-export"}
{"time":"2026-08-25T16:32:21.467975954+08:00","level":"INFO","msg":"meter provider initialized with auto-export"}
{"time":"2026-08-25T16:32:21.468916866+08:00","level":"INFO","msg":"logger provider initialized with auto-export"}
{"time":"2026-08-25T16:32:21.469001951+08:00","level":"INFO","msg":"OpenTelemetry initialized","instrumentation_name":"go.opentelemetry.io/otelc","instrumentation_version":"dev"}
{"time":"2026-08-25T16:32:21.470196036+08:00","level":"INFO","msg":"runtime metrics enabled"}
2026/08/25 16:32:21 HTTP server listening on :18080
发起请求
打开终端二,请求测试接口:
Bash
curl http://localhost:18080/ping
接口返回:
Plain
pong
此时 net/http 服务端 Hook 会自动创建 Span,并将 Trace 数据发送到 http://localhost:4317。业务代码没有发生任何与 OpenTelemetry 相关的改动。
如果需要确认构建阶段确实匹配了 HTTP 插桩规则,可以查看:
Bash
jq -r '.. | objects | select(has("name")) | .name' \
.otelc-build/matched.json
结果中应包含 server_hook。
在观测云查看链路
登录观测云控制台,进入「应用性能监测」-「链路」,使用服务名 http-otelc-demo 进行查询。
如果能够看到 /ping 请求对应的服务端 Span,就表示从应用到观测平台的链路已经打通:

Plain
HTTP 请求 -> net/http 自动插桩 -> OTLP/gRPC -> DataKit -> 观测云
在本次本地验证中,/ping 返回 HTTP 200 后,DataKit 的 OTLP Trace 接收计数同步增加,说明 Span 已经成功进入接收端。
写在最后
可观测性接入真正困难的地方,往往不是"让一个 Demo 产生一条 Trace",而是如何在大量服务中保持一致、可升级、可治理。
otelc 把 OpenTelemetry 接入点从业务源码移动到了构建阶段。它不会消除遥测运行时本身的成本,但能够显著减少应用团队需要维护的接入代码,让平台团队更容易统一工具版本、插桩范围和上报配置。
对于希望保持业务代码整洁,同时采用 OpenTelemetry 标准协议的 Go 项目,编译时插桩提供了一条值得尝试的路径。接入时只需记住三个原则:固定版本、配置外置、发布前验证真实数据。
项目地址: