Repository: zeromicro/go-zero
Pull request #3219 (2023-05-06 11:29:12)

feat: add otlptracegrpc otlptracehttp headers support for Uptrace
fix: https://github.com/zeromicro/go-zero/issues/3218

codecov[bot]: ## [Codecov](https://app.codecov.io/gh/zeromicro/go-zero/pull/3219?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None) Report
> Merging [#3219](https://app.codecov.io/gh/zeromicro/go-zero/pull/3219?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None) (135e21c) into [master](https://app.codecov.io/gh/zeromicro/go-zero/commit/63368d8b0c7bb122f93bf88f649b3a49d1dff609?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None) (63368d8) will **decrease** coverage by `0.03%`.
> The diff coverage is `62.50%`.


| [Impacted Files](https://app.codecov.io/gh/zeromicro/go-zero/pull/3219?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None) | Coverage Δ | |
|---|---|---|
| [core/trace/agent.go](https://app.codecov.io/gh/zeromicro/go-zero/pull/3219?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None#diff-Y29yZS90cmFjZS9hZ2VudC5nbw==) | `85.89% <62.50%> (-6.53%)` | :arrow_down: |

... and [2 files with indirect coverage changes](https://app.codecov.io/gh/zeromicro/go-zero/pull/3219/indirect-changes?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None)

zcong1993: LGTM @kevwan 

Patch:
diff --git a/core/trace/agent.go b/core/trace/agent.go
index 939c1d9e..9b293e45 100644
--- a/core/trace/agent.go
+++ b/core/trace/agent.go
@@ -71,17 +71,29 @@ func createExporter(c Config) (sdktrace.SpanExporter, error) {
 		// endpoint can not reach.
 		// If the connection not dial success, the global otel ErrorHandler will catch error
 		// when reporting data like other exporters.
-		return otlptracegrpc.New(
-			context.Background(),
+		opts := []otlptracegrpc.Option{
 			otlptracegrpc.WithInsecure(),
 			otlptracegrpc.WithEndpoint(c.Endpoint),
+		}
+		if len(c.OtlpHeaders) > 0 {
+			opts = append(opts, otlptracegrpc.WithHeaders(c.OtlpHeaders))
+		}
+		return otlptracegrpc.New(
+			context.Background(),
+			opts...,
 		)
 	case kindOtlpHttp:
 		// Not support flexible configuration now.
-		return otlptracehttp.New(
-			context.Background(),
+		opts := []otlptracehttp.Option{
 			otlptracehttp.WithInsecure(),
 			otlptracehttp.WithEndpoint(c.Endpoint),
+		}
+		if len(c.OtlpHeaders) > 0 {
+			opts = append(opts, otlptracehttp.WithHeaders(c.OtlpHeaders))
+		}
+		return otlptracehttp.New(
+			context.Background(),
+			opts...,
 		)
 	default:
 		return nil, fmt.Errorf("unknown exporter: %s", c.Batcher)
diff --git a/core/trace/config.go b/core/trace/config.go
index 83c62c3c..9e6f7fb0 100644
--- a/core/trace/config.go
+++ b/core/trace/config.go
@@ -5,8 +5,9 @@ const TraceName = "go-zero"
 
 // A Config is an opentelemetry config.
 type Config struct {
-	Name     string  `json:",optional"`
-	Endpoint string  `json:",optional"`
-	Sampler  float64 `json:",default=1.0"`
-	Batcher  string  `json:",default=jaeger,options=jaeger|zipkin|otlpgrpc|otlphttp"`
+	Name        string            `json:",optional"`
+	Endpoint    string            `json:",optional"`
+	Sampler     float64           `json:",default=1.0"`
+	Batcher     string            `json:",default=jaeger,options=jaeger|zipkin|otlpgrpc|otlphttp"`
+	OtlpHeaders map[string]string `json:",optional"` // uptrace-dsn: 'http://project2_secret_token@localhost:14317/2'
 }
diff --git a/go.mod b/go.mod
index 1e424007..2b764a15 100644
--- a/go.mod
+++ b/go.mod
@@ -32,7 +32,7 @@ require (
 	go.opentelemetry.io/otel/trace v1.14.0
 	go.uber.org/automaxprocs v1.5.2
 	go.uber.org/goleak v1.2.1
-	golang.org/x/net v0.9.0
+	golang.org/x/net v0.10.0
 	golang.org/x/sys v0.8.0
 	golang.org/x/time v0.3.0
 	google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4
@@ -106,7 +106,7 @@ require (
 	golang.org/x/crypto v0.6.0 // indirect
 	golang.org/x/oauth2 v0.6.0 // indirect
 	golang.org/x/sync v0.1.0 // indirect
-	golang.org/x/term v0.7.0 // indirect
+	golang.org/x/term v0.8.0 // indirect
 	golang.org/x/text v0.9.0 // indirect
 	google.golang.org/appengine v1.6.7 // indirect
 	gopkg.in/inf.v0 v0.9.1 // indirect
diff --git a/go.sum b/go.sum
index a63f74bd..404d97e6 100644
--- a/go.sum
+++ b/go.sum
@@ -428,8 +428,8 @@ golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81R
 golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
 golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
 golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
-golang.org/x/net v0.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM=
-golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
+golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M=
+golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
 golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -487,8 +487,8 @@ golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBc
 golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
 golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
-golang.org/x/term v0.7.0 h1:BEvjmm5fURWqcfbSKTdpkDXYBrUS1c0m8agp14W48vQ=
-golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY=
+golang.org/x/term v0.8.0 h1:n5xxQn2i3PC0yLAbjTpNT85q/Kgzcr2gIoX9OrJUols=
+golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
 golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=


Test patch:
diff --git a/core/trace/agent_test.go b/core/trace/agent_test.go
index 853fa6ba..a3871a42 100644
--- a/core/trace/agent_test.go
+++ b/core/trace/agent_test.go
@@ -36,14 +36,20 @@ func TestStartAgent(t *testing.T) {
 		Batcher:  "otlp",
 	}
 	c5 := Config{
-		Name:     "grpc",
+		Name:     "otlpgrpc",
 		Endpoint: endpoint3,
 		Batcher:  kindOtlpGrpc,
+		OtlpHeaders: map[string]string{
+			"uptrace-dsn": "http://project2_secret_token@localhost:14317/2",
+		},
 	}
 	c6 := Config{
 		Name:     "otlphttp",
 		Endpoint: endpoint4,
 		Batcher:  kindOtlpHttp,
+		OtlpHeaders: map[string]string{
+			"uptrace-dsn": "http://project2_secret_token@localhost:14318/2",
+		},
 	}
 	c7 := Config{
 		Name:     "UDP",