- 可观测性
【免费下载链接】opentelemetry-go
OpenTelemetry Go API and SDK
导读
本文以 RELEASING.md 为核心骨架,系统讲解 OpenTelemetry Go(opentelemetry-go)从语义约定升级、破坏性变更验证、多模块预发布与打标签,到制品签名、创建 Release 与发布后收尾的完整发布流程。读者将掌握semconv-generate、prerelease、add-tags、gorelease等 Make 目标与multimod工具链的实际用法,理解versions.yaml模块集(module sets)的版本管理机制,并能独立完成一次符合 CNCF 最佳实践的版本发布。
1. 发布流程全景:从 Version Release Issue 开始
任何一次版本发布都始于一个版本发布跟踪 Issue(Version Release issue)。它的作用有二:一是作为本次发布的 TODO 清单,逐项记录发布过程中的每个环节;二是在发布完成后统一关闭,形成可追溯的记录。
整个发布流程按时间线可分为六个阶段:
- 语义约定升级(如本次发布涉及 semconv 更新);
- 破坏性变更验证(
make gorelease)与contrib 仓库兼容性验证; - 预发布(更新
versions.yaml、生成发布分支、整理 CHANGELOG); - 打标签(
make add-tags+ 推送 tag 到 upstream); - 签名制品(GPG 签名
.tar.gz与.zip); - 创建 GitHub Release及发布后收尾(contrib 发布、官网文档更新、关闭里程碑与 Issue)。
下文逐一展开。
2. 语义约定升级(Semantic Convention Upgrade)
OpenTelemetry 的语义约定(Semantic Conventions)是跨语言统一的属性、指标命名规范。每次 OpenTelemetry Semantic Conventions 发布新版本,opentelemetry-go仓库中的semconv包都需要随之重新生成,并作为新的独立子包发布,例如仓库中现有的 semconv/v1.4.0、semconv/v1.34.0、semconv/v1.43.0 等一系列版本目录。
2.1 语义约定代码生成:make semconv-generate
生成新版本 semconv 包的核心入口是semconv-generate这个 Make 目标,共两步:
- 将
TAG环境变量设置为要生成的语义约定标签(tag); - 在本仓库根目录运行
make semconv-generate(该目标会自动读取已导出的TAG)。
官方示例:
export TAG="v1.30.0" # Change to the release version you are generating. make semconv-generate # Uses the exported TAG.运行完成后,semconv 目录下会生成一个新的版本子包。提交 Pull Request 前,务必人工确认生成结果是否正确。
从 Makefile 的源码实现可以看到该目标的真实执行链路:
- 首先强制校验
TAG必须已设置,否则直接报错退出(TAG unset: missing opentelemetry semantic-conventions tag); - 创建
semconv/<TAG>目标目录; - 通过 Docker 运行
otel/weaver镜像(镜像版本定义在 dependencies.Dockerfile 的weaver阶段),将 semconv/templates/registry/go 下的模板目录以只读方式挂载,并指定--registry指向语义约定仓库对应 tag 的 zip 归档,执行registry generate生成 Go 代码; - 最后调用仓库自研工具
semconvkit(源码位于 internal/tools/semconvkit/main.go)做二次加工,补齐 migration 文档等仓库特有产物。
模板目录中的 weaver.yaml 定义了生成规则:例如排除aspnetcore、nodejs等语言专属命名空间,指定attribute_group.go、metric.go的输出文件名与过滤器,以及string -> String、int[] -> IntSlice等类型映射表。生成产物包括常量形式的属性 Key(见 attribute_group.go,以AndroidAppStateKey = attribute.Key("android.app.state")为例)、SchemaURL(见 schema.go,形如https://opentelemetry.io/schemas/1.34.0)以及各领域的xxxconv辅助包(如httpconv、dbconv、k8sconv)。
2.2 同步更新 CHANGELOG
新 semconv 包加入后,CHANGELOG.md 需要记录这一变更,官方给出了标准条目模板:
- The `go.opentelemetry.io/otel/semconv/<NEW VERSION>` package. The package contains semantic conventions from the `<NEW VERSION>` version of the OpenTelemetry Semantic Conventions. See the [migration documentation](https://link.gitcode.com/i/2333a14b225d5319b4aa8e7d21064e1b) for information on how to upgrade from `go.opentelemetry.io/otel/semconv/<PREVIOUS VERSION>`. (#PR_NUMBER)Tip:将
<NEW VERSION>与<PREVIOUS VERSION>替换为本次升级前后的实际版本号。
注意这里的迁移文档链接应指向对应版本目录下的 MIGRATION.md。该文档由semconvkit自动生成(模板见 internal/tools/semconvkit/templates/MIGRATION.md.tmpl),它会对比上一版本与当前版本包中导出的声明,自动罗列出 Renames 与 Removed 清单。从 internal/tools/semconvkit/main.go 的prevVer函数可以看到,工具会扫描semconv/目录下所有符合 semver 的版本目录,自动选取"小于当前版本且最接近"的版本作为迁移对比基准。
2.3 更新 semconv 导入
生成新模块后,需要把整个代码库中所有引用旧 semconv 的 import 替换为新版本。典型改动如下:
// Before semconv "go.opentelemetry.io/otel/semconv/v1.37.0" "go.opentelemetry.io/otel/semconv/v1.37.0/otelconv" // After semconv "go.opentelemetry.io/otel/semconv/v1.39.0" "go.opentelemetry.io/otel/semconv/v1.39.0/otelconv"说明:上述版本号仅作示例,实际以本次升级目标版本为准。以当前仓库为例,代码中大量文件(如 bridge/opentracing/mock.go、
exporters/otlp/otlplog/otlploggrpc下的观测代码)已统一引用semconv/v1.43.0,替换时可先用search_in_files类工具全库搜索旧版本号,确保无遗漏。
替换完成后运行make检查编译与测试是否通过。仓库 Makefile 的默认目标precommit(见 Makefile)会依次执行generate、toolchain-check、license-check、misspell、go-mod-tidy、golangci-lint-fix、verify-readmes、verify-mods与test-default,可用于发布前的一次性全面校验。
2.4 属性变更的处理与 OTEL_SEMCONV_STABILITY_OPT_IN
部分 semconv 版本会新增属性,或影响当前正在使用的属性——改动可能只是简单重命名,也可能是更复杂的合并属性、修改属性值类型等。原则是:代码应迁移到取代旧属性的新属性上,遵循最新的语义约定。
同时需要了解OTEL_SEMCONV_STABILITY_OPT_IN环境变量:当用户设置该变量时,根据约定,旧属性可能仍会随遥测数据一并发出,用于兼容过渡。因此迁移时既要更新代码使用新属性,也要考虑对旧属性发射行为的兼容预期。
此类迁移的跟踪与执行方式可参考社区维护的 issue #7806 中的案例讨论。
2.5 更新 Go contrib 仓库的 linter 配置
若本次 semconv 升级会影响opentelemetry-go-contrib仓库,还需同步更新该仓库根目录下的.golangci.yml,强制要求 contrib 使用新的 semconv 版本,从而保证整个 OpenTelemetry Go 生态的语义约定版本保持一致。
3. 破坏性变更验证:make gorelease
公共 API 的意外变更对 Go 模块发布是致命问题。发布前必须运行:
make gorelease该命令会调用 gorelease 实现看,gorelease目标会遍历仓库中所有go.mod 所在目录逐个执行gorelease检查,即主模块与全部子模块都会覆盖到。
若发现 gorelease 本身的问题,可在 Go 官方 issue tracker(golang.org/issues/26420)中报告。工具对应的 Go 依赖声明在 internal/tools/tools.go 中(golang.org/x/exp/cmd/gorelease)。
4. 验证 contrib 仓库兼容性
如果主仓库的变更会影响 contrib 仓库,必须在合并前验证两者兼容。具体步骤遵循 contrib 仓库自身的 RELEASING.md 中 "Verify OTel changes" 一节:通常是先本地替换主仓库依赖、运行 contrib 的测试套件,确认无破坏后,主仓库的 PR 才可安全合并。
5. 预发布(Pre-Release):versions.yaml 与 multimod
预发布阶段的核心工作是确定本次要发布哪些模块集(module set)并更新它们的版本号。
5.1 更新 versions.yaml
首先在 versions.yaml 中为要发布的模块集设置新版本,并将该变更提交到新分支。当前仓库的模块集划分如下(以仓库现状为准):
| 模块集 | 当前版本 | 包含的典型模块 |
|---|---|---|
stable-v1 | v1.47.0-rc.1 | go.opentelemetry.io/otel、otel/sdk、otel/trace、otel/metric、otel/log及各 OTLP/stdout/zipkin exporter 等 |
experimental-metrics | v0.68.0 | exporters/prometheus、metric/x |
experimental-logs | v0.22.0 | log/logtest、sdk/log/logtest、各 otlplog/stdoutlog exporter |
experimental-traces | v0.1.0 | sdk/trace/x |
experimental-schema | v0.0.19 | schema |
可见本仓库采用"稳定模块主版本号 + 实验模块独立 0.x 版本号"的并行版本策略。versions.yaml还通过modules段的version-refs将各子模块的版本号与自身internal/version.go文件绑定(例如otel/exporters/stdout/stdouttrace对应 internal/version.go),主模块版本则体现于根目录 version.go 的Version()函数。
5.2 make prerelease 生成发布分支
更新完versions.yaml后,还需同步更新各子模块 go.mod 中对新版本的依赖引用。运行预发布目标:
make prerelease MODSET=<module set>该命令会创建一个名为prerelease_<module set>_<new tag>的分支,包含全部发布所需的版本改动。从 Makefile 实现看,prerelease首先执行verify-mods(即multimod verify,校验versions.yaml与各模块声明的一致性),然后调用multimod prerelease -m ${MODSET}完成版本改写,且强制要求MODSET环境变量已设置。
5.3 审阅变更并合入
用 git diff 审阅生成的分支改动:
git diff ...prerelease_<module set>_<new tag>正常结果应是所有模块的版本都被改写为<new tag>。确认无误后,将其合并到你的预发布分支:
git merge prerelease_<module set>_<new tag>5.4 更新 CHANGELOG
发布前必须整理 CHANGELOG.md,要点如下:
确保本次发布的所有相关变更都已收录,且措辞能让非贡献者看懂。可用以下命令直接查看自上个 tag 以来的全部提交,作为核对依据:
git --no-pager log --pretty=oneline "<last tag>..HEAD"将
Unreleased段的所有内容移动到新版本小节中,标题遵循[<new tag>] - <date of release>格式(Keep a Changelog 风格,见 CHANGELOG.md 头部说明);新小节必须位于
<!-- Released section -->注释之下(该注释标记已发布区段的起始位置),避免后续被自动生成流程覆盖;同步更新文件底部的所有版本链接。
5.5 推送并提交 PR
将改动推送到 upstream,创建 Pull Request,并在 PR 描述中附上整理好的 CHANGELOG 内容(即本次发布的 release notes)。
6. 打标签(Tag):make add-tags
PR 合入后即可对合并提交打标签。必须使用与预发布阶段完全相同的 tag,否则会破坏整个发布状态——只要预发布与打标签之间不修改versions.yaml,tag 就能保持一致。
另外有一个 Go 生态的硬约束需要特别注意:Go 模块目前没有删除错误 tag 的能力(对应 Go 官方 issue #34189)。一旦把错误的版本推送到 upstream,将很难补救,历史上曾因此引发过不小的事故(见 opentelemetry-go issue #331 的教训),因此推送前务必反复核对版本号。
打标签命令:
make add-tags MODSET=<module set> COMMIT=<commit hash>COMMIT指向主分支上合并 PR 的提交哈希;只有当当前工作目录的HEAD不是正确提交时才需要显式指定,否则可省略(Makefile 中COMMIT ?= "HEAD",默认取当前 HEAD);add-tags同样先执行verify-mods校验,再调用multimod tag -m ${MODSET} -c ${COMMIT}为模块集内所有模块生成 tag。
然后推送所有 tag 到 upstream(注意是主仓库而非你的 fork),主模块与各子模块的 tag 都要推送:
git push upstream <new tag> git push upstream <submodules-path/new tag> ...7. 签名制品(Sign artifacts)
为满足 CNCF 最佳实践,发布制品需要 GPG 签名。步骤为:
- 从 tag 页面下载新发布 tag 对应的
.tar.gz与.zip两个归档; - 建议先用社区提供的校验脚本(attest-sh)核对归档内容完整性,再签名;
- 查询本机 GPG 密钥 ID:
gpg --list-secret-keys --keyid-format=long密钥 ID 是sec rsa4096/(或类似字段)之后的 16 位字符串。
- 设置环境变量并签名两个归档:
export VERSION="<version>" # e.g., v1.32.0 export KEY_ID="<your-gpg-key-id>" gpg --local-user $KEY_ID --armor --detach-sign opentelemetry-go-$VERSION.tar.gz gpg --local-user $KEY_ID --armor --detach-sign opentelemetry-go-$VERSION.zip- 验证签名:
gpg --verify opentelemetry-go-$VERSION.tar.gz.asc opentelemetry-go-$VERSION.tar.gz gpg --verify opentelemetry-go-$VERSION.zip.asc opentelemetry-go-$VERSION.zip签名会生成.asc格式的独立签名文件(.tar.gz.asc与.zip.asc),与归档文件一并用于后续 Release 上传。
8. 创建 GitHub Release
最后为<new tag>创建 Release,正文内容包含本次发布在 CHANGELOG 中的全部 release notes。
关键约束:GitHub Release 一经创建即不可变(immutable),签名制品(.tar.gz、.tar.gz.asc、.zip、.zip.asc)必须在创建 Release 时一并上传,因为之后无法再添加或修改附件。
9. 发布后(Post-Release)
9.1 contrib 仓库发布
验证通过后,需要同步为opentelemetry-go-contrib仓库发布一个基于本次版本的新 Release,使 contrib 生态引用到刚发布的模块版本。
9.2 官网文档更新
更新 OpenTelemetry 官网中 Go 语言 instrumentation 文档(位于官网内容仓库的content/en/docs/languages/go目录)。重点包括:将文档中引用的所有包版本号提升为刚发布的最新版本,并确保全部代码示例仍可编译、内容准确。
9.3 关闭里程碑
为便于追踪每个版本包含了哪些变更,发布后需确保本次发布修复的 issue 与合入的 PR 都归入对应里程碑:
- 查找未归入里程碑的已关闭 issue(可按"无里程碑、已关闭、已完成原因、已关联 PR、排除 Stale 标签"等条件检索);
- 查找未归入里程碑的已合并 PR(按"无里程碑、已合并"条件检索);
- 全部归入后关闭该里程碑。
9.4 关闭 Version Release Issue
当Version Releaseissue 中的 TODO 清单全部完成(制品签名、Release 创建、contrib 发布、文档更新、里程碑关闭等),关闭该 issue,本次发布流程即告结束。
附录:发布工具链速览
本次流程涉及的核心工具与 Make 目标汇总:
| 工具/目标 | 用途 | 源码/配置位置 |
|---|---|---|
semconv-generate | 生成指定 TAG 的 semconv 子包(基于 weaver + semconvkit) | Makefile |
semconvkit | semconv 代码二次生成、MIGRATION.md 自动对比 | internal/tools/semconvkit/main.go |
multimod | 多模块版本管理(verify/prerelease/tag) | Makefile |
gorelease | 公共 API 破坏性变更检查 | Makefile、internal/tools/tools.go |
versions.yaml | 模块集(module sets)版本声明中心 | versions.yaml |
| weaver 模板 | semconv 生成规则(属性/指标过滤器、类型映射) | semconv/templates/registry/go/weaver.yaml |
crosslink | 仓库内多 go.mod 间依赖同步 | Makefile |
发布者只要遵循"Issue 跟踪 → 语义约定升级 → API 兼容验证 → 预发布 → 打标签 → 签名 → Release → 收尾"这条主线,并严格保证 tag 与versions.yaml的一致性与制品的完整签名,就能稳定地完成一次 OpenTelemetry Go 版本发布。
- 可观测性
【免费下载链接】opentelemetry-go
OpenTelemetry Go API and SDK
相关推荐
OpenTelemetry Go SDK 发布流程全指南:语义约定升级、模块打标签与制品签名实操解析
OpenTelemetry Go SDK 发布流程全指南:语义约定升级、模块打标签与制品签名实操解析 导读 distribution 仓库在 vendor/go
镜像仓库后端存储云原生OpenTelemetry Go 发布流程全解析:从 Semantic Convention 升级到版本打签、制品签名与发布收尾
OpenTelemetry Go 发布流程全解析:从 Semantic Convention 升级到版本打签、制品签名与发布收尾 本文基于 linuxkit 仓
操作系统云原生容器运行时OpenTelemetry Go 多模块发布流程全解:从 semconv 升级、打标签到 GPG 签名与 GitHub Release
OpenTelemetry Go 多模块发布流程全解:从 semconv 升级、打标签到 GPG 签名与 GitHub Release 导读 本文基于仓库中 v
人工智能AI AgentAgent 沙箱云原生容器运行时零信任
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考