From 84052a8ce925c32c136ec9d46c93d6b3809157cb Mon Sep 17 00:00:00 2001 From: John Watson Date: Fri, 12 Mar 2021 07:58:48 -0800 Subject: [PATCH] Update the SemanticAttributes and ResourceAttributes for specification v1.1.0 (#3016) Note: this contains breaking changes to ResourceAttributes. --- buildscripts/semantic-convention/generate.sh | 5 +- .../extension/aws/resource/Ec2Resource.java | 2 +- .../aws/resource/Ec2ResourceTest.java | 4 +- .../attributes/ResourceAttributes.java | 119 +++++++++++++++--- .../trace/attributes/SemanticAttributes.java | 6 + 5 files changed, 113 insertions(+), 23 deletions(-) diff --git a/buildscripts/semantic-convention/generate.sh b/buildscripts/semantic-convention/generate.sh index c6a1934154..d59e911c1f 100755 --- a/buildscripts/semantic-convention/generate.sh +++ b/buildscripts/semantic-convention/generate.sh @@ -2,10 +2,9 @@ SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" ROOT_DIR="${SCRIPT_DIR}/../../" + # freeze the spec version to make SemanticAttributes generation reproducible -# this hash was obtained by calling `git rev-parse master` on 2021/01/07 -# we can't use a version tag here because otel-spec releases are very rare -SPEC_VERSION=d01d110b41b384e3d90169ec8d66d07f8b5963cd +SPEC_VERSION=v1.1.0 cd ${SCRIPT_DIR} diff --git a/sdk-extensions/aws/src/main/java/io/opentelemetry/sdk/extension/aws/resource/Ec2Resource.java b/sdk-extensions/aws/src/main/java/io/opentelemetry/sdk/extension/aws/resource/Ec2Resource.java index bcd150b3ee..fb9623984c 100644 --- a/sdk-extensions/aws/src/main/java/io/opentelemetry/sdk/extension/aws/resource/Ec2Resource.java +++ b/sdk-extensions/aws/src/main/java/io/opentelemetry/sdk/extension/aws/resource/Ec2Resource.java @@ -94,7 +94,7 @@ public final class Ec2Resource { attrBuilders.put(ResourceAttributes.HOST_ID, value); break; case "availabilityZone": - attrBuilders.put(ResourceAttributes.CLOUD_ZONE, value); + attrBuilders.put(ResourceAttributes.CLOUD_AVAILABILITY_ZONE, value); break; case "instanceType": attrBuilders.put(ResourceAttributes.HOST_TYPE, value); diff --git a/sdk-extensions/aws/src/test/java/io/opentelemetry/sdk/extension/aws/resource/Ec2ResourceTest.java b/sdk-extensions/aws/src/test/java/io/opentelemetry/sdk/extension/aws/resource/Ec2ResourceTest.java index 9f834a9aa4..91c166770b 100644 --- a/sdk-extensions/aws/src/test/java/io/opentelemetry/sdk/extension/aws/resource/Ec2ResourceTest.java +++ b/sdk-extensions/aws/src/test/java/io/opentelemetry/sdk/extension/aws/resource/Ec2ResourceTest.java @@ -56,7 +56,7 @@ class Ec2ResourceTest { expectedAttrBuilders.put(ResourceAttributes.CLOUD_PROVIDER, "aws"); expectedAttrBuilders.put(ResourceAttributes.HOST_ID, "i-1234567890abcdef0"); - expectedAttrBuilders.put(ResourceAttributes.CLOUD_ZONE, "us-west-2b"); + expectedAttrBuilders.put(ResourceAttributes.CLOUD_AVAILABILITY_ZONE, "us-west-2b"); expectedAttrBuilders.put(ResourceAttributes.HOST_TYPE, "t2.micro"); expectedAttrBuilders.put(ResourceAttributes.HOST_IMAGE_ID, "ami-5fb8c835"); expectedAttrBuilders.put(ResourceAttributes.CLOUD_ACCOUNT_ID, "123456789012"); @@ -90,7 +90,7 @@ class Ec2ResourceTest { Attributes.builder() .put(ResourceAttributes.CLOUD_PROVIDER, "aws") .put(ResourceAttributes.HOST_ID, "i-1234567890abcdef0") - .put(ResourceAttributes.CLOUD_ZONE, "us-west-2b") + .put(ResourceAttributes.CLOUD_AVAILABILITY_ZONE, "us-west-2b") .put(ResourceAttributes.HOST_TYPE, "t2.micro") .put(ResourceAttributes.HOST_IMAGE_ID, "ami-5fb8c835") .put(ResourceAttributes.CLOUD_ACCOUNT_ID, "123456789012") diff --git a/semconv/src/main/java/io/opentelemetry/semconv/resource/attributes/ResourceAttributes.java b/semconv/src/main/java/io/opentelemetry/semconv/resource/attributes/ResourceAttributes.java index 8139bd6337..f5aa633559 100644 --- a/semconv/src/main/java/io/opentelemetry/semconv/resource/attributes/ResourceAttributes.java +++ b/semconv/src/main/java/io/opentelemetry/semconv/resource/attributes/ResourceAttributes.java @@ -19,18 +19,34 @@ public final class ResourceAttributes { /** Name of the cloud provider. */ public static final AttributeKey CLOUD_PROVIDER = stringKey("cloud.provider"); - /** The cloud account ID used to identify different entities. */ + /** The cloud account ID the resource is assigned to. */ public static final AttributeKey CLOUD_ACCOUNT_ID = stringKey("cloud.account.id"); - /** A specific geographical location where different entities can run. */ + /** + * The geographical region the resource is running. Refer to your provider's docs to see the + * available regions, for example [AWS + * regions](https://aws.amazon.com/about-aws/global-infrastructure/regions_az/), [Azure + * regions](https://azure.microsoft.com/en-us/global-infrastructure/geographies/), or [Google + * Cloud regions](https://cloud.google.com/about/locations). + */ public static final AttributeKey CLOUD_REGION = stringKey("cloud.region"); /** - * Zones are a sub set of the region connected through low-latency links. + * Cloud regions often have multiple, isolated locations known as zones to increase availability. + * Availability zone represents the zone where the resource is running. * - *

Note: In AWS, this is called availability-zone. + *

Note: Availability zones are called "zones" on Google Cloud. */ - public static final AttributeKey CLOUD_ZONE = stringKey("cloud.zone"); + public static final AttributeKey CLOUD_AVAILABILITY_ZONE = + stringKey("cloud.availability_zone"); + + /** + * The cloud infrastructure resource in use. + * + *

Note: The prefix of the service SHOULD match the one specified in `cloud.provider`. + */ + public static final AttributeKey CLOUD_INFRASTRUCTURE_SERVICE = + stringKey("cloud.infrastructure_service"); /** * The Amazon Resource Name (ARN) of an [ECS container @@ -61,6 +77,9 @@ public final class ResourceAttributes { /** The task definition family this task definition is a member of. */ public static final AttributeKey AWS_ECS_TASK_FAMILY = stringKey("aws.ecs.task.family"); + /** The ARN of an EKS cluster. */ + public static final AttributeKey AWS_EKS_CLUSTER_ARN = stringKey("aws.eks.cluster.arn"); + /** * The name(s) of the AWS log group(s) an application is writing to. * @@ -98,12 +117,15 @@ public final class ResourceAttributes { public static final AttributeKey CONTAINER_NAME = stringKey("container.name"); /** - * Container id. Usually a UUID, as for example used to [identify Docker + * Container ID. Usually a UUID, as for example used to [identify Docker * containers](https://docs.docker.com/engine/reference/run/#container-identification). The UUID * might be abbreviated. */ public static final AttributeKey CONTAINER_ID = stringKey("container.id"); + /** The container runtime managing this container. */ + public static final AttributeKey CONTAINER_RUNTIME = stringKey("container.runtime"); + /** Name of the image the container was built on. */ public static final AttributeKey CONTAINER_IMAGE_NAME = stringKey("container.image.name"); @@ -143,7 +165,7 @@ public final class ResourceAttributes { /** * The amount of memory available to the serverless function in MiB. * - *

Note: It's recommended to set this attribute in since e.g. too little memory can easily + *

Note: It's recommended to set this attribute since e.g. too little memory can easily * stop a Java AWS Lambda function from working correctly. On AWS Lambda, the environment variable * `AWS_LAMBDA_FUNCTION_MEMORY_SIZE` provides this information. */ @@ -161,6 +183,9 @@ public final class ResourceAttributes { /** Type of host. For Cloud, this must be the machine type. */ public static final AttributeKey HOST_TYPE = stringKey("host.type"); + /** The CPU architecture the host system is running on. */ + public static final AttributeKey HOST_ARCH = stringKey("host.arch"); + /** Name of the VM image or OS install the host was instantiated from. */ public static final AttributeKey HOST_IMAGE_NAME = stringKey("host.image.name"); @@ -176,6 +201,12 @@ public final class ResourceAttributes { /** The name of the cluster. */ public static final AttributeKey K8S_CLUSTER_NAME = stringKey("k8s.cluster.name"); + /** The name of the Node. */ + public static final AttributeKey K8S_NODE_NAME = stringKey("k8s.node.name"); + + /** The UID of the Node. */ + public static final AttributeKey K8S_NODE_UID = stringKey("k8s.node.uid"); + /** The name of the namespace that the pod is running in. */ public static final AttributeKey K8S_NAMESPACE_NAME = stringKey("k8s.namespace.name"); @@ -321,14 +352,14 @@ public final class ResourceAttributes { * The string ID of the service instance. * *

Note: MUST be unique for each instance of the same `service.namespace,service.name` pair (in - * other words `service.namespace,service.name,service.id` triplet MUST be globally unique). The - * ID helps to distinguish instances of the same service that exist at the same time (e.g. - * instances of a horizontally scaled service). It is preferable for the ID to be persistent and - * stay the same for the lifetime of the service instance, however it is acceptable that the ID is - * ephemeral and changes during important lifetime events for the service (e.g. service restarts). - * If the service has no inherent unique ID that can be used as the value of this attribute it is - * recommended to generate a random Version 1 or Version 4 RFC 4122 UUID (services aiming for - * reproducible UUIDs may also use Version 5, see RFC 4122 for more recommendations). + * other words `service.namespace,service.name,service.instance.id` triplet MUST be globally + * unique). The ID helps to distinguish instances of the same service that exist at the same time + * (e.g. instances of a horizontally scaled service). It is preferable for the ID to be persistent + * and stay the same for the lifetime of the service instance, however it is acceptable that the + * ID is ephemeral and changes during important lifetime events for the service (e.g. service + * restarts). If the service has no inherent unique ID that can be used as the value of this + * attribute it is recommended to generate a random Version 1 or Version 4 RFC 4122 UUID (services + * aiming for reproducible UUIDs may also use Version 5, see RFC 4122 for more recommendations). */ public static final AttributeKey SERVICE_INSTANCE_ID = stringKey("service.instance.id"); @@ -362,11 +393,46 @@ public final class ResourceAttributes { private CloudProviderValues() {} } + public static final class CloudInfrastructureServiceValues { + /** AWS Elastic Compute Cloud. */ + public static final String AWS_EC2 = "aws_ec2"; + /** AWS Elastic Container Service. */ + public static final String AWS_ECS = "aws_ecs"; + /** AWS Elastic Kubernetes Service. */ + public static final String AWS_EKS = "aws_eks"; + /** AWS Lambda. */ + public static final String AWS_LAMBDA = "aws_lambda"; + /** AWS Elastic Beanstalk. */ + public static final String AWS_ELASTICBEANSTALK = "aws_elastic_beanstalk"; + /** Azure Virtual Machines. */ + public static final String AZURE_VM = "azure_vm"; + /** Azure Container Instances. */ + public static final String AZURE_CONTAINERINSTANCES = "azure_container_instances"; + /** Azure Kubernetes Service. */ + public static final String AZURE_AKS = "azure_aks"; + /** Azure Functions. */ + public static final String AZURE_FUNCTIONS = "azure_functions"; + /** Azure App Service. */ + public static final String AZURE_APPSERVICE = "azure_app_service"; + /** Google Cloud Compute Engine (GCE). */ + public static final String GCP_COMPUTEENGINE = "gcp_compute_engine"; + /** Google Cloud Run. */ + public static final String GCP_CLOUDRUN = "gcp_cloud_run"; + /** Google Cloud Kubernetes Engine (GKE). */ + public static final String GCP_KUBERNETESENGINE = "gcp_kubernetes_engine"; + /** Google Cloud Functions (GCF). */ + public static final String GCP_CLOUDFUNCTIONS = "gcp_cloud_functions"; + /** Google Cloud App Engine (GAE). */ + public static final String GCP_APPENGINE = "gcp_app_engine"; + + private CloudInfrastructureServiceValues() {} + } + public enum AwsEcsLaunchtypeValues { /** ec2. */ - EC2("EC2"), + EC2("ec2"), /** fargate. */ - FARGATE("Fargate"), + FARGATE("fargate"), ; private final String value; @@ -380,6 +446,25 @@ public final class ResourceAttributes { } } + public static final class HostArchValues { + /** AMD64. */ + public static final String AMD64 = "amd64"; + /** ARM32. */ + public static final String ARM32 = "arm32"; + /** ARM64. */ + public static final String ARM64 = "arm64"; + /** Itanium. */ + public static final String IA64 = "ia64"; + /** 32-bit PowerPC. */ + public static final String PPC32 = "ppc32"; + /** 64-bit PowerPC. */ + public static final String PPC64 = "ppc64"; + /** 32-bit x86. */ + public static final String X86 = "x86"; + + private HostArchValues() {} + } + public static final class OsTypeValues { /** Microsoft Windows. */ public static final String WINDOWS = "WINDOWS"; diff --git a/semconv/src/main/java/io/opentelemetry/semconv/trace/attributes/SemanticAttributes.java b/semconv/src/main/java/io/opentelemetry/semconv/trace/attributes/SemanticAttributes.java index 129bd06ecd..657f207a42 100644 --- a/semconv/src/main/java/io/opentelemetry/semconv/trace/attributes/SemanticAttributes.java +++ b/semconv/src/main/java/io/opentelemetry/semconv/trace/attributes/SemanticAttributes.java @@ -239,6 +239,10 @@ public final class SemanticAttributes { /** * Full HTTP request URL in the form `scheme://host[:port]/path?query[#fragment]`. Usually the * fragment is not transmitted over HTTP, but if it is known, it should be included nevertheless. + * + *

Note: `http.url` MUST NOT contain credentials passed via URL in form of + * `https://username:password@www.example.com/`. In such case the attribute's value should be + * `https://www.example.com/`. */ public static final AttributeKey HTTP_URL = stringKey("http.url"); @@ -631,6 +635,8 @@ public final class SemanticAttributes { public static final String NEO4J = "neo4j"; /** Apache Geode. */ public static final String GEODE = "geode"; + /** Elasticsearch. */ + public static final String ELASTICSEARCH = "elasticsearch"; private DbSystemValues() {} }