You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@dubbo.apache.org by "Tsukikage7 (via GitHub)" <gi...@apache.org> on 2026/08/03 10:18:59 UTC

[PR] feat(observability): add end-to-end sample [dubbo-go-samples]

Tsukikage7 opened a new pull request, #1128:
URL: https://github.com/apache/dubbo-go-samples/pull/1128

   ## Summary
   
   Add a standalone end-to-end observability integration sample under
   `dubbo-go-samples/observability`.
   
   The sample demonstrates:
   
   - Dubbo Triple consumer/provider communication;
   - Nacos service discovery;
   - OpenTelemetry W3C trace-context propagation;
   - OTLP HTTP export through OpenTelemetry Collector;
   - Jaeger trace inspection;
   - Prometheus metrics collection and Grafana visualization;
   - application logs correlated with `trace_id` and `span_id`;
   - successful requests and business-error requests;
   - timeout, cancellation, provider-unavailable, registry-unavailable, and recovery scenarios;
   - a repeatable local smoke test.
   
   Related issue:
   
   https://github.com/apache/dubbo-go/issues/3562
   
   ## Relationship to existing work
   
   This PR implements the end-to-end sample and documentation scope described
   by Workstream 6 in `apache/dubbo-go#3562`.
   
   This PR intentionally does not reimplement or take ownership of the following
   core observability work:
   
   - `apache/dubbo-go#3337` — Metrics;
   - `apache/dubbo-go#3338` — OpenTelemetry diagnostics;
   - `apache/dubbo-go#3356` — Metadata observability;
   - `apache/dubbo-go#3551` — OpenTelemetry span names and base attributes;
   - `apache/dubbo-go#3463` — Metadata mapping metrics and errors;
   - `apache/dubbo-go#3568` — Dubbo protocol error classification.
   
   The historical observability umbrella is:
   
   https://github.com/apache/dubbo-go/issues/3292
   
   This PR is focused on integration validation, runnable examples, telemetry
   pipeline configuration, dashboards, and documentation. It does not change
   the observability implementation in the `dubbo-go` core repository.
   
   ## What changed
   
   - Add a standalone `observability/` sample;
   - Add a Dubbo Triple provider;
   - Add a Dubbo Triple consumer;
   - Add generated Triple protocol stubs;
   - Add Nacos-backed service discovery;
   - Add OpenTelemetry configuration for both consumer and provider;
   - Add W3C trace-context propagation through the Dubbo request path;
   - Add OTLP HTTP export through OpenTelemetry Collector;
   - Add Jaeger as the trace backend;
   - Add Prometheus scrape configuration;
   - Add a provisioned Grafana Prometheus data source;
   - Add a provisioned `Dubbo Go Observability` Grafana dashboard;
   - Add trace-correlated application logs;
   - Add deterministic business-error and timeout scenarios;
   - Add provider-unavailable and registry-unavailable recovery drills;
   - Add a repeatable `observability/smoke.sh` validation script;
   - Add bilingual documentation and a local troubleshooting runbook;
   - Update the repository-level README files to expose the new sample.
   
   ## Screenshots
   
   ### Grafana Dashboard
   
   The dashboard shows:
   
   - successful RPC request rates;
   - provider latency p95;
   - business failures;
   - in-flight RPC requests;
   - registry failures;
   - service-unavailable failures.
   
   <img width="965" height="837" alt="image" src="https://github.com/user-attachments/assets/121c7095-0bba-454b-ba8b-dc44e13e69ba" />
   
   ### Jaeger Trace
   
   The trace view shows:
   
   - the consumer root span;
   - the consumer RPC span;
   - the provider RPC span;
   - the cross-service trace relationship;
   - the measured request duration and span hierarchy.
   
   <img width="965" height="837" alt="image" src="https://github.com/user-attachments/assets/22b23254-5f32-463f-8902-9c6d3ac866fc" />
   
   ### Prometheus Targets
   
   The targets page shows:
   
   - `dubbo-observability-client` target is `UP`;
   - `dubbo-observability-server` target is `UP`;
   - Prometheus can scrape both application metrics endpoints.
   
   <img width="1280" height="720" alt="image" src="https://github.com/user-attachments/assets/09be85de-871a-4b9f-820c-7edb8e29284a" />
   
   ## Validation
   
   The following checks were run locally:
   
   - `go test ./observability/...`;
   - `go test -race ./observability/...`;
   - `go vet ./observability/...`;
   - `go build ./observability/...`;
   - `docker compose -f observability/docker-compose.yaml config -q`;
   - Grafana dashboard JSON validation;
   - `bash -n observability/smoke.sh`;
   - `./observability/smoke.sh`.
   
   The runtime integration was also verified with the local stack:
   
   - Nacos service discovery;
   - consumer/provider communication over Dubbo Triple;
   - client and provider Prometheus endpoints;
   - Prometheus scraping both application targets;
   - OpenTelemetry Collector receiving OTLP HTTP data;
   - Jaeger service visibility;
   - cross-service consumer/provider traces;
   - trace-correlated application logs;
   - successful requests;
   - forced business errors;
   - timeout and explicit cancellation;
   - provider-unavailable and recovery;
   - registry-unavailable and recovery.
   
   ## Scope and compatibility
   
   This PR changes only the `dubbo-go-samples` repository.
   
   It does not:
   
   - modify the `dubbo-go` core repository;
   - change core observability semantics;
   - add a local filesystem `replace` directive;
   - depend on unreleased core APIs;
   - reimplement the core observability issues listed above;
   - add a second observability implementation in another sample;
   - use a non-standard Grafana host port.
   
   Grafana uses the standard host port `3000`. If port `3000` is already
   occupied in a developer's local environment, the existing local process
   should be stopped or the sample should be run in an environment where the
   standard port is available.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@dubbo.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@dubbo.apache.org
For additional commands, e-mail: notifications-help@dubbo.apache.org


Re: [PR] feat(observability): add end-to-end sample [dubbo-go-samples]

Posted by "Alanxtl (via GitHub)" <gi...@apache.org>.
Alanxtl merged PR #1128:
URL: https://github.com/apache/dubbo-go-samples/pull/1128


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@dubbo.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@dubbo.apache.org
For additional commands, e-mail: notifications-help@dubbo.apache.org


Re: [PR] feat(observability): add end-to-end sample [dubbo-go-samples]

Posted by "Tsukikage7 (via GitHub)" <gi...@apache.org>.
Tsukikage7 commented on code in PR #1128:
URL: https://github.com/apache/dubbo-go-samples/pull/1128#discussion_r3728094531


##########
observability/integration/README_CN.md:
##########
@@ -0,0 +1,202 @@
+# Dubbo Go 可观测性集成验证样例
+
+[English](README.md) | 中文
+
+这个样例是一个集成验证样例,把 Dubbo Go 现有的可观测性能力组合成一条可运行链路:
+
+现有 Metrics 和 Kubernetes 探针样例现在作为兄弟样例统一放在这个
+`observability/` 目录中。本端到端样例专注于跨信号集成和验证,不替换这些已有样例。

Review Comment:
   这三处 suggestion block(第 8、22、202 行)渲染出来是空的,没有具体内容。两个 P1 修复已推送到 `f7e3fd24`,如果这三处另有期望措辞请补充说明,我来改。



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@dubbo.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@dubbo.apache.org
For additional commands, e-mail: notifications-help@dubbo.apache.org


Re: [PR] feat(observability): add end-to-end sample [dubbo-go-samples]

Posted by "Alanxtl (via GitHub)" <gi...@apache.org>.
Alanxtl commented on PR #1128:
URL: https://github.com/apache/dubbo-go-samples/pull/1128#issuecomment-5168215346

   这个sample放到 observability下面再建一个独立文件夹吧 和probe 和prometheus_grafana 并列


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@dubbo.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@dubbo.apache.org
For additional commands, e-mail: notifications-help@dubbo.apache.org


Re: [PR] feat(observability): add end-to-end sample [dubbo-go-samples]

Posted by "Alanxtl (via GitHub)" <gi...@apache.org>.
Alanxtl commented on code in PR #1128:
URL: https://github.com/apache/dubbo-go-samples/pull/1128#discussion_r3709283671


