Skip to content

Commit 4159d2d

Browse files
authored
fix: fix exporting grpc metrics (googleapis#13376)
1 parent 504ef74 commit 4159d2d

3 files changed

Lines changed: 43 additions & 3 deletions

File tree

java-bigtable/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/internal/csm/MetricsImpl.java

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@
8787
public class MetricsImpl implements Metrics, Closeable {
8888

8989
public static final String CUSTOM_METRIC = "bigtable.internal.enable-custom-metric";
90+
public static final String CUSTOM_METRIC_PREFIX = "bigtable.custom";
9091

9192
private static final boolean enableCustomMetric =
9293
Optional.ofNullable(System.getProperty(CUSTOM_METRIC))
@@ -319,7 +320,13 @@ public static OpenTelemetrySdk createBuiltinOtel(
319320
new BigtablePeriodicReader(
320321
new BigtableFilteringExporter(
321322
exporter,
322-
input -> input.getName().startsWith("bigtable.googleapis.com/internal/client")),
323+
input -> {
324+
// filter out custom metrics and keep everything else that's registered on metric
325+
// registry
326+
String name = input.getName();
327+
return metricRegistry.getMetric(name) != null
328+
&& !name.startsWith(CUSTOM_METRIC_PREFIX);
329+
}),
323330
executor));
324331

325332
if (enableCustomMetric) {
@@ -333,7 +340,7 @@ public static OpenTelemetrySdk createBuiltinOtel(
333340
PeriodicMetricReader.builder(
334341
new BigtableFilteringExporter(
335342
GoogleCloudMetricExporter.createWithConfiguration(metricConfig),
336-
input -> input.getName().startsWith("bigtable.custom")))
343+
input -> input.getName().startsWith(CUSTOM_METRIC_PREFIX)))
337344
.setInterval(Duration.ofMinutes(1))
338345
.build());
339346
}

java-bigtable/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/internal/csm/metrics/CustomAttemptLatency.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
import com.google.bigtable.v2.ClusterInformation;
1919
import com.google.bigtable.v2.PeerInfo;
20+
import com.google.cloud.bigtable.data.v2.internal.csm.MetricsImpl;
2021
import com.google.cloud.bigtable.data.v2.internal.csm.attributes.ClientInfo;
2122
import com.google.cloud.bigtable.data.v2.internal.csm.attributes.MethodInfo;
2223
import com.google.cloud.bigtable.data.v2.internal.csm.attributes.Util;
@@ -33,7 +34,7 @@
3334
* exported as a custom metric.
3435
*/
3536
public class CustomAttemptLatency extends MetricWrapper<CustomSchema> {
36-
private static final String NAME = "bigtable.custom.attempt_latencies";
37+
private static final String NAME = MetricsImpl.CUSTOM_METRIC_PREFIX + ".attempt_latencies";
3738

3839
public CustomAttemptLatency() {
3940
super(CustomSchema.INSTANCE, NAME);

java-bigtable/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/internal/csm/MetricRegistryExportTest.java

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -775,6 +775,38 @@ void testPacemaker() {
775775
.build());
776776
}
777777

778+
@Test
779+
void testGrpcMetricExport() {
780+
// 1. Record a gRPC metric using its internal name
781+
// Note: gRPC metrics are usually recorded by gRPC-Java's OpenTelemetry integration,
782+
// but we can simulate it by getting the instrument from the meter directly.
783+
meterProvider
784+
.get("grpc-java")
785+
.histogramBuilder("grpc.client.attempt.duration")
786+
.build()
787+
.record(
788+
123.0,
789+
io.opentelemetry.api.common.Attributes.of(
790+
io.opentelemetry.api.common.AttributeKey.stringKey("grpc.status"), "OK",
791+
io.opentelemetry.api.common.AttributeKey.stringKey("grpc.method"),
792+
"Bigtable.ReadRows"));
793+
794+
// 2. Flush the metrics to the exporter
795+
metricReader.forceFlush().join(1, TimeUnit.MINUTES);
796+
797+
// 3. Verify that the metric was exported under the Bigtable namespace
798+
// The internal 'grpc.client.attempt.duration' should be renamed by GrpcMetric.java
799+
TimeSeries timeSeries =
800+
metricService.getSingleTimeSeriesByName(
801+
"bigtable.googleapis.com/internal/client/grpc/client/attempt/duration");
802+
803+
// 4. Verify labels are correctly mapped (dots replaced with underscores)
804+
assertThat(timeSeries.getMetric().getLabelsMap())
805+
.containsAtLeast(
806+
"grpc_status", "OK",
807+
"grpc_method", "Bigtable.ReadRows");
808+
}
809+
778810
private static class FakeMetricService extends MetricServiceImplBase {
779811
final BlockingDeque<CreateTimeSeriesRequest> requests = new LinkedBlockingDeque<>();
780812

0 commit comments

Comments
 (0)