diff --git a/.gitignore b/.gitignore
index ce59c1a2e6..dc26aa2f82 100644
--- a/.gitignore
+++ b/.gitignore
@@ -57,7 +57,7 @@ tags
.cache/clangd/*
# Temporary dir used when generating semconv
-./buildscripts/semantic-convention/opentelemetry-specification
+buildscripts/semantic-convention/tmp-semconv/
# Generated cert keys in functional tests
functional/cert/ca.csr
diff --git a/api/include/opentelemetry/trace/semantic_conventions.h b/api/include/opentelemetry/trace/semantic_conventions.h
index ecada99a41..42cf57d0ec 100644
--- a/api/include/opentelemetry/trace/semantic_conventions.h
+++ b/api/include/opentelemetry/trace/semantic_conventions.h
@@ -21,7 +21,159 @@ namespace SemanticConventions
/**
* The URL of the OpenTelemetry schema for these keys and values.
*/
-static constexpr const char *kSchemaUrl = "https://opentelemetry.io/schemas/1.20.0";
+static constexpr const char *kSchemaUrl = "https://opentelemetry.io/schemas/1.21.0";
+
+/**
+ * Client address - unix domain socket name, IPv4 or IPv6 address.
+ *
+ *
Notes:
+
- When observed from the server side, and when communicating through an intermediary,
+ {@code client.address} SHOULD represent client address behind any intermediaries (e.g. proxies) if
+ it's available.
+ */
+static constexpr const char *kClientAddress = "client.address";
+
+/**
+ * Client port number
+ *
+ * Notes:
+
- When observed from the server side, and when communicating through an intermediary,
+ {@code client.port} SHOULD represent client port behind any intermediaries (e.g. proxies) if it's
+ available.
+ */
+static constexpr const char *kClientPort = "client.port";
+
+/**
+ * Immediate client peer address - unix domain socket name, IPv4 or IPv6 address.
+ */
+static constexpr const char *kClientSocketAddress = "client.socket.address";
+
+/**
+ * Immediate client peer port number
+ */
+static constexpr const char *kClientSocketPort = "client.socket.port";
+
+/**
+ * Deprecated, use {@code http.request.method} instead.
+ */
+static constexpr const char *kHttpMethod = "http.method";
+
+/**
+ * Deprecated, use {@code http.response.status_code} instead.
+ */
+static constexpr const char *kHttpStatusCode = "http.status_code";
+
+/**
+ * Deprecated, use {@code url.scheme} instead.
+ */
+static constexpr const char *kHttpScheme = "http.scheme";
+
+/**
+ * Deprecated, use {@code url.full} instead.
+ */
+static constexpr const char *kHttpUrl = "http.url";
+
+/**
+ * Deprecated, use {@code url.path} and {@code url.query} instead.
+ */
+static constexpr const char *kHttpTarget = "http.target";
+
+/**
+ * Deprecated, use {@code http.request.body.size} instead.
+ */
+static constexpr const char *kHttpRequestContentLength = "http.request_content_length";
+
+/**
+ * Deprecated, use {@code http.response.body.size} instead.
+ */
+static constexpr const char *kHttpResponseContentLength = "http.response_content_length";
+
+/**
+ * Deprecated, use {@code server.socket.domain} on client spans.
+ */
+static constexpr const char *kNetSockPeerName = "net.sock.peer.name";
+
+/**
+ * Deprecated, use {@code server.socket.address} on client spans and {@code client.socket.address}
+ * on server spans.
+ */
+static constexpr const char *kNetSockPeerAddr = "net.sock.peer.addr";
+
+/**
+ * Deprecated, use {@code server.socket.port} on client spans and {@code client.socket.port} on
+ * server spans.
+ */
+static constexpr const char *kNetSockPeerPort = "net.sock.peer.port";
+
+/**
+ * Deprecated, use {@code server.address} on client spans and {@code client.address} on server
+ * spans.
+ */
+static constexpr const char *kNetPeerName = "net.peer.name";
+
+/**
+ * Deprecated, use {@code server.port} on client spans and {@code client.port} on server spans.
+ */
+static constexpr const char *kNetPeerPort = "net.peer.port";
+
+/**
+ * Deprecated, use {@code server.address}.
+ */
+static constexpr const char *kNetHostName = "net.host.name";
+
+/**
+ * Deprecated, use {@code server.port}.
+ */
+static constexpr const char *kNetHostPort = "net.host.port";
+
+/**
+ * Deprecated, use {@code server.socket.address}.
+ */
+static constexpr const char *kNetSockHostAddr = "net.sock.host.addr";
+
+/**
+ * Deprecated, use {@code server.socket.port}.
+ */
+static constexpr const char *kNetSockHostPort = "net.sock.host.port";
+
+/**
+ * Deprecated, use {@code network.transport}.
+ */
+static constexpr const char *kNetTransport = "net.transport";
+
+/**
+ * Deprecated, use {@code network.protocol.name}.
+ */
+static constexpr const char *kNetProtocolName = "net.protocol.name";
+
+/**
+ * Deprecated, use {@code network.protocol.version}.
+ */
+static constexpr const char *kNetProtocolVersion = "net.protocol.version";
+
+/**
+ * Deprecated, use {@code network.transport} and {@code network.type}.
+ */
+static constexpr const char *kNetSockFamily = "net.sock.family";
+
+/**
+ * The domain name of the destination system.
+ *
+ * Notes:
+
- This value may be a host name, a fully qualified domain name, or another host naming
+ format.
+ */
+static constexpr const char *kDestinationDomain = "destination.domain";
+
+/**
+ * Peer address, for example IP address or UNIX socket name.
+ */
+static constexpr const char *kDestinationAddress = "destination.address";
+
+/**
+ * Peer port number
+ */
+static constexpr const char *kDestinationPort = "destination.port";
/**
* The type of the exception (its fully-qualified class name, if applicable). The dynamic type of
@@ -42,18 +194,32 @@ static constexpr const char *kExceptionStacktrace = "exception.stacktrace";
/**
* HTTP request method.
- */
-static constexpr const char *kHttpMethod = "http.method";
+ *
+ * Notes:
+
- HTTP request method value SHOULD be "known" to the instrumentation.
+By default, this convention defines "known" methods as the ones listed in RFC9110 and the PATCH method
+defined in RFC5789.
- If the HTTP
+request method is not known to instrumentation, it MUST set the {@code http.request.method}
+attribute to {@code _OTHER} and, except if reporting a metric, MUST set the exact method received in
+the request line as value of the {@code http.request.method_original} attribute.
- If the HTTP
+instrumentation could end up converting valid HTTP request methods to {@code _OTHER}, then it MUST
+provide a way to override the list of known HTTP methods. If this override is done via environment
+variable, then the environment variable MUST be named OTEL_INSTRUMENTATION_HTTP_KNOWN_METHODS and
+support a comma-separated list of case-sensitive known HTTP methods (this list MUST be a full
+override of the default known method, it is not a list of known methods in addition to the
+defaults).
- HTTP method names are case-sensitive and {@code http.request.method} attribute
+value MUST match a known HTTP method name exactly. Instrumentations for specific web frameworks that
+consider HTTP methods to be case insensitive, SHOULD populate a canonical equivalent. Tracing
+instrumentations that do so, MUST also set {@code http.request.method_original} to the original
+value.
+ */
+static constexpr const char *kHttpRequestMethod = "http.request.method";
/**
* HTTP response status code.
*/
-static constexpr const char *kHttpStatusCode = "http.status_code";
-
-/**
- * The URI scheme identifying the used protocol.
- */
-static constexpr const char *kHttpScheme = "http.scheme";
+static constexpr const char *kHttpResponseStatusCode = "http.response.status_code";
/**
* The matched route (path template in the format used by the respective server framework). See note
@@ -62,8 +228,8 @@ below
* Notes:
- MUST NOT be populated when this is not supported by the HTTP server framework as the
route attribute should have low-cardinality and the URI path can NOT substitute it. SHOULD include
-the application
-root if there is one.
+the application root if there is
+one.
*/
static constexpr const char *kHttpRoute = "http.route";
@@ -92,6 +258,97 @@ Sortable Identifier (ULID), but other identifiers (e.g. UUID) may be used as
*/
static constexpr const char *kLogRecordUid = "log.record.uid";
+/**
+ * The stream associated with the log. See below for a list of well-known values.
+ */
+static constexpr const char *kLogIostream = "log.iostream";
+
+/**
+ * The basename of the file.
+ */
+static constexpr const char *kLogFileName = "log.file.name";
+
+/**
+ * The full path to the file.
+ */
+static constexpr const char *kLogFilePath = "log.file.path";
+
+/**
+ * The basename of the file, with symlinks resolved.
+ */
+static constexpr const char *kLogFileNameResolved = "log.file.name_resolved";
+
+/**
+ * The full path to the file, with symlinks resolved.
+ */
+static constexpr const char *kLogFilePathResolved = "log.file.path_resolved";
+
+/**
+ * The type of memory.
+ */
+static constexpr const char *kType = "type";
+
+/**
+ * Name of the memory pool.
+ *
+ * Notes:
+
+ */
+static constexpr const char *kPool = "pool";
+
+/**
+ * Logical server hostname, matches server FQDN if available, and IP or socket address if FQDN is
+ * not known.
+ */
+static constexpr const char *kServerAddress = "server.address";
+
+/**
+ * Logical server port number
+ */
+static constexpr const char *kServerPort = "server.port";
+
+/**
+ * The domain name of an immediate peer.
+ *
+ * Notes:
+
- Typically observed from the client side, and represents a proxy or other intermediary
+ domain name.
+ */
+static constexpr const char *kServerSocketDomain = "server.socket.domain";
+
+/**
+ * Physical server IP address or Unix socket address. If set from the client, should simply use the
+ * socket's peer address, and not attempt to find any actual server IP (i.e., if set from client,
+ * this may represent some proxy server instead of the logical server).
+ */
+static constexpr const char *kServerSocketAddress = "server.socket.address";
+
+/**
+ * Physical server port.
+ */
+static constexpr const char *kServerSocketPort = "server.socket.port";
+
+/**
+ * The domain name of the source system.
+ *
+ * Notes:
+
- This value may be a host name, a fully qualified domain name, or another host naming
+ format.
+ */
+static constexpr const char *kSourceDomain = "source.domain";
+
+/**
+ * Source address, for example IP address or Unix socket name.
+ */
+static constexpr const char *kSourceAddress = "source.address";
+
+/**
+ * Source port number
+ */
+static constexpr const char *kSourcePort = "source.port";
+
/**
* The full invoked ARN as provided on the {@code Context} passed to the function ({@code
Lambda-Runtime-Invoked-Function-Arn} header on the {@code /runtime/invocation/next} applicable).
@@ -203,7 +460,7 @@ static constexpr const char *kDbOperation = "db.operation";
name connecting to. This name is used to determine the port of a named instance.
*
* Notes:
-
- If setting a {@code db.mssql.instance_name}, {@code net.peer.port} is no longer required
+
- If setting a {@code db.mssql.instance_name}, {@code server.port} is no longer required
(but still recommended if non-standard).
*/
static constexpr const char *kDbMssqlInstanceName = "db.mssql.instance_name";
@@ -443,117 +700,70 @@ unavailable. String representation of the value should be determined by the impl
static constexpr const char *kFeatureFlagVariant = "feature_flag.variant";
/**
- * Transport protocol used. See note below.
+ * OSI Transport Layer or Inter-process Communication
+ * method. The value SHOULD be normalized to lowercase.
*/
-static constexpr const char *kNetTransport = "net.transport";
+static constexpr const char *kNetworkTransport = "network.transport";
/**
- * Application layer protocol used. The value SHOULD be normalized to lowercase.
+ * OSI Network Layer or non-OSI equivalent. The
+ * value SHOULD be normalized to lowercase.
*/
-static constexpr const char *kNetProtocolName = "net.protocol.name";
+static constexpr const char *kNetworkType = "network.type";
+
+/**
+ * OSI Application Layer or non-OSI
+ * equivalent. The value SHOULD be normalized to lowercase.
+ */
+static constexpr const char *kNetworkProtocolName = "network.protocol.name";
/**
* Version of the application layer protocol used. See note below.
*
* Notes:
-
- {@code net.protocol.version} refers to the version of the protocol used and might be
+
- {@code network.protocol.version} refers to the version of the protocol used and might be
different from the protocol client's version. If the HTTP client used has a version of {@code
0.27.2}, but sends HTTP version {@code 1.1}, this attribute should be set to {@code 1.1}.
*/
-static constexpr const char *kNetProtocolVersion = "net.protocol.version";
-
-/**
- * Remote socket peer name.
- */
-static constexpr const char *kNetSockPeerName = "net.sock.peer.name";
-
-/**
- * Remote socket peer address: IPv4 or IPv6 for internet protocols, path for local communication, etc.
- */
-static constexpr const char *kNetSockPeerAddr = "net.sock.peer.addr";
-
-/**
- * Remote socket peer port.
- */
-static constexpr const char *kNetSockPeerPort = "net.sock.peer.port";
-
-/**
- * Protocol address
- * family which is used for communication.
- */
-static constexpr const char *kNetSockFamily = "net.sock.family";
+static constexpr const char *kNetworkProtocolVersion = "network.protocol.version";
/**
- * Logical remote hostname, see note below.
- *
- * Notes:
-
- {@code net.peer.name} SHOULD NOT be set if capturing it would require an extra DNS
- lookup.
+ * The internet connection type.
*/
-static constexpr const char *kNetPeerName = "net.peer.name";
-
-/**
- * Logical remote port number
- */
-static constexpr const char *kNetPeerPort = "net.peer.port";
-
-/**
- * Logical local hostname or similar, see note below.
- */
-static constexpr const char *kNetHostName = "net.host.name";
-
-/**
- * Logical local port number, preferably the one that the peer used to connect
- */
-static constexpr const char *kNetHostPort = "net.host.port";
-
-/**
- * Local socket address. Useful in case of a multi-IP host.
- */
-static constexpr const char *kNetSockHostAddr = "net.sock.host.addr";
-
-/**
- * Local socket port number.
- */
-static constexpr const char *kNetSockHostPort = "net.sock.host.port";
-
-/**
- * The internet connection type currently being used by the host.
- */
-static constexpr const char *kNetHostConnectionType = "net.host.connection.type";
+static constexpr const char *kNetworkConnectionType = "network.connection.type";
/**
* This describes more details regarding the connection.type. It may be the type of cell technology
* connection, but it could be used for describing details about a wifi connection.
*/
-static constexpr const char *kNetHostConnectionSubtype = "net.host.connection.subtype";
+static constexpr const char *kNetworkConnectionSubtype = "network.connection.subtype";
/**
* The name of the mobile carrier.
*/
-static constexpr const char *kNetHostCarrierName = "net.host.carrier.name";
+static constexpr const char *kNetworkCarrierName = "network.carrier.name";
/**
* The mobile carrier country code.
*/
-static constexpr const char *kNetHostCarrierMcc = "net.host.carrier.mcc";
+static constexpr const char *kNetworkCarrierMcc = "network.carrier.mcc";
/**
* The mobile carrier network code.
*/
-static constexpr const char *kNetHostCarrierMnc = "net.host.carrier.mnc";
+static constexpr const char *kNetworkCarrierMnc = "network.carrier.mnc";
/**
* The ISO 3166-1 alpha-2 2-character country code associated with the mobile carrier network.
*/
-static constexpr const char *kNetHostCarrierIcc = "net.host.carrier.icc";
+static constexpr const char *kNetworkCarrierIcc = "network.carrier.icc";
/**
- * The {@code service.name} of
- * the remote service. SHOULD be equal to the actual {@code service.name} resource attribute of the
- * remote service if any.
+ * The {@code service.name} of the remote service.
+ * SHOULD be equal to the actual {@code service.name} resource attribute of the remote service if
+ * any.
*/
static constexpr const char *kPeerService = "peer.service";
@@ -620,13 +830,18 @@ static constexpr const char *kCodeLineno = "code.lineno";
*/
static constexpr const char *kCodeColumn = "code.column";
+/**
+ * Original HTTP method sent by the client in the request line.
+ */
+static constexpr const char *kHttpRequestMethodOriginal = "http.request.method_original";
+
/**
* The size of the request payload body in bytes. This is the number of bytes transferred excluding
* headers and is often, but not always, present as the Content-Length
* header. For requests using transport encoding, this should be the compressed size.
*/
-static constexpr const char *kHttpRequestContentLength = "http.request_content_length";
+static constexpr const char *kHttpRequestBodySize = "http.request.body.size";
/**
* The size of the response payload body in bytes. This is the number of bytes transferred excluding
@@ -634,18 +849,7 @@ static constexpr const char *kHttpRequestContentLength = "http.request_content_l
* href="https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length">Content-Length
* header. For requests using transport encoding, this should be the compressed size.
*/
-static constexpr const char *kHttpResponseContentLength = "http.response_content_length";
-
-/**
- * Full HTTP request URL in the form {@code scheme://host[:port]/path?query[#fragment]}. Usually the
- fragment is not transmitted over HTTP, but if it is known, it should be included nevertheless.
- *
- * Notes:
-
- {@code http.url} MUST NOT contain credentials passed via URL in form of {@code
- https://username:password@www.example.com/}. In such case the attribute's value should be {@code
- https://www.example.com/}.
- */
-static constexpr const char *kHttpUrl = "http.url";
+static constexpr const char *kHttpResponseBodySize = "http.response.body.size";
/**
* The ordinal number of request resending attempt (for any reason, including redirects).
@@ -657,28 +861,6 @@ static constexpr const char *kHttpUrl = "http.url";
*/
static constexpr const char *kHttpResendCount = "http.resend_count";
-/**
- * The full request target as passed in a HTTP request line or equivalent.
- */
-static constexpr const char *kHttpTarget = "http.target";
-
-/**
- * The IP address of the original client behind all proxies, if known (e.g. from X-Forwarded-For).
- *
- * Notes:
-
- This is not necessarily the same as {@code net.sock.peer.addr}, which would
-identify the network-level peer, which may be a proxy.
- This attribute should be set when a
-source of information different from the one used for {@code net.sock.peer.addr}, is available even
-if that other source just confirms the same value as {@code net.sock.peer.addr}. Rationale: For
-{@code net.sock.peer.addr}, one typically does not know if it comes from a proxy, reverse proxy, or
-the actual client. Setting
-{@code http.client_ip} when it's the same as {@code net.sock.peer.addr} means that
-one is at least somewhat confident that the address is not that of
-the closest proxy.
- */
-static constexpr const char *kHttpClientIp = "http.client_ip";
-
/**
* The AWS request ID as returned in the response headers {@code x-amz-request-id} or {@code
* x-amz-requestid}.
@@ -989,39 +1171,6 @@ static constexpr const char *kMessagingDestinationTemporary = "messaging.destina
*/
static constexpr const char *kMessagingDestinationAnonymous = "messaging.destination.anonymous";
-/**
- * The message source name
- *
- * Notes:
-
- Source name SHOULD uniquely identify a specific queue, topic, or other entity within the
-broker. If the broker does not have such notion, the source name SHOULD uniquely identify the
-broker.
- */
-static constexpr const char *kMessagingSourceName = "messaging.source.name";
-
-/**
- * Low cardinality representation of the messaging source name
- *
- * Notes:
-
- Source names could be constructed from templates. An example would be a source name
- involving a user name or product id. Although the source name in this case is of high cardinality,
- the underlying template is of low cardinality and can be effectively used for grouping and
- aggregation.
- */
-static constexpr const char *kMessagingSourceTemplate = "messaging.source.template";
-
-/**
- * A boolean that is true if the message source is temporary and might not exist anymore after
- * messages are processed.
- */
-static constexpr const char *kMessagingSourceTemporary = "messaging.source.temporary";
-
-/**
- * A boolean that is true if the message source is anonymous (could be unnamed or have
- * auto-generated name).
- */
-static constexpr const char *kMessagingSourceAnonymous = "messaging.source.anonymous";
-
/**
* A string identifying the messaging system.
*/
@@ -1049,12 +1198,9 @@ static constexpr const char *kMessagingOperation = "messaging.operation";
static constexpr const char *kMessagingBatchMessageCount = "messaging.batch.message_count";
/**
- * The identifier for the consumer receiving a message. For Kafka, set it to {@code
- * {messaging.kafka.consumer.group} - {messaging.kafka.client_id}}, if both are present, or only
- * {@code messaging.kafka.consumer.group}. For brokers, such as RabbitMQ and Artemis, set it to the
- * {@code client_id} of the client consuming the message.
+ * A unique identifier for the client that consumes or produces a message.
*/
-static constexpr const char *kMessagingConsumerId = "messaging.consumer.id";
+static constexpr const char *kMessagingClientId = "messaging.client_id";
/**
* RabbitMQ message routing key.
@@ -1080,22 +1226,12 @@ static constexpr const char *kMessagingKafkaMessageKey = "messaging.kafka.messag
*/
static constexpr const char *kMessagingKafkaConsumerGroup = "messaging.kafka.consumer.group";
-/**
- * Client Id for the Consumer or Producer that is handling the message.
- */
-static constexpr const char *kMessagingKafkaClientId = "messaging.kafka.client_id";
-
/**
* Partition the message is sent to.
*/
static constexpr const char *kMessagingKafkaDestinationPartition =
"messaging.kafka.destination.partition";
-/**
- * Partition the message is received from.
- */
-static constexpr const char *kMessagingKafkaSourcePartition = "messaging.kafka.source.partition";
-
/**
* The offset of a record in the corresponding Kafka partition.
*/
@@ -1117,11 +1253,6 @@ static constexpr const char *kMessagingRocketmqNamespace = "messaging.rocketmq.n
*/
static constexpr const char *kMessagingRocketmqClientGroup = "messaging.rocketmq.client_group";
-/**
- * The unique identifier for each client.
- */
-static constexpr const char *kMessagingRocketmqClientId = "messaging.rocketmq.client_id";
-
/**
* The timestamp in milliseconds that the delay message is expected to be delivered to consumer.
*/
@@ -1269,6 +1400,50 @@ recorded at a time where it was not clear whether the exception will escape. URI scheme component
+ * identifying the used protocol.
+ */
+static constexpr const char *kUrlScheme = "url.scheme";
+
+/**
+ * Absolute URL describing a network resource according to RFC3986
+ *
+ * Notes:
+
- For network calls, URL usually has {@code scheme://host[:port][path][?query][#fragment]}
+format, where the fragment is not transmitted over HTTP, but if it is known, it should be included
+nevertheless.
+{@code url.full} MUST NOT contain credentials passed via URL in form of {@code
+https://username:password@www.example.com/}. In such case username and password should be redacted
+and attribute's value should be {@code https://REDACTED:REDACTED@www.example.com/}.
+{@code url.full} SHOULD capture the absolute URL when it is available (or can be reconstructed) and
+SHOULD NOT be validated or modified except for sanitizing purposes.
+ */
+static constexpr const char *kUrlFull = "url.full";
+
+/**
+ * The URI path component
+ *
+ * Notes:
+
- When missing, the value is assumed to be {@code /}
+ */
+static constexpr const char *kUrlPath = "url.path";
+
+/**
+ * The URI query component
+ *
+ * Notes:
+
- Sensitive content provided in query string SHOULD be scrubbed when instrumentations can
+ identify it.
+ */
+static constexpr const char *kUrlQuery = "url.query";
+
+/**
+ * The URI fragment component
+ */
+static constexpr const char *kUrlFragment = "url.fragment";
+
/**
* Value of the HTTP
* User-Agent header sent by the client.
@@ -1276,6 +1451,54 @@ static constexpr const char *kExceptionEscaped = "exception.escaped";
static constexpr const char *kUserAgentOriginal = "user_agent.original";
// Enum definitions
+namespace NetTransportValues
+{
+/** ip_tcp. */
+static constexpr const char *kIpTcp = "ip_tcp";
+/** ip_udp. */
+static constexpr const char *kIpUdp = "ip_udp";
+/** Named or anonymous pipe. */
+static constexpr const char *kPipe = "pipe";
+/** In-process communication. */
+static constexpr const char *kInproc = "inproc";
+/** Something else (non IP-based). */
+static constexpr const char *kOther = "other";
+} // namespace NetTransportValues
+
+namespace NetSockFamilyValues
+{
+/** IPv4 address. */
+static constexpr const char *kInet = "inet";
+/** IPv6 address. */
+static constexpr const char *kInet6 = "inet6";
+/** Unix domain socket path. */
+static constexpr const char *kUnix = "unix";
+} // namespace NetSockFamilyValues
+
+namespace HttpRequestMethodValues
+{
+/** CONNECT method. */
+static constexpr const char *kConnect = "CONNECT";
+/** DELETE method. */
+static constexpr const char *kDelete = "DELETE";
+/** GET method. */
+static constexpr const char *kGet = "GET";
+/** HEAD method. */
+static constexpr const char *kHead = "HEAD";
+/** OPTIONS method. */
+static constexpr const char *kOptions = "OPTIONS";
+/** PATCH method. */
+static constexpr const char *kPatch = "PATCH";
+/** POST method. */
+static constexpr const char *kPost = "POST";
+/** PUT method. */
+static constexpr const char *kPut = "PUT";
+/** TRACE method. */
+static constexpr const char *kTrace = "TRACE";
+/** Any HTTP method that the instrumentation has no prior knowledge of. */
+static constexpr const char *kOther = "_OTHER";
+} // namespace HttpRequestMethodValues
+
namespace EventDomainValues
{
/** Events from browser apps. */
@@ -1286,6 +1509,22 @@ static constexpr const char *kDevice = "device";
static constexpr const char *kK8s = "k8s";
} // namespace EventDomainValues
+namespace LogIostreamValues
+{
+/** Logs from stdout stream. */
+static constexpr const char *kStdout = "stdout";
+/** Events from stderr stream. */
+static constexpr const char *kStderr = "stderr";
+} // namespace LogIostreamValues
+
+namespace TypeValues
+{
+/** Heap memory. */
+static constexpr const char *kHeap = "heap";
+/** Non-heap memory. */
+static constexpr const char *kNonHeap = "non_heap";
+} // namespace TypeValues
+
namespace OpentracingRefTypeValues
{
/** The parent Span depends on the child Span in some capacity. */
@@ -1517,31 +1756,27 @@ static constexpr const char *kGcp = "gcp";
static constexpr const char *kTencentCloud = "tencent_cloud";
} // namespace FaasInvokedProviderValues
-namespace NetTransportValues
+namespace NetworkTransportValues
{
-/** ip_tcp. */
-static constexpr const char *kIpTcp = "ip_tcp";
-/** ip_udp. */
-static constexpr const char *kIpUdp = "ip_udp";
+/** TCP. */
+static constexpr const char *kTcp = "tcp";
+/** UDP. */
+static constexpr const char *kUdp = "udp";
/** Named or anonymous pipe. See note below. */
static constexpr const char *kPipe = "pipe";
-/** In-process communication. */
-static constexpr const char *kInproc = "inproc";
-/** Something else (non IP-based). */
-static constexpr const char *kOther = "other";
-} // namespace NetTransportValues
+/** Unix domain socket. */
+static constexpr const char *kUnix = "unix";
+} // namespace NetworkTransportValues
-namespace NetSockFamilyValues
+namespace NetworkTypeValues
{
-/** IPv4 address. */
-static constexpr const char *kInet = "inet";
-/** IPv6 address. */
-static constexpr const char *kInet6 = "inet6";
-/** Unix domain socket path. */
-static constexpr const char *kUnix = "unix";
-} // namespace NetSockFamilyValues
+/** IPv4. */
+static constexpr const char *kIpv4 = "ipv4";
+/** IPv6. */
+static constexpr const char *kIpv6 = "ipv6";
+} // namespace NetworkTypeValues
-namespace NetHostConnectionTypeValues
+namespace NetworkConnectionTypeValues
{
/** wifi. */
static constexpr const char *kWifi = "wifi";
@@ -1553,9 +1788,9 @@ static constexpr const char *kCell = "cell";
static constexpr const char *kUnavailable = "unavailable";
/** unknown. */
static constexpr const char *kUnknown = "unknown";
-} // namespace NetHostConnectionTypeValues
+} // namespace NetworkConnectionTypeValues
-namespace NetHostConnectionSubtypeValues
+namespace NetworkConnectionSubtypeValues
{
/** GPRS. */
static constexpr const char *kGprs = "gprs";
@@ -1599,7 +1834,7 @@ static constexpr const char *kNr = "nr";
static constexpr const char *kNrnsa = "nrnsa";
/** LTE CA. */
static constexpr const char *kLteCa = "lte_ca";
-} // namespace NetHostConnectionSubtypeValues
+} // namespace NetworkConnectionSubtypeValues
namespace GraphqlOperationTypeValues
{
diff --git a/buildscripts/semantic-convention/generate.sh b/buildscripts/semantic-convention/generate.sh
index 2fd203013f..2a6634baa4 100755
--- a/buildscripts/semantic-convention/generate.sh
+++ b/buildscripts/semantic-convention/generate.sh
@@ -14,23 +14,26 @@ ROOT_DIR="${SCRIPT_DIR}/../../"
# freeze the spec & generator tools versions to make SemanticAttributes generation reproducible
-# repository: https://github.com/open-telemetry/opentelemetry-specification
-SEMCONV_VERSION=1.20.0
+# Repository up to 1.20.0:
+# https://github.com/open-telemetry/opentelemetry-specification
+# Repository from 1.21.0:
+# https://github.com/open-telemetry/semantic-conventions
+SEMCONV_VERSION=1.21.0
# repository: https://github.com/open-telemetry/build-tools
-GENERATOR_VERSION=0.18.0
+GENERATOR_VERSION=0.19.0
SPEC_VERSION=v$SEMCONV_VERSION
SCHEMA_URL=https://opentelemetry.io/schemas/$SEMCONV_VERSION
cd ${SCRIPT_DIR}
-rm -rf opentelemetry-specification || true
-mkdir opentelemetry-specification
-cd opentelemetry-specification
+rm -rf tmp-semconv || true
+mkdir tmp-semconv
+cd tmp-semconv
git init
-git remote add origin https://github.com/open-telemetry/opentelemetry-specification.git
+git remote add origin https://github.com/open-telemetry/semantic-conventions.git
git fetch origin "$SPEC_VERSION"
git reset --hard FETCH_HEAD
cd ${SCRIPT_DIR}
@@ -42,7 +45,7 @@ cd ${SCRIPT_DIR}
echo "Generating semantic conventions for traces ..."
docker run --rm \
- -v ${SCRIPT_DIR}/opentelemetry-specification/semantic_conventions:/source \
+ -v ${SCRIPT_DIR}/tmp-semconv/model:/source \
-v ${SCRIPT_DIR}/templates:/templates \
-v ${ROOT_DIR}/api/include/opentelemetry/trace/:/output \
otel/semconvgen:$GENERATOR_VERSION \
@@ -59,7 +62,7 @@ docker run --rm \
echo "Generating semantic conventions for resources ..."
docker run --rm \
- -v ${SCRIPT_DIR}/opentelemetry-specification/semantic_conventions:/source \
+ -v ${SCRIPT_DIR}/tmp-semconv/model:/source \
-v ${SCRIPT_DIR}/templates:/templates \
-v ${ROOT_DIR}/sdk/include/opentelemetry/sdk/resource/:/output \
otel/semconvgen:$GENERATOR_VERSION \
diff --git a/examples/grpc/client.cc b/examples/grpc/client.cc
index 11fde192b3..92088c12f6 100644
--- a/examples/grpc/client.cc
+++ b/examples/grpc/client.cc
@@ -53,8 +53,8 @@ class GreeterClient
{{SemanticConventions::kRpcSystem, "grpc"},
{SemanticConventions::kRpcService, "grpc-example.GreetService"},
{SemanticConventions::kRpcMethod, "Greet"},
- {SemanticConventions::kNetSockPeerAddr, ip},
- {SemanticConventions::kNetPeerPort, port}},
+ {SemanticConventions::kServerSocketAddress, ip},
+ {SemanticConventions::kServerPort, port}},
options);
auto scope = get_tracer("grpc-client")->WithActiveSpan(span);
diff --git a/examples/http/client.cc b/examples/http/client.cc
index 46be83bf2e..433f51a64f 100644
--- a/examples/http/client.cc
+++ b/examples/http/client.cc
@@ -26,9 +26,9 @@ void sendRequest(const std::string &url)
std::string span_name = url_parser.path_;
auto span = get_tracer("http-client")
->StartSpan(span_name,
- {{SemanticConventions::kHttpUrl, url_parser.url_},
- {SemanticConventions::kHttpScheme, url_parser.scheme_},
- {SemanticConventions::kHttpMethod, "GET"}},
+ {{SemanticConventions::kUrlFull, url_parser.url_},
+ {SemanticConventions::kUrlScheme, url_parser.scheme_},
+ {SemanticConventions::kHttpRequestMethod, "GET"}},
options);
auto scope = get_tracer("http-client")->WithActiveSpan(span);
@@ -44,7 +44,7 @@ void sendRequest(const std::string &url)
{
// set span attributes
auto status_code = result.GetResponse().GetStatusCode();
- span->SetAttribute(SemanticConventions::kHttpStatusCode, status_code);
+ span->SetAttribute(SemanticConventions::kHttpResponseStatusCode, status_code);
result.GetResponse().ForEachHeader(
[&span](nostd::string_view header_name, nostd::string_view header_value) {
span->SetAttribute("http.header." + std::string(header_name.data()), header_value);
diff --git a/examples/http/server.cc b/examples/http/server.cc
index 13f250684e..c2d7a2c5a3 100644
--- a/examples/http/server.cc
+++ b/examples/http/server.cc
@@ -40,13 +40,13 @@ class RequestHandler : public HTTP_SERVER_NS::HttpRequestCallback
// start span with parent context extracted from http header
auto span = get_tracer("http-server")
->StartSpan(span_name,
- {{SemanticConventions::kNetHostName, server_name},
- {SemanticConventions::kNetHostPort, server_port},
- {SemanticConventions::kHttpMethod, request.method},
- {SemanticConventions::kHttpScheme, "http"},
- {SemanticConventions::kHttpRequestContentLength,
+ {{SemanticConventions::kServerAddress, server_name},
+ {SemanticConventions::kServerPort, server_port},
+ {SemanticConventions::kHttpRequestMethod, request.method},
+ {SemanticConventions::kUrlScheme, "http"},
+ {SemanticConventions::kHttpRequestBodySize,
static_cast(request.content.length())},
- {SemanticConventions::kHttpClientIp, request.client}},
+ {SemanticConventions::kClientAddress, request.client}},
options);
auto scope = get_tracer("http_server")->WithActiveSpan(span);
diff --git a/sdk/include/opentelemetry/sdk/resource/semantic_conventions.h b/sdk/include/opentelemetry/sdk/resource/semantic_conventions.h
index f1315d9262..e96f052caf 100644
--- a/sdk/include/opentelemetry/sdk/resource/semantic_conventions.h
+++ b/sdk/include/opentelemetry/sdk/resource/semantic_conventions.h
@@ -23,7 +23,7 @@ namespace SemanticConventions
/**
* The URL of the OpenTelemetry schema for these keys and values.
*/
-static constexpr const char *kSchemaUrl = "https://opentelemetry.io/schemas/1.20.0";
+static constexpr const char *kSchemaUrl = "https://opentelemetry.io/schemas/1.21.0";
/**
* Array of brand name and version separated by a space
@@ -221,6 +221,37 @@ static constexpr const char *kAwsLogStreamNames = "aws.log.stream.names";
*/
static constexpr const char *kAwsLogStreamArns = "aws.log.stream.arns";
+/**
+ * The name of the Cloud Run execution being run for the
+ * Job, as set by the {@code
+ * CLOUD_RUN_EXECUTION} environment variable.
+ */
+static constexpr const char *kGcpCloudRunJobExecution = "gcp.cloud_run.job.execution";
+
+/**
+ * The index for a task within an execution as provided by the {@code
+ * CLOUD_RUN_TASK_INDEX} environment variable.
+ */
+static constexpr const char *kGcpCloudRunJobTaskIndex = "gcp.cloud_run.job.task_index";
+
+/**
+ * The instance name of a GCE instance. This is the value provided by {@code host.name}, the visible
+ * name of the instance in the Cloud Console UI, and the prefix for the default hostname of the
+ * instance as defined by the default
+ * internal DNS name.
+ */
+static constexpr const char *kGcpGceInstanceName = "gcp.gce.instance.name";
+
+/**
+ * The hostname of a GCE instance. This is the full value of the default or custom hostname.
+ */
+static constexpr const char *kGcpGceInstanceHostname = "gcp.gce.instance.hostname";
+
/**
* Time and date the release was created
*/
@@ -263,6 +294,39 @@ static constexpr const char *kContainerImageName = "container.image.name";
*/
static constexpr const char *kContainerImageTag = "container.image.tag";
+/**
+ * Runtime specific image identifier. Usually a hash algorithm followed by a UUID.
+ *
+ * Notes:
+
- Docker defines a sha256 of the image id; {@code container.image.id} corresponds to the
+{@code Image} field from the Docker container inspect API
+endpoint. K8s defines a link to the container registry repository with digest {@code "imageID":
+"registry.azurecr.io
+/namespace/service/dockerfile@sha256:bdeabd40c3a8a492eaf9e8e44d0ebbb84bac7ee25ac0cf8a7159d25f62555625"}.
+OCI defines a digest of manifest.
+ */
+static constexpr const char *kContainerImageId = "container.image.id";
+
+/**
+ * The command used to run the container (i.e. the command name).
+ *
+ * Notes:
+
- If using embedded credentials or sensitive data, it is recommended to remove them to
+ prevent potential leakage.
+ */
+static constexpr const char *kContainerCommand = "container.command";
+
+/**
+ * The full command run by the container as a single string representing the full command. [2]
+ */
+static constexpr const char *kContainerCommandLine = "container.command_line";
+
+/**
+ * All the command arguments (including the command/executable itself) run by the container. [2]
+ */
+static constexpr const char *kContainerCommandArgs = "container.command_args";
+
/**
* Name of the deployment
* environment (aka deployment tier).
@@ -322,15 +386,14 @@ static constexpr const char *kDeviceManufacturer = "device.manufacturer";
- This is the name of the function as configured/deployed on the FaaS
platform and is usually different from the name of the callback
function (which may be stored in the
-{@code
-code.namespace}/{@code code.function} span attributes).
- For some cloud providers, the
-above definition is ambiguous. The following definition of function name MUST be used for this
-attribute (and consequently the span name) for the listed cloud
-providers/products:
- Azure: The full name {@code /}, i.e.,
-function app name followed by a forward slash followed by the function name (this form can also be
-seen in the resource JSON for the function). This means that a span attribute MUST be used, as an
-Azure function app can host multiple functions that would usually share a TracerProvider (see also
-the {@code cloud.resource_id} attribute).
+{@code code.namespace}/{@code
+code.function} span attributes).
- For some cloud providers, the above definition is
+ambiguous. The following definition of function name MUST be used for this attribute (and
+consequently the span name) for the listed cloud providers/products:
- Azure:
+The full name {@code /}, i.e., function app name followed by a forward slash followed
+by the function name (this form can also be seen in the resource JSON for the function). This means
+that a span attribute MUST be used, as an Azure function app can host multiple functions that would
+usually share a TracerProvider (see also the {@code cloud.resource_id} attribute).
*/
static constexpr const char *kFaasName = "faas.name";
@@ -341,10 +404,11 @@ static constexpr const char *kFaasName = "faas.name";
* Notes:
- Depending on the cloud provider and platform, use:
- AWS Lambda:
The function
-version (an integer represented as a decimal string).
- Google Cloud
-Run: The revision (i.e.,
-the function name plus the revision suffix).
- Google Cloud Functions: The
-value of the (an integer represented as a decimal string).
- Google Cloud Run
+(Services): The revision
+(i.e., the function name plus the revision suffix).
+- Google Cloud Functions: The value of the
+{@code
K_REVISION} environment variable.
- Azure Functions: Not applicable. Do
not set this attribute.
@@ -402,13 +466,13 @@ static constexpr const char *kHostArch = "host.arch";
static constexpr const char *kHostImageName = "host.image.name";
/**
- * VM image ID. For Cloud, this value is from the provider.
+ * VM image ID or host OS image ID. For Cloud, this value is from the provider.
*/
static constexpr const char *kHostImageId = "host.image.id";
/**
- * The version string of the VM image as defined in Version
- * Attributes.
+ * The version string of the VM image or host OS as defined in Version Attributes.
*/
static constexpr const char *kHostImageVersion = "host.image.version";
@@ -417,6 +481,30 @@ static constexpr const char *kHostImageVersion = "host.image.version";
*/
static constexpr const char *kK8sClusterName = "k8s.cluster.name";
+/**
+ * A pseudo-ID for the cluster, set to the UID of the {@code kube-system} namespace.
+ *
+ * Notes:
+
- K8s does not have support for obtaining a cluster ID. If this is ever
+added, we will recommend collecting the {@code k8s.cluster.uid} through the
+official APIs. In the meantime, we are able to use the {@code uid} of the
+{@code kube-system} namespace as a proxy for cluster ID. Read on for the
+rationale.
- Every object created in a K8s cluster is assigned a distinct UID. The
+{@code kube-system} namespace is used by Kubernetes itself and will exist
+for the lifetime of the cluster. Using the {@code uid} of the {@code kube-system}
+namespace is a reasonable proxy for the K8s ClusterID as it will only
+change if the cluster is rebuilt. Furthermore, Kubernetes UIDs are
+UUIDs as standardized by
+ISO/IEC 9834-8 and ITU-T X.667.
+Which states:
+- If generated according to one of the mechanisms defined in Rec.
+- ITU-T X.667 | ISO/IEC 9834-8, a UUID is either guaranteed to be
+ different from all other UUIDs generated before 3603 A.D., or is
+ extremely likely to be different (depending on the mechanism chosen).
- Therefore, UIDs
+between clusters should be extremely unlikely to conflict.
+ */
+static constexpr const char *kK8sClusterUid = "k8s.cluster.uid";
+
/**
* The name of the Node.
*/
@@ -532,7 +620,7 @@ static constexpr const char *kOsName = "os.name";
/**
* The version string of the operating system as defined in Version Attributes.
+ * href="/docs/resource/README.md#version-attributes">Version Attributes.
*/
static constexpr const char *kOsVersion = "os.version";
@@ -615,6 +703,12 @@ static constexpr const char *kProcessRuntimeDescription = "process.runtime.descr
*/
static constexpr const char *kServiceName = "service.name";
+/**
+ * The version string of the service API or implementation. The format is not defined by these
+ * conventions.
+ */
+static constexpr const char *kServiceVersion = "service.version";
+
/**
* A namespace for {@code service.name}.
*
@@ -644,13 +738,17 @@ static constexpr const char *kServiceNamespace = "service.namespace";
*/
static constexpr const char *kServiceInstanceId = "service.instance.id";
-/**
- * The version string of the service API or implementation.
- */
-static constexpr const char *kServiceVersion = "service.version";
-
/**
* The name of the telemetry SDK as defined above.
+ *
+ * Notes:
+
- The OpenTelemetry SDK MUST set the {@code telemetry.sdk.name} attribute to {@code
+opentelemetry}. If another SDK, like a fork or a vendor-provided implementation, is used, this SDK
+MUST set the
+{@code telemetry.sdk.name} attribute to the fully-qualified class or module name of this SDK's main
+entry point or another suitable identifier depending on the language. The identifier {@code
+opentelemetry} is reserved and MUST NOT be used in this case. All custom identifiers SHOULD be
+stable across different versions of an implementation.
*/
static constexpr const char *kTelemetrySdkName = "telemetry.sdk.name";
@@ -757,6 +855,8 @@ static constexpr const char *kAzureFunctions = "azure_functions";
static constexpr const char *kAzureAppService = "azure_app_service";
/** Azure Red Hat OpenShift. */
static constexpr const char *kAzureOpenshift = "azure_openshift";
+/** Google Bare Metal Solution (BMS). */
+static constexpr const char *kGcpBareMetalSolution = "gcp_bare_metal_solution";
/** Google Cloud Compute Engine (GCE). */
static constexpr const char *kGcpComputeEngine = "gcp_compute_engine";
/** Google Cloud Run. */
@@ -853,10 +953,12 @@ static constexpr const char *kPhp = "php";
static constexpr const char *kPython = "python";
/** ruby. */
static constexpr const char *kRuby = "ruby";
-/** webjs. */
-static constexpr const char *kWebjs = "webjs";
+/** rust. */
+static constexpr const char *kRust = "rust";
/** swift. */
static constexpr const char *kSwift = "swift";
+/** webjs. */
+static constexpr const char *kWebjs = "webjs";
} // namespace TelemetrySdkLanguageValues
} // namespace SemanticConventions