diff --git a/java-bigtable/google-cloud-bigtable/pom.xml b/java-bigtable/google-cloud-bigtable/pom.xml
index aeea17b40db0..17e1db391fa2 100644
--- a/java-bigtable/google-cloud-bigtable/pom.xml
+++ b/java-bigtable/google-cloud-bigtable/pom.xml
@@ -247,10 +247,6 @@
io.opentelemetry
opentelemetry-sdk-common
-
- com.google.cloud.opentelemetry
- detector-resources-support
-
io.opentelemetry
opentelemetry-sdk-testing
@@ -264,6 +260,14 @@
com.google.api.grpc
proto-google-cloud-monitoring-v3
+
+ io.opentelemetry.contrib
+ opentelemetry-gcp-resources
+
+
+ io.opentelemetry
+ opentelemetry-sdk-extension-autoconfigure-spi
+
diff --git a/java-bigtable/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/internal/csm/attributes/EnvInfo.java b/java-bigtable/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/internal/csm/attributes/EnvInfo.java
index e45ea2607f5b..f36b37e78221 100644
--- a/java-bigtable/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/internal/csm/attributes/EnvInfo.java
+++ b/java-bigtable/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/internal/csm/attributes/EnvInfo.java
@@ -17,19 +17,15 @@
package com.google.cloud.bigtable.data.v2.internal.csm.attributes;
import com.google.auto.value.AutoValue;
-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.Function;
import com.google.common.base.Splitter;
import com.google.common.base.Supplier;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
+import io.opentelemetry.api.common.AttributeKey;
+import io.opentelemetry.api.common.Attributes;
+import io.opentelemetry.contrib.gcp.resource.GCPResourceProvider;
import java.lang.management.ManagementFactory;
import java.net.InetAddress;
import java.net.UnknownHostException;
-import java.util.Map;
-import java.util.Objects;
import java.util.Optional;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicLong;
@@ -47,11 +43,6 @@
public abstract class EnvInfo {
private static final Logger logger = Logger.getLogger(EnvInfo.class.getName());
- 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 static final AtomicLong uidSuffix = new AtomicLong(0);
public abstract String getUid();
@@ -110,7 +101,7 @@ private static String computeUid() {
public static EnvInfo detect() {
return detect(
- GCPPlatformDetector.DEFAULT_INSTANCE.detectPlatform(),
+ new GCPResourceProvider().getAttributes(),
System::getenv,
() -> {
try {
@@ -123,11 +114,11 @@ public static EnvInfo detect() {
@Nullable
static EnvInfo detect(
- DetectedPlatform detectedPlatform,
+ Attributes detectedAttributes,
Function envGetter,
Supplier hostnameSupplier) {
@Nullable
- String cloud_platform = SUPPORTED_PLATFORM_MAP.get(detectedPlatform.getSupportedPlatform());
+ String cloud_platform = detectedAttributes.get(AttributeKey.stringKey("cloud.platform"));
if (cloud_platform == null) {
return EnvInfo.builder()
.setPlatform("unknown")
@@ -138,32 +129,33 @@ static EnvInfo detect(
.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");
+ // All platform except GKE uses "cloud.region" for region attribute.
+ // GKE could either use "cloud.region" or "cloud.availability_zone" for region attribute.
+ String region = detectedAttributes.get(AttributeKey.stringKey("cloud.region"));
+ String gkeZonalClusterLocation =
+ detectedAttributes.get(AttributeKey.stringKey("cloud.availability_zone"));
+ if (region == null && gkeZonalClusterLocation != null) {
+ region = gkeZonalClusterLocation;
+ }
+ region = region == null ? "global" : region;
// 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 = Splitter.on('-').splitToStream(region).limit(2).collect(Collectors.joining("-"));
- String hostname = attrs.get(AttributeKeys.GCE_INSTANCE_NAME);
+ String hostname = detectedAttributes.get(AttributeKey.stringKey("host.name"));
+
// TODO: add support for cloud run & gae by looking at SERVERLESS_COMPUTE_NAME & GAE_MODULE_NAME
if (hostname == null) {
hostname = detectHostname(envGetter, hostnameSupplier);
}
- String hostId = Optional.ofNullable(attrs.get(AttributeKeys.GCE_INSTANCE_ID)).orElse("");
+ String hostId =
+ Optional.ofNullable(detectedAttributes.get(AttributeKey.stringKey("host.id"))).orElse("");
return builder()
.setPlatform(cloud_platform)
- .setProject(detectedPlatform.getProjectId())
+ .setProject(detectedAttributes.get(AttributeKey.stringKey("cloud.account.id")))
.setRegion(region)
.setHostId(hostId)
.setHostName(hostname)
diff --git a/java-bigtable/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/internal/csm/attributes/EnvInfoTest.java b/java-bigtable/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/internal/csm/attributes/EnvInfoTest.java
index 4c81aeb09396..3b3b874d3392 100644
--- a/java-bigtable/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/internal/csm/attributes/EnvInfoTest.java
+++ b/java-bigtable/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/internal/csm/attributes/EnvInfoTest.java
@@ -17,34 +17,24 @@
package com.google.cloud.bigtable.data.v2.internal.csm.attributes;
import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.Mockito.when;
-import com.google.cloud.opentelemetry.detection.DetectedPlatform;
-import com.google.cloud.opentelemetry.detection.GCPPlatformDetector.SupportedPlatform;
import com.google.common.base.Function;
import com.google.common.base.Supplier;
import com.google.common.collect.ImmutableMap;
+import io.opentelemetry.api.common.Attributes;
import java.util.Map;
import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.mockito.Mock;
-import org.mockito.junit.jupiter.MockitoExtension;
-@ExtendWith(MockitoExtension.class)
class EnvInfoTest {
private static final Supplier NULL_HOST = () -> null;
@SuppressWarnings("UnnecessaryLambda")
private static final Function NULL_ENV = (ignored) -> null;
- @Mock private DetectedPlatform detectedPlatform;
-
@Test
void testUid() {
- when(detectedPlatform.getSupportedPlatform()).thenReturn(SupportedPlatform.UNKNOWN_PLATFORM);
-
- EnvInfo info1 = EnvInfo.detect(detectedPlatform, NULL_ENV, NULL_HOST);
- EnvInfo info2 = EnvInfo.detect(detectedPlatform, NULL_ENV, NULL_HOST);
+ EnvInfo info1 = EnvInfo.detect(Attributes.empty(), NULL_ENV, NULL_HOST);
+ EnvInfo info2 = EnvInfo.detect(Attributes.empty(), NULL_ENV, NULL_HOST);
assertThat(info1.getUid()).isNotEmpty();
assertThat(info2.getUid()).isNotEmpty();
@@ -53,8 +43,7 @@ void testUid() {
@Test
void testUnknown() {
- when(detectedPlatform.getSupportedPlatform()).thenReturn(SupportedPlatform.UNKNOWN_PLATFORM);
- EnvInfo envInfo = EnvInfo.detect(detectedPlatform, NULL_ENV, NULL_HOST);
+ EnvInfo envInfo = EnvInfo.detect(Attributes.empty(), NULL_ENV, NULL_HOST);
assertThat(envInfo.getHostName()).isEmpty();
assertThat(envInfo.getHostId()).isEmpty();
assertThat(envInfo.getPlatform()).isEqualTo("unknown");
@@ -63,19 +52,16 @@ void testUnknown() {
@Test
void testGce() {
- when(detectedPlatform.getSupportedPlatform())
- .thenReturn(SupportedPlatform.GOOGLE_COMPUTE_ENGINE);
- when(detectedPlatform.getProjectId()).thenReturn("my-project");
- when(detectedPlatform.getAttributes())
- .thenReturn(
- ImmutableMap.of(
- "machine_type", "n2-standard-8",
- "availability_zone", "us-central1-c",
- "instance_id", "1234567890",
- "instance_name", "my-vm-name",
- "cloud_region", "us-central1",
- "instance_hostname", "my-vm-name.us-central1-c.c.my-project.google.com.internal"));
- EnvInfo envInfo = EnvInfo.detect(detectedPlatform, NULL_ENV, NULL_HOST);
+ Attributes attributes =
+ Attributes.builder()
+ .put("cloud.platform", "gcp_compute_engine")
+ .put("cloud.account.id", "my-project")
+ .put("cloud.region", "us-central1")
+ .put("cloud.availability_zone", "us-central1-c")
+ .put("host.id", "1234567890")
+ .put("host.name", "my-vm-name")
+ .build();
+ EnvInfo envInfo = EnvInfo.detect(attributes, NULL_ENV, NULL_HOST);
assertThat(envInfo.getPlatform()).isEqualTo("gcp_compute_engine");
assertThat(envInfo.getProject()).isEqualTo("my-project");
assertThat(envInfo.getRegion()).isEqualTo("us-central1");
@@ -84,20 +70,37 @@ void testGce() {
}
@Test
- void testGke() {
- when(detectedPlatform.getSupportedPlatform())
- .thenReturn(SupportedPlatform.GOOGLE_KUBERNETES_ENGINE);
- when(detectedPlatform.getProjectId()).thenReturn("my-project");
- when(detectedPlatform.getAttributes())
- .thenReturn(
- ImmutableMap.of(
- "gke_cluster_name", "my-cluster",
- "gke_cluster_location", "us-central1",
- "gke_cluster_location_type", "country-region",
- "instance_id", "1234567890"));
+ void testGkeRegionalCluster() {
+ Attributes attributes =
+ Attributes.builder()
+ .put("cloud.platform", "gcp_kubernetes_engine")
+ .put("cloud.account.id", "my-project")
+ .put("cloud.region", "us-central1")
+ .put("host.id", "1234567890")
+ .build();
+ Map env = ImmutableMap.of("HOSTNAME", "my-hostname");
+
+ EnvInfo envInfo = EnvInfo.detect(attributes, env::get, NULL_HOST);
+ assertThat(envInfo.getPlatform()).isEqualTo("gcp_kubernetes_engine");
+ assertThat(envInfo.getProject()).isEqualTo("my-project");
+ assertThat(envInfo.getRegion()).isEqualTo("us-central1");
+ assertThat(envInfo.getHostId()).isEqualTo("1234567890");
+ assertThat(envInfo.getHostName()).isEqualTo("my-hostname");
+ }
+
+ @Test
+ void testGkeZonalCluster() {
+ // Zonal GKE clusters report their location via cloud.availability_zone instead of cloud.region.
+ Attributes attributes =
+ Attributes.builder()
+ .put("cloud.platform", "gcp_kubernetes_engine")
+ .put("cloud.account.id", "my-project")
+ .put("cloud.availability_zone", "us-central1-c")
+ .put("host.id", "1234567890")
+ .build();
Map env = ImmutableMap.of("HOSTNAME", "my-hostname");
- EnvInfo envInfo = EnvInfo.detect(detectedPlatform, env::get, NULL_HOST);
+ EnvInfo envInfo = EnvInfo.detect(attributes, env::get, NULL_HOST);
assertThat(envInfo.getPlatform()).isEqualTo("gcp_kubernetes_engine");
assertThat(envInfo.getProject()).isEqualTo("my-project");
assertThat(envInfo.getRegion()).isEqualTo("us-central1");
@@ -106,18 +109,15 @@ void testGke() {
}
@Test
- void testGkeHostanmeFallback() {
- when(detectedPlatform.getSupportedPlatform())
- .thenReturn(SupportedPlatform.GOOGLE_KUBERNETES_ENGINE);
- when(detectedPlatform.getProjectId()).thenReturn("my-project");
- when(detectedPlatform.getAttributes())
- .thenReturn(
- ImmutableMap.of(
- "gke_cluster_name", "my-cluster",
- "gke_cluster_location", "us-central1",
- "gke_cluster_location_type", "country-region",
- "instance_id", "1234567890"));
- EnvInfo envInfo = EnvInfo.detect(detectedPlatform, NULL_ENV, () -> "my-hostname");
+ void testGkeHostnameFallback() {
+ Attributes attributes =
+ Attributes.builder()
+ .put("cloud.platform", "gcp_kubernetes_engine")
+ .put("cloud.account.id", "my-project")
+ .put("cloud.region", "us-central1")
+ .put("host.id", "1234567890")
+ .build();
+ EnvInfo envInfo = EnvInfo.detect(attributes, NULL_ENV, () -> "my-hostname");
assertThat(envInfo.getPlatform()).isEqualTo("gcp_kubernetes_engine");
assertThat(envInfo.getProject()).isEqualTo("my-project");
assertThat(envInfo.getRegion()).isEqualTo("us-central1");
diff --git a/java-bigtable/pom.xml b/java-bigtable/pom.xml
index bc0bb829a4ef..21241da704fc 100644
--- a/java-bigtable/pom.xml
+++ b/java-bigtable/pom.xml
@@ -292,6 +292,7 @@
maven-dependency-plugin
true
+ io.opentelemetry:opentelemetry-sdk-extension-autoconfigure-spi