Skip to content

Commit 7f61cd5

Browse files
nareshzrahul2393harshachinta
authored
feat(spanner): Add x-goog-spanner-end-to-end-tracing header for requests to Spanner (#10241)
* Add x-goog-spanner-end-to-end-tracing header for requests to SpanFE * resolve comments * rename spanner option for end to end tracing * minor fix * add comments for server side tracing requirement * add environment variable to enable server side tracing * Rename server side tracing to spanner tracing * Rename spanner tracing to end to end tracing * fix comments * fix tests --------- Co-authored-by: rahul2393 <[email protected]> Co-authored-by: Sri Harsha CH <[email protected]> Co-authored-by: rahul yadav <[email protected]>
1 parent b98195d commit 7f61cd5

File tree

2 files changed

+76
-0
lines changed

2 files changed

+76
-0
lines changed

spanner/client.go

+19
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,10 @@ const (
6868

6969
requestsCompressionHeader = "x-response-encoding"
7070

71+
// endToEndTracingHeader is the name of the metadata header if client
72+
// has opted-in for the creation of trace spans on the Spanner layer.
73+
endToEndTracingHeader = "x-goog-spanner-end-to-end-tracing"
74+
7175
// numChannels is the default value for NumChannels of client.
7276
numChannels = 4
7377
)
@@ -337,6 +341,14 @@ type ClientConfig struct {
337341
DirectedReadOptions *sppb.DirectedReadOptions
338342

339343
OpenTelemetryMeterProvider metric.MeterProvider
344+
345+
// EnableEndToEndTracing indicates whether end to end tracing is enabled or not. If
346+
// it is enabled, trace spans will be created at Spanner layer. Enabling end to end
347+
// tracing requires OpenTelemetry to be set up. Simply enabling this option won't
348+
// generate traces at Spanner layer.
349+
//
350+
// Default: false
351+
EnableEndToEndTracing bool
340352
}
341353

342354
type openTelemetryConfig struct {
@@ -452,6 +464,13 @@ func newClientWithConfig(ctx context.Context, database string, config ClientConf
452464
if config.Compression == gzip.Name {
453465
md.Append(requestsCompressionHeader, gzip.Name)
454466
}
467+
// Append end to end tracing header if SPANNER_ENABLE_END_TO_END_TRACING
468+
// environment variable has been set or client has passed the opt-in
469+
// option in ClientConfig.
470+
endToEndTracingEnvironmentVariable := os.Getenv("SPANNER_ENABLE_END_TO_END_TRACING")
471+
if config.EnableEndToEndTracing || endToEndTracingEnvironmentVariable == "true" {
472+
md.Append(endToEndTracingHeader, "true")
473+
}
455474

456475
// Create a session client.
457476
sc := newSessionClient(pool, database, config.UserAgent, sessionLabels, config.DatabaseRole, config.DisableRouteToLeader, md, config.BatchTimeout, config.Logger, config.CallOptions)

spanner/client_test.go

+57
Original file line numberDiff line numberDiff line change
@@ -4387,6 +4387,63 @@ func TestClient_WithGRPCConnectionPoolAndNumChannels_Misconfigured(t *testing.T)
43874387
}
43884388
}
43894389

4390+
func TestClient_EndToEndTracingHeader(t *testing.T) {
4391+
tests := []struct {
4392+
name string
4393+
endToEndTracingEnv string
4394+
enableEndToEndTracing bool
4395+
wantEndToEndTracing bool
4396+
}{
4397+
{
4398+
name: "when end-to-end tracing is enabled via config",
4399+
enableEndToEndTracing: true,
4400+
wantEndToEndTracing: true,
4401+
endToEndTracingEnv: "false",
4402+
},
4403+
{
4404+
name: "when end-to-end tracing is enabled via env",
4405+
enableEndToEndTracing: false,
4406+
wantEndToEndTracing: true,
4407+
endToEndTracingEnv: "true",
4408+
},
4409+
{
4410+
name: "when end-to-end tracing is disabled",
4411+
enableEndToEndTracing: false,
4412+
wantEndToEndTracing: false,
4413+
endToEndTracingEnv: "false",
4414+
},
4415+
}
4416+
4417+
for _, tt := range tests {
4418+
t.Run(tt.name, func(t *testing.T) {
4419+
t.Setenv("SPANNER_ENABLE_END_TO_END_TRACING", tt.endToEndTracingEnv)
4420+
4421+
server, opts, teardown := NewMockedSpannerInMemTestServer(t)
4422+
defer teardown()
4423+
config := ClientConfig{}
4424+
if tt.enableEndToEndTracing {
4425+
config.EnableEndToEndTracing = true
4426+
}
4427+
4428+
client, err := makeClientWithConfig(context.Background(), "projects/p/instances/i/databases/d", config, server.ServerAddress, opts...)
4429+
if err != nil {
4430+
t.Fatalf("failed to get a client: %v", err)
4431+
}
4432+
4433+
gotEndToEndTracing := false
4434+
for _, val := range client.sc.md.Get(endToEndTracingHeader) {
4435+
if val == "true" {
4436+
gotEndToEndTracing = true
4437+
}
4438+
}
4439+
4440+
if gotEndToEndTracing != tt.wantEndToEndTracing {
4441+
t.Fatalf("mismatch in client configuration for property EnableEndToEndTracing: got %v, want %v", gotEndToEndTracing, tt.wantEndToEndTracing)
4442+
}
4443+
})
4444+
}
4445+
}
4446+
43904447
func TestClient_WithCustomBatchTimeout(t *testing.T) {
43914448
t.Parallel()
43924449

0 commit comments

Comments
 (0)