##########
observability/README_CN.md:
##########
@@ -0,0 +1,201 @@
+# Dubbo Go 可观测性集成验证样例
+
+[English](README.md) | 中文
+
+这个样例是一个集成验证样例,把 Dubbo Go 现有的可观测性能力组合成一条可运行链路:
+
+现有 Metrics 和 Kubernetes 探针样例现在作为兄弟样例统一放在这个
+`observability/` 目录中。本端到端样例专注于跨信号集成和验证,不替换这些已有样例。
+
+```text
+Nacos 注册中心
+       |
+Dubbo Triple 客户端 -> Dubbo Triple 服务端
+        |                    |
+        +-- Trace --> OpenTelemetry Collector --> Jaeger
+        +-- Metrics ---------------------------> Prometheus -> Grafana
+        +-- 日志 ------------------------------> stdout 中的 trace_id / span_id
+```
+
+这个样例刻意保持较小,定位是“现有能力的集成验证”,不是核心可观测性实现,
+也不是第二个业务商城。单项能力验证完成后,再使用 `online_boutique` 做更复杂的
+业务链路验收。
+
+## 目录结构
+
+```text
+observability/
+├── go-client/cmd/main.go           # Triple 消费端和请求生成器
+├── go-server/cmd/main.go           # Triple 提供端,包含可复现错误路径
+├── proto/                          # 独立的服务契约和生成代码
+├── docker-compose.yaml             # Nacos、Collector、Jaeger、Prometheus、Grafana
+├── otel-collector-config.yaml      # 转发到 Jaeger 的 OTLP Collector 管道
+├── prometheus.yml                  # 抓取两个本地 Metrics endpoint
+├── prometheus_grafana/              # Push/Pull Metrics 和 Grafana 样例
+├── probe/                           # Kubernetes 存活、就绪和启动探针样例
+└── grafana/                        # 自动配置数据源和 Dashboard
+```
+
+## 前置条件
+
+- Go 1.25 或更新版本;
+- Docker 和 Compose;
+- 本仓库的本地 checkout。
+
+Compose 中固定了 Nacos `v2.5.2`、OpenTelemetry Collector `0.104.0`、Jaeger
+`1.57`、Prometheus `v2.55.1` 和 Grafana `11.2.0`,以便使用确定的工具链复现
+这条验证链路。
+
+按仓库标准进行集成验证时,先启动根目录依赖,再使用根级集成测试入口。该入口会
+通过根目录 Makefile 构建和停止 `go-server/cmd`,运行 `go-client/cmd`,并启动本样例
+额外声明的可观测性服务:
+
+```bash
+docker compose -f docker-compose.yml up -d
+./integrate_test.sh observability
+```
+
+本样例也已经加入 `start_integrate_test.sh` 的集成测试列表。
+
+## 启动样例
+
+启动 Nacos、OpenTelemetry Collector、Jaeger、Prometheus 和 Grafana:
+
+```bash
+cd observability
+docker compose up -d
+cd ..
+```
+
+启动应用前,先等待 Nacos 健康:
+
+```bash
+docker compose -f observability/docker-compose.yaml ps
+```
+
+服务端会注册到 Nacos,客户端从 Nacos 发现服务。默认注册中心地址是
+`127.0.0.1:8848`;如果注册中心在其他主机,可以通过
+`DUBBO_OBSERVABILITY_REGISTRY_ADDRESS` 覆盖。
+
+Grafana 默认映射到标准宿主机 `3000` 端口。如果你的本地环境已经占用
+`3000`,请停止冲突进程;样例本身保持仓库统一的标准端口映射。
+
+在第二个终端启动 Dubbo 服务端:
+
+```bash
+go run ./observability/go-server/cmd
+```
+
+在第三个终端启动客户端。客户端每 5 个请求会故意发送一个 `error` 请求,
+用于在 Metrics、Trace 和日志中检查失败路径:
+
+```bash
+go run ./observability/go-client/cmd -requests 20 -interval 500ms
+```
+
+如果希望持续产生流量以观察 Dashboard,请传入 `-requests 0`:
+
+```bash
+go run ./observability/go-client/cmd -requests 0 -interval 500ms
+```
+
+如果要复现超时,可以设置一个小于服务端故意延迟 20 毫秒的请求超时:
+
+```bash
+go run ./observability/go-client/cmd -requests 5 -timeout 1ms
+```
+
+如果要复现显式取消而不是 deadline 到期:
+
+```bash
+go run ./observability/go-client/cmd -requests 5 -cancel-after 1ms
+```
+
+客户端默认执行有限次数,这样可以直接接入仓库集成测试;如果希望持续产生流量观察
+Dashboard,请显式传入 `-requests 0`。
+
+测试完成后使用 `Ctrl-C` 停止客户端和服务端,再回收监控栈:
+
+```bash
+docker compose -f observability/docker-compose.yaml down
+```
+
+## 查看信号
+
+- Jaeger:<http://localhost:16686>
+- Nacos:<http://localhost:8848/nacos>
+- Prometheus:<http://localhost:9090>
+- Grafana:<http://localhost:3000>
+- 服务端 Metrics:<http://localhost:9099/prometheus>
+- 客户端 Metrics:<http://localhost:9098/prometheus>
+
+Grafana 会自动配置 Prometheus 数据源和 `Dubbo Go Observability` Dashboard。
+应用日志保留在客户端和服务端终端中;每条应用日志都会读取当前 OpenTelemetry
+`SpanContext`,并包含和 Jaeger 中相同的 `trace_id`、`span_id`。这个样例刻意只使用
+已发布的 module API;Dubbo-Go 的 `CtxLogger` 集成由专门的
+`logger/trace-integration` 样例覆盖,这里不重复实现。
+
+## 使用本地 dubbo-go 工作树
+
+默认情况下,样例使用仓库根目录 module。要测试未提交的本地 Dubbo Go 修改,
+请创建一个同时包含本地 `dubbo-go` module 和本仓库的临时 Go workspace,然后使用
+`GOWORK` 执行命令:
+
+```bash
+GOWORK=/tmp/dubbo-go-observability.go.work \
+  go run ./observability/go-server/cmd
+
+GOWORK=/tmp/dubbo-go-observability.go.work \
+  go run ./observability/go-client/cmd -requests 20
+```
+
+客户端通过 Nacos 发现服务,而不是使用写死的服务端地址。如果注册中心运行在其他
+主机,可以通过 `DUBBO_OBSERVABILITY_REGISTRY_ADDRESS` 覆盖注册中心地址。
+
+临时 workspace 需要包含:
+
+```text
+/path/to/dubbo-go
+/path/to/dubbo-go-samples
+```
+
+这样不需要把本地文件系统 `replace` 指令写入正式 sample module。
+
+## 验证范围
+
+- 通过 Nacos 服务发现完成 Dubbo Triple consumer 到 provider 的 W3C Trace Context 传播;
+- OTLP HTTP 经 OpenTelemetry Collector 导出到 Jaeger;
+- consumer 和 provider 的 Prometheus RPC Metrics;
+- Grafana 中的成功、失败、不可用、在途请求、注册中心和延迟信号可视化;
+- 包含当前 Trace 标识的应用日志;
+- 同一条流程中的成功请求、业务错误、超时和恢复;
+- 显式请求取消和恢复;
+- 文档化注册中心不可用和服务端不可用演练;
+- 使用未提交的本地 `dubbo-go` 工作树进行测试。
+
+## 故障与恢复演练
+
+样例通过运行时操作复现故障,不向 `dubbo-go` 核心代码加入样例专用的故障逻辑:
+
+1. 服务端业务错误:每第五个请求使用 `error` 作为 name。
+2. 请求超时:使用 `-timeout 1ms` 启动客户端。
+3. 请求取消:使用 `-cancel-after 1ms` 启动客户端。
+4. 服务端不可用:停止服务端进程后发送请求,再重启服务端,确认服务发现和请求恢复。
+5. 注册中心不可用:执行 `docker compose stop nacos` 后发送请求,再执行
+   `docker compose start nacos`;必要时重启服务端和客户端。
+
+每次演练都检查应用日志、Jaeger 中的 Trace、Consumer/Provider Metrics endpoint
+以及 Grafana Dashboard。
+
+## 边界说明
+
+这个样例只验证当前 `dubbo-go` 能力在一条基于注册中心的 Consumer/Provider 链路
+以及外围遥测管道中的协同工作,不做以下事情:
+
+- 不新增或修改核心 Metrics、Trace、Logger、Metadata 语义;
+- 不替代现有可观测性 Issues 中已经在推进的实现;
+- 不宣称取得 `dubbo-go` 核心代码的 ownership;
+- 不把样例扩展成第二个业务应用。
+
+核心实现应放在 `dubbo-go` 中,并在和对应维护者、贡献者完成协调后,拆分为独立、
+可单独审查的 PR。

