Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ val OpenTelemetryVersion = "1.59.0"
val OpenTelemetryAlphaVersion = s"$OpenTelemetryVersion-alpha"
val OpenTelemetryInstrumentationVersion = "2.25.0"
val OpenTelemetryInstrumentationAlphaVersion = s"$OpenTelemetryInstrumentationVersion-alpha"
val OpenTelemetrySemConvVersion = "1.39.0"
val OpenTelemetrySemConvVersion = "1.40.0"
val OpenTelemetrySemConvAlphaVersion = s"$OpenTelemetrySemConvVersion-alpha"
val Otel4sAgentVersion = "2.22.0"
val PekkoStreamVersion = "1.4.0"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
{%- elif type == "stable" -%} Stability.stable
{%- elif type == "release_candidate" -%} Stability.releaseCandidate
{%- elif type == "alpha" -%} Stability.alpha
{%- elif type == "beta" -%} Stability.beta
{%- else -%} _unknown_stability_type_{{ type }}
{%- endif -%}
{%- endmacro -%}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,10 @@ object DbExperimentalAttributes {
* analyzing telemetry for database calls involving complex queries. <p> Summary may be available to the
* instrumentation through instrumentation hooks or other means. If it is not available, instrumentations that
* support query parsing SHOULD generate a summary following <a
* href="/docs/db/database-spans.md#generating-a-summary-of-the-query">Generating query summary</a> section.
* href="/docs/db/database-spans.md#generating-a-summary-of-the-query">Generating query summary</a> section. <p>
* For batch operations, if the individual operations are known to have the same query summary then that query
* summary SHOULD be used prepended by `BATCH `, otherwise `db.query.summary` SHOULD be `BATCH` or some other
* database system specific term if more applicable.
*/
@deprecated(
"use `org.typelevel.otel4s.semconv.attributes.DbAttributes.DbQuerySummary` instead.",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ object ErrorExperimentalAttributes {
* `exception.message` in `error.message`. <p> `error.message` is NOT RECOMMENDED for metrics or spans due to its
* unbounded cardinality and overlap with span status.
*/
@deprecated(
"Use domain-specific error message attribute. For example, use `feature_flag.error.message` for feature flag errors.",
""
)
val ErrorMessage: AttributeKey[String] =
AttributeKey("error.message")

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ package experimental.attributes
object ExceptionExperimentalAttributes {

/** The exception message.
*
* @note
* <blockquote> [!WARNING] <p> This attribute may contain sensitive information.</blockquote>
*/
@deprecated(
"use `org.typelevel.otel4s.semconv.attributes.ExceptionAttributes.ExceptionMessage` instead.",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,15 @@ object FeatureFlagExperimentalAttributes {
val FeatureFlagContextId: AttributeKey[String] =
AttributeKey("feature_flag.context.id")

/** Deprecated, use `error.message` instead.
/** A message providing more detail about an error that occurred during feature flag evaluation in human-readable
* form.
*/
@deprecated("Replaced by `error.message`.", "")
val FeatureFlagErrorMessage: AttributeKey[String] =
AttributeKey("feature_flag.error.message")

/** Deprecated, use `feature_flag.error.message` instead.
*/
@deprecated("Replaced by `feature_flag.error.message`.", "")
val FeatureFlagEvaluationErrorMessage: AttributeKey[String] =
AttributeKey("feature_flag.evaluation.error.message")

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,23 @@ object GcpExperimentalAttributes {
val GcpGceInstanceName: AttributeKey[String] =
AttributeKey("gcp.gce.instance.name")

/** The name of the Instance Group Manager (IGM) that manages this VM, if any.
*/
val GcpGceInstanceGroupManagerName: AttributeKey[String] =
AttributeKey("gcp.gce.instance_group_manager.name")

/** The region of a <strong>regional</strong> Instance Group Manager (e.g., `us-central1`). Set this
* <strong>only</strong> when the IGM is regional.
*/
val GcpGceInstanceGroupManagerRegion: AttributeKey[String] =
AttributeKey("gcp.gce.instance_group_manager.region")

/** The zone of a <strong>zonal</strong> Instance Group Manager (e.g., `us-central1-a`). Set this
* <strong>only</strong> when the IGM is zonal.
*/
val GcpGceInstanceGroupManagerZone: AttributeKey[String] =
AttributeKey("gcp.gce.instance_group_manager.zone")

/** Values for [[GcpApphubServiceCriticalityType]].
*/
abstract class GcpApphubServiceCriticalityTypeValue(val value: String)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ object GenAiExperimentalAttributes {
val GenAiAgentName: AttributeKey[String] =
AttributeKey("gen_ai.agent.name")

/** The version of the GenAI agent.
*/
val GenAiAgentVersion: AttributeKey[String] =
AttributeKey("gen_ai.agent.version")

/** Deprecated, use Event API to report completions contents.
*/
@deprecated("Removed, no replacement at this time.", "")
Expand Down Expand Up @@ -245,6 +250,14 @@ object GenAiExperimentalAttributes {
val GenAiResponseModel: AttributeKey[String] =
AttributeKey("gen_ai.response.model")

/** The query text used for retrieval.
*
* @note
* <blockquote> [!Warning] This attribute may contain sensitive information.</blockquote>
*/
val GenAiRetrievalQueryText: AttributeKey[String] =
AttributeKey("gen_ai.retrieval.query.text")

/** Deprecated, use `gen_ai.provider.name` instead.
*/
@deprecated("Replaced by `gen_ai.provider.name`.", "")
Expand Down Expand Up @@ -284,13 +297,34 @@ object GenAiExperimentalAttributes {
val GenAiToolType: AttributeKey[String] =
AttributeKey("gen_ai.tool.type")

/** The number of input tokens written to a provider-managed cache.
*
* @note
* <p> The value SHOULD be included in `gen_ai.usage.input_tokens`.
*/
val GenAiUsageCacheCreationInputTokens: AttributeKey[Long] =
AttributeKey("gen_ai.usage.cache_creation.input_tokens")

/** The number of input tokens served from a provider-managed cache.
*
* @note
* <p> The value SHOULD be included in `gen_ai.usage.input_tokens`.
*/
val GenAiUsageCacheReadInputTokens: AttributeKey[Long] =
AttributeKey("gen_ai.usage.cache_read.input_tokens")

/** Deprecated, use `gen_ai.usage.output_tokens` instead.
*/
@deprecated("Replaced by `gen_ai.usage.output_tokens`.", "")
val GenAiUsageCompletionTokens: AttributeKey[Long] =
AttributeKey("gen_ai.usage.completion_tokens")

/** The number of tokens used in the GenAI input (prompt).
*
* @note
* <p> This value SHOULD include all types of input tokens, including cached tokens. Instrumentations SHOULD make a
* best effort to populate this value, using a total provided by the provider when available or, depending on the
* provider API, by summing different token types parsed from the provider output.
*/
val GenAiUsageInputTokens: AttributeKey[Long] =
AttributeKey("gen_ai.usage.input_tokens")
Expand Down Expand Up @@ -372,6 +406,11 @@ object GenAiExperimentalAttributes {
*/
case object Embeddings extends GenAiOperationNameValue("embeddings")

/** Retrieval operation such as <a href="https://platform.openai.com/docs/api-reference/vector-stores/search">OpenAI
* Search Vector Store API</a>
*/
case object Retrieval extends GenAiOperationNameValue("retrieval")

/** Create GenAI agent
*/
case object CreateAgent extends GenAiOperationNameValue("create_agent")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,12 +96,16 @@ object HttpExperimentalAttributes {
* to `_OTHER`. <p> If the HTTP instrumentation could end up converting valid HTTP request methods to `_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). <p> HTTP method names are
* case-sensitive and `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 `http.request.method_original` to the
* original value.
* comma-separated list of case-sensitive known HTTP methods. <p>
*
* If this override is done via declarative configuration, then the list MUST be configurable via the `known_methods`
* property (an array of case-sensitive strings with minimum items 0) under
* `.instrumentation/development.general.http.client` and/or `.instrumentation/development.general.http.server`. <p>
* In either case, this list MUST be a full override of the default known methods, it is not a list of known methods
* in addition to the defaults. <p> HTTP method names are case-sensitive and `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 `http.request.method_original` to the original value.
*/
@deprecated(
"use `org.typelevel.otel4s.semconv.attributes.HttpAttributes.HttpRequestMethod` instead.",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -489,6 +489,122 @@ object K8sExperimentalAttributes {
val K8sResourcequotaUid: AttributeKey[String] =
AttributeKey("k8s.resourcequota.uid")

/** The annotation placed on the Service, the `<key>` being the annotation name, the value being the annotation value,
* even if the value is empty.
*
* @note
* <p> Examples: <ul> <li>An annotation `prometheus.io/scrape` with value `true` SHOULD be recorded as the
* `k8s.service.annotation.prometheus.io/scrape` attribute with value `"true"`. <li>An annotation `data` with empty
* string value SHOULD be recorded as the `k8s.service.annotation.data` attribute with value `""`. </ul>
*/
val K8sServiceAnnotation: AttributeKey[String] =
AttributeKey("k8s.service.annotation")

/** The address type of the service endpoint.
*
* @note
* <p> The network address family or type of the endpoint. This attribute aligns with the `addressType` field of
* the <a href="https://kubernetes.io/docs/reference/kubernetes-api/service-resources/endpoint-slice-v1/">K8s
* EndpointSlice</a>. It is used to differentiate metrics when a Service is backed by multiple address types (e.g.,
* in dual-stack clusters).
*/
val K8sServiceEndpointAddressType: AttributeKey[String] =
AttributeKey("k8s.service.endpoint.address_type")

/** The condition of the service endpoint.
*
* @note
* <p> The current operational condition of the service endpoint. An endpoint can have multiple conditions set at
* once (e.g., both `serving` and `terminating` during rollout). This attribute aligns with the condition fields in
* the <a href="https://kubernetes.io/docs/reference/kubernetes-api/service-resources/endpoint-slice-v1/">K8s
* EndpointSlice</a>.
*/
val K8sServiceEndpointCondition: AttributeKey[String] =
AttributeKey("k8s.service.endpoint.condition")

/** The zone of the service endpoint.
*
* @note
* <p> The zone where the endpoint is located, typically corresponding to a failure domain. This attribute aligns
* with the `zone` field of endpoints in the <a
* href="https://kubernetes.io/docs/reference/kubernetes-api/service-resources/endpoint-slice-v1/">K8s
* EndpointSlice</a>. It enables zone-aware monitoring of service endpoint distribution and supports features like
* <a href="https://kubernetes.io/docs/concepts/services-networking/topology-aware-routing/">Topology Aware
* Routing</a>. <p> If the zone is not populated (e.g., nodes without the `topology.kubernetes.io/zone` label), the
* attribute value will be an empty string.
*/
val K8sServiceEndpointZone: AttributeKey[String] =
AttributeKey("k8s.service.endpoint.zone")

/** The label placed on the Service, the `<key>` being the label name, the value being the label value, even if the
* value is empty.
*
* @note
* <p> Examples: <ul> <li>A label `app` with value `my-service` SHOULD be recorded as the `k8s.service.label.app`
* attribute with value `"my-service"`. <li>A label `data` with empty string value SHOULD be recorded as the
* `k8s.service.label.data` attribute with value `""`. </ul>
*/
val K8sServiceLabel: AttributeKey[String] =
AttributeKey("k8s.service.label")

/** The name of the Service.
*/
val K8sServiceName: AttributeKey[String] =
AttributeKey("k8s.service.name")

/** Whether the Service publishes not-ready endpoints.
*
* @note
* <p> Whether the Service is configured to publish endpoints before the pods are ready. This attribute is
* typically used to indicate that a Service (such as a headless Service for a StatefulSet) allows peer discovery
* before pods pass their readiness probes. It aligns with the `publishNotReadyAddresses` field of the <a
* href="https://kubernetes.io/docs/reference/kubernetes-api/service-resources/service-v1/#ServiceSpec">K8s
* ServiceSpec</a>.
*/
val K8sServicePublishNotReadyAddresses: AttributeKey[Boolean] =
AttributeKey("k8s.service.publish_not_ready_addresses")

/** The selector key-value pair placed on the Service, the `<key>` being the selector key, the value being the
* selector value.
*
* @note
* <p> These selectors are used to correlate with pod labels. Each selector key-value pair becomes a separate
* attribute. <p> Examples: <ul> <li>A selector `app=my-app` SHOULD be recorded as the `k8s.service.selector.app`
* attribute with value `"my-app"`. <li>A selector `version=v1` SHOULD be recorded as the
* `k8s.service.selector.version` attribute with value `"v1"`. </ul>
*/
val K8sServiceSelector: AttributeKey[String] =
AttributeKey("k8s.service.selector")

/** The traffic distribution policy for the Service.
*
* @note
* <p> Specifies how traffic is distributed to endpoints for this Service. This attribute aligns with the
* `trafficDistribution` field of the <a
* href="https://kubernetes.io/docs/reference/networking/virtual-ips/#traffic-distribution">K8s ServiceSpec</a>.
* Known values include `PreferSameZone` (prefer endpoints in the same zone as the client) and `PreferSameNode`
* (prefer endpoints on the same node, fallback to same zone, then cluster-wide). If this field is not set on the
* Service, the attribute SHOULD NOT be emitted. When not set, Kubernetes distributes traffic evenly across all
* endpoints cluster-wide.
*/
val K8sServiceTrafficDistribution: AttributeKey[String] =
AttributeKey("k8s.service.traffic_distribution")

/** The type of the Kubernetes Service.
*
* @note
* <p> This attribute aligns with the `type` field of the <a
* href="https://kubernetes.io/docs/reference/kubernetes-api/service-resources/service-v1/#ServiceSpec">K8s
* ServiceSpec</a>.
*/
val K8sServiceType: AttributeKey[String] =
AttributeKey("k8s.service.type")

/** The UID of the Service.
*/
val K8sServiceUid: AttributeKey[String] =
AttributeKey("k8s.service.uid")

/** The annotation placed on the StatefulSet, the `<key>` being the annotation name, the value being the annotation
* value, even if the value is empty.
*
Expand Down Expand Up @@ -725,6 +841,69 @@ object K8sExperimentalAttributes {
case object UnexpectedAdmissionError extends K8sPodStatusReasonValue("UnexpectedAdmissionError")
}

/** Values for [[K8sServiceEndpointAddressType]].
*/
abstract class K8sServiceEndpointAddressTypeValue(val value: String)
object K8sServiceEndpointAddressTypeValue {
implicit val attributeFromK8sServiceEndpointAddressTypeValue
: Attribute.From[K8sServiceEndpointAddressTypeValue, String] = _.value

/** IPv4 address type
*/
case object Ipv4 extends K8sServiceEndpointAddressTypeValue("IPv4")

/** IPv6 address type
*/
case object Ipv6 extends K8sServiceEndpointAddressTypeValue("IPv6")

/** FQDN address type
*/
case object Fqdn extends K8sServiceEndpointAddressTypeValue("FQDN")
}

/** Values for [[K8sServiceEndpointCondition]].
*/
abstract class K8sServiceEndpointConditionValue(val value: String)
object K8sServiceEndpointConditionValue {
implicit val attributeFromK8sServiceEndpointConditionValue
: Attribute.From[K8sServiceEndpointConditionValue, String] = _.value

/** The endpoint is ready to receive new connections.
*/
case object Ready extends K8sServiceEndpointConditionValue("ready")

/** The endpoint is currently handling traffic.
*/
case object Serving extends K8sServiceEndpointConditionValue("serving")

/** The endpoint is in the process of shutting down.
*/
case object Terminating extends K8sServiceEndpointConditionValue("terminating")
}

/** Values for [[K8sServiceType]].
*/
abstract class K8sServiceTypeValue(val value: String)
object K8sServiceTypeValue {
implicit val attributeFromK8sServiceTypeValue: Attribute.From[K8sServiceTypeValue, String] = _.value

/** ClusterIP service type
*/
case object ClusterIp extends K8sServiceTypeValue("ClusterIP")

/** NodePort service type
*/
case object NodePort extends K8sServiceTypeValue("NodePort")

/** LoadBalancer service type
*/
case object LoadBalancer extends K8sServiceTypeValue("LoadBalancer")

/** ExternalName service type
*/
case object ExternalName extends K8sServiceTypeValue("ExternalName")
}

/** Values for [[K8sVolumeType]].
*/
abstract class K8sVolumeTypeValue(val value: String)
Expand Down
Loading