Skip to content

Commit 106610d

Browse files
committed
feat(spanner): add setMetricsProjectId to fix metrics export
SpannerOptions.getProjectId() can resolve to the wrong project (e.g. host project on GKE), causing createServiceTimeSeries to fail with permission errors. Add resolveMetricsProjectId() which defaults to the database project and setMetricsProjectId(String) to allow explicit override when needed.
1 parent e0bdb6e commit 106610d

1 file changed

Lines changed: 26 additions & 3 deletions

File tree

java-spanner/google-cloud-spanner/src/main/java/com/google/cloud/spanner/SpannerOptions.java

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,7 @@ static GcpChannelPoolOptions mergeWithDefaultChannelPoolOptions(
306306
private final boolean enableExtendedTracing;
307307
private final boolean enableEndToEndTracing;
308308
private final String monitoringHost;
309+
private final String metricsProjectId;
309310
private final TransactionOptions defaultTransactionOptions;
310311
private final RequestOptions.ClientContext clientContext;
311312

@@ -991,6 +992,7 @@ protected SpannerOptions(Builder builder) {
991992
}
992993
enableEndToEndTracing = builder.enableEndToEndTracing;
993994
monitoringHost = builder.monitoringHost;
995+
metricsProjectId = builder.metricsProjectId;
994996
defaultTransactionOptions = builder.defaultTransactionOptions;
995997
clientContext = builder.clientContext;
996998
}
@@ -1251,6 +1253,7 @@ public static class Builder
12511253
private boolean enableBuiltInMetrics = SpannerOptions.environment.isEnableBuiltInMetrics();
12521254
private boolean enableLocationApi = SpannerOptions.environment.isEnableLocationApi();
12531255
private String monitoringHost = SpannerOptions.environment.getMonitoringHost();
1256+
private String metricsProjectId;
12541257
private SslContext mTLSContext = null;
12551258
private String experimentalHost = null;
12561259
private boolean usePlainText = false;
@@ -1360,6 +1363,7 @@ protected Builder() {
13601363
this.enableLocationApi = options.enableLocationApi;
13611364
this.enableEndToEndTracing = options.enableEndToEndTracing;
13621365
this.monitoringHost = options.monitoringHost;
1366+
this.metricsProjectId = options.metricsProjectId;
13631367
this.defaultTransactionOptions = options.defaultTransactionOptions;
13641368
this.clientContext = options.clientContext;
13651369
}
@@ -2033,6 +2037,17 @@ public Builder setMonitoringHost(String monitoringHost) {
20332037
return this;
20342038
}
20352039

2040+
/**
2041+
* Sets the GCP project ID for exporting client-side built-in metrics. Defaults to {@link
2042+
* SpannerOptions#getProjectId()} when not set. On GKE with shared VPC, the default project may
2043+
* resolve to the host project instead of the application project; set this explicitly to avoid
2044+
* {@code monitoring.metricWriter} permission errors.
2045+
*/
2046+
public Builder setMetricsProjectId(String metricsProjectId) {
2047+
this.metricsProjectId = metricsProjectId;
2048+
return this;
2049+
}
2050+
20362051
/**
20372052
* Sets whether to enable extended OpenTelemetry tracing. Enabling this option will add the
20382053
* following additional attributes to the traces that are generated by the client:
@@ -2443,14 +2458,14 @@ public ApiTracerFactory getApiTracerFactory() {
24432458
@InternalApi
24442459
public OpenTelemetry getBuiltInOpenTelemetry() {
24452460
return this.builtInMetricsProvider.getOrCreateOpenTelemetry(
2446-
this.getProjectId(), getCredentials(), this.monitoringHost, getUniverseDomain());
2461+
this.resolveMetricsProjectId(), getCredentials(), this.monitoringHost, getUniverseDomain());
24472462
}
24482463

24492464
public void enablegRPCMetrics(InstantiatingGrpcChannelProvider.Builder channelProviderBuilder) {
24502465
if (isEnableBuiltInMetrics() && SpannerOptions.environment.isEnableGRPCBuiltInMetrics()) {
24512466
this.builtInMetricsProvider.enableGrpcMetrics(
24522467
channelProviderBuilder,
2453-
this.getProjectId(),
2468+
this.resolveMetricsProjectId(),
24542469
getCredentials(),
24552470
this.monitoringHost,
24562471
getUniverseDomain());
@@ -2499,7 +2514,7 @@ private ApiTracerFactory getDefaultApiTracerFactory() {
24992514
private ApiTracerFactory createMetricsApiTracerFactory() {
25002515
OpenTelemetry openTelemetry =
25012516
this.builtInMetricsProvider.getOrCreateOpenTelemetry(
2502-
this.getProjectId(), getCredentials(), this.monitoringHost, getUniverseDomain());
2517+
this.resolveMetricsProjectId(), getCredentials(), this.monitoringHost, getUniverseDomain());
25032518

25042519
return openTelemetry != null
25052520
? new BuiltInMetricsTracerFactory(
@@ -2543,6 +2558,14 @@ String getMonitoringHost() {
25432558
return monitoringHost;
25442559
}
25452560

2561+
/**
2562+
* Returns the GCP project ID for client-side metrics export. Returns the explicit value if set
2563+
* via {@link Builder#setMetricsProjectId}, otherwise falls back to {@link #getProjectId()}.
2564+
*/
2565+
String resolveMetricsProjectId() {
2566+
return metricsProjectId != null ? metricsProjectId : getProjectId();
2567+
}
2568+
25462569
public TransactionOptions getDefaultTransactionOptions() {
25472570
return defaultTransactionOptions;
25482571
}

0 commit comments

Comments
 (0)