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: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]