diff --git a/contrib/resource_util/src/main/java/io/opencensus/contrib/resource/util/K8sResource.java b/contrib/resource_util/src/main/java/io/opencensus/contrib/resource/util/K8sResource.java index e2d7d2d367..6caa67fae9 100644 --- a/contrib/resource_util/src/main/java/io/opencensus/contrib/resource/util/K8sResource.java +++ b/contrib/resource_util/src/main/java/io/opencensus/contrib/resource/util/K8sResource.java @@ -19,8 +19,11 @@ import static com.google.common.base.MoreObjects.firstNonNull; import static com.google.common.base.Preconditions.checkNotNull; +import com.google.common.annotations.VisibleForTesting; +import com.google.common.base.Splitter; import io.opencensus.resource.Resource; import java.util.LinkedHashMap; +import java.util.List; import java.util.Map; /** @@ -57,6 +60,15 @@ public class K8sResource { */ public static final String POD_NAME_KEY = "k8s.pod.name"; + /** + * Key for the name of the deployment. + * + * @since 0.24 + */ + public static final String DEPLOYMENT_NAME_KEY = "k8s.deployment.name"; + + private static final Splitter splitter = Splitter.on('-'); + /** * Returns a {@link Resource} that describes Kubernetes deployment service. * @@ -65,20 +77,60 @@ public class K8sResource { * @param podName the k8s pod name. * @return a {@link Resource} that describes a k8s container. * @since 0.20 + * @deprecated in favor of {@link #create(String, String, String, String)}. */ + @Deprecated public static Resource create(String clusterName, String namespace, String podName) { + return create(clusterName, namespace, podName, ""); + } + + /** + * Returns a {@link Resource} that describes Kubernetes deployment service. + * + * @param clusterName the k8s cluster name. + * @param namespace the k8s namespace. + * @param podName the k8s pod name. + * @param deploymentName the k8s deployment name. + * @return a {@link Resource} that describes a k8s container. + * @since 0.24 + */ + public static Resource create( + String clusterName, String namespace, String podName, String deploymentName) { Map labels = new LinkedHashMap(); labels.put(CLUSTER_NAME_KEY, checkNotNull(clusterName, "clusterName")); labels.put(NAMESPACE_NAME_KEY, checkNotNull(namespace, "namespace")); labels.put(POD_NAME_KEY, checkNotNull(podName, "podName")); + labels.put(DEPLOYMENT_NAME_KEY, checkNotNull(deploymentName, "deploymentName")); return Resource.create(TYPE, labels); } static Resource detect() { + String podName = firstNonNull(System.getenv("HOSTNAME"), ""); + String deploymentName = getDeploymentNameFromPodName(podName); return create( GcpMetadataConfig.getClusterName(), firstNonNull(System.getenv("NAMESPACE"), ""), - firstNonNull(System.getenv("HOSTNAME"), "")); + podName, + deploymentName); + } + + @VisibleForTesting + static String getDeploymentNameFromPodName(String podName) { + StringBuilder deploymentName = new StringBuilder(); + // Extract deployment name from the pod name. Pod name is created using + // format: [deployment-name]-[Random-String-For-ReplicaSet]-[Random-String-For-Pod] + List parts = splitter.splitToList(podName); + if (parts.size() == 3) { + deploymentName.append(parts.get(0)); + } else if (parts.size() > 3) { // Deployment name could also contain '-' + for (int i = 0; i < parts.size() - 2; i++) { + if (deploymentName.length() > 0) { + deploymentName.append('-'); + } + deploymentName.append(parts.get(i)); + } + } + return deploymentName.toString(); } private K8sResource() {} diff --git a/contrib/resource_util/src/test/java/io/opencensus/contrib/resource/util/K8sResourceTest.java b/contrib/resource_util/src/test/java/io/opencensus/contrib/resource/util/K8sResourceTest.java index 5ed030fea5..0ed4f261aa 100644 --- a/contrib/resource_util/src/test/java/io/opencensus/contrib/resource/util/K8sResourceTest.java +++ b/contrib/resource_util/src/test/java/io/opencensus/contrib/resource/util/K8sResourceTest.java @@ -28,10 +28,11 @@ public class K8sResourceTest { private static final String K8S_CLUSTER_NAME = "cluster"; private static final String K8S_NAMESPACE_NAME = "namespace"; - private static final String K8S_POD_NAME = "pod-id"; + private static final String K8S_POD_NAME = "deployment-replica-pod"; + private static final String K8S_DEPLOYMENT_NAME = "deployment"; @Test - public void create_K8sContainerResourceTest() { + public void create_K8sContainerResourceTest_Deprecated() { Resource resource = K8sResource.create(K8S_CLUSTER_NAME, K8S_NAMESPACE_NAME, K8S_POD_NAME); assertThat(resource.getType()).isEqualTo(K8sResource.TYPE); assertThat(resource.getLabels()) @@ -41,6 +42,35 @@ public void create_K8sContainerResourceTest() { K8sResource.NAMESPACE_NAME_KEY, K8S_NAMESPACE_NAME, K8sResource.POD_NAME_KEY, - K8S_POD_NAME); + K8S_POD_NAME, + K8sResource.DEPLOYMENT_NAME_KEY, + ""); + } + + @Test + public void create_K8sContainerResourceTest() { + Resource resource = + K8sResource.create(K8S_CLUSTER_NAME, K8S_NAMESPACE_NAME, K8S_POD_NAME, K8S_DEPLOYMENT_NAME); + assertThat(resource.getType()).isEqualTo(K8sResource.TYPE); + assertThat(resource.getLabels()) + .containsExactly( + K8sResource.CLUSTER_NAME_KEY, + K8S_CLUSTER_NAME, + K8sResource.NAMESPACE_NAME_KEY, + K8S_NAMESPACE_NAME, + K8sResource.POD_NAME_KEY, + K8S_POD_NAME, + K8sResource.DEPLOYMENT_NAME_KEY, + K8S_DEPLOYMENT_NAME); + } + + @Test + public void getDeploymentNameFromPodName() { + assertThat(K8sResource.getDeploymentNameFromPodName(K8S_POD_NAME)) + .isEqualTo(K8S_DEPLOYMENT_NAME); + assertThat(K8sResource.getDeploymentNameFromPodName("")).isEqualTo(""); + assertThat(K8sResource.getDeploymentNameFromPodName("simple-name")).isEqualTo(""); + assertThat(K8sResource.getDeploymentNameFromPodName("deployment-name-replica-pod")) + .isEqualTo("deployment-name"); } }