Skip to content

Commit 8b2e5ef

Browse files
authored
fix: Client built in metrics. Skip export if instance id is null (#3447)
* fix: skip instance id, and public doc * review comments * revert:review comments
1 parent 07b777d commit 8b2e5ef

File tree

3 files changed

+65
-1
lines changed

3 files changed

+65
-1
lines changed

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

+9-1
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,14 @@ private CompletableResultCode exportSpannerClientMetrics(Collection<MetricData>
138138
return CompletableResultCode.ofFailure();
139139
}
140140

141+
// Verifies if metrics data has missing instance id.
142+
if (spannerMetricData.stream()
143+
.flatMap(metricData -> metricData.getData().getPoints().stream())
144+
.anyMatch(pd -> SpannerCloudMonitoringExporterUtils.getInstanceId(pd) == null)) {
145+
logger.log(Level.WARNING, "Metric data has missing instanceId. Skipping export.");
146+
return CompletableResultCode.ofFailure();
147+
}
148+
141149
List<TimeSeries> spannerTimeSeries;
142150
try {
143151
spannerTimeSeries =
@@ -166,7 +174,7 @@ public void onFailure(Throwable throwable) {
166174
// TODO: Add the link of public documentation when available in the log message.
167175
msg +=
168176
String.format(
169-
" Need monitoring metric writer permission on project=%s.",
177+
" Need monitoring metric writer permission on project=%s. Follow https://cloud.google.com/spanner/docs/view-manage-client-side-metrics#access-client-side-metrics to set up permissions",
170178
projectName.getProject());
171179
}
172180
logger.log(Level.WARNING, msg, throwable);

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

+5
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import static com.google.api.MetricDescriptor.ValueType.DOUBLE;
2424
import static com.google.api.MetricDescriptor.ValueType.INT64;
2525
import static com.google.cloud.spanner.BuiltInMetricsConstant.GAX_METER_NAME;
26+
import static com.google.cloud.spanner.BuiltInMetricsConstant.INSTANCE_ID_KEY;
2627
import static com.google.cloud.spanner.BuiltInMetricsConstant.PROJECT_ID_KEY;
2728
import static com.google.cloud.spanner.BuiltInMetricsConstant.SPANNER_PROMOTED_RESOURCE_LABELS;
2829
import static com.google.cloud.spanner.BuiltInMetricsConstant.SPANNER_RESOURCE_TYPE;
@@ -66,6 +67,10 @@ static String getProjectId(PointData pointData) {
6667
return pointData.getAttributes().get(PROJECT_ID_KEY);
6768
}
6869

70+
static String getInstanceId(PointData pointData) {
71+
return pointData.getAttributes().get(INSTANCE_ID_KEY);
72+
}
73+
6974
static List<TimeSeries> convertToSpannerTimeSeries(List<MetricData> collection) {
7075
List<TimeSeries> allTimeSeries = new ArrayList<>();
7176

google-cloud-spanner/src/test/java/com/google/cloud/spanner/SpannerCloudMonitoringExporterTest.java

+51
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
package com.google.cloud.spanner;
1818

19+
import static com.google.cloud.spanner.BuiltInMetricsConstant.ATTEMPT_COUNT_NAME;
1920
import static com.google.cloud.spanner.BuiltInMetricsConstant.CLIENT_HASH_KEY;
2021
import static com.google.cloud.spanner.BuiltInMetricsConstant.CLIENT_NAME_KEY;
2122
import static com.google.cloud.spanner.BuiltInMetricsConstant.CLIENT_UID_KEY;
@@ -44,6 +45,7 @@
4445
import com.google.monitoring.v3.TimeSeries;
4546
import com.google.protobuf.Empty;
4647
import io.opentelemetry.api.common.Attributes;
48+
import io.opentelemetry.sdk.common.CompletableResultCode;
4749
import io.opentelemetry.sdk.common.InstrumentationScopeInfo;
4850
import io.opentelemetry.sdk.metrics.InstrumentType;
4951
import io.opentelemetry.sdk.metrics.data.AggregationTemporality;
@@ -340,6 +342,55 @@ public void getAggregationTemporality() throws IOException {
340342
.isEqualTo(AggregationTemporality.CUMULATIVE);
341343
}
342344

345+
@Test
346+
public void testSkipExportingDataIfMissingInstanceId() throws IOException {
347+
Attributes attributesWithoutInstanceId =
348+
Attributes.builder().putAll(attributes).remove(INSTANCE_ID_KEY).build();
349+
350+
SpannerCloudMonitoringExporter actualExporter =
351+
SpannerCloudMonitoringExporter.create(projectId, null);
352+
assertThat(actualExporter.getAggregationTemporality(InstrumentType.COUNTER))
353+
.isEqualTo(AggregationTemporality.CUMULATIVE);
354+
ArgumentCaptor<CreateTimeSeriesRequest> argumentCaptor =
355+
ArgumentCaptor.forClass(CreateTimeSeriesRequest.class);
356+
357+
UnaryCallable<CreateTimeSeriesRequest, Empty> mockCallable = Mockito.mock(UnaryCallable.class);
358+
Mockito.when(mockMetricServiceStub.createServiceTimeSeriesCallable()).thenReturn(mockCallable);
359+
ApiFuture<Empty> future = ApiFutures.immediateFuture(Empty.getDefaultInstance());
360+
Mockito.when(mockCallable.futureCall(argumentCaptor.capture())).thenReturn(future);
361+
362+
long fakeValue = 11L;
363+
364+
long startEpoch = 10;
365+
long endEpoch = 15;
366+
LongPointData longPointData =
367+
ImmutableLongPointData.create(startEpoch, endEpoch, attributesWithoutInstanceId, fakeValue);
368+
369+
MetricData operationLongData =
370+
ImmutableMetricData.createLongSum(
371+
resource,
372+
scope,
373+
"spanner.googleapis.com/internal/client/" + OPERATION_COUNT_NAME,
374+
"description",
375+
"1",
376+
ImmutableSumData.create(
377+
true, AggregationTemporality.CUMULATIVE, ImmutableList.of(longPointData)));
378+
379+
MetricData attemptLongData =
380+
ImmutableMetricData.createLongSum(
381+
resource,
382+
scope,
383+
"spanner.googleapis.com/internal/client/" + ATTEMPT_COUNT_NAME,
384+
"description",
385+
"1",
386+
ImmutableSumData.create(
387+
true, AggregationTemporality.CUMULATIVE, ImmutableList.of(longPointData)));
388+
389+
CompletableResultCode resultCode =
390+
exporter.export(Arrays.asList(operationLongData, attemptLongData));
391+
assertThat(resultCode).isEqualTo(CompletableResultCode.ofFailure());
392+
}
393+
343394
private static class FakeMetricServiceClient extends MetricServiceClient {
344395

345396
protected FakeMetricServiceClient(MetricServiceStub stub) {

0 commit comments

Comments
 (0)