Review Comment:
   英文版本也同步修改
   ```suggestion
   # Dubbo Go 可观测性集成验证样例
   
   [English](README.md) | 中文
   
   这个样例是一个集成验证样例,把 Dubbo Go 现有的可观测性能力组合成一条可运行链路:
   
   现有 Metrics 和 Kubernetes 探针样例现在作为兄弟样例统一放在这个
   `observability/` 目录中。本端到端样例专注于跨信号集成和验证,不替换这些已有样例。
   
   ```text
   Nacos 注册中心
          |
   Dubbo Triple 客户端 -> Dubbo Triple 服务端
           |                    |
           +-- Trace --> OpenTelemetry Collector --> Jaeger
           +-- Metrics ---------------------------> Prometheus -> Grafana
           +-- 日志 ------------------------------> stdout 中的 trace_id / span_id
   ```
   
   ## 目录结构
   
   ```text
   observability/
   ├── go-client/cmd/main.go           # Triple 消费端和请求生成器
   ├── go-server/cmd/main.go           # Triple 提供端,包含可复现错误路径
   ├── proto/                          # 独立的服务契约和生成代码
   ├── docker-compose.yaml             # Nacos、Collector、Jaeger、Prometheus、Grafana
   ├── otel-collector-config.yaml      # 转发到 Jaeger 的 OTLP Collector 管道
   ├── prometheus.yml                  # 抓取两个本地 Metrics endpoint
   ├── prometheus_grafana/              # Push/Pull Metrics 和 Grafana 样例
   ├── probe/                           # Kubernetes 存活、就绪和启动探针样例
   └── grafana/                        # 自动配置数据源和 Dashboard
   ```
   
   ## 前置条件
   
   - Go 1.25 或更新版本;
   - Docker 和 Compose;
   - 本仓库的本地 checkout。
   
   Compose 中固定了 Nacos `v2.5.2`、OpenTelemetry Collector `0.104.0`、Jaeger
   `1.57`、Prometheus `v2.55.1` 和 Grafana `11.2.0`,以便使用确定的工具链复现
   这条验证链路。
   
   按仓库标准进行集成验证时,先启动根目录依赖,再使用根级集成测试入口。该入口会
   通过根目录 Makefile 构建和停止 `go-server/cmd`,运行 `go-client/cmd`,并启动本样例
   额外声明的可观测性服务:
   
   ```bash
   docker compose -f docker-compose.yml up -d
   ./integrate_test.sh observability
   ```
   
   ## 启动样例
   
   启动 Nacos、OpenTelemetry Collector、Jaeger、Prometheus 和 Grafana:
   
   ```bash
   cd observability
   docker compose up -d
   cd ..
   ```
   
   启动应用前,先等待 Nacos 健康:
   
   ```bash
   docker compose -f observability/docker-compose.yaml ps
   ```
   
   服务端会注册到 Nacos,客户端从 Nacos 发现服务。默认注册中心地址是
   `127.0.0.1:8848`;如果注册中心在其他主机,可以通过
   `DUBBO_OBSERVABILITY_REGISTRY_ADDRESS` 覆盖。
   
   Grafana 默认映射到标准宿主机 `3000` 端口。如果你的本地环境已经占用
   `3000`,请停止冲突进程;样例本身保持仓库统一的标准端口映射。
   
   在第二个终端启动 Dubbo 服务端:
   
   ```bash
   go run ./observability/go-server/cmd
   ```
   
   在第三个终端启动客户端。客户端每 5 个请求会故意发送一个 `error` 请求,
   用于在 Metrics、Trace 和日志中检查失败路径:
   
   ```bash
   go run ./observability/go-client/cmd -requests 20 -interval 500ms
   ```
   
   如果希望持续产生流量以观察 Dashboard,请传入 `-requests 0`:
   
   ```bash
   go run ./observability/go-client/cmd -requests 0 -interval 500ms
   ```
   
   如果要复现超时,可以设置一个小于服务端故意延迟 20 毫秒的请求超时:
   
   ```bash
   go run ./observability/go-client/cmd -requests 5 -timeout 1ms
   ```
   
   如果要复现显式取消而不是 deadline 到期:
   
   ```bash
   go run ./observability/go-client/cmd -requests 5 -cancel-after 1ms
   ```
   
   客户端默认执行有限次数,这样可以直接接入仓库集成测试;如果希望持续产生流量观察
   Dashboard,请显式传入 `-requests 0`。
   
   测试完成后使用 `Ctrl-C` 停止客户端和服务端,再回收监控栈:
   
   ```bash
   docker compose -f observability/docker-compose.yaml down
   ```
   
   ## 查看信号
   
   - Jaeger:<http://localhost:16686>
   - Nacos:<http://localhost:8848/nacos>
   - Prometheus:<http://localhost:9090>
   - Grafana:<http://localhost:3000>
   - 服务端 Metrics:<http://localhost:9099/prometheus>
   - 客户端 Metrics:<http://localhost:9098/prometheus>
   
   Grafana 会自动配置 Prometheus 数据源和 `Dubbo Go Observability` Dashboard。
   应用日志保留在客户端和服务端终端中;每条应用日志都会读取当前 OpenTelemetry
   `SpanContext`,并包含和 Jaeger 中相同的 `trace_id`、`span_id`。这个样例刻意只使用
   已发布的 module API;Dubbo-Go 的 `CtxLogger` 集成由专门的
   `logger/trace-integration` 样例覆盖,这里不重复实现。
   
   ## 故障与恢复演练
   
   样例通过运行时操作复现故障,不向 `dubbo-go` 核心代码加入样例专用的故障逻辑:
   
   1. 服务端业务错误:每第五个请求使用 `error` 作为 name。
   2. 请求超时:使用 `-timeout 1ms` 启动客户端。
   3. 请求取消:使用 `-cancel-after 1ms` 启动客户端。
   4. 服务端不可用:停止服务端进程后发送请求,再重启服务端,确认服务发现和请求恢复。
   5. 注册中心不可用:执行 `docker compose stop nacos` 后发送请求,再执行
      `docker compose start nacos`;必要时重启服务端和客户端。
   
   每次演练都检查应用日志、Jaeger 中的 Trace、Consumer/Provider Metrics endpoint
   以及 Grafana Dashboard。
   ```



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@dubbo.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@dubbo.apache.org
For additional commands, e-mail: notifications-help@dubbo.apache.org


Re: [PR] feat(observability): add end-to-end sample [dubbo-go-samples]

Posted by "Alanxtl (via GitHub)" <gi...@apache.org>.
Alanxtl commented on PR #1128:
URL: https://github.com/apache/dubbo-go-samples/pull/1128#issuecomment-5168192066

   这个sample放到 observability下面再建一个独立文件夹吧 和probe 和prometheus_grafana 并列


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@dubbo.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@dubbo.apache.org
For additional commands, e-mail: notifications-help@dubbo.apache.org


Re: [PR] feat(observability): add end-to-end sample [dubbo-go-samples]

Posted by "Alanxtl (via GitHub)" <gi...@apache.org>.
Alanxtl commented on code in PR #1128:
URL: https://github.com/apache/dubbo-go-samples/pull/1128#discussion_r3709283671


