From 17cde56e78741c699059b400d7c203dc61935219 Mon Sep 17 00:00:00 2001 From: Mattie Fu Date: Mon, 5 Jan 2026 21:38:14 -0500 Subject: [PATCH 1/8] fix: move batch metrics to internal views --- .../stub/metrics/BuiltinMetricsConstants.java | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/BuiltinMetricsConstants.java b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/BuiltinMetricsConstants.java index 810d555de2..52a89a0d70 100644 --- a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/BuiltinMetricsConstants.java +++ b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/BuiltinMetricsConstants.java @@ -279,6 +279,23 @@ public static Map getInternalViews() { ImmutableSet.builder() .add(BIGTABLE_PROJECT_ID_KEY, INSTANCE_ID_KEY, APP_PROFILE_KEY, CLIENT_NAME_KEY) .build()); + defineView( + views, + BATCH_WRITE_FLOW_CONTROL_TARGET_QPS_NAME, + null, + InstrumentType.GAUGE, + "1", + ImmutableSet.builder().addAll(COMMON_ATTRIBUTES).build()); + defineView( + views, + BATCH_WRITE_FLOW_CONTROL_FACTOR_NAME, + AGGREGATION_BATCH_WRITE_FLOW_CONTROL_FACTOR_HISTOGRAM, + InstrumentType.HISTOGRAM, + "1", + ImmutableSet.builder() + .addAll(COMMON_ATTRIBUTES) + .add(STATUS_KEY, APPLIED_KEY) + .build()); return views.build(); } @@ -373,23 +390,6 @@ public static Map getAllViews() { .addAll(COMMON_ATTRIBUTES) .add(STREAMING_KEY, STATUS_KEY) .build()); - defineView( - views, - BATCH_WRITE_FLOW_CONTROL_TARGET_QPS_NAME, - null, - InstrumentType.GAUGE, - "1", - ImmutableSet.builder().addAll(COMMON_ATTRIBUTES).build()); - defineView( - views, - BATCH_WRITE_FLOW_CONTROL_FACTOR_NAME, - AGGREGATION_BATCH_WRITE_FLOW_CONTROL_FACTOR_HISTOGRAM, - InstrumentType.HISTOGRAM, - "1", - ImmutableSet.builder() - .addAll(COMMON_ATTRIBUTES) - .add(STATUS_KEY, APPLIED_KEY) - .build()); return views.build(); } } From 0f77238d4b67b2ee310009fb1222a7292ededfa3 Mon Sep 17 00:00:00 2001 From: Mattie Fu Date: Mon, 5 Jan 2026 21:58:38 -0500 Subject: [PATCH 2/8] fix test --- .../data/v2/stub/metrics/BuiltinMetricsTracerTest.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/stub/metrics/BuiltinMetricsTracerTest.java b/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/stub/metrics/BuiltinMetricsTracerTest.java index a59cf84751..5f8c816f7c 100644 --- a/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/stub/metrics/BuiltinMetricsTracerTest.java +++ b/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/stub/metrics/BuiltinMetricsTracerTest.java @@ -179,6 +179,11 @@ public void setUp() throws Exception { meterProvider.registerView(entry.getKey(), entry.getValue()); } + for (Map.Entry entry : + BuiltinMetricsConstants.getInternalViews().entrySet()) { + meterProvider.registerView(entry.getKey(), entry.getValue()); + } + OpenTelemetrySdk otel = OpenTelemetrySdk.builder().setMeterProvider(meterProvider.build()).build(); BuiltinMetricsTracerFactory facotry = BuiltinMetricsTracerFactory.create(otel, baseAttributes); From 89b0dc1d975c7153636f8b5a6e814e6b0cf544c1 Mon Sep 17 00:00:00 2001 From: Mattie Fu Date: Thu, 8 Jan 2026 13:42:17 -0500 Subject: [PATCH 3/8] fix --- .../clirr-ignored-differences.xml | 6 +++++ .../data/v2/BigtableDataClientFactory.java | 16 +++++++++--- .../data/v2/stub/BigtableClientContext.java | 4 +++ .../data/v2/stub/EnhancedBigtableStub.java | 25 +++++++++++-------- .../BigtableCloudMonitoringExporter.java | 6 ----- .../stub/metrics/BigtableExporterUtils.java | 6 +++-- .../stub/metrics/BuiltinMetricsConstants.java | 19 +++++++------- .../bigtable/data/v2/stub/metrics/Util.java | 12 +++++---- .../metrics/BigtableTracerCallableTest.java | 2 ++ .../v2/stub/metrics/MetricsTracerTest.java | 1 + 10 files changed, 61 insertions(+), 36 deletions(-) diff --git a/google-cloud-bigtable/clirr-ignored-differences.xml b/google-cloud-bigtable/clirr-ignored-differences.xml index c3a0fa05e1..5104f9e990 100644 --- a/google-cloud-bigtable/clirr-ignored-differences.xml +++ b/google-cloud-bigtable/clirr-ignored-differences.xml @@ -492,4 +492,10 @@ com/google/cloud/bigtable/gaxx/grpc/BigtableChannelPoolSettings$Builder com.google.cloud.bigtable.gaxx.grpc.BigtableChannelPoolSettings$Builder setLoadBalancingStrategy(com.google.cloud.bigtable.gaxx.grpc.BigtableChannelPoolSettings$LoadBalancingStrategy) + + + 6001 + com/google/cloud/bigtable/data/v2/stub/metrics/BuiltinMetricsConstants + * + diff --git a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/BigtableDataClientFactory.java b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/BigtableDataClientFactory.java index cddea20c7d..f290f8ec4d 100644 --- a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/BigtableDataClientFactory.java +++ b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/BigtableDataClientFactory.java @@ -111,7 +111,9 @@ public BigtableDataClient createDefault() { sharedClientContext.getClientContext().toBuilder() .setTracerFactory( EnhancedBigtableStub.createBigtableTracerFactory( - defaultSettings.getStubSettings(), sharedClientContext.getOpenTelemetry())) + defaultSettings.getStubSettings(), + sharedClientContext.getOpenTelemetry(), + sharedClientContext.getInternalOpenTelemtry())) .build(); return BigtableDataClient.createWithClientContext(defaultSettings, clientContext); @@ -139,7 +141,9 @@ public BigtableDataClient createForAppProfile(@Nonnull String appProfileId) thro sharedClientContext.getClientContext().toBuilder() .setTracerFactory( EnhancedBigtableStub.createBigtableTracerFactory( - settings.getStubSettings(), sharedClientContext.getOpenTelemetry())) + settings.getStubSettings(), + sharedClientContext.getOpenTelemetry(), + sharedClientContext.getInternalOpenTelemtry())) .build(); return BigtableDataClient.createWithClientContext(settings, clientContext); } @@ -166,7 +170,9 @@ public BigtableDataClient createForInstance(@Nonnull String projectId, @Nonnull sharedClientContext.getClientContext().toBuilder() .setTracerFactory( EnhancedBigtableStub.createBigtableTracerFactory( - settings.getStubSettings(), sharedClientContext.getOpenTelemetry())) + settings.getStubSettings(), + sharedClientContext.getOpenTelemetry(), + sharedClientContext.getInternalOpenTelemtry())) .build(); return BigtableDataClient.createWithClientContext(settings, clientContext); @@ -194,7 +200,9 @@ public BigtableDataClient createForInstance( sharedClientContext.getClientContext().toBuilder() .setTracerFactory( EnhancedBigtableStub.createBigtableTracerFactory( - settings.getStubSettings(), sharedClientContext.getOpenTelemetry())) + settings.getStubSettings(), + sharedClientContext.getOpenTelemetry(), + sharedClientContext.getInternalOpenTelemtry())) .build(); return BigtableDataClient.createWithClientContext(settings, clientContext); } diff --git a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/BigtableClientContext.java b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/BigtableClientContext.java index bac1ec4a06..d77562bca2 100644 --- a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/BigtableClientContext.java +++ b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/BigtableClientContext.java @@ -193,6 +193,10 @@ public OpenTelemetry getOpenTelemetry() { return this.openTelemetry; } + public OpenTelemetry getInternalOpenTelemtry() { + return this.internalOpenTelemetry; + } + public ClientContext getClientContext() { return this.clientContext; } diff --git a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/EnhancedBigtableStub.java b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/EnhancedBigtableStub.java index 5f6b69dea8..ffebece2a6 100644 --- a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/EnhancedBigtableStub.java +++ b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/EnhancedBigtableStub.java @@ -205,9 +205,10 @@ public static EnhancedBigtableStub create(EnhancedBigtableStubSettings settings) throws IOException { BigtableClientContext bigtableClientContext = createBigtableClientContext(settings); OpenTelemetry openTelemetry = bigtableClientContext.getOpenTelemetry(); + OpenTelemetry internalOtel = bigtableClientContext.getInternalOpenTelemtry(); ClientContext contextWithTracer = bigtableClientContext.getClientContext().toBuilder() - .setTracerFactory(createBigtableTracerFactory(settings, openTelemetry)) + .setTracerFactory(createBigtableTracerFactory(settings, openTelemetry, internalOtel)) .build(); return new EnhancedBigtableStub(settings, contextWithTracer); } @@ -224,10 +225,12 @@ public static BigtableClientContext createBigtableClientContext( } public static ApiTracerFactory createBigtableTracerFactory( - EnhancedBigtableStubSettings settings, @Nullable OpenTelemetry openTelemetry) + EnhancedBigtableStubSettings settings, + @Nullable OpenTelemetry openTelemetry, + @Nullable OpenTelemetry internalOtel) throws IOException { return createBigtableTracerFactory( - settings, Tags.getTagger(), Stats.getStatsRecorder(), openTelemetry); + settings, Tags.getTagger(), Stats.getStatsRecorder(), openTelemetry, internalOtel); } @VisibleForTesting @@ -235,7 +238,8 @@ public static ApiTracerFactory createBigtableTracerFactory( EnhancedBigtableStubSettings settings, Tagger tagger, StatsRecorder stats, - @Nullable OpenTelemetry openTelemetry) + @Nullable OpenTelemetry openTelemetry, + @Nullable OpenTelemetry internalOtel) throws IOException { String projectId = settings.getProjectId(); String instanceId = settings.getInstanceId(); @@ -267,12 +271,13 @@ public static ApiTracerFactory createBigtableTracerFactory( .add(MetricsTracerFactory.create(tagger, stats, attributes)) // Add user configured tracer .add(settings.getTracerFactory()); - BuiltinMetricsTracerFactory builtinMetricsTracerFactory = - openTelemetry != null - ? BuiltinMetricsTracerFactory.create(openTelemetry, createBuiltinAttributes(settings)) - : null; - if (builtinMetricsTracerFactory != null) { - tracerFactories.add(builtinMetricsTracerFactory); + if (openTelemetry != null) { + tracerFactories.add( + BuiltinMetricsTracerFactory.create(openTelemetry, createBuiltinAttributes(settings))); + } + if (internalOtel != null) { + tracerFactories.add( + BuiltinMetricsTracerFactory.create(internalOtel, createBuiltinAttributes(settings))); } return new CompositeTracerFactory(tracerFactories.build()); } diff --git a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/BigtableCloudMonitoringExporter.java b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/BigtableCloudMonitoringExporter.java index 1244ee5fdc..bd92d3d628 100644 --- a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/BigtableCloudMonitoringExporter.java +++ b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/BigtableCloudMonitoringExporter.java @@ -23,7 +23,6 @@ import static com.google.cloud.bigtable.data.v2.stub.metrics.BuiltinMetricsConstants.FIRST_RESPONSE_LATENCIES_NAME; import static com.google.cloud.bigtable.data.v2.stub.metrics.BuiltinMetricsConstants.METER_NAME; import static com.google.cloud.bigtable.data.v2.stub.metrics.BuiltinMetricsConstants.OPERATION_LATENCIES_NAME; -import static com.google.cloud.bigtable.data.v2.stub.metrics.BuiltinMetricsConstants.PER_CONNECTION_ERROR_COUNT_NAME; import static com.google.cloud.bigtable.data.v2.stub.metrics.BuiltinMetricsConstants.REMAINING_DEADLINE_NAME; import static com.google.cloud.bigtable.data.v2.stub.metrics.BuiltinMetricsConstants.RETRY_COUNT_NAME; import static com.google.cloud.bigtable.data.v2.stub.metrics.BuiltinMetricsConstants.SERVER_LATENCIES_NAME; @@ -331,11 +330,6 @@ public Map> convert(Collection metricD } static class InternalTimeSeriesConverter implements TimeSeriesConverter { - private static final ImmutableList APPLICATION_METRICS = - ImmutableSet.of(PER_CONNECTION_ERROR_COUNT_NAME).stream() - .map(m -> METER_NAME + m) - .collect(ImmutableList.toImmutableList()); - private final Supplier monitoredResource; InternalTimeSeriesConverter(Supplier monitoredResource) { diff --git a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/BigtableExporterUtils.java b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/BigtableExporterUtils.java index 882365c6b4..749eed84ca 100644 --- a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/BigtableExporterUtils.java +++ b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/BigtableExporterUtils.java @@ -25,12 +25,12 @@ import static com.google.api.MetricDescriptor.ValueType.DISTRIBUTION; import static com.google.api.MetricDescriptor.ValueType.DOUBLE; import static com.google.api.MetricDescriptor.ValueType.INT64; +import static com.google.cloud.bigtable.data.v2.stub.metrics.BuiltinMetricsConstants.BIGTABLE_CLIENT_METRICS; import static com.google.cloud.bigtable.data.v2.stub.metrics.BuiltinMetricsConstants.BIGTABLE_PROJECT_ID_KEY; import static com.google.cloud.bigtable.data.v2.stub.metrics.BuiltinMetricsConstants.CLIENT_UID_KEY; import static com.google.cloud.bigtable.data.v2.stub.metrics.BuiltinMetricsConstants.CLUSTER_ID_KEY; import static com.google.cloud.bigtable.data.v2.stub.metrics.BuiltinMetricsConstants.GRPC_METRICS; import static com.google.cloud.bigtable.data.v2.stub.metrics.BuiltinMetricsConstants.INSTANCE_ID_KEY; -import static com.google.cloud.bigtable.data.v2.stub.metrics.BuiltinMetricsConstants.INTERNAL_METRICS; import static com.google.cloud.bigtable.data.v2.stub.metrics.BuiltinMetricsConstants.METER_NAME; import static com.google.cloud.bigtable.data.v2.stub.metrics.BuiltinMetricsConstants.TABLE_ID_KEY; import static com.google.cloud.bigtable.data.v2.stub.metrics.BuiltinMetricsConstants.ZONE_ID_KEY; @@ -171,6 +171,7 @@ static List convertToApplicationResourceTimeSeries( "convert application metrics is called when the supported resource is not detected"); List allTimeSeries = new ArrayList<>(); for (MetricData metricData : collection) { + System.out.println("====== metric data: " + metricData.getName() + " data: " + metricData); metricData.getData().getPoints().stream() .map( pointData -> @@ -186,6 +187,7 @@ static MonitoredResource createInternalMonitoredResource(EnhancedBigtableStubSet try { MonitoredResource monitoredResource = detectResource(settings); logger.log(Level.FINE, "Internal metrics monitored resource: %s", monitoredResource); + System.out.println("detected resource: " + monitoredResource); return monitoredResource; } catch (Exception e) { logger.log( @@ -317,7 +319,7 @@ private static Optional createInternalMetricsTimeSeries( // To unify these: // - the useless views should be removed // - internal metrics should use relative metric names w/o the prefix - if (INTERNAL_METRICS.contains(metricData.getName())) { + if (BIGTABLE_CLIENT_METRICS.contains(metricData.getName())) { metricBuilder = newApplicationMetricBuilder(metricData.getName(), pointData.getAttributes()); } else if (GRPC_METRICS.containsKey(metricData.getName())) { metricBuilder = newGrpcMetricBuilder(metricData.getName(), pointData.getAttributes()); diff --git a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/BuiltinMetricsConstants.java b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/BuiltinMetricsConstants.java index 52a89a0d70..a21d4295c1 100644 --- a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/BuiltinMetricsConstants.java +++ b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/BuiltinMetricsConstants.java @@ -167,8 +167,13 @@ public class BuiltinMetricsConstants { GRPC_TARGET_KEY.getKey())) .build(); - public static final Set INTERNAL_METRICS = - ImmutableSet.of(PER_CONNECTION_ERROR_COUNT_NAME, OUTSTANDING_RPCS_PER_CHANNEL_NAME).stream() + public static final Set BIGTABLE_CLIENT_METRICS = + ImmutableSet.of( + PER_CONNECTION_ERROR_COUNT_NAME, + OUTSTANDING_RPCS_PER_CHANNEL_NAME, + BATCH_WRITE_FLOW_CONTROL_FACTOR_NAME, + BATCH_WRITE_FLOW_CONTROL_TARGET_QPS_NAME) + .stream() .map(m -> METER_NAME + m) .collect(ImmutableSet.toImmutableSet()); // End allow list of metrics that will be exported @@ -246,8 +251,6 @@ static void defineView( .build(); Set attributesFilter = ImmutableSet.builder() - .addAll( - COMMON_ATTRIBUTES.stream().map(AttributeKey::getKey).collect(Collectors.toSet())) .addAll(attributes.stream().map(AttributeKey::getKey).collect(Collectors.toSet())) .build(); ViewBuilder viewBuilder = @@ -285,20 +288,18 @@ public static Map getInternalViews() { null, InstrumentType.GAUGE, "1", - ImmutableSet.builder().addAll(COMMON_ATTRIBUTES).build()); + ImmutableSet.builder().add(METHOD_KEY).build()); defineView( views, BATCH_WRITE_FLOW_CONTROL_FACTOR_NAME, AGGREGATION_BATCH_WRITE_FLOW_CONTROL_FACTOR_HISTOGRAM, InstrumentType.HISTOGRAM, "1", - ImmutableSet.builder() - .addAll(COMMON_ATTRIBUTES) - .add(STATUS_KEY, APPLIED_KEY) - .build()); + ImmutableSet.builder().add(STATUS_KEY, APPLIED_KEY, METHOD_KEY).build()); return views.build(); } + // uses cloud.BigtableTable schema public static Map getAllViews() { ImmutableMap.Builder views = ImmutableMap.builder(); diff --git a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/Util.java b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/Util.java index 012aae024d..74b38954c0 100644 --- a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/Util.java +++ b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/Util.java @@ -259,11 +259,6 @@ public static OpenTelemetrySdk newInternalOpentelemetry( EnhancedBigtableStubSettings settings, Credentials credentials) throws IOException { SdkMeterProviderBuilder meterProviderBuilder = SdkMeterProvider.builder(); - for (Map.Entry e : - BuiltinMetricsConstants.getInternalViews().entrySet()) { - meterProviderBuilder.registerView(e.getKey(), e.getValue()); - } - meterProviderBuilder.registerMetricReader( PeriodicMetricReader.create( BigtableCloudMonitoringExporter.create( @@ -274,6 +269,13 @@ public static OpenTelemetrySdk newInternalOpentelemetry( new BigtableCloudMonitoringExporter.InternalTimeSeriesConverter( Suppliers.memoize( () -> BigtableExporterUtils.createInternalMonitoredResource(settings)))))); + + for (Map.Entry e : + BuiltinMetricsConstants.getInternalViews().entrySet()) { + System.out.println("register internal view " + e.getKey().getInstrumentName()); + meterProviderBuilder.registerView(e.getKey(), e.getValue()); + } + return OpenTelemetrySdk.builder().setMeterProvider(meterProviderBuilder.build()).build(); } } diff --git a/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/stub/metrics/BigtableTracerCallableTest.java b/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/stub/metrics/BigtableTracerCallableTest.java index b0966a2166..d3a001ada3 100644 --- a/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/stub/metrics/BigtableTracerCallableTest.java +++ b/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/stub/metrics/BigtableTracerCallableTest.java @@ -136,6 +136,7 @@ public void sendHeaders(Metadata headers) { settings.getStubSettings(), Tags.getTagger(), localStats.getStatsRecorder(), + null, null)) .build(); attempts = settings.getStubSettings().readRowsSettings().getRetrySettings().getMaxAttempts(); @@ -161,6 +162,7 @@ public void sendHeaders(Metadata headers) { noHeaderSettings.getStubSettings(), Tags.getTagger(), localStats.getStatsRecorder(), + null, null)) .build(); noHeaderStub = diff --git a/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/stub/metrics/MetricsTracerTest.java b/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/stub/metrics/MetricsTracerTest.java index a9f3aa038b..c50351f0be 100644 --- a/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/stub/metrics/MetricsTracerTest.java +++ b/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/stub/metrics/MetricsTracerTest.java @@ -131,6 +131,7 @@ public void setUp() throws Exception { settings.getStubSettings(), Tags.getTagger(), localStats.getStatsRecorder(), + null, null)) .build(); stub = new EnhancedBigtableStub(settings.getStubSettings(), clientContext); From f0b12d038abc205a0bb17f15eb60e41584edd7f3 Mon Sep 17 00:00:00 2001 From: Mattie Fu Date: Thu, 8 Jan 2026 13:50:00 -0500 Subject: [PATCH 4/8] fix test --- .../stub/metrics/BigtableExporterUtils.java | 2 -- .../bigtable/data/v2/stub/metrics/Util.java | 11 +++++----- .../metrics/BuiltinMetricsTracerTest.java | 21 +++++++++---------- 3 files changed, 15 insertions(+), 19 deletions(-) diff --git a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/BigtableExporterUtils.java b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/BigtableExporterUtils.java index 749eed84ca..623503f406 100644 --- a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/BigtableExporterUtils.java +++ b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/BigtableExporterUtils.java @@ -171,7 +171,6 @@ static List convertToApplicationResourceTimeSeries( "convert application metrics is called when the supported resource is not detected"); List allTimeSeries = new ArrayList<>(); for (MetricData metricData : collection) { - System.out.println("====== metric data: " + metricData.getName() + " data: " + metricData); metricData.getData().getPoints().stream() .map( pointData -> @@ -187,7 +186,6 @@ static MonitoredResource createInternalMonitoredResource(EnhancedBigtableStubSet try { MonitoredResource monitoredResource = detectResource(settings); logger.log(Level.FINE, "Internal metrics monitored resource: %s", monitoredResource); - System.out.println("detected resource: " + monitoredResource); return monitoredResource; } catch (Exception e) { logger.log( diff --git a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/Util.java b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/Util.java index 74b38954c0..071664d9f6 100644 --- a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/Util.java +++ b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/Util.java @@ -259,6 +259,11 @@ public static OpenTelemetrySdk newInternalOpentelemetry( EnhancedBigtableStubSettings settings, Credentials credentials) throws IOException { SdkMeterProviderBuilder meterProviderBuilder = SdkMeterProvider.builder(); + for (Map.Entry e : + BuiltinMetricsConstants.getInternalViews().entrySet()) { + meterProviderBuilder.registerView(e.getKey(), e.getValue()); + } + meterProviderBuilder.registerMetricReader( PeriodicMetricReader.create( BigtableCloudMonitoringExporter.create( @@ -270,12 +275,6 @@ public static OpenTelemetrySdk newInternalOpentelemetry( Suppliers.memoize( () -> BigtableExporterUtils.createInternalMonitoredResource(settings)))))); - for (Map.Entry e : - BuiltinMetricsConstants.getInternalViews().entrySet()) { - System.out.println("register internal view " + e.getKey().getInstrumentName()); - meterProviderBuilder.registerView(e.getKey(), e.getValue()); - } - return OpenTelemetrySdk.builder().setMeterProvider(meterProviderBuilder.build()).build(); } } diff --git a/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/stub/metrics/BuiltinMetricsTracerTest.java b/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/stub/metrics/BuiltinMetricsTracerTest.java index 5f8c816f7c..47c9984ba4 100644 --- a/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/stub/metrics/BuiltinMetricsTracerTest.java +++ b/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/stub/metrics/BuiltinMetricsTracerTest.java @@ -832,15 +832,14 @@ public void testBatchWriteFlowControlTargetQpsIncreased() throws InterruptedExce MetricData targetQpsMetric = getMetricData(metricReader, BATCH_WRITE_FLOW_CONTROL_TARGET_QPS_NAME); - Attributes targetQpsAttributes = - baseAttributes.toBuilder().put(METHOD_KEY, "Bigtable.MutateRows").build(); + Attributes targetQpsAttributes = Attributes.of(METHOD_KEY, "Bigtable.MutateRows"); double actual_qps = getAggregatedDoubleValue(targetQpsMetric, targetQpsAttributes); double expected_qps = 12; assertThat(expected_qps).isEqualTo(actual_qps); MetricData factorMetric = getMetricData(metricReader, BATCH_WRITE_FLOW_CONTROL_FACTOR_NAME); Attributes factorAttributes = - baseAttributes.toBuilder() + Attributes.builder() .put(METHOD_KEY, "Bigtable.MutateRows") .put(APPLIED_KEY, true) .put(STATUS_KEY, "OK") @@ -863,14 +862,14 @@ public void testBatchWriteFlowControlTargetQpsDecreased() throws InterruptedExce MetricData targetQpsMetric = getMetricData(metricReader, BATCH_WRITE_FLOW_CONTROL_TARGET_QPS_NAME); Attributes targetQpsAttributes = - baseAttributes.toBuilder().put(METHOD_KEY, "Bigtable.MutateRows").build(); + Attributes.builder().put(METHOD_KEY, "Bigtable.MutateRows").build(); double actual_qps = getAggregatedDoubleValue(targetQpsMetric, targetQpsAttributes); double expected_qps = 8.0; assertThat(expected_qps).isEqualTo(actual_qps); MetricData factorMetric = getMetricData(metricReader, BATCH_WRITE_FLOW_CONTROL_FACTOR_NAME); Attributes factorAttributes = - baseAttributes.toBuilder() + Attributes.builder() .put(METHOD_KEY, "Bigtable.MutateRows") .put(APPLIED_KEY, true) .put(STATUS_KEY, "OK") @@ -893,7 +892,7 @@ public void testBatchWriteFlowControlTargetQpsCappedOnMaxFactor() throws Interru MetricData targetQpsMetric = getMetricData(metricReader, BATCH_WRITE_FLOW_CONTROL_TARGET_QPS_NAME); Attributes targetQpsAttributes = - baseAttributes.toBuilder().put(METHOD_KEY, "Bigtable.MutateRows").build(); + Attributes.builder().put(METHOD_KEY, "Bigtable.MutateRows").build(); double actual_qps = getAggregatedDoubleValue(targetQpsMetric, targetQpsAttributes); // Factor is 1.8 but capped at 1.3 so updated QPS is 13. double expected_qps = 13; @@ -901,7 +900,7 @@ public void testBatchWriteFlowControlTargetQpsCappedOnMaxFactor() throws Interru MetricData factorMetric = getMetricData(metricReader, BATCH_WRITE_FLOW_CONTROL_FACTOR_NAME); Attributes factorAttributes = - baseAttributes.toBuilder() + Attributes.builder() .put(METHOD_KEY, "Bigtable.MutateRows") .put(APPLIED_KEY, true) .put(STATUS_KEY, "OK") @@ -925,7 +924,7 @@ public void testBatchWriteFlowControlTargetQpsCappedOnMinFactor() throws Interru MetricData targetQpsMetric = getMetricData(metricReader, BATCH_WRITE_FLOW_CONTROL_TARGET_QPS_NAME); Attributes targetQpsAttributes = - baseAttributes.toBuilder().put(METHOD_KEY, "Bigtable.MutateRows").build(); + Attributes.builder().put(METHOD_KEY, "Bigtable.MutateRows").build(); double actual_qps = getAggregatedDoubleValue(targetQpsMetric, targetQpsAttributes); // Factor is 0.5 but capped at 0.7 so updated QPS is 7. double expected_qps = 7; @@ -933,7 +932,7 @@ public void testBatchWriteFlowControlTargetQpsCappedOnMinFactor() throws Interru MetricData factorMetric = getMetricData(metricReader, BATCH_WRITE_FLOW_CONTROL_FACTOR_NAME); Attributes factorAttributes = - baseAttributes.toBuilder() + Attributes.builder() .put(METHOD_KEY, "Bigtable.MutateRows") .put(APPLIED_KEY, true) .put(STATUS_KEY, "OK") @@ -958,7 +957,7 @@ public void testBatchWriteFlowControlTargetQpsDecreasedForError() throws Interru MetricData targetQpsMetric = getMetricData(metricReader, BATCH_WRITE_FLOW_CONTROL_TARGET_QPS_NAME); Attributes targetQpsAttributes = - baseAttributes.toBuilder().put(METHOD_KEY, "Bigtable.MutateRows").build(); + Attributes.builder().put(METHOD_KEY, "Bigtable.MutateRows").build(); double actual_qps = getAggregatedDoubleValue(targetQpsMetric, targetQpsAttributes); // On error, min factor is applied. double expected_qps = 7; @@ -966,7 +965,7 @@ public void testBatchWriteFlowControlTargetQpsDecreasedForError() throws Interru MetricData factorMetric = getMetricData(metricReader, BATCH_WRITE_FLOW_CONTROL_FACTOR_NAME); Attributes factorAttributes = - baseAttributes.toBuilder() + Attributes.builder() .put(METHOD_KEY, "Bigtable.MutateRows") .put(APPLIED_KEY, true) .put(STATUS_KEY, "UNAVAILABLE") From 250d0e3845332022a9bed2db924ab0372597b563 Mon Sep 17 00:00:00 2001 From: Mattie Fu Date: Thu, 8 Jan 2026 13:57:17 -0500 Subject: [PATCH 5/8] rename --- google-cloud-bigtable/clirr-ignored-differences.xml | 6 ++++++ .../data/v2/stub/metrics/BuiltinMetricsConstants.java | 4 ++-- .../bigtable/data/v2/stub/metrics/BuiltinMetricsView.java | 2 +- .../google/cloud/bigtable/data/v2/stub/metrics/Util.java | 2 +- .../data/v2/stub/metrics/BuiltinMetricsTracerTest.java | 4 ++-- 5 files changed, 12 insertions(+), 6 deletions(-) diff --git a/google-cloud-bigtable/clirr-ignored-differences.xml b/google-cloud-bigtable/clirr-ignored-differences.xml index 5104f9e990..14640691e0 100644 --- a/google-cloud-bigtable/clirr-ignored-differences.xml +++ b/google-cloud-bigtable/clirr-ignored-differences.xml @@ -498,4 +498,10 @@ com/google/cloud/bigtable/data/v2/stub/metrics/BuiltinMetricsConstants * + + + 7002 + com/google/cloud/bigtable/data/v2/stub/metrics/BuiltinMetricsConstants + * + diff --git a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/BuiltinMetricsConstants.java b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/BuiltinMetricsConstants.java index a21d4295c1..848b485039 100644 --- a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/BuiltinMetricsConstants.java +++ b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/BuiltinMetricsConstants.java @@ -262,7 +262,7 @@ static void defineView( } // uses cloud.BigtableClient schema - public static Map getInternalViews() { + public static Map getBigtableClientViews() { ImmutableMap.Builder views = ImmutableMap.builder(); defineView( views, @@ -300,7 +300,7 @@ public static Map getInternalViews() { } // uses cloud.BigtableTable schema - public static Map getAllViews() { + public static Map getBigtableTableViews() { ImmutableMap.Builder views = ImmutableMap.builder(); defineView( diff --git a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/BuiltinMetricsView.java b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/BuiltinMetricsView.java index f6df7fe6cd..3ca66548f4 100644 --- a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/BuiltinMetricsView.java +++ b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/BuiltinMetricsView.java @@ -118,7 +118,7 @@ static void registerBuiltinMetricsWithUniverseDomain( new BigtableCloudMonitoringExporter.PublicTimeSeriesConverter()); for (Map.Entry entry : - BuiltinMetricsConstants.getAllViews().entrySet()) { + BuiltinMetricsConstants.getBigtableTableViews().entrySet()) { builder.registerView(entry.getKey(), entry.getValue()); } builder.registerMetricReader(PeriodicMetricReader.create(publicExporter)); diff --git a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/Util.java b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/Util.java index 071664d9f6..b9ea151872 100644 --- a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/Util.java +++ b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/Util.java @@ -260,7 +260,7 @@ public static OpenTelemetrySdk newInternalOpentelemetry( SdkMeterProviderBuilder meterProviderBuilder = SdkMeterProvider.builder(); for (Map.Entry e : - BuiltinMetricsConstants.getInternalViews().entrySet()) { + BuiltinMetricsConstants.getBigtableClientViews().entrySet()) { meterProviderBuilder.registerView(e.getKey(), e.getValue()); } diff --git a/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/stub/metrics/BuiltinMetricsTracerTest.java b/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/stub/metrics/BuiltinMetricsTracerTest.java index 47c9984ba4..800ebebc70 100644 --- a/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/stub/metrics/BuiltinMetricsTracerTest.java +++ b/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/stub/metrics/BuiltinMetricsTracerTest.java @@ -175,12 +175,12 @@ public void setUp() throws Exception { SdkMeterProvider.builder().registerMetricReader(metricReader); for (Map.Entry entry : - BuiltinMetricsConstants.getAllViews().entrySet()) { + BuiltinMetricsConstants.getBigtableTableViews().entrySet()) { meterProvider.registerView(entry.getKey(), entry.getValue()); } for (Map.Entry entry : - BuiltinMetricsConstants.getInternalViews().entrySet()) { + BuiltinMetricsConstants.getBigtableClientViews().entrySet()) { meterProvider.registerView(entry.getKey(), entry.getValue()); } From 45e1137fdcdd8b176c4e0cb6804629b58a2ddc9a Mon Sep 17 00:00:00 2001 From: Mattie Fu Date: Thu, 8 Jan 2026 18:51:43 -0500 Subject: [PATCH 6/8] fix broken outstanding rpc metrics --- .../stub/metrics/BigtableExporterUtils.java | 23 ++++++-- .../stub/metrics/BuiltinMetricsConstants.java | 23 ++++++-- .../metrics/BuiltinMetricsTracerTest.java | 54 +++++++++++++++++-- 3 files changed, 89 insertions(+), 11 deletions(-) diff --git a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/BigtableExporterUtils.java b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/BigtableExporterUtils.java index 623503f406..126c4535fa 100644 --- a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/BigtableExporterUtils.java +++ b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/BigtableExporterUtils.java @@ -25,6 +25,7 @@ import static com.google.api.MetricDescriptor.ValueType.DISTRIBUTION; import static com.google.api.MetricDescriptor.ValueType.DOUBLE; import static com.google.api.MetricDescriptor.ValueType.INT64; +import static com.google.cloud.bigtable.data.v2.stub.metrics.BuiltinMetricsConstants.APP_PROFILE_KEY; import static com.google.cloud.bigtable.data.v2.stub.metrics.BuiltinMetricsConstants.BIGTABLE_CLIENT_METRICS; import static com.google.cloud.bigtable.data.v2.stub.metrics.BuiltinMetricsConstants.BIGTABLE_PROJECT_ID_KEY; import static com.google.cloud.bigtable.data.v2.stub.metrics.BuiltinMetricsConstants.CLIENT_UID_KEY; @@ -99,6 +100,14 @@ class BigtableExporterUtils { ImmutableSet.of( BIGTABLE_PROJECT_ID_KEY, INSTANCE_ID_KEY, TABLE_ID_KEY, CLUSTER_ID_KEY, ZONE_ID_KEY); + // These labels are defined on the Bigtable client resource. It's hard coded when we create the + // internal exporter for connection level metrics. For request level metrics, these attributes + // are updated with the actual value from the request and we use them to update the monitored + // schema. This is needed for BigtableDataClientFactory, when the otel instance is created with + // one instance / app profile but the actual call is on a different instance / app profile. + private static final Set> BIGTABLE_CLIENT_RESOURCE_LABEL = + ImmutableSet.of(BIGTABLE_PROJECT_ID_KEY, INSTANCE_ID_KEY, APP_PROFILE_KEY); + private static final Map SUPPORTED_PLATFORM_MAP = ImmutableMap.of( GCPPlatformDetector.SupportedPlatform.GOOGLE_COMPUTE_ENGINE, "gcp_compute_engine", @@ -318,7 +327,9 @@ private static Optional createInternalMetricsTimeSeries( // - the useless views should be removed // - internal metrics should use relative metric names w/o the prefix if (BIGTABLE_CLIENT_METRICS.contains(metricData.getName())) { - metricBuilder = newApplicationMetricBuilder(metricData.getName(), pointData.getAttributes()); + metricBuilder = + newApplicationMetricBuilder( + metricData.getName(), pointData.getAttributes(), applicationResource); } else if (GRPC_METRICS.containsKey(metricData.getName())) { metricBuilder = newGrpcMetricBuilder(metricData.getName(), pointData.getAttributes()); } else { @@ -343,11 +354,17 @@ private static Optional createInternalMetricsTimeSeries( } private static Metric.Builder newApplicationMetricBuilder( - String metricName, Attributes attributes) { + String metricName, Attributes attributes, MonitoredResource applicationResource) { + MonitoredResource.Builder updatedResource = applicationResource.toBuilder(); // TODO: unify handling of metric prefixes Metric.Builder metricBuilder = Metric.newBuilder().setType(metricName); for (Map.Entry, Object> e : attributes.asMap().entrySet()) { - metricBuilder.putLabels(e.getKey().getKey(), String.valueOf(e.getValue())); + AttributeKey key = e.getKey(); + if (BIGTABLE_CLIENT_RESOURCE_LABEL.contains(key)) { + updatedResource.putLabels(key.getKey(), String.valueOf(e.getValue())); + } else { + metricBuilder.putLabels(e.getKey().getKey(), String.valueOf(e.getValue())); + } } return metricBuilder; } diff --git a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/BuiltinMetricsConstants.java b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/BuiltinMetricsConstants.java index 848b485039..160e6716ea 100644 --- a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/BuiltinMetricsConstants.java +++ b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/BuiltinMetricsConstants.java @@ -57,6 +57,7 @@ public class BuiltinMetricsConstants { static final AttributeKey TRANSPORT_REGION = AttributeKey.stringKey("transport_region"); static final AttributeKey TRANSPORT_ZONE = AttributeKey.stringKey("transport_zone"); static final AttributeKey TRANSPORT_SUBZONE = AttributeKey.stringKey("transport_subzone"); + static final AttributeKey LB_POLICY_KEY = AttributeKey.stringKey("lb_policy"); // gRPC attribute keys // Note that these attributes keys from transformed from @@ -280,7 +281,13 @@ public static Map getBigtableClientViews() { InstrumentType.HISTOGRAM, "1", ImmutableSet.builder() - .add(BIGTABLE_PROJECT_ID_KEY, INSTANCE_ID_KEY, APP_PROFILE_KEY, CLIENT_NAME_KEY) + .add( + BIGTABLE_PROJECT_ID_KEY, + INSTANCE_ID_KEY, + APP_PROFILE_KEY, + TRANSPORT_TYPE, + STREAMING_KEY, + LB_POLICY_KEY) .build()); defineView( views, @@ -288,14 +295,24 @@ public static Map getBigtableClientViews() { null, InstrumentType.GAUGE, "1", - ImmutableSet.builder().add(METHOD_KEY).build()); + ImmutableSet.builder() + .add(BIGTABLE_PROJECT_ID_KEY, INSTANCE_ID_KEY, APP_PROFILE_KEY, METHOD_KEY) + .build()); defineView( views, BATCH_WRITE_FLOW_CONTROL_FACTOR_NAME, AGGREGATION_BATCH_WRITE_FLOW_CONTROL_FACTOR_HISTOGRAM, InstrumentType.HISTOGRAM, "1", - ImmutableSet.builder().add(STATUS_KEY, APPLIED_KEY, METHOD_KEY).build()); + ImmutableSet.builder() + .add( + BIGTABLE_PROJECT_ID_KEY, + INSTANCE_ID_KEY, + APP_PROFILE_KEY, + STATUS_KEY, + APPLIED_KEY, + METHOD_KEY) + .build()); return views.build(); } diff --git a/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/stub/metrics/BuiltinMetricsTracerTest.java b/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/stub/metrics/BuiltinMetricsTracerTest.java index 96aa8f91ec..5d158f865d 100644 --- a/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/stub/metrics/BuiltinMetricsTracerTest.java +++ b/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/stub/metrics/BuiltinMetricsTracerTest.java @@ -17,14 +17,17 @@ import static com.google.cloud.bigtable.data.v2.stub.metrics.BuiltinMetricsConstants.APPLICATION_BLOCKING_LATENCIES_NAME; import static com.google.cloud.bigtable.data.v2.stub.metrics.BuiltinMetricsConstants.APPLIED_KEY; +import static com.google.cloud.bigtable.data.v2.stub.metrics.BuiltinMetricsConstants.APP_PROFILE_KEY; import static com.google.cloud.bigtable.data.v2.stub.metrics.BuiltinMetricsConstants.ATTEMPT_LATENCIES_NAME; import static com.google.cloud.bigtable.data.v2.stub.metrics.BuiltinMetricsConstants.BATCH_WRITE_FLOW_CONTROL_FACTOR_NAME; import static com.google.cloud.bigtable.data.v2.stub.metrics.BuiltinMetricsConstants.BATCH_WRITE_FLOW_CONTROL_TARGET_QPS_NAME; +import static com.google.cloud.bigtable.data.v2.stub.metrics.BuiltinMetricsConstants.BIGTABLE_PROJECT_ID_KEY; import static com.google.cloud.bigtable.data.v2.stub.metrics.BuiltinMetricsConstants.CLIENT_BLOCKING_LATENCIES_NAME; import static com.google.cloud.bigtable.data.v2.stub.metrics.BuiltinMetricsConstants.CLIENT_NAME_KEY; import static com.google.cloud.bigtable.data.v2.stub.metrics.BuiltinMetricsConstants.CLUSTER_ID_KEY; import static com.google.cloud.bigtable.data.v2.stub.metrics.BuiltinMetricsConstants.CONNECTIVITY_ERROR_COUNT_NAME; import static com.google.cloud.bigtable.data.v2.stub.metrics.BuiltinMetricsConstants.FIRST_RESPONSE_LATENCIES_NAME; +import static com.google.cloud.bigtable.data.v2.stub.metrics.BuiltinMetricsConstants.INSTANCE_ID_KEY; import static com.google.cloud.bigtable.data.v2.stub.metrics.BuiltinMetricsConstants.METHOD_KEY; import static com.google.cloud.bigtable.data.v2.stub.metrics.BuiltinMetricsConstants.OPERATION_LATENCIES_NAME; import static com.google.cloud.bigtable.data.v2.stub.metrics.BuiltinMetricsConstants.REMAINING_DEADLINE_NAME; @@ -832,7 +835,13 @@ public void testBatchWriteFlowControlTargetQpsIncreased() throws InterruptedExce MetricData targetQpsMetric = getMetricData(metricReader, BATCH_WRITE_FLOW_CONTROL_TARGET_QPS_NAME); - Attributes targetQpsAttributes = Attributes.of(METHOD_KEY, "Bigtable.MutateRows"); + Attributes targetQpsAttributes = + Attributes.builder() + .put(METHOD_KEY, "Bigtable.MutateRows") + .put(BIGTABLE_PROJECT_ID_KEY, PROJECT_ID) + .put(INSTANCE_ID_KEY, INSTANCE_ID) + .put(APP_PROFILE_KEY, APP_PROFILE_ID) + .build(); double actual_qps = getAggregatedDoubleValue(targetQpsMetric, targetQpsAttributes); double expected_qps = 12; assertThat(expected_qps).isEqualTo(actual_qps); @@ -843,6 +852,9 @@ public void testBatchWriteFlowControlTargetQpsIncreased() throws InterruptedExce .put(METHOD_KEY, "Bigtable.MutateRows") .put(APPLIED_KEY, true) .put(STATUS_KEY, "OK") + .put(BIGTABLE_PROJECT_ID_KEY, PROJECT_ID) + .put(INSTANCE_ID_KEY, INSTANCE_ID) + .put(APP_PROFILE_KEY, APP_PROFILE_ID) .build(); double actual_factor_mean = getAggregatedDoubleValue(factorMetric, factorAttributes); double expected_factor_mean = 1.2; @@ -862,7 +874,12 @@ public void testBatchWriteFlowControlTargetQpsDecreased() throws InterruptedExce MetricData targetQpsMetric = getMetricData(metricReader, BATCH_WRITE_FLOW_CONTROL_TARGET_QPS_NAME); Attributes targetQpsAttributes = - Attributes.builder().put(METHOD_KEY, "Bigtable.MutateRows").build(); + Attributes.builder() + .put(METHOD_KEY, "Bigtable.MutateRows") + .put(BIGTABLE_PROJECT_ID_KEY, PROJECT_ID) + .put(INSTANCE_ID_KEY, INSTANCE_ID) + .put(APP_PROFILE_KEY, APP_PROFILE_ID) + .build(); double actual_qps = getAggregatedDoubleValue(targetQpsMetric, targetQpsAttributes); double expected_qps = 8.0; assertThat(expected_qps).isEqualTo(actual_qps); @@ -873,6 +890,9 @@ public void testBatchWriteFlowControlTargetQpsDecreased() throws InterruptedExce .put(METHOD_KEY, "Bigtable.MutateRows") .put(APPLIED_KEY, true) .put(STATUS_KEY, "OK") + .put(BIGTABLE_PROJECT_ID_KEY, PROJECT_ID) + .put(INSTANCE_ID_KEY, INSTANCE_ID) + .put(APP_PROFILE_KEY, APP_PROFILE_ID) .build(); double actual_factor_mean = getAggregatedDoubleValue(factorMetric, factorAttributes); double expected_factor_mean = 0.8; @@ -892,7 +912,12 @@ public void testBatchWriteFlowControlTargetQpsCappedOnMaxFactor() throws Interru MetricData targetQpsMetric = getMetricData(metricReader, BATCH_WRITE_FLOW_CONTROL_TARGET_QPS_NAME); Attributes targetQpsAttributes = - Attributes.builder().put(METHOD_KEY, "Bigtable.MutateRows").build(); + Attributes.builder() + .put(METHOD_KEY, "Bigtable.MutateRows") + .put(BIGTABLE_PROJECT_ID_KEY, PROJECT_ID) + .put(INSTANCE_ID_KEY, INSTANCE_ID) + .put(APP_PROFILE_KEY, APP_PROFILE_ID) + .build(); double actual_qps = getAggregatedDoubleValue(targetQpsMetric, targetQpsAttributes); // Factor is 1.8 but capped at 1.3 so updated QPS is 13. double expected_qps = 13; @@ -904,6 +929,9 @@ public void testBatchWriteFlowControlTargetQpsCappedOnMaxFactor() throws Interru .put(METHOD_KEY, "Bigtable.MutateRows") .put(APPLIED_KEY, true) .put(STATUS_KEY, "OK") + .put(BIGTABLE_PROJECT_ID_KEY, PROJECT_ID) + .put(INSTANCE_ID_KEY, INSTANCE_ID) + .put(APP_PROFILE_KEY, APP_PROFILE_ID) .build(); double actual_factor_mean = getAggregatedDoubleValue(factorMetric, factorAttributes); // Factor is 1.8 but capped at 1.3 @@ -924,7 +952,12 @@ public void testBatchWriteFlowControlTargetQpsCappedOnMinFactor() throws Interru MetricData targetQpsMetric = getMetricData(metricReader, BATCH_WRITE_FLOW_CONTROL_TARGET_QPS_NAME); Attributes targetQpsAttributes = - Attributes.builder().put(METHOD_KEY, "Bigtable.MutateRows").build(); + Attributes.builder() + .put(METHOD_KEY, "Bigtable.MutateRows") + .put(BIGTABLE_PROJECT_ID_KEY, PROJECT_ID) + .put(INSTANCE_ID_KEY, INSTANCE_ID) + .put(APP_PROFILE_KEY, APP_PROFILE_ID) + .build(); double actual_qps = getAggregatedDoubleValue(targetQpsMetric, targetQpsAttributes); // Factor is 0.5 but capped at 0.7 so updated QPS is 7. double expected_qps = 7; @@ -936,6 +969,9 @@ public void testBatchWriteFlowControlTargetQpsCappedOnMinFactor() throws Interru .put(METHOD_KEY, "Bigtable.MutateRows") .put(APPLIED_KEY, true) .put(STATUS_KEY, "OK") + .put(BIGTABLE_PROJECT_ID_KEY, PROJECT_ID) + .put(INSTANCE_ID_KEY, INSTANCE_ID) + .put(APP_PROFILE_KEY, APP_PROFILE_ID) .build(); double actual_factor_mean = getAggregatedDoubleValue(factorMetric, factorAttributes); // Factor is 0.5 but capped at 0.7 @@ -957,7 +993,12 @@ public void testBatchWriteFlowControlTargetQpsDecreasedForError() throws Interru MetricData targetQpsMetric = getMetricData(metricReader, BATCH_WRITE_FLOW_CONTROL_TARGET_QPS_NAME); Attributes targetQpsAttributes = - Attributes.builder().put(METHOD_KEY, "Bigtable.MutateRows").build(); + Attributes.builder() + .put(METHOD_KEY, "Bigtable.MutateRows") + .put(BIGTABLE_PROJECT_ID_KEY, PROJECT_ID) + .put(INSTANCE_ID_KEY, INSTANCE_ID) + .put(APP_PROFILE_KEY, APP_PROFILE_ID) + .build(); double actual_qps = getAggregatedDoubleValue(targetQpsMetric, targetQpsAttributes); // On error, min factor is applied. double expected_qps = 7; @@ -969,6 +1010,9 @@ public void testBatchWriteFlowControlTargetQpsDecreasedForError() throws Interru .put(METHOD_KEY, "Bigtable.MutateRows") .put(APPLIED_KEY, true) .put(STATUS_KEY, "UNAVAILABLE") + .put(BIGTABLE_PROJECT_ID_KEY, PROJECT_ID) + .put(INSTANCE_ID_KEY, INSTANCE_ID) + .put(APP_PROFILE_KEY, APP_PROFILE_ID) .build(); double actual_factor_mean = getAggregatedDoubleValue(factorMetric, factorAttributes); // On error, min factor is applied. From 74c071dc594b2241cee64d3167382d241ca7a561 Mon Sep 17 00:00:00 2001 From: Mattie Fu Date: Thu, 8 Jan 2026 19:04:44 -0500 Subject: [PATCH 7/8] fix test --- .../bigtable/data/v2/stub/metrics/BigtableExporterUtils.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/BigtableExporterUtils.java b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/BigtableExporterUtils.java index 126c4535fa..621c8cd648 100644 --- a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/BigtableExporterUtils.java +++ b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/BigtableExporterUtils.java @@ -362,9 +362,9 @@ private static Metric.Builder newApplicationMetricBuilder( AttributeKey key = e.getKey(); if (BIGTABLE_CLIENT_RESOURCE_LABEL.contains(key)) { updatedResource.putLabels(key.getKey(), String.valueOf(e.getValue())); - } else { - metricBuilder.putLabels(e.getKey().getKey(), String.valueOf(e.getValue())); } + + metricBuilder.putLabels(e.getKey().getKey(), String.valueOf(e.getValue())); } return metricBuilder; } From 40bfd69c522ce9fd01b3d60041311a4e9ceccd0f Mon Sep 17 00:00:00 2001 From: Mattie Fu Date: Thu, 8 Jan 2026 19:13:06 -0500 Subject: [PATCH 8/8] update comment --- .../data/v2/stub/metrics/BigtableExporterUtils.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/BigtableExporterUtils.java b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/BigtableExporterUtils.java index 621c8cd648..57c2251f1a 100644 --- a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/BigtableExporterUtils.java +++ b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/BigtableExporterUtils.java @@ -100,11 +100,11 @@ class BigtableExporterUtils { ImmutableSet.of( BIGTABLE_PROJECT_ID_KEY, INSTANCE_ID_KEY, TABLE_ID_KEY, CLUSTER_ID_KEY, ZONE_ID_KEY); - // These labels are defined on the Bigtable client resource. It's hard coded when we create the - // internal exporter for connection level metrics. For request level metrics, these attributes - // are updated with the actual value from the request and we use them to update the monitored - // schema. This is needed for BigtableDataClientFactory, when the otel instance is created with - // one instance / app profile but the actual call is on a different instance / app profile. + // These labels are defined on the bigtable_client monitored resource. For connection level + // metrics, they are hard coded from the settings when we create the internal otel. For per + // request metrics, we update the values of these fields with the values from metrics label. + // This is needed for BigtableDataClientFactory when the otel instance is created with the + // shared settings and the clients are created with different instances / app profile ids. private static final Set> BIGTABLE_CLIENT_RESOURCE_LABEL = ImmutableSet.of(BIGTABLE_PROJECT_ID_KEY, INSTANCE_ID_KEY, APP_PROFILE_KEY);