diff --git a/CHANGELOG.md b/CHANGELOG.md
index bbb24b357182..745d661ebd7b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,12 @@
# Changelog
+## [2.57.2](https://github.com/googleapis/java-bigtable/compare/v2.57.1...v2.57.2) (2025-03-31)
+
+
+### Bug Fixes
+
+* Library should released as 2.57.2 ([#2549](https://github.com/googleapis/java-bigtable/issues/2549)) ([58d0bbd](https://github.com/googleapis/java-bigtable/commit/58d0bbdcb983e3b5ee403edf45c4e98a6eb8dc16))
+
## [2.57.1](https://github.com/googleapis/java-bigtable/compare/v2.57.0...v2.57.1) (2025-03-24)
diff --git a/README.md b/README.md
index 84a689238e80..731d1d541970 100644
--- a/README.md
+++ b/README.md
@@ -56,13 +56,13 @@ implementation 'com.google.cloud:google-cloud-bigtable'
If you are using Gradle without BOM, add this to your dependencies:
```Groovy
-implementation 'com.google.cloud:google-cloud-bigtable:2.57.1'
+implementation 'com.google.cloud:google-cloud-bigtable:2.57.2'
```
If you are using SBT, add this to your dependencies:
```Scala
-libraryDependencies += "com.google.cloud" % "google-cloud-bigtable" % "2.57.1"
+libraryDependencies += "com.google.cloud" % "google-cloud-bigtable" % "2.57.2"
```
## Authentication
@@ -543,7 +543,7 @@ Java is a registered trademark of Oracle and/or its affiliates.
[kokoro-badge-link-5]: http://storage.googleapis.com/cloud-devrel-public/java/badges/java-bigtable/java11.html
[stability-image]: https://img.shields.io/badge/stability-stable-green
[maven-version-image]: https://img.shields.io/maven-central/v/com.google.cloud/google-cloud-bigtable.svg
-[maven-version-link]: https://central.sonatype.com/artifact/com.google.cloud/google-cloud-bigtable/2.57.1
+[maven-version-link]: https://central.sonatype.com/artifact/com.google.cloud/google-cloud-bigtable/2.57.2
[authentication]: https://github.com/googleapis/google-cloud-java#authentication
[auth-scopes]: https://developers.google.com/identity/protocols/oauth2/scopes
[predefined-iam-roles]: https://cloud.google.com/iam/docs/understanding-roles#predefined_roles
diff --git a/google-cloud-bigtable-bom/pom.xml b/google-cloud-bigtable-bom/pom.xml
index 3b98a74657cd..d33b117f584e 100644
--- a/google-cloud-bigtable-bom/pom.xml
+++ b/google-cloud-bigtable-bom/pom.xml
@@ -3,7 +3,7 @@
4.0.0
com.google.cloud
google-cloud-bigtable-bom
- 2.57.1
+ 2.57.2
pom
com.google.cloud
@@ -63,37 +63,37 @@
com.google.cloud
google-cloud-bigtable
- 2.57.1
+ 2.57.2
com.google.cloud
google-cloud-bigtable-emulator
- 0.194.1
+ 0.194.2
com.google.cloud
google-cloud-bigtable-emulator-core
- 0.194.1
+ 0.194.2
com.google.api.grpc
grpc-google-cloud-bigtable-admin-v2
- 2.57.1
+ 2.57.2
com.google.api.grpc
grpc-google-cloud-bigtable-v2
- 2.57.1
+ 2.57.2
com.google.api.grpc
proto-google-cloud-bigtable-admin-v2
- 2.57.1
+ 2.57.2
com.google.api.grpc
proto-google-cloud-bigtable-v2
- 2.57.1
+ 2.57.2
diff --git a/google-cloud-bigtable-deps-bom/pom.xml b/google-cloud-bigtable-deps-bom/pom.xml
index ce4ae5fd2258..f6d6361ef46d 100644
--- a/google-cloud-bigtable-deps-bom/pom.xml
+++ b/google-cloud-bigtable-deps-bom/pom.xml
@@ -13,7 +13,7 @@
com.google.cloud
google-cloud-bigtable-deps-bom
- 2.57.1
+ 2.57.2
pom
diff --git a/google-cloud-bigtable-emulator-core/pom.xml b/google-cloud-bigtable-emulator-core/pom.xml
index c7ae4011b2fd..ebfdd3a1ed90 100644
--- a/google-cloud-bigtable-emulator-core/pom.xml
+++ b/google-cloud-bigtable-emulator-core/pom.xml
@@ -7,11 +7,11 @@
google-cloud-bigtable-parent
com.google.cloud
- 2.57.1
+ 2.57.2
google-cloud-bigtable-emulator-core
- 0.194.1
+ 0.194.2
A Java wrapper for the Cloud Bigtable emulator.
diff --git a/google-cloud-bigtable-emulator/pom.xml b/google-cloud-bigtable-emulator/pom.xml
index ca3591a4a191..92c01699b273 100644
--- a/google-cloud-bigtable-emulator/pom.xml
+++ b/google-cloud-bigtable-emulator/pom.xml
@@ -5,7 +5,7 @@
4.0.0
google-cloud-bigtable-emulator
- 0.194.1
+ 0.194.2
Google Cloud Java - Bigtable Emulator
https://github.com/googleapis/java-bigtable
@@ -14,7 +14,7 @@
com.google.cloud
google-cloud-bigtable-parent
- 2.57.1
+ 2.57.2
scm:git:git@github.com:googleapis/java-bigtable.git
@@ -81,14 +81,14 @@
com.google.cloud
google-cloud-bigtable-deps-bom
- 2.57.1
+ 2.57.2
pom
import
com.google.cloud
google-cloud-bigtable-bom
- 2.57.1
+ 2.57.2
pom
import
@@ -99,7 +99,7 @@
com.google.cloud
google-cloud-bigtable-emulator-core
- 0.194.1
+ 0.194.2
diff --git a/google-cloud-bigtable/pom.xml b/google-cloud-bigtable/pom.xml
index cb7014698427..44b31f2c5f5c 100644
--- a/google-cloud-bigtable/pom.xml
+++ b/google-cloud-bigtable/pom.xml
@@ -2,7 +2,7 @@
4.0.0
google-cloud-bigtable
- 2.57.1
+ 2.57.2
jar
Google Cloud Bigtable
https://github.com/googleapis/java-bigtable
@@ -12,11 +12,11 @@
com.google.cloud
google-cloud-bigtable-parent
- 2.57.1
+ 2.57.2
- 2.57.1
+ 2.57.2
google-cloud-bigtable
@@ -52,14 +52,14 @@
com.google.cloud
google-cloud-bigtable-deps-bom
- 2.57.1
+ 2.57.2
pom
import
com.google.cloud
google-cloud-bigtable-bom
- 2.57.1
+ 2.57.2
pom
import
@@ -134,6 +134,10 @@
com.google.protobuf
protobuf-java-util
+
+ com.google.code.gson
+ gson
+
io.opencensus
opencensus-api
@@ -202,6 +206,10 @@
io.grpc
grpc-protobuf
+
+ io.grpc
+ grpc-opentelemetry
+
org.threeten
threetenbp
diff --git a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/Version.java b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/Version.java
index 8d409598c9af..d618ea6805c6 100644
--- a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/Version.java
+++ b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/Version.java
@@ -20,6 +20,6 @@
@InternalApi("For internal use only")
public final class Version {
// {x-version-update-start:google-cloud-bigtable:current}
- public static String VERSION = "2.57.1";
+ public static String VERSION = "2.57.2";
// {x-version-update-end}
}
diff --git a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/BigtableDataSettings.java b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/BigtableDataSettings.java
index ad1e70ba6aac..885cf36ab8d7 100644
--- a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/BigtableDataSettings.java
+++ b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/BigtableDataSettings.java
@@ -128,6 +128,7 @@ public static Builder newBuilderForEmulator(String hostname, int port) {
// disable channel refreshing when creating an emulator
.setRefreshingChannel(false)
.setMetricsProvider(NoopMetricsProvider.INSTANCE) // disable exporting metrics for emulator
+ .disableInternalMetrics()
.setTransportChannelProvider(
InstantiatingGrpcChannelProvider.newBuilder()
.setMaxInboundMessageSize(256 * 1024 * 1024)
@@ -297,6 +298,11 @@ public MetricsProvider getMetricsProvider() {
return stubSettings.getMetricsProvider();
}
+ /** Checks if internal metrics are enabled */
+ public boolean areInternalMetricsEnabled() {
+ return stubSettings.areInternalMetricsEnabled();
+ }
+
/** Returns the underlying RPC settings. */
public EnhancedBigtableStubSettings getStubSettings() {
return stubSettings;
@@ -570,6 +576,15 @@ public MetricsProvider getMetricsProvider() {
return stubSettings.getMetricsProvider();
}
+ public Builder disableInternalMetrics() {
+ stubSettings.disableInternalMetrics();
+ return this;
+ }
+
+ public boolean areInternalMetricsEnabled() {
+ return stubSettings.areInternalMetricsEnabled();
+ }
+
/**
* Returns the underlying settings for making RPC calls. The settings should be changed with
* care.
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 a2587b0dd90a..3fbdf29f39bf 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
@@ -26,13 +26,16 @@
import com.google.auth.oauth2.ServiceAccountJwtAccessCredentials;
import com.google.cloud.bigtable.data.v2.BigtableDataSettings;
import com.google.cloud.bigtable.data.v2.internal.JwtCredentialsWithAudience;
+import com.google.cloud.bigtable.data.v2.stub.metrics.BuiltinMetricsConstants;
import com.google.cloud.bigtable.data.v2.stub.metrics.CustomOpenTelemetryMetricsProvider;
import com.google.cloud.bigtable.data.v2.stub.metrics.DefaultMetricsProvider;
import com.google.cloud.bigtable.data.v2.stub.metrics.ErrorCountPerConnectionMetricTracker;
import com.google.cloud.bigtable.data.v2.stub.metrics.MetricsProvider;
import com.google.cloud.bigtable.data.v2.stub.metrics.NoopMetricsProvider;
import io.grpc.ManagedChannelBuilder;
+import io.grpc.opentelemetry.GrpcOpenTelemetry;
import io.opentelemetry.api.OpenTelemetry;
+import io.opentelemetry.sdk.OpenTelemetrySdk;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
@@ -50,6 +53,7 @@ public class BigtableClientContext {
private static final Logger logger = Logger.getLogger(BigtableClientContext.class.getName());
@Nullable private final OpenTelemetry openTelemetry;
+ @Nullable private final OpenTelemetrySdk internalOpenTelemetry;
private final ClientContext clientContext;
public static BigtableClientContext create(EnhancedBigtableStubSettings settings)
@@ -84,18 +88,32 @@ public static BigtableClientContext create(EnhancedBigtableStubSettings settings
? ((InstantiatingGrpcChannelProvider) builder.getTransportChannelProvider()).toBuilder()
: null;
- ErrorCountPerConnectionMetricTracker errorCountPerConnectionMetricTracker = null;
+ @Nullable OpenTelemetrySdk internalOtel = null;
+ @Nullable ErrorCountPerConnectionMetricTracker errorCountPerConnectionMetricTracker = null;
+
+ // Internal metrics are scoped to the connections, so we need a mutable transportProvider,
+ // otherwise there is
+ // no reason to build the internal OtelProvider
+ if (transportProvider != null) {
+ internalOtel =
+ settings.getInternalMetricsProvider().createOtelProvider(settings, credentials);
+ if (internalOtel != null) {
+ // Set up per connection error count tracker if all dependencies are met:
+ // a configurable transport provider + otel
+ errorCountPerConnectionMetricTracker =
+ setupPerConnectionErrorTracer(builder, transportProvider, internalOtel);
+
+ // Configure grpc metrics
+ configureGrpcOtel(transportProvider, internalOtel);
+ }
+ }
if (transportProvider != null) {
// Set up cookie holder if routing cookie is enabled
if (builder.getEnableRoutingCookie()) {
setupCookieHolder(transportProvider);
}
- // Set up per connection error count tracker if OpenTelemetry is not null
- if (openTelemetry != null) {
- errorCountPerConnectionMetricTracker =
- setupPerConnectionErrorTracer(builder, transportProvider, openTelemetry);
- }
+
// Inject channel priming if enabled
if (builder.isRefreshingChannel()) {
transportProvider.setChannelPrimer(
@@ -117,12 +135,43 @@ public static BigtableClientContext create(EnhancedBigtableStubSettings settings
clientContext.getExecutor());
}
- return new BigtableClientContext(clientContext, openTelemetry);
+ return new BigtableClientContext(clientContext, openTelemetry, internalOtel);
}
- private BigtableClientContext(ClientContext clientContext, OpenTelemetry openTelemetry) {
+ private static void configureGrpcOtel(
+ InstantiatingGrpcChannelProvider.Builder transportProvider, OpenTelemetrySdk otel) {
+
+ GrpcOpenTelemetry grpcOtel =
+ GrpcOpenTelemetry.newBuilder()
+ .sdk(otel)
+ .addOptionalLabel("grpc.lb.locality")
+ // Disable default grpc metrics
+ .disableAllMetrics()
+ // Enable specific grpc metrics
+ .enableMetrics(BuiltinMetricsConstants.GRPC_METRICS.keySet())
+ .build();
+
+ @SuppressWarnings("rawtypes")
+ ApiFunction oldConfigurator =
+ transportProvider.getChannelConfigurator();
+
+ transportProvider.setChannelConfigurator(
+ b -> {
+ if (oldConfigurator != null) {
+ b = oldConfigurator.apply(b);
+ }
+ grpcOtel.configureChannelBuilder(b);
+ return b;
+ });
+ }
+
+ private BigtableClientContext(
+ ClientContext clientContext,
+ OpenTelemetry openTelemetry,
+ @Nullable OpenTelemetrySdk internalOtel) {
this.clientContext = clientContext;
this.openTelemetry = openTelemetry;
+ this.internalOpenTelemetry = internalOtel;
}
public OpenTelemetry getOpenTelemetry() {
@@ -137,6 +186,9 @@ public void close() throws Exception {
for (BackgroundResource resource : clientContext.getBackgroundResources()) {
resource.close();
}
+ if (internalOpenTelemetry != null) {
+ internalOpenTelemetry.close();
+ }
}
private static OpenTelemetry getOpenTelemetryFromMetricsProvider(
diff --git a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/EnhancedBigtableStubSettings.java b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/EnhancedBigtableStubSettings.java
index d756a523707f..28d93863c958 100644
--- a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/EnhancedBigtableStubSettings.java
+++ b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/EnhancedBigtableStubSettings.java
@@ -32,6 +32,7 @@
import com.google.api.gax.rpc.StubSettings;
import com.google.api.gax.rpc.TransportChannelProvider;
import com.google.api.gax.rpc.UnaryCallSettings;
+import com.google.auth.Credentials;
import com.google.bigtable.v2.FeatureFlags;
import com.google.bigtable.v2.PingAndWarmRequest;
import com.google.cloud.bigtable.Version;
@@ -50,6 +51,7 @@
import com.google.cloud.bigtable.data.v2.models.sql.BoundStatement;
import com.google.cloud.bigtable.data.v2.stub.metrics.DefaultMetricsProvider;
import com.google.cloud.bigtable.data.v2.stub.metrics.MetricsProvider;
+import com.google.cloud.bigtable.data.v2.stub.metrics.Util;
import com.google.cloud.bigtable.data.v2.stub.mutaterows.MutateRowsBatchingDescriptor;
import com.google.cloud.bigtable.data.v2.stub.readrows.ReadRowsBatchingDescriptor;
import com.google.common.base.MoreObjects;
@@ -57,6 +59,7 @@
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
+import io.opentelemetry.sdk.OpenTelemetrySdk;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
@@ -283,6 +286,7 @@ public class EnhancedBigtableStubSettings extends StubSettings getJwtAudienceMapping() {
return jwtAudienceMapping;
@@ -1304,7 +1337,21 @@ public String toString() {
.add("prepareQuerySettings", prepareQuerySettings)
.add("metricsProvider", metricsProvider)
.add("metricsEndpoint", metricsEndpoint)
+ .add("areInternalMetricsEnabled", internalMetricsProvider == DEFAULT_INTERNAL_OTEL_PROVIDER)
.add("parent", super.toString())
.toString();
}
+
+ @InternalApi
+ @FunctionalInterface
+ public interface InternalMetricsProvider {
+ @Nullable
+ OpenTelemetrySdk createOtelProvider(
+ EnhancedBigtableStubSettings userSettings, Credentials creds) throws IOException;
+ }
+
+ private static final InternalMetricsProvider DEFAULT_INTERNAL_OTEL_PROVIDER =
+ Util::newInternalOpentelemetry;
+ private static final InternalMetricsProvider DISABLED_INTERNAL_OTEL_PROVIDER =
+ (ignored1, ignored2) -> null;
}
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 97c465127891..56c86027dac2 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
@@ -16,6 +16,7 @@
package com.google.cloud.bigtable.data.v2.stub.metrics;
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.ATTEMPT_LATENCIES2_NAME;
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.CLIENT_BLOCKING_LATENCIES_NAME;
import static com.google.cloud.bigtable.data.v2.stub.metrics.BuiltinMetricsConstants.CONNECTIVITY_ERROR_COUNT_NAME;
@@ -172,8 +173,10 @@ private CompletableResultCode doExport(Collection metricData) {
// Skips exporting if there's none
if (bigtableTimeSeries.isEmpty()) {
+ System.out.println("skipping empty metrics: " + this.exporterName);
return CompletableResultCode.ofSuccess();
}
+ System.out.println(bigtableTimeSeries);
CompletableResultCode exportCode = new CompletableResultCode();
bigtableTimeSeries.forEach(
@@ -282,6 +285,7 @@ static class PublicTimeSeriesConverter implements TimeSeriesConverter {
ImmutableSet.of(
OPERATION_LATENCIES_NAME,
ATTEMPT_LATENCIES_NAME,
+ ATTEMPT_LATENCIES2_NAME,
SERVER_LATENCIES_NAME,
FIRST_RESPONSE_LATENCIES_NAME,
CLIENT_BLOCKING_LATENCIES_NAME,
@@ -296,7 +300,7 @@ static class PublicTimeSeriesConverter implements TimeSeriesConverter {
private final String taskId;
PublicTimeSeriesConverter() {
- this(BigtableExporterUtils.DEFAULT_TABLE_VALUE.get());
+ this(BigtableExporterUtils.DEFAULT_TASK_VALUE.get());
}
PublicTimeSeriesConverter(String taskId) {
@@ -322,16 +326,10 @@ static class InternalTimeSeriesConverter implements TimeSeriesConverter {
.map(m -> METER_NAME + m)
.collect(ImmutableList.toImmutableList());
- private final String taskId;
private final Supplier monitoredResource;
InternalTimeSeriesConverter(Supplier monitoredResource) {
- this(monitoredResource, BigtableExporterUtils.DEFAULT_TABLE_VALUE.get());
- }
-
- InternalTimeSeriesConverter(Supplier monitoredResource, String taskId) {
this.monitoredResource = monitoredResource;
- this.taskId = taskId;
}
@Override
@@ -341,18 +339,10 @@ public Map> convert(Collection metricD
return ImmutableMap.of();
}
- List relevantData =
- metricData.stream()
- .filter(md -> APPLICATION_METRICS.contains(md.getName()))
- .collect(Collectors.toList());
- if (relevantData.isEmpty()) {
- return ImmutableMap.of();
- }
-
return ImmutableMap.of(
ProjectName.of(monitoredResource.getLabelsOrThrow(APPLICATION_RESOURCE_PROJECT_ID)),
BigtableExporterUtils.convertToApplicationResourceTimeSeries(
- relevantData, taskId, monitoredResource));
+ metricData, 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 904119891cf1..7998b5cfc61e 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
@@ -28,7 +28,9 @@
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;
@@ -36,13 +38,16 @@
import com.google.api.Distribution;
import com.google.api.Metric;
import com.google.api.MonitoredResource;
+import com.google.cloud.bigtable.Version;
+import com.google.cloud.bigtable.data.v2.stub.EnhancedBigtableStubSettings;
import com.google.cloud.opentelemetry.detection.AttributeKeys;
import com.google.cloud.opentelemetry.detection.DetectedPlatform;
import com.google.cloud.opentelemetry.detection.GCPPlatformDetector;
-import com.google.common.base.MoreObjects;
import com.google.common.base.Preconditions;
import com.google.common.base.Supplier;
import com.google.common.base.Suppliers;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.monitoring.v3.Point;
import com.google.monitoring.v3.ProjectName;
@@ -65,18 +70,23 @@
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
import java.util.Set;
import java.util.UUID;
import java.util.logging.Level;
import java.util.logging.Logger;
+import java.util.stream.Collectors;
import javax.annotation.Nullable;
/** Utils to convert OpenTelemetry types to Google Cloud Monitoring types. */
class BigtableExporterUtils {
+ private static final String CLIENT_NAME = "java-bigtable/" + Version.VERSION;
private static final Logger logger = Logger.getLogger(BigtableExporterUtils.class.getName());
@@ -87,6 +97,11 @@ class BigtableExporterUtils {
ImmutableSet.of(
BIGTABLE_PROJECT_ID_KEY, INSTANCE_ID_KEY, TABLE_ID_KEY, CLUSTER_ID_KEY, ZONE_ID_KEY);
+ private static final Map SUPPORTED_PLATFORM_MAP =
+ ImmutableMap.of(
+ GCPPlatformDetector.SupportedPlatform.GOOGLE_COMPUTE_ENGINE, "gcp_compute_engine",
+ GCPPlatformDetector.SupportedPlatform.GOOGLE_KUBERNETES_ENGINE, "gcp_kubernetes_engine");
+
private BigtableExporterUtils() {}
/**
@@ -95,7 +110,7 @@ private BigtableExporterUtils() {}
*/
private static String defaultTaskValue = null;
- static final Supplier DEFAULT_TABLE_VALUE =
+ static final Supplier DEFAULT_TASK_VALUE =
Suppliers.memoize(BigtableExporterUtils::computeDefaultTaskValue);
private static String computeDefaultTaskValue() {
@@ -146,30 +161,28 @@ static Map> convertToBigtableTimeSeries(
}
static List convertToApplicationResourceTimeSeries(
- Collection collection, String taskId, MonitoredResource applicationResource) {
+ Collection collection, MonitoredResource applicationResource) {
Preconditions.checkNotNull(
applicationResource,
"convert application metrics is called when the supported resource is not detected");
List allTimeSeries = new ArrayList<>();
for (MetricData metricData : collection) {
- if (!metricData.getInstrumentationScopeInfo().getName().equals(METER_NAME)) {
- // Filter out metric data for instruments that are not part of the bigtable builtin metrics
- continue;
- }
metricData.getData().getPoints().stream()
.map(
pointData ->
- convertPointToApplicationResourceTimeSeries(
- metricData, pointData, taskId, applicationResource))
- .forEach(allTimeSeries::add);
+ createInternalMetricsTimeSeries(metricData, pointData, applicationResource))
+ .filter(Optional::isPresent)
+ .forEach(ts -> ts.ifPresent(allTimeSeries::add));
}
return allTimeSeries;
}
@Nullable
- static MonitoredResource detectResourceSafe() {
+ static MonitoredResource createInternalMonitoredResource(EnhancedBigtableStubSettings settings) {
try {
- return detectResource();
+ MonitoredResource monitoredResource = detectResource(settings);
+ logger.log(Level.FINE, "Internal metrics monitored resource: %s", monitoredResource);
+ return monitoredResource;
} catch (Exception e) {
logger.log(
Level.WARNING,
@@ -180,64 +193,66 @@ static MonitoredResource detectResourceSafe() {
}
@Nullable
- private static MonitoredResource detectResource() {
+ private static MonitoredResource detectResource(EnhancedBigtableStubSettings settings) {
GCPPlatformDetector detector = GCPPlatformDetector.DEFAULT_INSTANCE;
DetectedPlatform detectedPlatform = detector.detectPlatform();
- MonitoredResource monitoredResource = null;
- try {
- switch (detectedPlatform.getSupportedPlatform()) {
- case GOOGLE_COMPUTE_ENGINE:
- monitoredResource =
- createGceMonitoredResource(
- detectedPlatform.getProjectId(), detectedPlatform.getAttributes());
- break;
- case GOOGLE_KUBERNETES_ENGINE:
- monitoredResource =
- createGkeMonitoredResource(
- detectedPlatform.getProjectId(), detectedPlatform.getAttributes());
- break;
- }
- } catch (IllegalStateException e) {
- logger.log(
- Level.WARNING,
- "Failed to create monitored resource for " + detectedPlatform.getSupportedPlatform(),
- e);
+
+ @Nullable
+ String cloud_platform = SUPPORTED_PLATFORM_MAP.get(detectedPlatform.getSupportedPlatform());
+ if (cloud_platform == null) {
+ return null;
}
- return monitoredResource;
- }
- private static MonitoredResource createGceMonitoredResource(
- String projectId, Map attributes) {
- return MonitoredResource.newBuilder()
- .setType("gce_instance")
- .putLabels("project_id", projectId)
- .putLabels("instance_id", getAttribute(attributes, AttributeKeys.GCE_INSTANCE_ID))
- .putLabels("zone", getAttribute(attributes, AttributeKeys.GCE_AVAILABILITY_ZONE))
- .build();
- }
+ Map attrs = detectedPlatform.getAttributes();
+ ImmutableList locationKeys =
+ ImmutableList.of(
+ AttributeKeys.GCE_CLOUD_REGION,
+ AttributeKeys.GCE_AVAILABILITY_ZONE,
+ AttributeKeys.GKE_LOCATION_TYPE_REGION,
+ AttributeKeys.GKE_CLUSTER_LOCATION);
+
+ String region =
+ locationKeys.stream().map(attrs::get).filter(Objects::nonNull).findFirst().orElse("global");
+
+ // Deal with possibility of a zone. Zones are of the form us-east1-c, but we want a region
+ // which, which is us-east1.
+ region = Arrays.stream(region.split("-")).limit(2).collect(Collectors.joining("-"));
+
+ String hostname = attrs.get(AttributeKeys.GCE_INSTANCE_HOSTNAME);
+ // if (hostname == null) {
+ // hostname = attrs.get(AttributeKeys.SERVERLESS_COMPUTE_NAME);
+ // }
+ // if (hostname == null) {
+ // hostname = attrs.get(AttributeKeys.GAE_MODULE_NAME);
+ // }
+ if (hostname == null) {
+ hostname = System.getenv("HOSTNAME");
+ }
+ if (hostname == null) {
+ try {
+ hostname = InetAddress.getLocalHost().getHostName();
+ } catch (UnknownHostException ignored) {
+ }
+ }
+ if (hostname == null) {
+ hostname = "";
+ }
- private static MonitoredResource createGkeMonitoredResource(
- String projectId, Map attributes) {
return MonitoredResource.newBuilder()
- .setType("k8s_container")
- .putLabels("project_id", projectId)
- .putLabels("location", getAttribute(attributes, AttributeKeys.GKE_CLUSTER_LOCATION))
- .putLabels("cluster_name", getAttribute(attributes, AttributeKeys.GKE_CLUSTER_NAME))
- .putLabels("namespace_name", MoreObjects.firstNonNull(System.getenv("NAMESPACE"), ""))
- .putLabels("pod_name", MoreObjects.firstNonNull(System.getenv("HOSTNAME"), ""))
- .putLabels("container_name", MoreObjects.firstNonNull(System.getenv("CONTAINER_NAME"), ""))
+ .setType("bigtable_client")
+ .putLabels("project_id", settings.getProjectId())
+ .putLabels("instance", settings.getInstanceId())
+ .putLabels("app_profile", settings.getAppProfileId())
+ .putLabels("client_project", detectedPlatform.getProjectId())
+ .putLabels("region", region)
+ .putLabels("cloud_platform", cloud_platform)
+ .putLabels("host_id", attrs.get(AttributeKeys.GKE_HOST_ID))
+ .putLabels("host_name", hostname)
+ .putLabels("client_name", CLIENT_NAME)
+ .putLabels("uuid", DEFAULT_TASK_VALUE.get())
.build();
}
- private static String getAttribute(Map attributes, String key) {
- String value = attributes.get(key);
- if (value == null) {
- throw new IllegalStateException(
- "Required attribute " + key + " does not exist in the attributes map " + attributes);
- }
- return value;
- }
-
private static TimeSeries convertPointToBigtableTimeSeries(
MetricData metricData, PointData pointData, String taskId) {
TimeSeries.Builder builder =
@@ -274,25 +289,30 @@ private static TimeSeries convertPointToBigtableTimeSeries(
return builder.build();
}
- private static TimeSeries convertPointToApplicationResourceTimeSeries(
- MetricData metricData,
- PointData pointData,
- String taskId,
- MonitoredResource applicationResource) {
+ private static Optional createInternalMetricsTimeSeries(
+ MetricData metricData, PointData pointData, MonitoredResource applicationResource) {
TimeSeries.Builder builder =
TimeSeries.newBuilder()
.setMetricKind(convertMetricKind(metricData))
.setValueType(convertValueType(metricData.getType()))
.setResource(applicationResource);
- Metric.Builder metricBuilder = Metric.newBuilder().setType(metricData.getName());
-
- Attributes attributes = pointData.getAttributes();
- for (AttributeKey> key : attributes.asMap().keySet()) {
- metricBuilder.putLabels(key.getKey(), String.valueOf(attributes.get(key)));
+ final Metric.Builder metricBuilder;
+ // TODO: clean this up
+ // Internal metrics are based on views that include the metric prefix
+ // gRPC metrics dont have views and are dot encoded
+ // 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())) {
+ metricBuilder = newApplicationMetricBuilder(metricData.getName(), pointData.getAttributes());
+ } else if (GRPC_METRICS.containsKey(metricData.getName())) {
+ metricBuilder = newGrpcMetricBuilder(metricData.getName(), pointData.getAttributes());
+ } else {
+ logger.fine("Skipping unexpected internal metric: " + metricData.getName());
+ return Optional.empty();
}
- metricBuilder.putLabels(CLIENT_UID_KEY.getKey(), taskId);
builder.setMetric(metricBuilder.build());
TimeInterval timeInterval =
@@ -302,7 +322,42 @@ private static TimeSeries convertPointToApplicationResourceTimeSeries(
.build();
builder.addPoints(createPoint(metricData.getType(), pointData, timeInterval));
- return builder.build();
+ return Optional.of(builder.build());
+ }
+
+ private static Metric.Builder newApplicationMetricBuilder(
+ String metricName, Attributes attributes) {
+ // 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()));
+ }
+ return metricBuilder;
+ }
+
+ private static Metric.Builder newGrpcMetricBuilder(String grpcMetricName, Attributes attributes) {
+ Set allowedAttrs = GRPC_METRICS.get(grpcMetricName);
+
+ Metric.Builder metricBuilder =
+ Metric.newBuilder()
+ .setType("bigtable.googleapis.com/internal/client/" + grpcMetricName.replace('.', '/'));
+ for (Map.Entry, Object> e : attributes.asMap().entrySet()) {
+ String attrKey = e.getKey().getKey();
+ Object attrValue = e.getValue();
+
+ // gRPC metrics are experimental and can change attribute names, to avoid incompatibility with
+ // the predefined
+ // metric schemas in stackdriver, filter out unknown keys
+ if (!allowedAttrs.contains(attrKey)) {
+ continue;
+ }
+ // translate grpc key format to be compatible with cloud monitoring:
+ // grpc.xds_client.server_failure -> grpc_xds_client_server_failure
+ String normalizedKey = attrKey.replace('.', '_');
+ metricBuilder.putLabels(normalizedKey, String.valueOf(attrValue));
+ }
+
+ return metricBuilder;
}
private static MetricKind convertMetricKind(MetricData metricData) {
diff --git a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/BigtableGrpcStreamTracer.java b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/BigtableGrpcStreamTracer.java
index 80fcdd0419de..a364adbc46e2 100644
--- a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/BigtableGrpcStreamTracer.java
+++ b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/BigtableGrpcStreamTracer.java
@@ -15,8 +15,10 @@
*/
package com.google.cloud.bigtable.data.v2.stub.metrics;
+import com.google.cloud.bigtable.data.v2.stub.metrics.BuiltinMetricsTracer.TransportAttrs;
import io.grpc.ClientStreamTracer;
import io.grpc.Metadata;
+import io.grpc.Status;
/**
* Records the time a request is enqueued in a grpc channel queue. This a bridge between gRPC stream
@@ -24,10 +26,16 @@
* asking gRPC to start an RPC and gRPC actually serializing that RPC.
*/
class BigtableGrpcStreamTracer extends ClientStreamTracer {
+ private static final String GRPC_LB_LOCALITY_KEY = "grpc.lb.locality";
+ private static final String GRPC_LB_BACKEND_SERVICE_KEY = "grpc.lb.backend_service";
+ private final StreamInfo info;
private final BigtableTracer tracer;
+ private volatile String backendService = null;
+ private volatile String locality = null;
- public BigtableGrpcStreamTracer(BigtableTracer tracer) {
+ public BigtableGrpcStreamTracer(StreamInfo info, BigtableTracer tracer) {
+ this.info = info;
this.tracer = tracer;
}
@@ -36,6 +44,26 @@ public void outboundMessageSent(int seqNo, long optionalWireSize, long optionalU
tracer.grpcMessageSent();
}
+ @Override
+ public void addOptionalLabel(String key, String value) {
+ switch (key) {
+ case GRPC_LB_LOCALITY_KEY:
+ this.locality = value;
+ break;
+ case GRPC_LB_BACKEND_SERVICE_KEY:
+ this.backendService = value;
+ break;
+ }
+
+ super.addOptionalLabel(key, value);
+ }
+
+ @Override
+ public void streamClosed(Status status) {
+ tracer.setTransportAttrs(TransportAttrs.create(locality, backendService));
+ super.streamClosed(status);
+ }
+
static class Factory extends ClientStreamTracer.Factory {
private final BigtableTracer tracer;
@@ -47,7 +75,7 @@ static class Factory extends ClientStreamTracer.Factory {
@Override
public ClientStreamTracer newClientStreamTracer(
ClientStreamTracer.StreamInfo info, Metadata headers) {
- return new BigtableGrpcStreamTracer(tracer);
+ return new BigtableGrpcStreamTracer(info, tracer);
}
}
}
diff --git a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/BigtableTracer.java b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/BigtableTracer.java
index 587475151216..1647bc4e6f96 100644
--- a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/BigtableTracer.java
+++ b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/BigtableTracer.java
@@ -91,6 +91,9 @@ public void setLocations(String zone, String cluster) {
// noop
}
+ /** Set the underlying transport used to process the attempt */
+ public void setTransportAttrs(BuiltinMetricsTracer.TransportAttrs attrs) {}
+
@Deprecated
/** @deprecated {@link #grpcMessageSent()} is called instead. */
public void grpcChannelQueuedLatencies(long queuedTimeMs) {
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 62ac0f11535c..78ed689cc3ab 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
@@ -50,9 +50,18 @@ public class BuiltinMetricsConstants {
static final AttributeKey STATUS_KEY = AttributeKey.stringKey("status");
static final AttributeKey CLIENT_UID_KEY = AttributeKey.stringKey("client_uid");
+ static final AttributeKey TRANSPORT_TYPE = AttributeKey.stringKey("transport_type");
+ 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");
+
+ public static final String METER_NAME = "bigtable.googleapis.com/internal/client/";
+
// Metric names
public static final String OPERATION_LATENCIES_NAME = "operation_latencies";
public static final String ATTEMPT_LATENCIES_NAME = "attempt_latencies";
+ // Temporary workaround for not being able to add new labels to ATTEMPT_LATENCIES_NAME
+ public static final String ATTEMPT_LATENCIES2_NAME = "attempt_latencies2";
static final String RETRY_COUNT_NAME = "retry_count";
static final String CONNECTIVITY_ERROR_COUNT_NAME = "connectivity_error_count";
static final String SERVER_LATENCIES_NAME = "server_latencies";
@@ -62,6 +71,40 @@ public class BuiltinMetricsConstants {
static final String CLIENT_BLOCKING_LATENCIES_NAME = "throttling_latencies";
static final String PER_CONNECTION_ERROR_COUNT_NAME = "per_connection_error_count";
+ // Start allow list of metrics that will be exported as internal
+ public static final Map> GRPC_METRICS =
+ ImmutableMap.>builder()
+ .put(
+ "grpc.client.attempt.duration",
+ ImmutableSet.of("grpc.lb.locality", "grpc.method", "grpc.target", "grpc.status"))
+ .put(
+ "grpc.lb.rls.default_target_picks",
+ ImmutableSet.of("grpc.lb.rls.data_plane_target", "grpc.lb.pick_result"))
+ .put(
+ "grpc.lb.rls.target_picks",
+ ImmutableSet.of(
+ "grpc.target",
+ "grpc.lb.rls.server_target",
+ "grpc.lb.rls.data_plane_target",
+ "grpc.lb.pick_result"))
+ .put(
+ "grpc.lb.rls.failed_picks",
+ ImmutableSet.of("grpc.target", "grpc.lb.rls.server_target"))
+ // TODO: "grpc.xds_client.connected"
+ .put("grpc.xds_client.server_failure", ImmutableSet.of("grpc.target", "grpc.xds.server"))
+ // TODO: "grpc.xds_client.resource_updates_valid",
+ .put(
+ "grpc.xds_client.resource_updates_invalid",
+ ImmutableSet.of("grpc.target", "grpc.xds.server", "grpc.xds.resource_type"))
+ // TODO: "grpc.xds_client.resources"
+ .build();
+
+ public static final Set INTERNAL_METRICS =
+ ImmutableSet.of(PER_CONNECTION_ERROR_COUNT_NAME).stream()
+ .map(m -> METER_NAME + m)
+ .collect(ImmutableSet.toImmutableSet());
+ // End allow list of metrics that will be exported
+
// Buckets under 100,000 are identical to buckets for server side metrics handler_latencies.
// Extending client side bucket to up to 3,200,000.
private static final Aggregation AGGREGATION_WITH_MILLIS_HISTOGRAM =
@@ -97,8 +140,6 @@ public class BuiltinMetricsConstants {
500_000.0,
1_000_000.0));
- public static final String METER_NAME = "bigtable.googleapis.com/internal/client/";
-
static final Set COMMON_ATTRIBUTES =
ImmutableSet.of(
BIGTABLE_PROJECT_ID_KEY,
@@ -140,6 +181,20 @@ static void defineView(
viewMap.put(selector, view);
}
+ public static Map getInternalViews() {
+ ImmutableMap.Builder views = ImmutableMap.builder();
+ defineView(
+ views,
+ PER_CONNECTION_ERROR_COUNT_NAME,
+ AGGREGATION_PER_CONNECTION_ERROR_COUNT_HISTOGRAM,
+ InstrumentType.HISTOGRAM,
+ "1",
+ ImmutableSet.builder()
+ .add(BIGTABLE_PROJECT_ID_KEY, INSTANCE_ID_KEY, APP_PROFILE_KEY, CLIENT_NAME_KEY)
+ .build());
+ return views.build();
+ }
+
public static Map getAllViews() {
ImmutableMap.Builder views = ImmutableMap.builder();
@@ -163,6 +218,22 @@ public static Map getAllViews() {
.addAll(COMMON_ATTRIBUTES)
.add(STREAMING_KEY, STATUS_KEY)
.build());
+ defineView(
+ views,
+ ATTEMPT_LATENCIES2_NAME,
+ AGGREGATION_WITH_MILLIS_HISTOGRAM,
+ InstrumentType.HISTOGRAM,
+ "ms",
+ ImmutableSet.builder()
+ .addAll(COMMON_ATTRIBUTES)
+ .add(
+ STREAMING_KEY,
+ STATUS_KEY,
+ TRANSPORT_TYPE,
+ TRANSPORT_REGION,
+ TRANSPORT_ZONE,
+ TRANSPORT_SUBZONE)
+ .build());
defineView(
views,
SERVER_LATENCIES_NAME,
@@ -205,16 +276,6 @@ public static Map getAllViews() {
InstrumentType.COUNTER,
"1",
ImmutableSet.builder().addAll(COMMON_ATTRIBUTES).add(STATUS_KEY).build());
-
- defineView(
- views,
- PER_CONNECTION_ERROR_COUNT_NAME,
- AGGREGATION_PER_CONNECTION_ERROR_COUNT_HISTOGRAM,
- InstrumentType.HISTOGRAM,
- "1",
- ImmutableSet.builder()
- .add(BIGTABLE_PROJECT_ID_KEY, INSTANCE_ID_KEY, APP_PROFILE_KEY, CLIENT_NAME_KEY)
- .build());
defineView(
views,
REMAINING_DEADLINE_NAME,
diff --git a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/BuiltinMetricsTracer.java b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/BuiltinMetricsTracer.java
index 92aa26c50c33..f9528759e649 100644
--- a/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/BuiltinMetricsTracer.java
+++ b/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/stub/metrics/BuiltinMetricsTracer.java
@@ -23,24 +23,34 @@
import static com.google.cloud.bigtable.data.v2.stub.metrics.BuiltinMetricsConstants.STATUS_KEY;
import static com.google.cloud.bigtable.data.v2.stub.metrics.BuiltinMetricsConstants.STREAMING_KEY;
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.TRANSPORT_REGION;
+import static com.google.cloud.bigtable.data.v2.stub.metrics.BuiltinMetricsConstants.TRANSPORT_SUBZONE;
+import static com.google.cloud.bigtable.data.v2.stub.metrics.BuiltinMetricsConstants.TRANSPORT_TYPE;
+import static com.google.cloud.bigtable.data.v2.stub.metrics.BuiltinMetricsConstants.TRANSPORT_ZONE;
import static com.google.cloud.bigtable.data.v2.stub.metrics.BuiltinMetricsConstants.ZONE_ID_KEY;
import com.google.api.core.ObsoleteApi;
import com.google.api.gax.retrying.ServerStreamingAttemptException;
import com.google.api.gax.tracing.SpanName;
+import com.google.auto.value.AutoValue;
import com.google.cloud.bigtable.Version;
import com.google.common.base.Stopwatch;
+import com.google.common.base.Strings;
import com.google.common.math.IntMath;
+import com.google.gson.Gson;
+import com.google.gson.reflect.TypeToken;
import io.grpc.Deadline;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.metrics.DoubleHistogram;
import io.opentelemetry.api.metrics.LongCounter;
import java.time.Duration;
+import java.util.Map;
import java.util.concurrent.CancellationException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
+import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.Nullable;
@@ -49,8 +59,23 @@
* bigtable.googleapis.com/client namespace
*/
class BuiltinMetricsTracer extends BigtableTracer {
+ @AutoValue
+ abstract static class TransportAttrs {
+ @Nullable
+ abstract String getLocality();
+
+ @Nullable
+ abstract String getBackendService();
+
+ static TransportAttrs create(@Nullable String locality, @Nullable String backendService) {
+ return new AutoValue_BuiltinMetricsTracer_TransportAttrs(locality, backendService);
+ }
+ }
private static final Logger logger = Logger.getLogger(BuiltinMetricsTracer.class.getName());
+ private static final Gson GSON = new Gson();
+ private static final TypeToken