##########
observability/integration/README_CN.md:
##########
@@ -0,0 +1,201 @@
+# Dubbo Go 可观测性集成验证样例
+
+[English](README.md) | 中文
+
+这个样例是一个集成验证样例,把 Dubbo Go 现有的可观测性能力组合成一条可运行链路:
+
+现有 Metrics 和 Kubernetes 探针样例现在作为兄弟样例统一放在这个
+`observability/` 目录中。本端到端样例专注于跨信号集成和验证,不替换这些已有样例。
+
+```text
+Nacos 注册中心
+       |
+Dubbo Triple 客户端 -> Dubbo Triple 服务端
+        |                    |
+        +-- Trace --> OpenTelemetry Collector --> Jaeger
+        +-- Metrics ---------------------------> Prometheus -> Grafana
+        +-- 日志 ------------------------------> stdout 中的 trace_id / span_id
+```
+
+这个样例刻意保持较小,定位是“现有能力的集成验证”,不是核心可观测性实现,
+也不是第二个业务商城。单项能力验证完成后,再使用 `online_boutique` 做更复杂的
+业务链路验收。
+
+## 目录结构
+
+```text
+observability/
+├── go-client/cmd/main.go           # Triple 消费端和请求生成器
+├── go-server/cmd/main.go           # Triple 提供端,包含可复现错误路径
+├── proto/                          # 独立的服务契约和生成代码
+├── docker-compose.yaml             # Nacos、Collector、Jaeger、Prometheus、Grafana
+├── otel-collector-config.yaml      # 转发到 Jaeger 的 OTLP Collector 管道
+├── prometheus.yml                  # 抓取两个本地 Metrics endpoint
+├── prometheus_grafana/              # Push/Pull Metrics 和 Grafana 样例
+├── probe/                           # Kubernetes 存活、就绪和启动探针样例
+└── grafana/                        # 自动配置数据源和 Dashboard
+```
+
+## 前置条件
+
+- Go 1.25 或更新版本;
+- Docker 和 Compose;
+- 本仓库的本地 checkout。
+
+Compose 中固定了 Nacos `v2.5.2`、OpenTelemetry Collector `0.104.0`、Jaeger
+`1.57`、Prometheus `v2.55.1` 和 Grafana `11.2.0`,以便使用确定的工具链复现
+这条验证链路。
+
+按仓库标准进行集成验证时,先启动根目录依赖,再使用根级集成测试入口。该入口会
+通过根目录 Makefile 构建和停止 `go-server/cmd`,运行 `go-client/cmd`,并启动本样例
+额外声明的可观测性服务:
+
+```bash
+docker compose -f docker-compose.yml up -d
+./integrate_test.sh observability
+```
+
+本样例也已经加入 `start_integrate_test.sh` 的集成测试列表。
+
+## 启动样例
+
+启动 Nacos、OpenTelemetry Collector、Jaeger、Prometheus 和 Grafana:
+
+```bash
+cd observability
+docker compose up -d
+cd ..
+```
+
+启动应用前,先等待 Nacos 健康:
+
+```bash
+docker compose -f observability/docker-compose.yaml ps
+```
+
+服务端会注册到 Nacos,客户端从 Nacos 发现服务。默认注册中心地址是
+`127.0.0.1:8848`;如果注册中心在其他主机,可以通过
+`DUBBO_OBSERVABILITY_REGISTRY_ADDRESS` 覆盖。
+
+Grafana 默认映射到标准宿主机 `3000` 端口。如果你的本地环境已经占用
+`3000`,请停止冲突进程;样例本身保持仓库统一的标准端口映射。
+
+在第二个终端启动 Dubbo 服务端:
+
+```bash
+go run ./observability/go-server/cmd
+```
+
+在第三个终端启动客户端。客户端每 5 个请求会故意发送一个 `error` 请求,
+用于在 Metrics、Trace 和日志中检查失败路径:
+
+```bash
+go run ./observability/go-client/cmd -requests 20 -interval 500ms
+```
+
+如果希望持续产生流量以观察 Dashboard,请传入 `-requests 0`:
+
+```bash
+go run ./observability/go-client/cmd -requests 0 -interval 500ms
+```
+
+如果要复现超时,可以设置一个小于服务端故意延迟 20 毫秒的请求超时:
+
+```bash
+go run ./observability/go-client/cmd -requests 5 -timeout 1ms
+```
+
+如果要复现显式取消而不是 deadline 到期:
+
+```bash
+go run ./observability/go-client/cmd -requests 5 -cancel-after 1ms
+```
+
+客户端默认执行有限次数,这样可以直接接入仓库集成测试;如果希望持续产生流量观察
+Dashboard,请显式传入 `-requests 0`。
+
+测试完成后使用 `Ctrl-C` 停止客户端和服务端,再回收监控栈:
+
+```bash
+docker compose -f observability/docker-compose.yaml down
+```
+
+## 查看信号
+
+- Jaeger:<http://localhost:16686>
+- Nacos:<http://localhost:8848/nacos>
+- Prometheus:<http://localhost:9090>
+- Grafana:<http://localhost:3000>
+- 服务端 Metrics:<http://localhost:9099/prometheus>
+- 客户端 Metrics:<http://localhost:9098/prometheus>
+
+Grafana 会自动配置 Prometheus 数据源和 `Dubbo Go Observability` Dashboard。
+应用日志保留在客户端和服务端终端中;每条应用日志都会读取当前 OpenTelemetry
+`SpanContext`,并包含和 Jaeger 中相同的 `trace_id`、`span_id`。这个样例刻意只使用
+已发布的 module API;Dubbo-Go 的 `CtxLogger` 集成由专门的
+`logger/trace-integration` 样例覆盖,这里不重复实现。
+
+## 使用本地 dubbo-go 工作树
+
+默认情况下,样例使用仓库根目录 module。要测试未提交的本地 Dubbo Go 修改,
+请创建一个同时包含本地 `dubbo-go` module 和本仓库的临时 Go workspace,然后使用
+`GOWORK` 执行命令:
+
+```bash
+GOWORK=/tmp/dubbo-go-observability.go.work \
+  go run ./observability/go-server/cmd
+
+GOWORK=/tmp/dubbo-go-observability.go.work \
+  go run ./observability/go-client/cmd -requests 20
+```
+
+客户端通过 Nacos 发现服务,而不是使用写死的服务端地址。如果注册中心运行在其他
+主机,可以通过 `DUBBO_OBSERVABILITY_REGISTRY_ADDRESS` 覆盖注册中心地址。
+
+临时 workspace 需要包含:
+
+```text
+/path/to/dubbo-go
+/path/to/dubbo-go-samples
+```
+
+这样不需要把本地文件系统 `replace` 指令写入正式 sample module。
+
+## 验证范围
+
+- 通过 Nacos 服务发现完成 Dubbo Triple consumer 到 provider 的 W3C Trace Context 传播;
+- OTLP HTTP 经 OpenTelemetry Collector 导出到 Jaeger;
+- consumer 和 provider 的 Prometheus RPC Metrics;
+- Grafana 中的成功、失败、不可用、在途请求、注册中心和延迟信号可视化;
+- 包含当前 Trace 标识的应用日志;
+- 同一条流程中的成功请求、业务错误、超时和恢复;
+- 显式请求取消和恢复;
+- 文档化注册中心不可用和服务端不可用演练;
+- 使用未提交的本地 `dubbo-go` 工作树进行测试。
+
+## 故障与恢复演练
+
+样例通过运行时操作复现故障,不向 `dubbo-go` 核心代码加入样例专用的故障逻辑:
+
+1. 服务端业务错误:每第五个请求使用 `error` 作为 name。
+2. 请求超时:使用 `-timeout 1ms` 启动客户端。
+3. 请求取消:使用 `-cancel-after 1ms` 启动客户端。
+4. 服务端不可用:停止服务端进程后发送请求,再重启服务端,确认服务发现和请求恢复。
+5. 注册中心不可用:执行 `docker compose stop nacos` 后发送请求,再执行
+   `docker compose start nacos`;必要时重启服务端和客户端。
+
+每次演练都检查应用日志、Jaeger 中的 Trace、Consumer/Provider Metrics endpoint
+以及 Grafana Dashboard。
+
+## 边界说明
+
+这个样例只验证当前 `dubbo-go` 能力在一条基于注册中心的 Consumer/Provider 链路
+以及外围遥测管道中的协同工作,不做以下事情:
+
+- 不新增或修改核心 Metrics、Trace、Logger、Metadata 语义;
+- 不替代现有可观测性 Issues 中已经在推进的实现;
+- 不宣称取得 `dubbo-go` 核心代码的 ownership;
+- 不把样例扩展成第二个业务应用。
+
+核心实现应放在 `dubbo-go` 中,并在和对应维护者、贡献者完成协调后,拆分为独立、
+可单独审查的 PR。

Review Comment:
   英文版本也同步修改
   ```suggestion
   # Dubbo Go 可观测性集成验证样例
   
   [English](README.md) | 中文
   
   这个样例是一个集成验证样例,把 Dubbo Go 现有的可观测性能力组合成一条可运行链路:
   
   现有 Metrics 和 Kubernetes 探针样例现在作为兄弟样例统一放在这个
   `observability/` 目录中。本端到端样例专注于跨信号集成和验证,不替换这些已有样例。
   
   ```text
   Nacos 注册中心
          |
   Dubbo Triple 客户端 -> Dubbo Triple 服务端
           |                    |
           +-- Trace --> OpenTelemetry Collector --> Jaeger
           +-- Metrics ---------------------------> Prometheus -> Grafana
           +-- 日志 ------------------------------> stdout 中的 trace_id / span_id
   ```
   
   ## 目录结构
   
   ```text
   observability/
   ├── go-client/cmd/main.go           # Triple 消费端和请求生成器
   ├── go-server/cmd/main.go           # Triple 提供端,包含可复现错误路径
   ├── proto/                          # 独立的服务契约和生成代码
   ├── docker-compose.yaml             # Nacos、Collector、Jaeger、Prometheus、Grafana
   ├── otel-collector-config.yaml      # 转发到 Jaeger 的 OTLP Collector 管道
   ├── prometheus.yml                  # 抓取两个本地 Metrics endpoint
   ├── prometheus_grafana/              # Push/Pull Metrics 和 Grafana 样例
   ├── probe/                           # Kubernetes 存活、就绪和启动探针样例
   └── grafana/                        # 自动配置数据源和 Dashboard
   ```
   
   ## 前置条件
   
   - Go 1.25 或更新版本;
   - Docker 和 Compose;
   - 本仓库的本地 checkout。
   
   Compose 中固定了 Nacos `v2.5.2`、OpenTelemetry Collector `0.104.0`、Jaeger
   `1.57`、Prometheus `v2.55.1` 和 Grafana `11.2.0`,以便使用确定的工具链复现
   这条验证链路。
   
   按仓库标准进行集成验证时,先启动根目录依赖,再使用根级集成测试入口。该入口会
   通过根目录 Makefile 构建和停止 `go-server/cmd`,运行 `go-client/cmd`,并启动本样例
   额外声明的可观测性服务:
   
   ```bash
   docker compose -f docker-compose.yml up -d
   ./integrate_test.sh observability
   ```
   
   ## 启动样例
   
   启动 Nacos、OpenTelemetry Collector、Jaeger、Prometheus 和 Grafana:
   
   ```bash
   cd observability
   docker compose up -d
   cd ..
   ```
   
   启动应用前,先等待 Nacos 健康:
   
   ```bash
   docker compose -f observability/docker-compose.yaml ps
   ```
   
   服务端会注册到 Nacos,客户端从 Nacos 发现服务。默认注册中心地址是
   `127.0.0.1:8848`;如果注册中心在其他主机,可以通过
   `DUBBO_OBSERVABILITY_REGISTRY_ADDRESS` 覆盖。
   
   Grafana 默认映射到标准宿主机 `3000` 端口。如果你的本地环境已经占用
   `3000`,请停止冲突进程;样例本身保持仓库统一的标准端口映射。
   
   在第二个终端启动 Dubbo 服务端:
   
   ```bash
   go run ./observability/go-server/cmd
   ```
   
   在第三个终端启动客户端。客户端每 5 个请求会故意发送一个 `error` 请求,
   用于在 Metrics、Trace 和日志中检查失败路径:
   
   ```bash
   go run ./observability/go-client/cmd -requests 20 -interval 500ms
   ```
   
   如果希望持续产生流量以观察 Dashboard,请传入 `-requests 0`:
   
   ```bash
   go run ./observability/go-client/cmd -requests 0 -interval 500ms
   ```
   
   如果要复现超时,可以设置一个小于服务端故意延迟 20 毫秒的请求超时:
   
   ```bash
   go run ./observability/go-client/cmd -requests 5 -timeout 1ms
   ```
   
   如果要复现显式取消而不是 deadline 到期:
   
   ```bash
   go run ./observability/go-client/cmd -requests 5 -cancel-after 1ms
   ```
   
   客户端默认执行有限次数,这样可以直接接入仓库集成测试;如果希望持续产生流量观察
   Dashboard,请显式传入 `-requests 0`。
   
   测试完成后使用 `Ctrl-C` 停止客户端和服务端,再回收监控栈:
   
   ```bash
   docker compose -f observability/docker-compose.yaml down
   ```
   
   ## 查看信号
   
   - Jaeger:<http://localhost:16686>
   - Nacos:<http://localhost:8848/nacos>
   - Prometheus:<http://localhost:9090>
   - Grafana:<http://localhost:3000>
   - 服务端 Metrics:<http://localhost:9099/prometheus>
   - 客户端 Metrics:<http://localhost:9098/prometheus>
   
   Grafana 会自动配置 Prometheus 数据源和 `Dubbo Go Observability` Dashboard。
   应用日志保留在客户端和服务端终端中;每条应用日志都会读取当前 OpenTelemetry
   `SpanContext`,并包含和 Jaeger 中相同的 `trace_id`、`span_id`。这个样例刻意只使用
   已发布的 module API;Dubbo-Go 的 `CtxLogger` 集成由专门的
   `logger/trace-integration` 样例覆盖,这里不重复实现。
   
   ## 故障与恢复演练
   
   样例通过运行时操作复现故障,不向 `dubbo-go` 核心代码加入样例专用的故障逻辑:
   
   1. 服务端业务错误:每第五个请求使用 `error` 作为 name。
   2. 请求超时:使用 `-timeout 1ms` 启动客户端。
   3. 请求取消:使用 `-cancel-after 1ms` 启动客户端。
   4. 服务端不可用:停止服务端进程后发送请求,再重启服务端,确认服务发现和请求恢复。
   5. 注册中心不可用:执行 `docker compose stop nacos` 后发送请求,再执行
      `docker compose start nacos`;必要时重启服务端和客户端。
   
   每次演练都检查应用日志、Jaeger 中的 Trace、Consumer/Provider Metrics endpoint
   以及 Grafana Dashboard。
   ```



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@dubbo.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@dubbo.apache.org
For additional commands, e-mail: notifications-help@dubbo.apache.org


Re: [PR] feat(observability): add end-to-end sample [dubbo-go-samples]

Posted by "Tsukikage7 (via GitHub)" <gi...@apache.org>.
Tsukikage7 commented on code in PR #1128:
URL: https://github.com/apache/dubbo-go-samples/pull/1128#discussion_r3728093277


##########
integrate_test.sh:
##########
@@ -447,11 +577,16 @@ main() {
   fi
 
   start_go_server
+  start_sample_dependencies
   start_aux_go_servers
 
   run_go_client
   run_java_client_if_present
 
+  if [ -n "$SAMPLE_COMPOSE_FILE" ]; then
+    stop_sample_dependencies

Review Comment:
   已修复:teardown 前增加语义断言,带超时查询 Prometheus targets 与关键指标(`dubbo_provider_requests_succeed_total`)、从 Jaeger 校验同一条 trace 下的 consumer/provider spans、并验证 Grafana 预置数据源;任一环节失败均以非零码退出。此外 observability/integration 模式下客户端校验失败现在也会直接导致集成流程失败,避免 CI 假绿。



##########
observability/integration/go-client/cmd/main.go:
##########
@@ -0,0 +1,180 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package main
+
+import (
+	"context"
+	"flag"
+	"fmt"
+	"os"
+	"strconv"
+	"time"
+)
+
+import (
+	"dubbo.apache.org/dubbo-go/v3"
+	_ "dubbo.apache.org/dubbo-go/v3/imports"
+	dubbolog "dubbo.apache.org/dubbo-go/v3/logger"
+	"dubbo.apache.org/dubbo-go/v3/metrics"
+	"dubbo.apache.org/dubbo-go/v3/otel/trace"
+	"dubbo.apache.org/dubbo-go/v3/registry"
+
+	"github.com/dubbogo/gost/log/logger"
+
+	"go.opentelemetry.io/otel"
+	"go.opentelemetry.io/otel/codes"
+	sdktrace "go.opentelemetry.io/otel/sdk/trace"
+)
+
+import (
+	"github.com/apache/dubbo-go-samples/observability/integration/internal/tracefields"
+	observability "github.com/apache/dubbo-go-samples/observability/integration/proto"
+)
+
+var (
+	requests    = flag.Int("requests", 5, "number of requests to send; 0 runs until interrupted")
+	interval    = flag.Duration("interval", time.Second, "delay between requests")
+	timeout     = flag.Duration("timeout", 0, "per-request timeout; 0 disables the timeout")
+	cancelAfter = flag.Duration("cancel-after", 0, "cancel each request after this duration; 0 disables cancellation")
+)
+
+func traceOptions() []trace.Option {
+	return []trace.Option{
+		trace.WithEnabled(),
+		trace.WithOtlpHttpExporter(),
+		trace.WithW3cPropagator(),
+		trace.WithAlwaysMode(),
+		trace.WithEndpoint(getEnv("DUBBO_OBSERVABILITY_OTLP_ENDPOINT", "127.0.0.1:4318")),
+		trace.WithInsecure(),
+	}
+}
+
+func metricsOptions() []metrics.Option {
+	port, err := strconv.Atoi(getEnv("DUBBO_OBSERVABILITY_METRICS_PORT", "9098"))
+	if err != nil {
+		port = 9098
+	}
+	return []metrics.Option{
+		metrics.WithEnabled(),
+		metrics.WithPrometheus(),
+		metrics.WithPrometheusExporterEnabled(),
+		metrics.WithRegistryEnabled(),
+		metrics.WithMetadataEnabled(),
+		metrics.WithPort(port),
+		metrics.WithPath("/prometheus"),
+	}
+}
+
+func registryOptions() []registry.Option {
+	return []registry.Option{
+		registry.WithNacos(),
+		registry.WithAddress(getEnv("DUBBO_OBSERVABILITY_REGISTRY_ADDRESS", "127.0.0.1:8848")),
+	}
+}
+
+func getEnv(key, fallback string) string {
+	if value := os.Getenv(key); value != "" {
+		return value
+	}
+	return fallback
+}
+
+func main() {
+	flag.Parse()
+
+	ins, err := dubbo.NewInstance(
+		dubbo.WithName("dubbo-observability-client"),
+		dubbo.WithRegistry(registryOptions()...),
+		dubbo.WithTracing(traceOptions()...),
+		dubbo.WithMetrics(metricsOptions()...),
+		dubbo.WithLogger(
+			dubbolog.WithZap(),
+			dubbolog.WithLevel("debug"),
+		),
+	)
+	if err != nil {
+		panic(err)
+	}
+
+	cli, err := ins.NewClient()
+	if err != nil {
+		panic(err)
+	}
+
+	svc, err := observability.NewGreetService(cli)
+	if err != nil {
+		panic(err)
+	}
+
+	tracer := otel.Tracer("dubbo-observability-client")
+	unexpectedErrors := 0
+
+	for i := 1; *requests == 0 || i <= *requests; i++ {
+		requestCtx := context.Background()
+		cancel := context.CancelFunc(func() {})
+		if *timeout > 0 {
+			requestCtx, cancel = context.WithTimeout(requestCtx, *timeout)
+		}
+		var cancelTimer *time.Timer
+		if *cancelAfter > 0 {
+			parentCancel := cancel
+			var cancelRequest context.CancelFunc
+			requestCtx, cancelRequest = context.WithCancel(requestCtx)
+			cancel = func() {
+				cancelRequest()
+				parentCancel()
+			}
+			cancelTimer = time.AfterFunc(*cancelAfter, cancelRequest)
+		}
+		ctx, span := tracer.Start(requestCtx, "observability.request")
+		name := fmt.Sprintf("request-%d", i)
+		if i%5 == 0 {
+			name = "error"
+		}
+		logger.Infof("sending greet request: name=%s%s", name, tracefields.Fields(ctx))
+
+		resp, callErr := svc.Greet(ctx, &observability.GreetRequest{Name: name})
+		if callErr != nil {
+			span.RecordError(callErr)
+			span.SetStatus(codes.Error, callErr.Error())
+			logger.Errorf("greet request failed: %v%s", callErr, tracefields.Fields(ctx))
+			if name != "error" && *timeout == 0 && *cancelAfter == 0 {

Review Comment:
   已修复:普通请求校验 `resp` 非空且 greeting 精确为 `hello <name>`;forced-error 请求由服务端返回 typed `CodeAborted` 错误,客户端要求 `callErr` 非空且错误码为 `CodeAborted`,所有不匹配累计为失败并退出。校验逻辑抽到 `internal/verify` 包,新增变异测试覆盖 greeting 错误、nil 响应、意外错误、缺失 error 分支(forced-error 请求误成功)及错误码不符等场景。



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@dubbo.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@dubbo.apache.org
For additional commands, e-mail: notifications-help@dubbo.apache.org


Re: [PR] feat(observability): add end-to-end sample [dubbo-go-samples]

Posted by "Alanxtl (via GitHub)" <gi...@apache.org>.
Alanxtl commented on PR #1128:
URL: https://github.com/apache/dubbo-go-samples/pull/1128#issuecomment-5166877084

   把dubbo-go-samples/metrics路径改为observability  然后放到里面吧
   dubbo-go-samples/metrics路径下面已经有一个差不多的例子了


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@dubbo.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@dubbo.apache.org
For additional commands, e-mail: notifications-help@dubbo.apache.org


Re: [PR] feat(observability): add end-to-end sample [dubbo-go-samples]

Posted by "Tsukikage7 (via GitHub)" <gi...@apache.org>.
Tsukikage7 commented on PR #1128:
URL: https://github.com/apache/dubbo-go-samples/pull/1128#issuecomment-5167894430

   @Alanxtl Thanks for the clarification. I checked the current diff and the new end-to-end sample is already under `observability/`; the existing `metrics/` samples remain unchanged.
   
   I also added an explicit directory-boundary note to both `observability/README.md` and `observability/README_CN.md` so the sample is clearly separated from the existing Metrics examples. The change was pushed as `9d3a6a6e` (`docs(observability): clarify sample directory boundary`).
   
   `go test ./observability/...`, `go vet ./observability/...`, and `git diff --check` pass. Please let me know if there is any additional path or scope adjustment needed.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@dubbo.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@dubbo.apache.org
For additional commands, e-mail: notifications-help@dubbo.apache.org


Re: [PR] feat(observability): add end-to-end sample [dubbo-go-samples]

Posted by "Tsukikage7 (via GitHub)" <gi...@apache.org>.
Tsukikage7 commented on code in PR #1128:
URL: https://github.com/apache/dubbo-go-samples/pull/1128#discussion_r3734218788


##########
observability/integration/README_CN.md:
##########


Review Comment:
   已按意见处理,并同步修改英文版 README:
   
   - 删除第 7-8 行的兄弟样例说明;
   - 删除第 20-22 行的样例定位说明;
   - 删除本地 `dubbo-go` workspace、验证范围、故障恢复演练和边界说明整段;
   - 英文版同步删除对应内容。
   
   提交:`9dbe1050`



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@dubbo.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@dubbo.apache.org
For additional commands, e-mail: notifications-help@dubbo.apache.org


Re: [PR] feat(observability): add end-to-end sample [dubbo-go-samples]

Posted by "Tsukikage7 (via GitHub)" <gi...@apache.org>.
Tsukikage7 commented on code in PR #1128:
URL: https://github.com/apache/dubbo-go-samples/pull/1128#discussion_r3728199910


##########
observability/integration/go-client/cmd/main.go:
##########
@@ -0,0 +1,180 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package main
+
+import (
+	"context"
+	"flag"
+	"fmt"
+	"os"
+	"strconv"
+	"time"
+)
+
+import (
+	"dubbo.apache.org/dubbo-go/v3"
+	_ "dubbo.apache.org/dubbo-go/v3/imports"
+	dubbolog "dubbo.apache.org/dubbo-go/v3/logger"
+	"dubbo.apache.org/dubbo-go/v3/metrics"
+	"dubbo.apache.org/dubbo-go/v3/otel/trace"
+	"dubbo.apache.org/dubbo-go/v3/registry"
+
+	"github.com/dubbogo/gost/log/logger"
+
+	"go.opentelemetry.io/otel"
+	"go.opentelemetry.io/otel/codes"
+	sdktrace "go.opentelemetry.io/otel/sdk/trace"
+)
+
+import (
+	"github.com/apache/dubbo-go-samples/observability/integration/internal/tracefields"
+	observability "github.com/apache/dubbo-go-samples/observability/integration/proto"
+)
+
+var (
+	requests    = flag.Int("requests", 5, "number of requests to send; 0 runs until interrupted")
+	interval    = flag.Duration("interval", time.Second, "delay between requests")
+	timeout     = flag.Duration("timeout", 0, "per-request timeout; 0 disables the timeout")
+	cancelAfter = flag.Duration("cancel-after", 0, "cancel each request after this duration; 0 disables cancellation")
+)
+
+func traceOptions() []trace.Option {
+	return []trace.Option{
+		trace.WithEnabled(),
+		trace.WithOtlpHttpExporter(),
+		trace.WithW3cPropagator(),
+		trace.WithAlwaysMode(),
+		trace.WithEndpoint(getEnv("DUBBO_OBSERVABILITY_OTLP_ENDPOINT", "127.0.0.1:4318")),
+		trace.WithInsecure(),
+	}
+}
+
+func metricsOptions() []metrics.Option {
+	port, err := strconv.Atoi(getEnv("DUBBO_OBSERVABILITY_METRICS_PORT", "9098"))
+	if err != nil {
+		port = 9098
+	}
+	return []metrics.Option{
+		metrics.WithEnabled(),
+		metrics.WithPrometheus(),
+		metrics.WithPrometheusExporterEnabled(),
+		metrics.WithRegistryEnabled(),
+		metrics.WithMetadataEnabled(),
+		metrics.WithPort(port),
+		metrics.WithPath("/prometheus"),
+	}
+}
+
+func registryOptions() []registry.Option {
+	return []registry.Option{
+		registry.WithNacos(),
+		registry.WithAddress(getEnv("DUBBO_OBSERVABILITY_REGISTRY_ADDRESS", "127.0.0.1:8848")),
+	}
+}
+
+func getEnv(key, fallback string) string {
+	if value := os.Getenv(key); value != "" {
+		return value
+	}
+	return fallback
+}
+
+func main() {
+	flag.Parse()
+
+	ins, err := dubbo.NewInstance(
+		dubbo.WithName("dubbo-observability-client"),
+		dubbo.WithRegistry(registryOptions()...),
+		dubbo.WithTracing(traceOptions()...),
+		dubbo.WithMetrics(metricsOptions()...),
+		dubbo.WithLogger(
+			dubbolog.WithZap(),
+			dubbolog.WithLevel("debug"),
+		),
+	)
+	if err != nil {
+		panic(err)
+	}
+
+	cli, err := ins.NewClient()
+	if err != nil {
+		panic(err)
+	}
+
+	svc, err := observability.NewGreetService(cli)
+	if err != nil {
+		panic(err)
+	}
+
+	tracer := otel.Tracer("dubbo-observability-client")
+	unexpectedErrors := 0
+
+	for i := 1; *requests == 0 || i <= *requests; i++ {
+		requestCtx := context.Background()
+		cancel := context.CancelFunc(func() {})
+		if *timeout > 0 {
+			requestCtx, cancel = context.WithTimeout(requestCtx, *timeout)
+		}
+		var cancelTimer *time.Timer
+		if *cancelAfter > 0 {
+			parentCancel := cancel
+			var cancelRequest context.CancelFunc
+			requestCtx, cancelRequest = context.WithCancel(requestCtx)
+			cancel = func() {
+				cancelRequest()
+				parentCancel()
+			}
+			cancelTimer = time.AfterFunc(*cancelAfter, cancelRequest)
+		}
+		ctx, span := tracer.Start(requestCtx, "observability.request")
+		name := fmt.Sprintf("request-%d", i)
+		if i%5 == 0 {
+			name = "error"
+		}
+		logger.Infof("sending greet request: name=%s%s", name, tracefields.Fields(ctx))
+
+		resp, callErr := svc.Greet(ctx, &observability.GreetRequest{Name: name})
+		if callErr != nil {
+			span.RecordError(callErr)
+			span.SetStatus(codes.Error, callErr.Error())
+			logger.Errorf("greet request failed: %v%s", callErr, tracefields.Fields(ctx))
+			if name != "error" && *timeout == 0 && *cancelAfter == 0 {

Review Comment:
   补充复核:forced-error 的最终稳定分类已调整为 Triple 现有的 `CodeBizError`(`code_17`),不再使用 `CodeAborted`,与样例业务错误语义和 PR 描述保持一致。真实 consumer/provider 调用已验证客户端收到 `code_17`,错误分支和变异测试均通过。



##########
integrate_test.sh:
##########
@@ -447,11 +577,16 @@ main() {
   fi
 
   start_go_server
+  start_sample_dependencies
   start_aux_go_servers
 
   run_go_client
   run_java_client_if_present
 
+  if [ -n "$SAMPLE_COMPOSE_FILE" ]; then
+    stop_sample_dependencies

Review Comment:
   补充复核:最初的 Grafana 校验未带认证,实际运行会返回 401。现已显式配置本地 `admin/admin`,校验固定 datasource UID、datasource health、通过 Grafana datasource proxy 执行关键 PromQL,并确认 dashboard 已加载。四项检查改为同一轮并发轮询,避免前一项耗尽后续重试时间。完整 `./integrate_test.sh observability/integration` 已验证通过。



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@dubbo.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@dubbo.apache.org
For additional commands, e-mail: notifications-help@dubbo.apache.org


Re: [PR] feat(observability): add end-to-end sample [dubbo-go-samples]

Posted by "Alanxtl (via GitHub)" <gi...@apache.org>.
Alanxtl commented on code in PR #1128:
URL: https://github.com/apache/dubbo-go-samples/pull/1128#discussion_r3725391176


##########
observability/integration/README_CN.md:
##########
@@ -0,0 +1,202 @@
+# Dubbo Go 可观测性集成验证样例
+
+[English](README.md) | 中文
+
+这个样例是一个集成验证样例,把 Dubbo Go 现有的可观测性能力组合成一条可运行链路:
+
+现有 Metrics 和 Kubernetes 探针样例现在作为兄弟样例统一放在这个
+`observability/` 目录中。本端到端样例专注于跨信号集成和验证,不替换这些已有样例。

Review Comment:
   ```suggestion
   ```



##########
observability/integration/README_CN.md:
##########
@@ -0,0 +1,202 @@
+# Dubbo Go 可观测性集成验证样例
+
+[English](README.md) | 中文
+
+这个样例是一个集成验证样例,把 Dubbo Go 现有的可观测性能力组合成一条可运行链路:
+
+现有 Metrics 和 Kubernetes 探针样例现在作为兄弟样例统一放在这个
+`observability/` 目录中。本端到端样例专注于跨信号集成和验证,不替换这些已有样例。
+
+```text
+Nacos 注册中心
+       |
+Dubbo Triple 客户端 -> Dubbo Triple 服务端
+        |                    |
+        +-- Trace --> OpenTelemetry Collector --> Jaeger
+        +-- Metrics ---------------------------> Prometheus -> Grafana
+        +-- 日志 ------------------------------> stdout 中的 trace_id / span_id
+```
+
+这个样例刻意保持较小,定位是“现有能力的集成验证”,不是核心可观测性实现,
+也不是第二个业务商城。单项能力验证完成后,再使用 `online_boutique` 做更复杂的
+业务链路验收。

Review Comment:
   ```suggestion
   ```



##########
observability/integration/README_CN.md:
##########
@@ -0,0 +1,202 @@
+# Dubbo Go 可观测性集成验证样例
+
+[English](README.md) | 中文
+
+这个样例是一个集成验证样例,把 Dubbo Go 现有的可观测性能力组合成一条可运行链路:
+
+现有 Metrics 和 Kubernetes 探针样例现在作为兄弟样例统一放在这个
+`observability/` 目录中。本端到端样例专注于跨信号集成和验证,不替换这些已有样例。
+
+```text
+Nacos 注册中心
+       |
+Dubbo Triple 客户端 -> Dubbo Triple 服务端
+        |                    |
+        +-- Trace --> OpenTelemetry Collector --> Jaeger
+        +-- Metrics ---------------------------> Prometheus -> Grafana
+        +-- 日志 ------------------------------> stdout 中的 trace_id / span_id
+```
+
+这个样例刻意保持较小,定位是“现有能力的集成验证”,不是核心可观测性实现,
+也不是第二个业务商城。单项能力验证完成后,再使用 `online_boutique` 做更复杂的
+业务链路验收。
+
+## 目录结构
+
+```text
+observability/
+├── integration/                    # 本端到端集成验证样例
+│   ├── go-client/cmd/main.go       # Triple 消费端和请求生成器
+│   ├── go-server/cmd/main.go       # Triple 提供端,包含可复现错误路径
+│   ├── proto/                      # 独立的服务契约和生成代码
+│   ├── docker-compose.yaml         # Nacos、Collector、Jaeger、Prometheus、Grafana
+│   ├── otel-collector-config.yaml  # 转发到 Jaeger 的 OTLP Collector 管道
+│   ├── prometheus.yml              # 抓取两个本地 Metrics endpoint
+│   └── grafana/                    # 自动配置数据源和 Dashboard
+├── probe/                          # Kubernetes 存活、就绪和启动探针样例
+└── prometheus_grafana/             # Push/Pull Metrics 和 Grafana 样例
+```
+
+## 前置条件
+
+- Go 1.25 或更新版本;
+- Docker 和 Compose;
+- 本仓库的本地 checkout。
+
+Compose 中固定了 Nacos `v2.5.2`、OpenTelemetry Collector `0.104.0`、Jaeger
+`1.57`、Prometheus `v2.55.1` 和 Grafana `11.2.0`,以便使用确定的工具链复现
+这条验证链路。
+
+按仓库标准进行集成验证时,先启动根目录依赖,再使用根级集成测试入口。该入口会
+通过根目录 Makefile 构建和停止 `go-server/cmd`,运行 `go-client/cmd`,并启动本样例
+额外声明的可观测性服务:
+
+```bash
+docker compose -f docker-compose.yml up -d
+./integrate_test.sh observability/integration
+```
+
+本样例也已经加入 `start_integrate_test.sh` 的集成测试列表。
+
+## 启动样例
+
+启动 Nacos、OpenTelemetry Collector、Jaeger、Prometheus 和 Grafana:
+
+```bash
+cd observability/integration
+docker compose up -d
+cd ../..
+```
+
+启动应用前,先等待 Nacos 健康:
+
+```bash
+docker compose -f observability/integration/docker-compose.yaml ps
+```
+
+服务端会注册到 Nacos,客户端从 Nacos 发现服务。默认注册中心地址是
+`127.0.0.1:8848`;如果注册中心在其他主机,可以通过
+`DUBBO_OBSERVABILITY_REGISTRY_ADDRESS` 覆盖。
+
+Grafana 默认映射到标准宿主机 `3000` 端口。如果你的本地环境已经占用
+`3000`,请停止冲突进程;样例本身保持仓库统一的标准端口映射。
+
+在第二个终端启动 Dubbo 服务端:
+
+```bash
+go run ./observability/integration/go-server/cmd
+```
+
+在第三个终端启动客户端。客户端每 5 个请求会故意发送一个 `error` 请求,
+用于在 Metrics、Trace 和日志中检查失败路径:
+
+```bash
+go run ./observability/integration/go-client/cmd -requests 20 -interval 500ms
+```
+
+如果希望持续产生流量以观察 Dashboard,请传入 `-requests 0`:
+
+```bash
+go run ./observability/integration/go-client/cmd -requests 0 -interval 500ms
+```
+
+如果要复现超时,可以设置一个小于服务端故意延迟 20 毫秒的请求超时:
+
+```bash
+go run ./observability/integration/go-client/cmd -requests 5 -timeout 1ms
+```
+
+如果要复现显式取消而不是 deadline 到期:
+
+```bash
+go run ./observability/integration/go-client/cmd -requests 5 -cancel-after 1ms
+```
+
+客户端默认执行有限次数,这样可以直接接入仓库集成测试;如果希望持续产生流量观察
+Dashboard,请显式传入 `-requests 0`。
+
+测试完成后使用 `Ctrl-C` 停止客户端和服务端,再回收监控栈:
+
+```bash
+docker compose -f observability/integration/docker-compose.yaml down
+```
+
+## 查看信号
+
+- Jaeger:<http://localhost:16686>
+- Nacos:<http://localhost:8848/nacos>
+- Prometheus:<http://localhost:9090>
+- Grafana:<http://localhost:3000>
+- 服务端 Metrics:<http://localhost:9099/prometheus>
+- 客户端 Metrics:<http://localhost:9098/prometheus>
+
+Grafana 会自动配置 Prometheus 数据源和 `Dubbo Go Observability` Dashboard。
+应用日志保留在客户端和服务端终端中;每条应用日志都会读取当前 OpenTelemetry
+`SpanContext`,并包含和 Jaeger 中相同的 `trace_id`、`span_id`。这个样例刻意只使用
+已发布的 module API;Dubbo-Go 的 `CtxLogger` 集成由专门的
+`logger/trace-integration` 样例覆盖,这里不重复实现。
+
+## 使用本地 dubbo-go 工作树
+
+默认情况下,样例使用仓库根目录 module。要测试未提交的本地 Dubbo Go 修改,
+请创建一个同时包含本地 `dubbo-go` module 和本仓库的临时 Go workspace,然后使用
+`GOWORK` 执行命令:
+
+```bash
+GOWORK=/tmp/dubbo-go-observability.go.work \
+  go run ./observability/integration/go-server/cmd
+
+GOWORK=/tmp/dubbo-go-observability.go.work \
+  go run ./observability/integration/go-client/cmd -requests 20
+```
+
+客户端通过 Nacos 发现服务,而不是使用写死的服务端地址。如果注册中心运行在其他
+主机,可以通过 `DUBBO_OBSERVABILITY_REGISTRY_ADDRESS` 覆盖注册中心地址。
+
+临时 workspace 需要包含:
+
+```text
+/path/to/dubbo-go
+/path/to/dubbo-go-samples
+```
+
+这样不需要把本地文件系统 `replace` 指令写入正式 sample module。
+
+## 验证范围
+
+- 通过 Nacos 服务发现完成 Dubbo Triple consumer 到 provider 的 W3C Trace Context 传播;
+- OTLP HTTP 经 OpenTelemetry Collector 导出到 Jaeger;
+- consumer 和 provider 的 Prometheus RPC Metrics;
+- Grafana 中的成功、失败、不可用、在途请求、注册中心和延迟信号可视化;
+- 包含当前 Trace 标识的应用日志;
+- 同一条流程中的成功请求、业务错误、超时和恢复;
+- 显式请求取消和恢复;
+- 文档化注册中心不可用和服务端不可用演练;
+- 使用未提交的本地 `dubbo-go` 工作树进行测试。
+
+## 故障与恢复演练
+
+样例通过运行时操作复现故障,不向 `dubbo-go` 核心代码加入样例专用的故障逻辑:
+
+1. 服务端业务错误:每第五个请求使用 `error` 作为 name。
+2. 请求超时:使用 `-timeout 1ms` 启动客户端。
+3. 请求取消:使用 `-cancel-after 1ms` 启动客户端。
+4. 服务端不可用:停止服务端进程后发送请求,再重启服务端,确认服务发现和请求恢复。
+5. 注册中心不可用:执行 `docker compose -f observability/integration/docker-compose.yaml stop nacos` 后发送请求,再执行
+   `docker compose -f observability/integration/docker-compose.yaml start nacos`;必要时重启服务端和客户端。
+
+每次演练都检查应用日志、Jaeger 中的 Trace、Consumer/Provider Metrics endpoint
+以及 Grafana Dashboard。
+
+## 边界说明
+
+这个样例只验证当前 `dubbo-go` 能力在一条基于注册中心的 Consumer/Provider 链路
+以及外围遥测管道中的协同工作,不做以下事情:
+
+- 不新增或修改核心 Metrics、Trace、Logger、Metadata 语义;
+- 不替代现有可观测性 Issues 中已经在推进的实现;
+- 不宣称取得 `dubbo-go` 核心代码的 ownership;
+- 不把样例扩展成第二个业务应用。
+
+核心实现应放在 `dubbo-go` 中,并在和对应维护者、贡献者完成协调后,拆分为独立、
+可单独审查的 PR。

Review Comment:
   ```suggestion
   ```



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@dubbo.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@dubbo.apache.org
For additional commands, e-mail: notifications-help@dubbo.apache.org


Re: [PR] feat(observability): add end-to-end sample [dubbo-go-samples]

Posted by "Alanxtl (via GitHub)" <gi...@apache.org>.
Alanxtl commented on code in PR #1128:
URL: https://github.com/apache/dubbo-go-samples/pull/1128#discussion_r3733577051


##########
observability/integration/README_CN.md:
##########


Review Comment:
   7-8行删掉 20-22行删掉 139-202行删掉
   英文版做对应修改



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@dubbo.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@dubbo.apache.org
For additional commands, e-mail: notifications-help@dubbo.apache.org


Re: [PR] feat(observability): add end-to-end sample [dubbo-go-samples]

Posted by "Tsukikage7 (via GitHub)" <gi...@apache.org>.
Tsukikage7 commented on PR #1128:
URL: https://github.com/apache/dubbo-go-samples/pull/1128#issuecomment-5165868182

   Additional local integration evidence:
   
   The provider log shows trace-correlated successful requests and the deliberately forced business error. The consumer log shows the matching `name=error` request and `code_17` response. The error is intentional and demonstrates error-to-trace correlation.
   
   ![provider trace-correlated logs](https://github.com/user-attachments/assets/f8320ff7-05cf-4dbe-a8ac-e1bb7f13850f)
   
   ![consumer business error](https://github.com/user-attachments/assets/0e32adfb-afb9-41dc-bfd0-9fbd6f200d79)


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@dubbo.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@dubbo.apache.org
For additional commands, e-mail: notifications-help@dubbo.apache.org


Re: [PR] feat(observability): add end-to-end sample [dubbo-go-samples]

Posted by "AlexStocks (via GitHub)" <gi...@apache.org>.
AlexStocks commented on code in PR #1128:
URL: https://github.com/apache/dubbo-go-samples/pull/1128#discussion_r3710897256


##########
integrate_test.sh:
##########
@@ -447,11 +577,16 @@ main() {
   fi
 
   start_go_server
+  start_sample_dependencies
   start_aux_go_servers
 
   run_go_client
   run_java_client_if_present
 
+  if [ -n "$SAMPLE_COMPOSE_FILE" ]; then
+    stop_sample_dependencies

Review Comment:
   [P1] 停止依赖前验证可观测性链路语义
   
   当前流程在客户端结束后直接停止 telemetry stack;启动阶段只探测 Collector `4318` 和 Prometheus `9090` 的 TCP 端口。当前 Head 的 Build And Integration 日志也只出现 RPC 响应、trace ID 和 forced error,随后即报告 sample completed,没有查询 Prometheus targets/关键指标、Jaeger 中同一 trace 的 consumer/provider spans,或 Grafana provisioning。因此 scrape target、OTLP endpoint、跨服务传播或 dashboard 查询失效时 CI 仍会绿色,与本 PR 声明的端到端验证不符。请在 teardown 前增加带超时的 HTTP 语义断言,并让错误 target、错误 OTLP endpoint或缺失 provider span 必须非零退出。



##########
observability/integration/go-client/cmd/main.go:
##########
@@ -0,0 +1,180 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package main
+
+import (
+	"context"
+	"flag"
+	"fmt"
+	"os"
+	"strconv"
+	"time"
+)
+
+import (
+	"dubbo.apache.org/dubbo-go/v3"
+	_ "dubbo.apache.org/dubbo-go/v3/imports"
+	dubbolog "dubbo.apache.org/dubbo-go/v3/logger"
+	"dubbo.apache.org/dubbo-go/v3/metrics"
+	"dubbo.apache.org/dubbo-go/v3/otel/trace"
+	"dubbo.apache.org/dubbo-go/v3/registry"
+
+	"github.com/dubbogo/gost/log/logger"
+
+	"go.opentelemetry.io/otel"
+	"go.opentelemetry.io/otel/codes"
+	sdktrace "go.opentelemetry.io/otel/sdk/trace"
+)
+
+import (
+	"github.com/apache/dubbo-go-samples/observability/integration/internal/tracefields"
+	observability "github.com/apache/dubbo-go-samples/observability/integration/proto"
+)
+
+var (
+	requests    = flag.Int("requests", 5, "number of requests to send; 0 runs until interrupted")
+	interval    = flag.Duration("interval", time.Second, "delay between requests")
+	timeout     = flag.Duration("timeout", 0, "per-request timeout; 0 disables the timeout")
+	cancelAfter = flag.Duration("cancel-after", 0, "cancel each request after this duration; 0 disables cancellation")
+)
+
+func traceOptions() []trace.Option {
+	return []trace.Option{
+		trace.WithEnabled(),
+		trace.WithOtlpHttpExporter(),
+		trace.WithW3cPropagator(),
+		trace.WithAlwaysMode(),
+		trace.WithEndpoint(getEnv("DUBBO_OBSERVABILITY_OTLP_ENDPOINT", "127.0.0.1:4318")),
+		trace.WithInsecure(),
+	}
+}
+
+func metricsOptions() []metrics.Option {
+	port, err := strconv.Atoi(getEnv("DUBBO_OBSERVABILITY_METRICS_PORT", "9098"))
+	if err != nil {
+		port = 9098
+	}
+	return []metrics.Option{
+		metrics.WithEnabled(),
+		metrics.WithPrometheus(),
+		metrics.WithPrometheusExporterEnabled(),
+		metrics.WithRegistryEnabled(),
+		metrics.WithMetadataEnabled(),
+		metrics.WithPort(port),
+		metrics.WithPath("/prometheus"),
+	}
+}
+
+func registryOptions() []registry.Option {
+	return []registry.Option{
+		registry.WithNacos(),
+		registry.WithAddress(getEnv("DUBBO_OBSERVABILITY_REGISTRY_ADDRESS", "127.0.0.1:8848")),
+	}
+}
+
+func getEnv(key, fallback string) string {
+	if value := os.Getenv(key); value != "" {
+		return value
+	}
+	return fallback
+}
+
+func main() {
+	flag.Parse()
+
+	ins, err := dubbo.NewInstance(
+		dubbo.WithName("dubbo-observability-client"),
+		dubbo.WithRegistry(registryOptions()...),
+		dubbo.WithTracing(traceOptions()...),
+		dubbo.WithMetrics(metricsOptions()...),
+		dubbo.WithLogger(
+			dubbolog.WithZap(),
+			dubbolog.WithLevel("debug"),
+		),
+	)
+	if err != nil {
+		panic(err)
+	}
+
+	cli, err := ins.NewClient()
+	if err != nil {
+		panic(err)
+	}
+
+	svc, err := observability.NewGreetService(cli)
+	if err != nil {
+		panic(err)
+	}
+
+	tracer := otel.Tracer("dubbo-observability-client")
+	unexpectedErrors := 0
+
+	for i := 1; *requests == 0 || i <= *requests; i++ {
+		requestCtx := context.Background()
+		cancel := context.CancelFunc(func() {})
+		if *timeout > 0 {
+			requestCtx, cancel = context.WithTimeout(requestCtx, *timeout)
+		}
+		var cancelTimer *time.Timer
+		if *cancelAfter > 0 {
+			parentCancel := cancel
+			var cancelRequest context.CancelFunc
+			requestCtx, cancelRequest = context.WithCancel(requestCtx)
+			cancel = func() {
+				cancelRequest()
+				parentCancel()
+			}
+			cancelTimer = time.AfterFunc(*cancelAfter, cancelRequest)
+		}
+		ctx, span := tracer.Start(requestCtx, "observability.request")
+		name := fmt.Sprintf("request-%d", i)
+		if i%5 == 0 {
+			name = "error"
+		}
+		logger.Infof("sending greet request: name=%s%s", name, tracefields.Fields(ctx))
+
+		resp, callErr := svc.Greet(ctx, &observability.GreetRequest{Name: name})
+		if callErr != nil {
+			span.RecordError(callErr)
+			span.SetStatus(codes.Error, callErr.Error())
+			logger.Errorf("greet request failed: %v%s", callErr, tracefields.Fields(ctx))
+			if name != "error" && *timeout == 0 && *cancelAfter == 0 {

Review Comment:
   [P1] 精确校验成功响应和强制业务错误
   
   当前计数只覆盖“普通请求发生 RPC error”:普通成功没有断言 `resp != nil` 及 `hello <name>`,`name=error` 时任意错误都被接受,甚至错误地返回成功也不会计为失败。因此 provider 返回空/错误 greeting,或删除 `code_17` 分支,客户端仍可 0 退出,现有集成测试无法发现业务合同回归。请对普通请求精确校验 greeting;对 forced-error 请求要求 `callErr != nil` 并校验稳定错误码/分类,把所有不匹配累计为失败并补对应变异测试。



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: notifications-unsubscribe@dubbo.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@dubbo.apache.org
For additional commands, e-mail: notifications-help@dubbo.apache.org