diff --git a/buildscripts/semantic-convention/templates/registry/otel4s/metrics/SemanticMetrics.scala.j2 b/buildscripts/semantic-convention/templates/registry/otel4s/metrics/SemanticMetrics.scala.j2 index e3e05ed2e..e8b24f6cd 100644 --- a/buildscripts/semantic-convention/templates/registry/otel4s/metrics/SemanticMetrics.scala.j2 +++ b/buildscripts/semantic-convention/templates/registry/otel4s/metrics/SemanticMetrics.scala.j2 @@ -57,7 +57,8 @@ {%- endmacro -%} {%- macro stability(type) -%} -{%- if type == "experimental" -%} Stability.experimental +{%- if type == "development" -%} Stability.development +{%- elif not type -%} Stability.development {%- elif type == "stable" -%} Stability.stable {%- else -%} _unknown_stability_type_{{ type }} {%- endif -%} @@ -68,7 +69,11 @@ {%- elif type == "double" -%} {{ input }} {%- elif type == "boolean" -%} {{ input }} {%- elif type == "string" -%} "{{ input }}" -{%- else -%} _unknown type_{{ input }} +{%- elif type == "int[]" -%} Seq({{ input | join(', ') }}) +{%- elif type == "double[]" -%} Seq({{ input | join(', ') }}) +{%- elif type == "boolean[]" -%} Seq({{ input | join(', ') }}) +{%- elif type == "string[]" -%} Seq({{ input | map('tojson') | join(', ') }}) +{%- else -%} _unknown type_{{ type }}_{{ input }} {%- endif -%} {% endmacro %} @@ -132,7 +137,7 @@ import org.typelevel.otel4s.metrics._ {%- if required_imports.stable == true %} import org.typelevel.otel4s.semconv.attributes._ {%- endif %} -{%- if required_imports.experimental == true %} +{%- if required_imports.experimental == true and params.experimental == true %} import org.typelevel.otel4s.semconv.experimental.attributes._ {%- endif %} @@ -161,16 +166,20 @@ object {{ object_name }} { @deprecated("Use stable `{{ stableRef(metric) }}` instead.", "") {%- endif %} object {{ objectName(metric) }} extends MetricSpec { - + {%- if params.experimental == true -%} + {%- set metric_attributes = metric.attributes %} + {% else %} + {%- set metric_attributes = metric.attributes | selectattr("stability", "equalto", "stable") | list %} + {% endif %} val name: String = "{{ metric.metric_name }}" val description: String = "{{ metric.brief }}" val unit: String = "{{ metric.unit }}" val stability: Stability = {{ stability(metric.stability) }} - val attributeSpecs: List[AttributeSpec[_]] = {% if metric.attributes | length > 0 %}AttributeSpecs.specs{% else %}Nil{% endif %} + val attributeSpecs: List[AttributeSpec[_]] = {% if metric_attributes | length > 0 %}AttributeSpecs.specs{% else %}Nil{% endif %} - {% if metric.attributes | length > 0 %} + {% if metric_attributes | length > 0 %} object AttributeSpecs { - {% for attribute in metric.attributes | sort(attribute='name') %} + {% for attribute in metric_attributes | sort(attribute='name') %} {{ [attribute.brief, concat_if("\n\n@note\n\n", attribute.note)] | comment(indent=6) | replace('$', "$$")}} {%- if attribute is deprecated %} @deprecated("{{ attribute.deprecated }}", "") @@ -186,7 +195,7 @@ object {{ object_name }} { ) {% endfor %} val specs: List[AttributeSpec[_]] = - List({%- for attribute in metric.attributes | sort(attribute='name') %} + List({%- for attribute in metric_attributes | sort(attribute='name') %} {{ attribute.name | camel_case }},{% endfor %} ) } diff --git a/project/SemanticConventionsGenerator.scala b/project/SemanticConventionsGenerator.scala index 5c01a6b8d..0aabfa894 100644 --- a/project/SemanticConventionsGenerator.scala +++ b/project/SemanticConventionsGenerator.scala @@ -3,7 +3,7 @@ import scala.sys.process._ object SemanticConventionsGenerator { - private val generatorVersion = "v0.9.1" + private val generatorVersion = "v0.12.0" // generates semantic conventions by using `otel/weaver` in docker def generate(version: String, rootDir: File): Unit = { diff --git a/semconv/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/attributes/AwsExperimentalAttributes.scala b/semconv/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/attributes/AwsExperimentalAttributes.scala index 868ecb010..fafb8c3d2 100644 --- a/semconv/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/attributes/AwsExperimentalAttributes.scala +++ b/semconv/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/attributes/AwsExperimentalAttributes.scala @@ -235,7 +235,7 @@ object AwsExperimentalAttributes { * @note *
The `copy_source` attribute applies to S3 copy operations and corresponds to the `--copy-source` parameter * of the copy-object operation - * within the S3 API. This applies in particular to the following operations:
* @note *
The `key` attribute is applicable to all object-related S3 operations, i.e. that require the object key as a - * mandatory parameter. This applies in particular to the following operations:
On some cloud providers, it may not be possible to determine the full ID at startup, so it may be necessary * to set `cloud.resource_id` as a span attribute instead.
The exact value to use for `cloud.resource_id` * depends on the cloud provider. The following well-known definitions MUST be used if you set this attribute and - * they apply:
* @note *
CloudFoundry defines the `instance_id` in the Loggegator v2 envelope. It is used for + * href="https://github.com/cloudfoundry/loggregator-api#v2-envelope">Loggregator v2 envelope
Application instrumentation should use the value from environment * variable `CF_INSTANCE_INDEX`. diff --git a/semconv/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/attributes/DbExperimentalAttributes.scala b/semconv/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/attributes/DbExperimentalAttributes.scala index b509b0671..121b49c8d 100644 --- a/semconv/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/attributes/DbExperimentalAttributes.scala +++ b/semconv/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/attributes/DbExperimentalAttributes.scala @@ -88,10 +88,9 @@ object DbExperimentalAttributes { /** The name of a collection (table, container) within the database.
* @note *
It is RECOMMENDED to capture the value as provided by the application without attempting to do any case - * normalization. If the collection name is parsed from the query text, it SHOULD be the first collection name - * found in the query and it SHOULD match the value provided in the query text including any schema and database - * name prefix. For batch operations, if the individual operations are known to have the same collection name then - * that collection name SHOULD be used, otherwise `db.collection.name` SHOULD NOT be captured. This attribute has + * normalization.
The collection name SHOULD NOT be extracted from `db.query.text`, unless the query format is + * known to only ever have a single collection name present.
For batch operations, if the individual operations + * are known to have the same collection name then that collection name SHOULD be used.
This attribute has * stability level RELEASE CANDIDATE. */ val DbCollectionName: AttributeKey[String] = @@ -113,23 +112,39 @@ object DbExperimentalAttributes { val DbCosmosdbConnectionMode: AttributeKey[String] = AttributeKey("db.cosmosdb.connection_mode") + /** Account or request consistency level. + */ + val DbCosmosdbConsistencyLevel: AttributeKey[String] = + AttributeKey("db.cosmosdb.consistency_level") + /** Deprecated, use `db.collection.name` instead. */ @deprecated("Replaced by `db.collection.name`.", "") val DbCosmosdbContainer: AttributeKey[String] = AttributeKey("db.cosmosdb.container") - /** Cosmos DB Operation Type. + /** Deprecated, no replacement at this time. */ + @deprecated("No replacement at this time.", "") val DbCosmosdbOperationType: AttributeKey[String] = AttributeKey("db.cosmosdb.operation_type") - /** RU consumed for that operation + /** List of regions contacted during operation in the order that they were contacted. If there is more than one region + * listed, it indicates that the operation was performed on multiple regions i.e. cross-regional call.
+ * @note + *
Region name matches the format of `displayName` in Azure + * Location API + */ + val DbCosmosdbRegionsContacted: AttributeKey[Seq[String]] = + AttributeKey("db.cosmosdb.regions_contacted") + + /** Request units consumed for the operation. */ val DbCosmosdbRequestCharge: AttributeKey[Double] = AttributeKey("db.cosmosdb.request_charge") - /** Request payload size in bytes + /** Request payload size in bytes. */ val DbCosmosdbRequestContentLength: AttributeKey[Long] = AttributeKey("db.cosmosdb.request_content_length") @@ -230,25 +245,44 @@ object DbExperimentalAttributes { /** The name of the operation or command being executed.
* @note *
It is RECOMMENDED to capture the value as provided by the application without attempting to do any case - * normalization. If the operation name is parsed from the query text, it SHOULD be the first operation name found - * in the query. For batch operations, if the individual operations are known to have the same operation name then - * that operation name SHOULD be used prepended by `BATCH `, otherwise `db.operation.name` SHOULD be `BATCH` or - * some other database system specific term if more applicable. This attribute has stability level RELEASE - * CANDIDATE. + * normalization.
The operation name SHOULD NOT be extracted from `db.query.text`, unless the query format is + * known to only ever have a single operation name present.
For batch operations, if the individual operations + * are known to have the same operation name then that operation name SHOULD be used prepended by `BATCH `, + * otherwise `db.operation.name` SHOULD be `BATCH` or some other database system specific term if more applicable. + *
This attribute has stability level RELEASE CANDIDATE.
*/
val DbOperationName: AttributeKey[String] =
AttributeKey("db.operation.name")
- /** A query parameter used in `db.query.text`, with `
+ /** A database operation parameter, with `
* @note
- * Query parameters should only be captured when `db.query.text` is parameterized with placeholders. If a
- * parameter has no name and instead is referenced only by index, then ` If a parameter has no name and instead is referenced only by index, then `
+ * @note
+ * `db.query.summary` provides static summary of the query text. It describes a class of database queries and
+ * is useful as a grouping key, especially when analyzing telemetry for database calls involving complex queries.
+ * 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 Generating query summary
+ * section. This attribute has stability level RELEASE CANDIDATE.
+ */
+ val DbQuerySummary: AttributeKey[String] =
+ AttributeKey("db.query.summary")
+
/** The database query being executed.
* @note
* For sanitization see
* @note
* The status code returned by the database. Usually it represents an error code, but may also represent
@@ -391,7 +430,7 @@ object DbExperimentalAttributes {
abstract class DbCosmosdbConnectionModeValue(val value: String)
object DbCosmosdbConnectionModeValue {
- /** Gateway (HTTP) connections mode
+ /** Gateway (HTTP) connection.
*/
case object Gateway extends DbCosmosdbConnectionModeValue("gateway")
@@ -400,9 +439,37 @@ object DbExperimentalAttributes {
case object Direct extends DbCosmosdbConnectionModeValue("direct")
}
+ /** Values for [[DbCosmosdbConsistencyLevel]].
+ */
+ abstract class DbCosmosdbConsistencyLevelValue(val value: String)
+ object DbCosmosdbConsistencyLevelValue {
+
+ /** strong.
+ */
+ case object Strong extends DbCosmosdbConsistencyLevelValue("Strong")
+
+ /** bounded_staleness.
+ */
+ case object BoundedStaleness extends DbCosmosdbConsistencyLevelValue("BoundedStaleness")
+
+ /** session.
+ */
+ case object Session extends DbCosmosdbConsistencyLevelValue("Session")
+
+ /** eventual.
+ */
+ case object Eventual extends DbCosmosdbConsistencyLevelValue("Eventual")
+
+ /** consistent_prefix.
+ */
+ case object ConsistentPrefix extends DbCosmosdbConsistencyLevelValue("ConsistentPrefix")
+ }
+
/** Values for [[DbCosmosdbOperationType]].
*/
+ @deprecated("No replacement at this time.", "")
abstract class DbCosmosdbOperationTypeValue(val value: String)
+ @annotation.nowarn("cat=deprecation")
object DbCosmosdbOperationTypeValue {
/** batch.
diff --git a/semconv/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/attributes/DeploymentExperimentalAttributes.scala b/semconv/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/attributes/DeploymentExperimentalAttributes.scala
index 803d233c1..dc3945275 100644
--- a/semconv/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/attributes/DeploymentExperimentalAttributes.scala
+++ b/semconv/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/attributes/DeploymentExperimentalAttributes.scala
@@ -32,7 +32,7 @@ object DeploymentExperimentalAttributes {
* @note
* `deployment.environment.name` does not affect the uniqueness constraints defined through the
* `service.namespace`, `service.name` and `service.instance.id` resource attributes. This implies that resources
- * carrying the following attribute combinations MUST be considered to be identifying the same service: If the operation has completed successfully, instrumentations
* SHOULD NOT set `error.type`. If a specific domain defines its own set of error identifiers (such as HTTP or
- * gRPC status codes), it's RECOMMENDED to:
* @note
- * 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:
* @note
- * Depending on the cloud provider and platform, use:
+ /** The identifier of the flag set to which the
+ * feature flag belongs.
+ */
+ val FeatureFlagSetId: AttributeKey[String] =
+ AttributeKey("feature_flag.set.id")
+
+ /** A semantic identifier for an evaluated flag value.
* @note
* A semantic identifier, commonly referred to as a variant, provides a means for referring to a value without
* including the value itself. This can provide additional context for understanding the meaning behind a value.
- * For example, the variant `red` maybe be used for the value `#c05543`. A stringified version of the value can
- * be used in situations where a semantic identifier is unavailable. String representation of the value should be
- * determined by the implementer.
+ * For example, the variant `red` maybe be used for the value `#c05543`.
*/
val FeatureFlagVariant: AttributeKey[String] =
AttributeKey("feature_flag.variant")
+ /** The version of the ruleset used during the evaluation. This may be any stable value which uniquely identifies the
+ * ruleset.
+ */
+ val FeatureFlagVersion: AttributeKey[String] =
+ AttributeKey("feature_flag.version")
+
+ /** Values for [[FeatureFlagEvaluationReason]].
+ */
+ abstract class FeatureFlagEvaluationReasonValue(val value: String)
+ object FeatureFlagEvaluationReasonValue {
+
+ /** The resolved value is static (no dynamic evaluation).
+ */
+ case object Static extends FeatureFlagEvaluationReasonValue("static")
+
+ /** The resolved value fell back to a pre-configured value (no dynamic evaluation occurred or dynamic evaluation
+ * yielded no result).
+ */
+ case object Default extends FeatureFlagEvaluationReasonValue("default")
+
+ /** The resolved value was the result of a dynamic evaluation, such as a rule or specific user-targeting.
+ */
+ case object TargetingMatch extends FeatureFlagEvaluationReasonValue("targeting_match")
+
+ /** The resolved value was the result of pseudorandom assignment.
+ */
+ case object Split extends FeatureFlagEvaluationReasonValue("split")
+
+ /** The resolved value was retrieved from cache.
+ */
+ case object Cached extends FeatureFlagEvaluationReasonValue("cached")
+
+ /** The resolved value was the result of the flag being disabled in the management system.
+ */
+ case object Disabled extends FeatureFlagEvaluationReasonValue("disabled")
+
+ /** The reason for the resolved value could not be determined.
+ */
+ case object Unknown extends FeatureFlagEvaluationReasonValue("unknown")
+
+ /** The resolved value is non-authoritative or possibly out of date
+ */
+ case object Stale extends FeatureFlagEvaluationReasonValue("stale")
+
+ /** The resolved value was the result of an error.
+ */
+ case object Error extends FeatureFlagEvaluationReasonValue("error")
+ }
+
}
diff --git a/semconv/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/attributes/GenAiExperimentalAttributes.scala b/semconv/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/attributes/GenAiExperimentalAttributes.scala
index 01311f1f0..9e1b71728 100644
--- a/semconv/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/attributes/GenAiExperimentalAttributes.scala
+++ b/semconv/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/attributes/GenAiExperimentalAttributes.scala
@@ -37,7 +37,7 @@ object GenAiExperimentalAttributes {
val GenAiOpenaiRequestSeed: AttributeKey[Long] =
AttributeKey("gen_ai.openai.request.seed")
- /** The service tier requested. May be a specific tier, detault, or auto.
+ /** The service tier requested. May be a specific tier, default, or auto.
*/
val GenAiOpenaiRequestServiceTier: AttributeKey[String] =
AttributeKey("gen_ai.openai.request.service_tier")
@@ -47,6 +47,11 @@ object GenAiExperimentalAttributes {
val GenAiOpenaiResponseServiceTier: AttributeKey[String] =
AttributeKey("gen_ai.openai.response.service_tier")
+ /** A fingerprint to track any eventual change in the Generative AI environment.
+ */
+ val GenAiOpenaiResponseSystemFingerprint: AttributeKey[String] =
+ AttributeKey("gen_ai.openai.response.system_fingerprint")
+
/** The name of the operation being performed.
* @note
* If one of the predefined values applies, but specific system uses a different name it's RECOMMENDED to
@@ -63,6 +68,14 @@ object GenAiExperimentalAttributes {
val GenAiPrompt: AttributeKey[String] =
AttributeKey("gen_ai.prompt")
+ /** The encoding formats requested in an embeddings operation, if specified.
+ * @note
+ * In some GenAI systems the encoding formats are called embedding types. Also, some GenAI systems only accept
+ * a single format per request.
+ */
+ val GenAiRequestEncodingFormats: AttributeKey[Seq[String]] =
+ AttributeKey("gen_ai.request.encoding_formats")
+
/** The frequency penalty setting for the GenAI request.
*/
val GenAiRequestFrequencyPenalty: AttributeKey[Double] =
@@ -202,6 +215,11 @@ object GenAiExperimentalAttributes {
* Completions API (Legacy) Therefore, UIDs between clusters should be extremely unlikely to conflict.
+ * A.D., or is extremely likely to be different (depending on the mechanism chosen). Therefore,
+ * UIDs between clusters should be extremely unlikely to conflict.
*/
val K8sClusterUid: AttributeKey[String] =
AttributeKey("k8s.cluster.uid")
diff --git a/semconv/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/attributes/NetworkExperimentalAttributes.scala b/semconv/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/attributes/NetworkExperimentalAttributes.scala
index 6a89e7771..373c07b91 100644
--- a/semconv/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/attributes/NetworkExperimentalAttributes.scala
+++ b/semconv/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/attributes/NetworkExperimentalAttributes.scala
@@ -52,6 +52,11 @@ object NetworkExperimentalAttributes {
val NetworkConnectionType: AttributeKey[String] =
AttributeKey("network.connection.type")
+ /** The network interface name.
+ */
+ val NetworkInterfaceName: AttributeKey[String] =
+ AttributeKey("network.interface.name")
+
/** The network IO operation direction.
*/
val NetworkIoDirection: AttributeKey[String] =
@@ -93,7 +98,7 @@ object NetworkExperimentalAttributes {
val NetworkPeerPort: AttributeKey[Long] =
AttributeKey("network.peer.port")
- /** OSI application layer or non-OSI equivalent.
+ /** OSI application layer or non-OSI equivalent.
* @note
* The value SHOULD be normalized to lowercase.
*/
@@ -117,7 +122,7 @@ object NetworkExperimentalAttributes {
val NetworkProtocolVersion: AttributeKey[String] =
AttributeKey("network.protocol.version")
- /** OSI transport layer or OSI transport layer or inter-process communication method.
* @note
* The value SHOULD be normalized to lowercase. Consider always setting the transport when setting a port
@@ -131,7 +136,7 @@ object NetworkExperimentalAttributes {
val NetworkTransport: AttributeKey[String] =
AttributeKey("network.transport")
- /** OSI network layer or non-OSI equivalent.
+ /** OSI network layer or non-OSI equivalent.
* @note
* The value SHOULD be normalized to lowercase.
*/
diff --git a/semconv/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/attributes/ProcessExperimentalAttributes.scala b/semconv/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/attributes/ProcessExperimentalAttributes.scala
index 1a8029fa5..4cb98b87a 100644
--- a/semconv/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/attributes/ProcessExperimentalAttributes.scala
+++ b/semconv/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/attributes/ProcessExperimentalAttributes.scala
@@ -78,6 +78,12 @@ object ProcessExperimentalAttributes {
/** Profiling specific build ID for executables. See the OTel specification for Profiles for more information.
*/
+ val ProcessExecutableBuildIdHtlhash: AttributeKey[String] =
+ AttributeKey("process.executable.build_id.htlhash")
+
+ /** "Deprecated, use `process.executable.build_id.htlhash` instead."
+ */
+ @deprecated("Replaced by `process.executable.build_id.htlhash`", "")
val ProcessExecutableBuildIdProfiling: AttributeKey[String] =
AttributeKey("process.executable.build_id.profiling")
@@ -113,6 +119,15 @@ object ProcessExperimentalAttributes {
val ProcessInteractive: AttributeKey[Boolean] =
AttributeKey("process.interactive")
+ /** The control group associated with the process.
+ * @note
+ * Control groups (cgroups) are a kernel feature used to organize and manage process resources. This attribute
+ * provides the path(s) to the cgroup(s) associated with the process, which should match the contents of the /proc/ UUIDs are
* typically recommended, as only an opaque value for the purposes of identifying a service instance is needed.
* Similar to what can be seen in the man page for the `/etc/machine-id` file, the
+ * href="https://www.freedesktop.org/software/systemd/man/latest/machine-id.html">`/etc/machine-id`
+ * carrying the following attribute combinations MUST be considered to be identifying the same service:
. Which states:
*
*/
diff --git a/semconv/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/attributes/ErrorExperimentalAttributes.scala b/semconv/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/attributes/ErrorExperimentalAttributes.scala
index 6ed5809a3..941118583 100644
--- a/semconv/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/attributes/ErrorExperimentalAttributes.scala
+++ b/semconv/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/attributes/ErrorExperimentalAttributes.scala
@@ -30,7 +30,7 @@ object ErrorExperimentalAttributes {
* instrumentation libraries and applications should be prepared for `error.type` to have high cardinality at query
* time when no additional filters are applied.
*/
@deprecated(
diff --git a/semconv/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/attributes/FaasExperimentalAttributes.scala b/semconv/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/attributes/FaasExperimentalAttributes.scala
index e385d97e0..d9bdab057 100644
--- a/semconv/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/attributes/FaasExperimentalAttributes.scala
+++ b/semconv/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/attributes/FaasExperimentalAttributes.scala
@@ -59,7 +59,7 @@ object FaasExperimentalAttributes {
/** The execution environment ID as a string, that will be potentially reused for other invocations to the same
* function/function version.
+ *
*/
val FaasInstance: AttributeKey[String] =
AttributeKey("faas.instance")
@@ -105,7 +105,7 @@ object FaasExperimentalAttributes {
* the name of the callback function (which may be stored in the `code.namespace`/`code.function` span attributes).
*
+ * be used for this attribute (and consequently the span name) for the listed cloud providers/products:
*
*/
case object TextCompletion extends GenAiOperationNameValue("text_completion")
+
+ /** Embeddings operation such as OpenAI
+ * Create embeddings API
+ */
+ case object Embeddings extends GenAiOperationNameValue("embeddings")
}
/** Values for [[GenAiSystem]].
@@ -224,6 +242,18 @@ object GenAiExperimentalAttributes {
/** Cohere
*/
case object Cohere extends GenAiSystemValue("cohere")
+
+ /** Azure AI Inference
+ */
+ case object AzAiInference extends GenAiSystemValue("az.ai.inference")
+
+ /** IBM Watsonx AI
+ */
+ case object IbmWatsonxAi extends GenAiSystemValue("ibm.watsonx.ai")
+
+ /** AWS Bedrock
+ */
+ case object AwsBedrock extends GenAiSystemValue("aws.bedrock")
}
/** Values for [[GenAiTokenType]].
diff --git a/semconv/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/attributes/K8sExperimentalAttributes.scala b/semconv/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/attributes/K8sExperimentalAttributes.scala
index 9464e945f..4c87beca2 100644
--- a/semconv/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/attributes/K8sExperimentalAttributes.scala
+++ b/semconv/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/attributes/K8sExperimentalAttributes.scala
@@ -35,11 +35,10 @@ object K8sExperimentalAttributes {
* lifetime of the cluster. Using the `uid` of the `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
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).
- *
- *
For applications running behind an application server (like * unicorn), we do not recommend using one identifier for all processes participating in the application. Instead, diff --git a/semconv/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/attributes/TestExperimentalAttributes.scala b/semconv/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/attributes/TestExperimentalAttributes.scala index 1029d5527..612ff6da1 100644 --- a/semconv/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/attributes/TestExperimentalAttributes.scala +++ b/semconv/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/attributes/TestExperimentalAttributes.scala @@ -21,7 +21,7 @@ package experimental.attributes // DO NOT EDIT, this is an Auto-generated file from buildscripts/templates/registry/otel4s/attributes/SemanticAttributes.scala.j2 object TestExperimentalAttributes { - /** The fully qualified human readable name of the test case. + /** The fully qualified human readable name of the test case. */ val TestCaseName: AttributeKey[String] = AttributeKey("test.case.name") @@ -31,7 +31,7 @@ object TestExperimentalAttributes { val TestCaseResultStatus: AttributeKey[String] = AttributeKey("test.case.result.status") - /** The human readable name of a test suite. + /** The human readable name of a test suite. */ val TestSuiteName: AttributeKey[String] = AttributeKey("test.suite.name") diff --git a/semconv/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/attributes/UrlExperimentalAttributes.scala b/semconv/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/attributes/UrlExperimentalAttributes.scala index 0bc4afa04..5c6576c22 100644 --- a/semconv/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/attributes/UrlExperimentalAttributes.scala +++ b/semconv/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/attributes/UrlExperimentalAttributes.scala @@ -52,12 +52,22 @@ object UrlExperimentalAttributes { * href="https://www.rfc-editor.org/rfc/rfc3986">RFC3986
* @note *
For network calls, URL usually has `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. `url.full` MUST - * NOT contain credentials passed via URL in form of `https://username:password@www.example.com/`. In such case - * username and password SHOULD be redacted and attribute's value SHOULD be - * `https://REDACTED:REDACTED@www.example.com/`. `url.full` SHOULD capture the absolute URL when it is available - * (or can be reconstructed). Sensitive content provided in `url.full` SHOULD be scrubbed when instrumentations can - * identify it. + * fragment is not transmitted over HTTP, but if it is known, it SHOULD be included nevertheless.
`url.full` + * MUST NOT contain credentials passed via URL in form of `https://username:password@www.example.com/`. In such + * case username and password SHOULD be redacted and attribute's value SHOULD be + * `https://REDACTED:REDACTED@www.example.com/`.
`url.full` SHOULD capture the absolute URL when it is + * available (or can be reconstructed).
Sensitive content provided in `url.full` SHOULD be scrubbed when + * instrumentations can identify it.
+ * + * Query string values for the following keys SHOULD be redacted by default and replaced by the value `REDACTED`: + *
This list + * is subject to change over time.
When a query string value is redacted, the query string key SHOULD still be + * preserved, e.g. `https://www.example.com/path?color=blue&sig=REDACTED`. */ @deprecated( "use `org.typelevel.otel4s.semconv.attributes.UrlAttributes.UrlFull` instead.", @@ -94,7 +104,17 @@ object UrlExperimentalAttributes { /** The URI query component
* @note - *
Sensitive content provided in `url.query` SHOULD be scrubbed when instrumentations can identify it. + *
Sensitive content provided in `url.query` SHOULD be scrubbed when instrumentations can identify it.
+ * + * Query string values for the following keys SHOULD be redacted by default and replaced by the value `REDACTED`: + *
This list + * is subject to change over time.
When a query string value is redacted, the query string key SHOULD still be + * preserved, e.g. `q=OpenTelemetry&sig=REDACTED`. */ @deprecated( "use `org.typelevel.otel4s.semconv.attributes.UrlAttributes.UrlQuery` instead.", diff --git a/semconv/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/attributes/UserAgentExperimentalAttributes.scala b/semconv/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/attributes/UserAgentExperimentalAttributes.scala index ea06ea126..2fc0c6fa3 100644 --- a/semconv/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/attributes/UserAgentExperimentalAttributes.scala +++ b/semconv/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/attributes/UserAgentExperimentalAttributes.scala @@ -41,6 +41,17 @@ object UserAgentExperimentalAttributes { val UserAgentOriginal: AttributeKey[String] = AttributeKey("user_agent.original") + /** Specifies the category of synthetic traffic, such as tests or bots.
+ * @note + *
This attribute MAY be derived from the contents of the `user_agent.original` attribute. Components that + * populate the attribute are responsible for determining what they consider to be synthetic bot or test traffic. + * This attribute can either be set for self-identification purposes, or on telemetry detected to be generated as a + * result of a synthetic request. This attribute is useful for distinguishing between genuine client traffic and + * synthetic traffic generated by bots or tests. + */ + val UserAgentSyntheticType: AttributeKey[String] = + AttributeKey("user_agent.synthetic.type") + /** Version of the user-agent extracted from original. Usually refers to the browser's version
* @note *
Example of extracting browser's version from original string. In @@ -51,4 +62,18 @@ object UserAgentExperimentalAttributes { val UserAgentVersion: AttributeKey[String] = AttributeKey("user_agent.version") + /** Values for [[UserAgentSyntheticType]]. + */ + abstract class UserAgentSyntheticTypeValue(val value: String) + object UserAgentSyntheticTypeValue { + + /** Bot source. + */ + case object Bot extends UserAgentSyntheticTypeValue("bot") + + /** Synthetic test source. + */ + case object Test extends UserAgentSyntheticTypeValue("test") + } + } diff --git a/semconv/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/attributes/VcsExperimentalAttributes.scala b/semconv/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/attributes/VcsExperimentalAttributes.scala index b821d4f58..b96aadc90 100644 --- a/semconv/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/attributes/VcsExperimentalAttributes.scala +++ b/semconv/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/attributes/VcsExperimentalAttributes.scala @@ -21,23 +21,58 @@ package experimental.attributes // DO NOT EDIT, this is an Auto-generated file from buildscripts/templates/registry/otel4s/attributes/SemanticAttributes.scala.j2 object VcsExperimentalAttributes { - /** The ID of the change (pull request/merge request) if applicable. This is usually a unique (within repository) - * identifier generated by the VCS system. + /** The ID of the change (pull request/merge request/changelist) if applicable. This is usually a unique (within + * repository) identifier generated by the VCS system. */ - val VcsRepositoryChangeId: AttributeKey[String] = - AttributeKey("vcs.repository.change.id") + val VcsChangeId: AttributeKey[String] = + AttributeKey("vcs.change.id") - /** The human readable title of the change (pull request/merge request). This title is often a brief summary of the - * change and may get merged in to a ref as the commit summary. + /** The state of the change (pull request/merge request/changelist). */ - val VcsRepositoryChangeTitle: AttributeKey[String] = - AttributeKey("vcs.repository.change.title") + val VcsChangeState: AttributeKey[String] = + AttributeKey("vcs.change.state") + + /** The human readable title of the change (pull request/merge request/changelist). This title is often a brief + * summary of the change and may get merged in to a ref as the commit summary. + */ + val VcsChangeTitle: AttributeKey[String] = + AttributeKey("vcs.change.title") + + /** The type of line change being measured on a branch or change. + */ + val VcsLineChangeType: AttributeKey[String] = + AttributeKey("vcs.line_change.type") /** The name of the reference such as * branch or tag in the repository. */ - val VcsRepositoryRefName: AttributeKey[String] = - AttributeKey("vcs.repository.ref.name") + val VcsRefBaseName: AttributeKey[String] = + AttributeKey("vcs.ref.base.name") + + /** The revision, literally revised version, The + * revision most often refers to a commit object in Git, or a revision number in SVN.
+ * @note + *
The revision can be a full hash value + * (see glossary), of the recorded change to a ref within a repository pointing to a commit commit object. It does not necessarily have to be a hash; it can + * simply define a revision number + * which is an integer that is monotonically increasing. In cases where it is identical to the `ref.base.name`, it + * SHOULD still be included. It is up to the implementer to decide which value to set as the revision based on the + * VCS system and situational context. + */ + val VcsRefBaseRevision: AttributeKey[String] = + AttributeKey("vcs.ref.base.revision") + + /** The type of the reference in the repository. + */ + val VcsRefBaseType: AttributeKey[String] = + AttributeKey("vcs.ref.base.type") + + /** The name of the reference such as + * branch or tag in the repository. + */ + val VcsRefHeadName: AttributeKey[String] = + AttributeKey("vcs.ref.head.name") /** The revision, literally revised version, The * revision most often refers to a commit object in Git, or a revision number in SVN.
@@ -46,27 +81,151 @@ object VcsExperimentalAttributes { * (see glossary), of the recorded change to a ref within a repository pointing to a commit commit object. It does not necessarily have to be a hash; it can * simply define a revision number - * which is an integer that is monotonically increasing. In cases where it is identical to the `ref.name`, it + * which is an integer that is monotonically increasing. In cases where it is identical to the `ref.head.name`, it * SHOULD still be included. It is up to the implementer to decide which value to set as the revision based on the * VCS system and situational context. */ + val VcsRefHeadRevision: AttributeKey[String] = + AttributeKey("vcs.ref.head.revision") + + /** The type of the reference in the repository. + */ + val VcsRefHeadType: AttributeKey[String] = + AttributeKey("vcs.ref.head.type") + + /** The type of the reference in the repository. + */ + val VcsRefType: AttributeKey[String] = + AttributeKey("vcs.ref.type") + + /** Deprecated, use `vcs.change.id` instead. + */ + @deprecated("Deprecated, use `vcs.change.id` instead.", "") + val VcsRepositoryChangeId: AttributeKey[String] = + AttributeKey("vcs.repository.change.id") + + /** Deprecated, use `vcs.change.title` instead. + */ + @deprecated("Deprecated, use `vcs.change.title` instead.", "") + val VcsRepositoryChangeTitle: AttributeKey[String] = + AttributeKey("vcs.repository.change.title") + + /** Deprecated, use `vcs.ref.head.name` instead. + */ + @deprecated("Deprecated, use `vcs.ref.head.name` instead.", "") + val VcsRepositoryRefName: AttributeKey[String] = + AttributeKey("vcs.repository.ref.name") + + /** Deprecated, use `vcs.ref.head.revision` instead. + */ + @deprecated("Deprecated, use `vcs.ref.head.revision` instead.", "") val VcsRepositoryRefRevision: AttributeKey[String] = AttributeKey("vcs.repository.ref.revision") - /** The type of the reference in the repository. + /** Deprecated, use `vcs.ref.head.type` instead. */ + @deprecated("Deprecated, use `vcs.ref.head.type` instead.", "") val VcsRepositoryRefType: AttributeKey[String] = AttributeKey("vcs.repository.ref.type") - /** The URL of the repository providing the complete address in order - * to locate and identify the repository. + /** The URL of the repository providing the complete address in order to + * locate and identify the repository. */ val VcsRepositoryUrlFull: AttributeKey[String] = AttributeKey("vcs.repository.url.full") + /** The type of revision comparison. + */ + val VcsRevisionDeltaDirection: AttributeKey[String] = + AttributeKey("vcs.revision_delta.direction") + + /** Values for [[VcsChangeState]]. + */ + abstract class VcsChangeStateValue(val value: String) + object VcsChangeStateValue { + + /** Open means the change is currently active and under review. It hasn't been merged into the target branch yet, + * and it's still possible to make changes or add comments. + */ + case object Open extends VcsChangeStateValue("open") + + /** WIP (work-in-progress, draft) means the change is still in progress and not yet ready for a full review. It + * might still undergo significant changes. + */ + case object Wip extends VcsChangeStateValue("wip") + + /** Closed means the merge request has been closed without merging. This can happen for various reasons, such as the + * changes being deemed unnecessary, the issue being resolved in another way, or the author deciding to withdraw + * the request. + */ + case object Closed extends VcsChangeStateValue("closed") + + /** Merged indicates that the change has been successfully integrated into the target codebase. + */ + case object Merged extends VcsChangeStateValue("merged") + } + + /** Values for [[VcsLineChangeType]]. + */ + abstract class VcsLineChangeTypeValue(val value: String) + object VcsLineChangeTypeValue { + + /** How many lines were added. + */ + case object Added extends VcsLineChangeTypeValue("added") + + /** How many lines were removed. + */ + case object Removed extends VcsLineChangeTypeValue("removed") + } + + /** Values for [[VcsRefBaseType]]. + */ + abstract class VcsRefBaseTypeValue(val value: String) + object VcsRefBaseTypeValue { + + /** branch + */ + case object Branch extends VcsRefBaseTypeValue("branch") + + /** tag + */ + case object Tag extends VcsRefBaseTypeValue("tag") + } + + /** Values for [[VcsRefHeadType]]. + */ + abstract class VcsRefHeadTypeValue(val value: String) + object VcsRefHeadTypeValue { + + /** branch + */ + case object Branch extends VcsRefHeadTypeValue("branch") + + /** tag + */ + case object Tag extends VcsRefHeadTypeValue("tag") + } + + /** Values for [[VcsRefType]]. + */ + abstract class VcsRefTypeValue(val value: String) + object VcsRefTypeValue { + + /** branch + */ + case object Branch extends VcsRefTypeValue("branch") + + /** tag + */ + case object Tag extends VcsRefTypeValue("tag") + } + /** Values for [[VcsRepositoryRefType]]. */ + @deprecated("Deprecated, use `vcs.ref.head.type` instead.", "") abstract class VcsRepositoryRefTypeValue(val value: String) + @annotation.nowarn("cat=deprecation") object VcsRepositoryRefTypeValue { /** branch @@ -78,4 +237,18 @@ object VcsExperimentalAttributes { case object Tag extends VcsRepositoryRefTypeValue("tag") } + /** Values for [[VcsRevisionDeltaDirection]]. + */ + abstract class VcsRevisionDeltaDirectionValue(val value: String) + object VcsRevisionDeltaDirectionValue { + + /** How many revisions the change is behind the target ref. + */ + case object Behind extends VcsRevisionDeltaDirectionValue("behind") + + /** How many revisions the change is ahead of the target ref. + */ + case object Ahead extends VcsRevisionDeltaDirectionValue("ahead") + } + } diff --git a/semconv/metrics/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/metrics/ContainerExperimentalMetrics.scala b/semconv/metrics/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/metrics/ContainerExperimentalMetrics.scala index 39f78dfa6..049b7891e 100644 --- a/semconv/metrics/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/metrics/ContainerExperimentalMetrics.scala +++ b/semconv/metrics/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/metrics/ContainerExperimentalMetrics.scala @@ -32,6 +32,7 @@ object ContainerExperimentalMetrics { DiskIo, MemoryUsage, NetworkIo, + Uptime, ) /** Total CPU time consumed
@@ -43,7 +44,7 @@ object ContainerExperimentalMetrics { val name: String = "container.cpu.time" val description: String = "Total CPU time consumed" val unit: String = "s" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { @@ -63,7 +64,7 @@ object ContainerExperimentalMetrics { Requirement.conditionallyRequired( "Required if mode is available, i.e. metrics coming from the Docker Stats API." ), - Stability.experimental + Stability.development ) val specs: List[AttributeSpec[_]] = @@ -106,7 +107,7 @@ object ContainerExperimentalMetrics { val name: String = "container.cpu.usage" val description: String = "Container's CPU usage, measured in cpus. Range from 0 to the number of allocatable CPUs" val unit: String = "{cpu}" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { @@ -126,7 +127,7 @@ object ContainerExperimentalMetrics { Requirement.conditionallyRequired( "Required if mode is available, i.e. metrics coming from the Docker Stats API." ), - Stability.experimental + Stability.development ) val specs: List[AttributeSpec[_]] = @@ -169,7 +170,7 @@ object ContainerExperimentalMetrics { val name: String = "container.disk.io" val description: String = "Disk bytes for the container." val unit: String = "By" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { @@ -183,7 +184,7 @@ object ContainerExperimentalMetrics { "read", ), Requirement.recommended, - Stability.experimental + Stability.development ) /** The device identifier @@ -195,7 +196,7 @@ object ContainerExperimentalMetrics { "(identifier)", ), Requirement.recommended, - Stability.experimental + Stability.development ) val specs: List[AttributeSpec[_]] = @@ -239,7 +240,7 @@ object ContainerExperimentalMetrics { val name: String = "container.memory.usage" val description: String = "Memory usage of the container." val unit: String = "By" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = Nil def create[F[_]: Meter, A: MeasurementValue]: F[Counter[F, A]] = @@ -276,39 +277,40 @@ object ContainerExperimentalMetrics { val name: String = "container.network.io" val description: String = "Network bytes for the container." val unit: String = "By" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { - /** The network IO operation direction. + /** The network interface name. */ - val networkIoDirection: AttributeSpec[String] = + val networkInterfaceName: AttributeSpec[String] = AttributeSpec( - NetworkExperimentalAttributes.NetworkIoDirection, + NetworkExperimentalAttributes.NetworkInterfaceName, List( - "transmit", + "lo", + "eth0", ), Requirement.recommended, - Stability.experimental + Stability.development ) - /** The device identifier + /** The network IO operation direction. */ - val systemDevice: AttributeSpec[String] = + val networkIoDirection: AttributeSpec[String] = AttributeSpec( - SystemExperimentalAttributes.SystemDevice, + NetworkExperimentalAttributes.NetworkIoDirection, List( - "(identifier)", + "transmit", ), Requirement.recommended, - Stability.experimental + Stability.development ) val specs: List[AttributeSpec[_]] = List( + networkInterfaceName, networkIoDirection, - systemDevice, ) } @@ -337,4 +339,43 @@ object ContainerExperimentalMetrics { } + /** The time the container has been running
+ * @note + *
Instrumentations SHOULD use a gauge with type `double` and measure uptime in seconds as a floating point + * number with the highest precision available. The actual accuracy would depend on the instrumentation and + * operating system. + */ + object Uptime extends MetricSpec { + + val name: String = "container.uptime" + val description: String = "The time the container has been running" + val unit: String = "s" + val stability: Stability = Stability.development + val attributeSpecs: List[AttributeSpec[_]] = Nil + + def create[F[_]: Meter, A: MeasurementValue]: F[Gauge[F, A]] = + Meter[F] + .gauge[A](name) + .withDescription(description) + .withUnit(unit) + .create + + def createObserver[F[_]: Meter, A: MeasurementValue]: F[ObservableMeasurement[F, A]] = + Meter[F] + .observableGauge[A](name) + .withDescription(description) + .withUnit(unit) + .createObserver + + def createWithCallback[F[_]: Meter, A: MeasurementValue]( + callback: ObservableMeasurement[F, A] => F[Unit] + ): Resource[F, ObservableGauge] = + Meter[F] + .observableGauge[A](name) + .withDescription(description) + .withUnit(unit) + .createWithCallback(callback) + + } + } diff --git a/semconv/metrics/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/metrics/DbExperimentalMetrics.scala b/semconv/metrics/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/metrics/DbExperimentalMetrics.scala index 690374028..1e375e875 100644 --- a/semconv/metrics/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/metrics/DbExperimentalMetrics.scala +++ b/semconv/metrics/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/metrics/DbExperimentalMetrics.scala @@ -47,7 +47,10 @@ object DbExperimentalMetrics { ClientConnectionsUsage, ClientConnectionsUseTime, ClientConnectionsWaitTime, + ClientCosmosdbActiveInstanceCount, + ClientCosmosdbOperationRequestCharge, ClientOperationDuration, + ClientResponseReturnedRows, ) /** The number of connections that are currently in state described by the `state` attribute @@ -57,7 +60,7 @@ object DbExperimentalMetrics { val name: String = "db.client.connection.count" val description: String = "The number of connections that are currently in state described by the `state` attribute" val unit: String = "{connection}" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { @@ -75,7 +78,7 @@ object DbExperimentalMetrics { "myDataSource", ), Requirement.required, - Stability.experimental + Stability.development ) /** The state of a connection in the pool @@ -87,7 +90,7 @@ object DbExperimentalMetrics { "idle", ), Requirement.required, - Stability.experimental + Stability.development ) val specs: List[AttributeSpec[_]] = @@ -129,7 +132,7 @@ object DbExperimentalMetrics { val name: String = "db.client.connection.create_time" val description: String = "The time it took to create a new connection" val unit: String = "s" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { @@ -147,7 +150,7 @@ object DbExperimentalMetrics { "myDataSource", ), Requirement.required, - Stability.experimental + Stability.development ) val specs: List[AttributeSpec[_]] = @@ -173,7 +176,7 @@ object DbExperimentalMetrics { val name: String = "db.client.connection.idle.max" val description: String = "The maximum number of idle open connections allowed" val unit: String = "{connection}" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { @@ -191,7 +194,7 @@ object DbExperimentalMetrics { "myDataSource", ), Requirement.required, - Stability.experimental + Stability.development ) val specs: List[AttributeSpec[_]] = @@ -232,7 +235,7 @@ object DbExperimentalMetrics { val name: String = "db.client.connection.idle.min" val description: String = "The minimum number of idle open connections allowed" val unit: String = "{connection}" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { @@ -250,7 +253,7 @@ object DbExperimentalMetrics { "myDataSource", ), Requirement.required, - Stability.experimental + Stability.development ) val specs: List[AttributeSpec[_]] = @@ -291,7 +294,7 @@ object DbExperimentalMetrics { val name: String = "db.client.connection.max" val description: String = "The maximum number of open connections allowed" val unit: String = "{connection}" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { @@ -309,7 +312,7 @@ object DbExperimentalMetrics { "myDataSource", ), Requirement.required, - Stability.experimental + Stability.development ) val specs: List[AttributeSpec[_]] = @@ -350,7 +353,7 @@ object DbExperimentalMetrics { val name: String = "db.client.connection.pending_requests" val description: String = "The number of current pending requests for an open connection" val unit: String = "{request}" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { @@ -368,7 +371,7 @@ object DbExperimentalMetrics { "myDataSource", ), Requirement.required, - Stability.experimental + Stability.development ) val specs: List[AttributeSpec[_]] = @@ -410,7 +413,7 @@ object DbExperimentalMetrics { val description: String = "The number of connection timeouts that have occurred trying to obtain a connection from the pool" val unit: String = "{timeout}" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { @@ -428,7 +431,7 @@ object DbExperimentalMetrics { "myDataSource", ), Requirement.required, - Stability.experimental + Stability.development ) val specs: List[AttributeSpec[_]] = @@ -469,7 +472,7 @@ object DbExperimentalMetrics { val name: String = "db.client.connection.use_time" val description: String = "The time between borrowing a connection and returning it to the pool" val unit: String = "s" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { @@ -487,7 +490,7 @@ object DbExperimentalMetrics { "myDataSource", ), Requirement.required, - Stability.experimental + Stability.development ) val specs: List[AttributeSpec[_]] = @@ -513,7 +516,7 @@ object DbExperimentalMetrics { val name: String = "db.client.connection.wait_time" val description: String = "The time it took to obtain an open connection from the pool" val unit: String = "s" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { @@ -531,7 +534,7 @@ object DbExperimentalMetrics { "myDataSource", ), Requirement.required, - Stability.experimental + Stability.development ) val specs: List[AttributeSpec[_]] = @@ -559,7 +562,7 @@ object DbExperimentalMetrics { val description: String = "Deprecated, use `db.client.connection.create_time` instead. Note: the unit also changed from `ms` to `s`." val unit: String = "ms" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { @@ -574,7 +577,7 @@ object DbExperimentalMetrics { "myDataSource", ), Requirement.required, - Stability.experimental + Stability.development ) val specs: List[AttributeSpec[_]] = @@ -601,7 +604,7 @@ object DbExperimentalMetrics { val name: String = "db.client.connections.idle.max" val description: String = "Deprecated, use `db.client.connection.idle.max` instead." val unit: String = "{connection}" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { @@ -616,7 +619,7 @@ object DbExperimentalMetrics { "myDataSource", ), Requirement.required, - Stability.experimental + Stability.development ) val specs: List[AttributeSpec[_]] = @@ -658,7 +661,7 @@ object DbExperimentalMetrics { val name: String = "db.client.connections.idle.min" val description: String = "Deprecated, use `db.client.connection.idle.min` instead." val unit: String = "{connection}" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { @@ -673,7 +676,7 @@ object DbExperimentalMetrics { "myDataSource", ), Requirement.required, - Stability.experimental + Stability.development ) val specs: List[AttributeSpec[_]] = @@ -715,7 +718,7 @@ object DbExperimentalMetrics { val name: String = "db.client.connections.max" val description: String = "Deprecated, use `db.client.connection.max` instead." val unit: String = "{connection}" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { @@ -730,7 +733,7 @@ object DbExperimentalMetrics { "myDataSource", ), Requirement.required, - Stability.experimental + Stability.development ) val specs: List[AttributeSpec[_]] = @@ -772,7 +775,7 @@ object DbExperimentalMetrics { val name: String = "db.client.connections.pending_requests" val description: String = "Deprecated, use `db.client.connection.pending_requests` instead." val unit: String = "{request}" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { @@ -787,7 +790,7 @@ object DbExperimentalMetrics { "myDataSource", ), Requirement.required, - Stability.experimental + Stability.development ) val specs: List[AttributeSpec[_]] = @@ -829,7 +832,7 @@ object DbExperimentalMetrics { val name: String = "db.client.connections.timeouts" val description: String = "Deprecated, use `db.client.connection.timeouts` instead." val unit: String = "{timeout}" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { @@ -844,7 +847,7 @@ object DbExperimentalMetrics { "myDataSource", ), Requirement.required, - Stability.experimental + Stability.development ) val specs: List[AttributeSpec[_]] = @@ -886,7 +889,7 @@ object DbExperimentalMetrics { val name: String = "db.client.connections.usage" val description: String = "Deprecated, use `db.client.connection.count` instead." val unit: String = "{connection}" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { @@ -901,7 +904,7 @@ object DbExperimentalMetrics { "myDataSource", ), Requirement.required, - Stability.experimental + Stability.development ) /** Deprecated, use `db.client.connection.state` instead. @@ -914,7 +917,7 @@ object DbExperimentalMetrics { "idle", ), Requirement.required, - Stability.experimental + Stability.development ) val specs: List[AttributeSpec[_]] = @@ -958,7 +961,7 @@ object DbExperimentalMetrics { val description: String = "Deprecated, use `db.client.connection.use_time` instead. Note: the unit also changed from `ms` to `s`." val unit: String = "ms" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { @@ -973,7 +976,7 @@ object DbExperimentalMetrics { "myDataSource", ), Requirement.required, - Stability.experimental + Stability.development ) val specs: List[AttributeSpec[_]] = @@ -1001,7 +1004,7 @@ object DbExperimentalMetrics { val description: String = "Deprecated, use `db.client.connection.wait_time` instead. Note: the unit also changed from `ms` to `s`." val unit: String = "ms" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { @@ -1016,7 +1019,7 @@ object DbExperimentalMetrics { "myDataSource", ), Requirement.required, - Stability.experimental + Stability.development ) val specs: List[AttributeSpec[_]] = @@ -1035,6 +1038,303 @@ object DbExperimentalMetrics { } + /** Number of active client instances + */ + object ClientCosmosdbActiveInstanceCount extends MetricSpec { + + val name: String = "db.client.cosmosdb.active_instance.count" + val description: String = "Number of active client instances" + val unit: String = "{instance}" + val stability: Stability = Stability.development + val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs + + object AttributeSpecs { + + /** Name of the database host.
+ * @note + *
When observed from the client side, and when communicating through an intermediary, `server.address` + * SHOULD represent the server address behind any intermediaries, for example proxies, if it's available. + */ + val serverAddress: AttributeSpec[String] = + AttributeSpec( + ServerAttributes.ServerAddress, + List( + "example.com", + "10.1.2.80", + "/tmp/my.sock", + ), + Requirement.recommended, + Stability.stable + ) + + /** Server port number.
+ * @note + *
When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD + * represent the server port behind any intermediaries, for example proxies, if it's available. + */ + val serverPort: AttributeSpec[Long] = + AttributeSpec( + ServerAttributes.ServerPort, + List( + 80, + 8080, + 443, + ), + Requirement.conditionallyRequired( + "If using a port other than the default port for this DBMS and if `server.address` is set." + ), + Stability.stable + ) + + val specs: List[AttributeSpec[_]] = + List( + serverAddress, + serverPort, + ) + } + + def create[F[_]: Meter, A: MeasurementValue]: F[UpDownCounter[F, A]] = + Meter[F] + .upDownCounter[A](name) + .withDescription(description) + .withUnit(unit) + .create + + def createObserver[F[_]: Meter, A: MeasurementValue]: F[ObservableMeasurement[F, A]] = + Meter[F] + .observableUpDownCounter[A](name) + .withDescription(description) + .withUnit(unit) + .createObserver + + def createWithCallback[F[_]: Meter, A: MeasurementValue]( + callback: ObservableMeasurement[F, A] => F[Unit] + ): Resource[F, ObservableUpDownCounter] = + Meter[F] + .observableUpDownCounter[A](name) + .withDescription(description) + .withUnit(unit) + .createWithCallback(callback) + + } + + /** Request charge consumed by the operation + */ + object ClientCosmosdbOperationRequestCharge extends MetricSpec { + + val name: String = "db.client.cosmosdb.operation.request_charge" + val description: String = + "[Request charge](https://learn.microsoft.com/azure/cosmos-db/request-units) consumed by the operation" + val unit: String = "{request_unit}" + val stability: Stability = Stability.development + val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs + + object AttributeSpecs { + + /** Cosmos DB container name.
+ * @note + *
It is RECOMMENDED to capture the value as provided by the application without attempting to do any case + * normalization.
The collection name SHOULD NOT be extracted from `db.query.text`, unless the query format + * is known to only ever have a single collection name present.
For batch operations, if the individual + * operations are known to have the same collection name then that collection name SHOULD be used.
This + * attribute has stability level RELEASE CANDIDATE. + */ + val dbCollectionName: AttributeSpec[String] = + AttributeSpec( + DbExperimentalAttributes.DbCollectionName, + List( + "public.users", + "customers", + ), + Requirement.conditionallyRequired("If available."), + Stability.development + ) + + /** Account or request consistency + * level. + */ + val dbCosmosdbConsistencyLevel: AttributeSpec[String] = + AttributeSpec( + DbExperimentalAttributes.DbCosmosdbConsistencyLevel, + List( + "Eventual", + "ConsistentPrefix", + "BoundedStaleness", + "Strong", + "Session", + ), + Requirement.conditionallyRequired("If available."), + Stability.development + ) + + /** List of regions contacted during operation in the order that they were contacted. If there is more than one + * region listed, it indicates that the operation was performed on multiple regions i.e. cross-regional call.
+ * @note + *
Region name matches the format of `displayName` in Azure + * Location API + */ + val dbCosmosdbRegionsContacted: AttributeSpec[Seq[String]] = + AttributeSpec( + DbExperimentalAttributes.DbCosmosdbRegionsContacted, + List( + Seq("North Central US", "Australia East", "Australia Southeast"), + ), + Requirement.recommended("If available"), + Stability.development + ) + + /** Cosmos DB sub status code. + */ + val dbCosmosdbSubStatusCode: AttributeSpec[Long] = + AttributeSpec( + DbExperimentalAttributes.DbCosmosdbSubStatusCode, + List( + 1000, + 1002, + ), + Requirement.conditionallyRequired("when response was received and contained sub-code."), + Stability.development + ) + + /** The name of the database, fully qualified within the server address and port. + */ + val dbNamespace: AttributeSpec[String] = + AttributeSpec( + DbExperimentalAttributes.DbNamespace, + List( + "customers", + "test.users", + ), + Requirement.conditionallyRequired("If available."), + Stability.development + ) + + /** The name of the operation or command being executed.
+ * @note + *
It is RECOMMENDED to capture the value as provided by the application without attempting to do any case + * normalization.
The operation name SHOULD NOT be extracted from `db.query.text`, unless the query format + * is known to only ever have a single operation name present.
For batch operations, if the individual + * operations are known to have the same operation name then that operation name SHOULD be used prepended by + * `BATCH `, otherwise `db.operation.name` SHOULD be `BATCH` or some other database system specific term if + * more applicable.
This attribute has stability level RELEASE CANDIDATE. + */ + val dbOperationName: AttributeSpec[String] = + AttributeSpec( + DbExperimentalAttributes.DbOperationName, + List( + "findAndModify", + "HMSET", + "SELECT", + ), + Requirement.conditionallyRequired( + "If readily available and if there is a single operation name that describes the database call. The operation name MAY be parsed from the query text, in which case it SHOULD be the single operation name found in the query." + ), + Stability.development + ) + + /** Database response status code.
+ * @note + *
The status code returned by the database. Usually it represents an error code, but may also represent + * partial success, warning, or differentiate between various types of successful outcomes. Semantic + * conventions for individual database systems SHOULD document what `db.response.status_code` means in the + * context of that system. This attribute has stability level RELEASE CANDIDATE. + */ + val dbResponseStatusCode: AttributeSpec[String] = + AttributeSpec( + DbExperimentalAttributes.DbResponseStatusCode, + List( + "102", + "ORA-17002", + "08P01", + "404", + ), + Requirement.conditionallyRequired("If the operation failed and status code is available."), + Stability.development + ) + + /** Describes a class of error the operation ended with.
+ * @note + *
The `error.type` SHOULD match the `db.response.status_code` returned by the database or the client + * library, or the canonical name of exception that occurred. When using canonical exception type name, + * instrumentation SHOULD do the best effort to report the most relevant type. For example, if the original + * exception is wrapped into a generic one, the original exception SHOULD be preferred. Instrumentations SHOULD + * document how `error.type` is populated. + */ + val errorType: AttributeSpec[String] = + AttributeSpec( + ErrorAttributes.ErrorType, + List( + "timeout", + "java.net.UnknownHostException", + "server_certificate_invalid", + "500", + ), + Requirement.conditionallyRequired("If and only if the operation failed."), + Stability.stable + ) + + /** Name of the database host.
+ * @note + *
When observed from the client side, and when communicating through an intermediary, `server.address` + * SHOULD represent the server address behind any intermediaries, for example proxies, if it's available. + */ + val serverAddress: AttributeSpec[String] = + AttributeSpec( + ServerAttributes.ServerAddress, + List( + "example.com", + "10.1.2.80", + "/tmp/my.sock", + ), + Requirement.recommended, + Stability.stable + ) + + /** Server port number.
+ * @note + *
When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD + * represent the server port behind any intermediaries, for example proxies, if it's available. + */ + val serverPort: AttributeSpec[Long] = + AttributeSpec( + ServerAttributes.ServerPort, + List( + 80, + 8080, + 443, + ), + Requirement.conditionallyRequired( + "If using a port other than the default port for this DBMS and if `server.address` is set." + ), + Stability.stable + ) + + val specs: List[AttributeSpec[_]] = + List( + dbCollectionName, + dbCosmosdbConsistencyLevel, + dbCosmosdbRegionsContacted, + dbCosmosdbSubStatusCode, + dbNamespace, + dbOperationName, + dbResponseStatusCode, + errorType, + serverAddress, + serverPort, + ) + } + + def create[F[_]: Meter, A: MeasurementValue](boundaries: BucketBoundaries): F[Histogram[F, A]] = + Meter[F] + .histogram[A](name) + .withDescription(description) + .withUnit(unit) + .withExplicitBucketBoundaries(boundaries) + .create + + } + /** Duration of database client operations.
* @note *
Batch operations SHOULD be recorded as a single operation. @@ -1044,7 +1344,277 @@ object DbExperimentalMetrics { val name: String = "db.client.operation.duration" val description: String = "Duration of database client operations." val unit: String = "s" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development + val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs + + object AttributeSpecs { + + /** The name of a collection (table, container) within the database.
+ * @note + *
It is RECOMMENDED to capture the value as provided by the application without attempting to do any case + * normalization.
The collection name SHOULD NOT be extracted from `db.query.text`, unless the query format + * is known to only ever have a single collection name present.
For batch operations, if the individual + * operations are known to have the same collection name then that collection name SHOULD be used.
This + * attribute has stability level RELEASE CANDIDATE. + */ + val dbCollectionName: AttributeSpec[String] = + AttributeSpec( + DbExperimentalAttributes.DbCollectionName, + List( + "public.users", + "customers", + ), + Requirement.conditionallyRequired( + "If readily available and if a database call is performed on a single collection. The collection name MAY be parsed from the query text, in which case it SHOULD be the single collection name in the query." + ), + Stability.development + ) + + /** The name of the database, fully qualified within the server address and port.
+ * @note + *
If a database system has multiple namespace components, they SHOULD be concatenated (potentially using + * database system specific conventions) from most general to most specific namespace component, and more + * specific namespaces SHOULD NOT be captured without the more general namespaces, to ensure that "startswith" + * queries for the more general namespaces will be valid. Semantic conventions for individual database systems + * SHOULD document what `db.namespace` means in the context of that system. It is RECOMMENDED to capture the + * value as provided by the application without attempting to do any case normalization. This attribute has + * stability level RELEASE CANDIDATE. + */ + val dbNamespace: AttributeSpec[String] = + AttributeSpec( + DbExperimentalAttributes.DbNamespace, + List( + "customers", + "test.users", + ), + Requirement.conditionallyRequired("If available."), + Stability.development + ) + + /** The name of the operation or command being executed.
+ * @note + *
It is RECOMMENDED to capture the value as provided by the application without attempting to do any case + * normalization.
The operation name SHOULD NOT be extracted from `db.query.text`, unless the query format + * is known to only ever have a single operation name present.
For batch operations, if the individual + * operations are known to have the same operation name then that operation name SHOULD be used prepended by + * `BATCH `, otherwise `db.operation.name` SHOULD be `BATCH` or some other database system specific term if + * more applicable.
This attribute has stability level RELEASE CANDIDATE. + */ + val dbOperationName: AttributeSpec[String] = + AttributeSpec( + DbExperimentalAttributes.DbOperationName, + List( + "findAndModify", + "HMSET", + "SELECT", + ), + Requirement.conditionallyRequired( + "If readily available and if there is a single operation name that describes the database call. The operation name MAY be parsed from the query text, in which case it SHOULD be the single operation name found in the query." + ), + Stability.development + ) + + /** Low cardinality representation of a database query text.
+ * @note + *
`db.query.summary` provides static summary of the query text. It describes a class of database queries + * and is useful as a grouping key, especially when analyzing telemetry for database calls involving complex + * queries. 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 Generating query + * summary section. This attribute has stability level RELEASE CANDIDATE. + */ + val dbQuerySummary: AttributeSpec[String] = + AttributeSpec( + DbExperimentalAttributes.DbQuerySummary, + List( + "SELECT wuser_table", + "INSERT shipping_details SELECT orders", + "get user by id", + ), + Requirement.recommended("if readily available or if instrumentation supports query summarization."), + Stability.development + ) + + /** The database query being executed.
+ * @note + *
For sanitization see Sanitization of + * `db.query.text`. For batch operations, if the individual operations are known to have the same query + * text then that query text SHOULD be used, otherwise all of the individual query texts SHOULD be concatenated + * with separator `; ` or some other database system specific separator if more applicable. Even though + * parameterized query text can potentially have sensitive data, by using a parameterized query the user is + * giving a strong signal that any sensitive data will be passed as parameter values, and the benefit to + * observability of capturing the static part of the query text by default outweighs the risk. This attribute + * has stability level RELEASE CANDIDATE. + */ + val dbQueryText: AttributeSpec[String] = + AttributeSpec( + DbExperimentalAttributes.DbQueryText, + List( + "SELECT * FROM wuser_table where username = ?", + "SET mykey ?", + ), + Requirement.optIn, + Stability.development + ) + + /** Database response status code.
+ * @note + *
The status code returned by the database. Usually it represents an error code, but may also represent + * partial success, warning, or differentiate between various types of successful outcomes. Semantic + * conventions for individual database systems SHOULD document what `db.response.status_code` means in the + * context of that system. This attribute has stability level RELEASE CANDIDATE. + */ + val dbResponseStatusCode: AttributeSpec[String] = + AttributeSpec( + DbExperimentalAttributes.DbResponseStatusCode, + List( + "102", + "ORA-17002", + "08P01", + "404", + ), + Requirement.conditionallyRequired("If the operation failed and status code is available."), + Stability.development + ) + + /** The database management system (DBMS) product as identified by the client instrumentation.
+ * @note + *
The actual DBMS may differ from the one identified by the client. For example, when using PostgreSQL + * client libraries to connect to a CockroachDB, the `db.system` is set to `postgresql` based on the + * instrumentation's best knowledge. This attribute has stability level RELEASE CANDIDATE. + */ + val dbSystem: AttributeSpec[String] = + AttributeSpec( + DbExperimentalAttributes.DbSystem, + List( + ), + Requirement.required, + Stability.development + ) + + /** Describes a class of error the operation ended with.
+ * @note + *
The `error.type` SHOULD match the `db.response.status_code` returned by the database or the client + * library, or the canonical name of exception that occurred. When using canonical exception type name, + * instrumentation SHOULD do the best effort to report the most relevant type. For example, if the original + * exception is wrapped into a generic one, the original exception SHOULD be preferred. Instrumentations SHOULD + * document how `error.type` is populated. + */ + val errorType: AttributeSpec[String] = + AttributeSpec( + ErrorAttributes.ErrorType, + List( + "timeout", + "java.net.UnknownHostException", + "server_certificate_invalid", + "500", + ), + Requirement.conditionallyRequired("If and only if the operation failed."), + Stability.stable + ) + + /** Peer address of the database node where the operation was performed.
+ * @note + *
Semantic conventions for individual database systems SHOULD document whether `network.peer.*` attributes + * are applicable. Network peer address and port are useful when the application interacts with individual + * database nodes directly. If a database operation involved multiple network calls (for example retries), the + * address of the last contacted node SHOULD be used. + */ + val networkPeerAddress: AttributeSpec[String] = + AttributeSpec( + NetworkAttributes.NetworkPeerAddress, + List( + "10.1.2.80", + "/tmp/my.sock", + ), + Requirement.recommended("If applicable for this database system."), + Stability.stable + ) + + /** Peer port number of the network connection. + */ + val networkPeerPort: AttributeSpec[Long] = + AttributeSpec( + NetworkAttributes.NetworkPeerPort, + List( + 65123, + ), + Requirement.recommended("If and only if `network.peer.address` is set."), + Stability.stable + ) + + /** Name of the database host.
+ * @note + *
When observed from the client side, and when communicating through an intermediary, `server.address` + * SHOULD represent the server address behind any intermediaries, for example proxies, if it's available. + */ + val serverAddress: AttributeSpec[String] = + AttributeSpec( + ServerAttributes.ServerAddress, + List( + "example.com", + "10.1.2.80", + "/tmp/my.sock", + ), + Requirement.recommended, + Stability.stable + ) + + /** Server port number.
+ * @note + *
When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD + * represent the server port behind any intermediaries, for example proxies, if it's available. + */ + val serverPort: AttributeSpec[Long] = + AttributeSpec( + ServerAttributes.ServerPort, + List( + 80, + 8080, + 443, + ), + Requirement.conditionallyRequired( + "If using a port other than the default port for this DBMS and if `server.address` is set." + ), + Stability.stable + ) + + val specs: List[AttributeSpec[_]] = + List( + dbCollectionName, + dbNamespace, + dbOperationName, + dbQuerySummary, + dbQueryText, + dbResponseStatusCode, + dbSystem, + errorType, + networkPeerAddress, + networkPeerPort, + serverAddress, + serverPort, + ) + } + + def create[F[_]: Meter, A: MeasurementValue](boundaries: BucketBoundaries): F[Histogram[F, A]] = + Meter[F] + .histogram[A](name) + .withDescription(description) + .withUnit(unit) + .withExplicitBucketBoundaries(boundaries) + .create + + } + + /** The actual number of records returned by the database operation. + */ + object ClientResponseReturnedRows extends MetricSpec { + + val name: String = "db.client.response.returned_rows" + val description: String = "The actual number of records returned by the database operation." + val unit: String = "{row}" + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { @@ -1052,11 +1622,10 @@ object DbExperimentalMetrics { /** The name of a collection (table, container) within the database.
* @note *
It is RECOMMENDED to capture the value as provided by the application without attempting to do any case - * normalization. If the collection name is parsed from the query text, it SHOULD be the first collection name - * found in the query and it SHOULD match the value provided in the query text including any schema and - * database name prefix. For batch operations, if the individual operations are known to have the same - * collection name then that collection name SHOULD be used, otherwise `db.collection.name` SHOULD NOT be - * captured. This attribute has stability level RELEASE CANDIDATE. + * normalization.
The collection name SHOULD NOT be extracted from `db.query.text`, unless the query format + * is known to only ever have a single collection name present.
For batch operations, if the individual + * operations are known to have the same collection name then that collection name SHOULD be used.
This + * attribute has stability level RELEASE CANDIDATE. */ val dbCollectionName: AttributeSpec[String] = AttributeSpec( @@ -1066,9 +1635,9 @@ object DbExperimentalMetrics { "customers", ), Requirement.conditionallyRequired( - "If readily available. The collection name MAY be parsed from the query text, in which case it SHOULD be the first collection name in the query." + "If readily available and if a database call is performed on a single collection. The collection name MAY be parsed from the query text, in which case it SHOULD be the single collection name in the query." ), - Stability.experimental + Stability.development ) /** The name of the database, fully qualified within the server address and port.
@@ -1089,17 +1658,17 @@ object DbExperimentalMetrics { "test.users", ), Requirement.conditionallyRequired("If available."), - Stability.experimental + Stability.development ) /** The name of the operation or command being executed.
* @note *
It is RECOMMENDED to capture the value as provided by the application without attempting to do any case - * normalization. If the operation name is parsed from the query text, it SHOULD be the first operation name - * found in the query. For batch operations, if the individual operations are known to have the same operation - * name then that operation name SHOULD be used prepended by `BATCH `, otherwise `db.operation.name` SHOULD be - * `BATCH` or some other database system specific term if more applicable. This attribute has stability level - * RELEASE CANDIDATE. + * normalization.
The operation name SHOULD NOT be extracted from `db.query.text`, unless the query format + * is known to only ever have a single operation name present.
For batch operations, if the individual + * operations are known to have the same operation name then that operation name SHOULD be used prepended by + * `BATCH `, otherwise `db.operation.name` SHOULD be `BATCH` or some other database system specific term if + * more applicable.
This attribute has stability level RELEASE CANDIDATE. */ val dbOperationName: AttributeSpec[String] = AttributeSpec( @@ -1110,9 +1679,53 @@ object DbExperimentalMetrics { "SELECT", ), Requirement.conditionallyRequired( - "If readily available. The operation name MAY be parsed from the query text, in which case it SHOULD be the first operation name found in the query." + "If readily available and if there is a single operation name that describes the database call. The operation name MAY be parsed from the query text, in which case it SHOULD be the single operation name found in the query." + ), + Stability.development + ) + + /** Low cardinality representation of a database query text.
+ * @note + *
`db.query.summary` provides static summary of the query text. It describes a class of database queries + * and is useful as a grouping key, especially when analyzing telemetry for database calls involving complex + * queries. 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 Generating query + * summary section. This attribute has stability level RELEASE CANDIDATE. + */ + val dbQuerySummary: AttributeSpec[String] = + AttributeSpec( + DbExperimentalAttributes.DbQuerySummary, + List( + "SELECT wuser_table", + "INSERT shipping_details SELECT orders", + "get user by id", + ), + Requirement.recommended("if readily available or if instrumentation supports query summarization."), + Stability.development + ) + + /** The database query being executed.
+ * @note + *
For sanitization see Sanitization of + * `db.query.text`. For batch operations, if the individual operations are known to have the same query + * text then that query text SHOULD be used, otherwise all of the individual query texts SHOULD be concatenated + * with separator `; ` or some other database system specific separator if more applicable. Even though + * parameterized query text can potentially have sensitive data, by using a parameterized query the user is + * giving a strong signal that any sensitive data will be passed as parameter values, and the benefit to + * observability of capturing the static part of the query text by default outweighs the risk. This attribute + * has stability level RELEASE CANDIDATE. + */ + val dbQueryText: AttributeSpec[String] = + AttributeSpec( + DbExperimentalAttributes.DbQueryText, + List( + "SELECT * FROM wuser_table where username = ?", + "SET mykey ?", ), - Stability.experimental + Requirement.optIn, + Stability.development ) /** Database response status code.
@@ -1132,7 +1745,7 @@ object DbExperimentalMetrics { "404", ), Requirement.conditionallyRequired("If the operation failed and status code is available."), - Stability.experimental + Stability.development ) /** The database management system (DBMS) product as identified by the client instrumentation.
@@ -1147,7 +1760,7 @@ object DbExperimentalMetrics { List( ), Requirement.required, - Stability.experimental + Stability.development ) /** Describes a class of error the operation ended with.
@@ -1242,6 +1855,8 @@ object DbExperimentalMetrics { dbCollectionName, dbNamespace, dbOperationName, + dbQuerySummary, + dbQueryText, dbResponseStatusCode, dbSystem, errorType, diff --git a/semconv/metrics/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/metrics/DnsExperimentalMetrics.scala b/semconv/metrics/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/metrics/DnsExperimentalMetrics.scala index 5092cc903..d89025600 100644 --- a/semconv/metrics/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/metrics/DnsExperimentalMetrics.scala +++ b/semconv/metrics/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/metrics/DnsExperimentalMetrics.scala @@ -37,7 +37,7 @@ object DnsExperimentalMetrics { val name: String = "dns.lookup.duration" val description: String = "Measures the time taken to perform a DNS lookup." val unit: String = "s" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { @@ -56,7 +56,7 @@ object DnsExperimentalMetrics { "dot.net", ), Requirement.required, - Stability.experimental + Stability.development ) /** Describes the error the DNS lookup failed with.
diff --git a/semconv/metrics/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/metrics/FaasExperimentalMetrics.scala b/semconv/metrics/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/metrics/FaasExperimentalMetrics.scala index 9f4d09d00..85c0c5b3b 100644 --- a/semconv/metrics/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/metrics/FaasExperimentalMetrics.scala +++ b/semconv/metrics/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/metrics/FaasExperimentalMetrics.scala @@ -45,7 +45,7 @@ object FaasExperimentalMetrics { val name: String = "faas.coldstarts" val description: String = "Number of invocation cold starts" val unit: String = "{coldstart}" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { @@ -58,7 +58,7 @@ object FaasExperimentalMetrics { List( ), Requirement.recommended, - Stability.experimental + Stability.development ) val specs: List[AttributeSpec[_]] = @@ -99,7 +99,7 @@ object FaasExperimentalMetrics { val name: String = "faas.cpu_usage" val description: String = "Distribution of CPU usage per invocation" val unit: String = "s" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { @@ -112,7 +112,7 @@ object FaasExperimentalMetrics { List( ), Requirement.recommended, - Stability.experimental + Stability.development ) val specs: List[AttributeSpec[_]] = @@ -138,7 +138,7 @@ object FaasExperimentalMetrics { val name: String = "faas.errors" val description: String = "Number of invocation errors" val unit: String = "{error}" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { @@ -151,7 +151,7 @@ object FaasExperimentalMetrics { List( ), Requirement.recommended, - Stability.experimental + Stability.development ) val specs: List[AttributeSpec[_]] = @@ -192,7 +192,7 @@ object FaasExperimentalMetrics { val name: String = "faas.init_duration" val description: String = "Measures the duration of the function's initialization, such as a cold start" val unit: String = "s" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { @@ -205,7 +205,7 @@ object FaasExperimentalMetrics { List( ), Requirement.recommended, - Stability.experimental + Stability.development ) val specs: List[AttributeSpec[_]] = @@ -231,7 +231,7 @@ object FaasExperimentalMetrics { val name: String = "faas.invocations" val description: String = "Number of successful invocations" val unit: String = "{invocation}" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { @@ -244,7 +244,7 @@ object FaasExperimentalMetrics { List( ), Requirement.recommended, - Stability.experimental + Stability.development ) val specs: List[AttributeSpec[_]] = @@ -285,7 +285,7 @@ object FaasExperimentalMetrics { val name: String = "faas.invoke_duration" val description: String = "Measures the duration of the function's logic execution" val unit: String = "s" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { @@ -298,7 +298,7 @@ object FaasExperimentalMetrics { List( ), Requirement.recommended, - Stability.experimental + Stability.development ) val specs: List[AttributeSpec[_]] = @@ -324,7 +324,7 @@ object FaasExperimentalMetrics { val name: String = "faas.mem_usage" val description: String = "Distribution of max memory usage per invocation" val unit: String = "By" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { @@ -337,7 +337,7 @@ object FaasExperimentalMetrics { List( ), Requirement.recommended, - Stability.experimental + Stability.development ) val specs: List[AttributeSpec[_]] = @@ -363,7 +363,7 @@ object FaasExperimentalMetrics { val name: String = "faas.net_io" val description: String = "Distribution of net I/O usage per invocation" val unit: String = "By" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { @@ -376,7 +376,7 @@ object FaasExperimentalMetrics { List( ), Requirement.recommended, - Stability.experimental + Stability.development ) val specs: List[AttributeSpec[_]] = @@ -402,7 +402,7 @@ object FaasExperimentalMetrics { val name: String = "faas.timeouts" val description: String = "Number of invocation timeouts" val unit: String = "{timeout}" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { @@ -415,7 +415,7 @@ object FaasExperimentalMetrics { List( ), Requirement.recommended, - Stability.experimental + Stability.development ) val specs: List[AttributeSpec[_]] = diff --git a/semconv/metrics/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/metrics/GenAiExperimentalMetrics.scala b/semconv/metrics/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/metrics/GenAiExperimentalMetrics.scala index f36a75db7..1479de333 100644 --- a/semconv/metrics/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/metrics/GenAiExperimentalMetrics.scala +++ b/semconv/metrics/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/metrics/GenAiExperimentalMetrics.scala @@ -41,7 +41,7 @@ object GenAiExperimentalMetrics { val name: String = "gen_ai.client.operation.duration" val description: String = "GenAI operation duration" val unit: String = "s" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { @@ -78,7 +78,7 @@ object GenAiExperimentalMetrics { List( ), Requirement.required, - Stability.experimental + Stability.development ) /** The name of the GenAI model a request is being made to. @@ -93,8 +93,8 @@ object GenAiExperimentalMetrics { "-", "4", ), - Requirement.required, - Stability.experimental + Requirement.conditionallyRequired("If available."), + Stability.development ) /** The name of the model that generated the response. @@ -106,7 +106,7 @@ object GenAiExperimentalMetrics { "gpt-4-0613", ), Requirement.recommended, - Stability.experimental + Stability.development ) /** The Generative AI product as identified by the client or server instrumentation.
@@ -130,7 +130,7 @@ object GenAiExperimentalMetrics { "i", ), Requirement.required, - Stability.experimental + Stability.development ) /** GenAI server address.
@@ -196,7 +196,7 @@ object GenAiExperimentalMetrics { val name: String = "gen_ai.client.token.usage" val description: String = "Measures number of input and output tokens used" val unit: String = "{token}" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { @@ -214,7 +214,7 @@ object GenAiExperimentalMetrics { List( ), Requirement.required, - Stability.experimental + Stability.development ) /** The name of the GenAI model a request is being made to. @@ -229,8 +229,8 @@ object GenAiExperimentalMetrics { "-", "4", ), - Requirement.required, - Stability.experimental + Requirement.conditionallyRequired("If available."), + Stability.development ) /** The name of the model that generated the response. @@ -242,7 +242,7 @@ object GenAiExperimentalMetrics { "gpt-4-0613", ), Requirement.recommended, - Stability.experimental + Stability.development ) /** The Generative AI product as identified by the client or server instrumentation.
@@ -266,7 +266,7 @@ object GenAiExperimentalMetrics { "i", ), Requirement.required, - Stability.experimental + Stability.development ) /** The type of token being counted. @@ -279,7 +279,7 @@ object GenAiExperimentalMetrics { "output", ), Requirement.required, - Stability.experimental + Stability.development ) /** GenAI server address.
@@ -345,7 +345,7 @@ object GenAiExperimentalMetrics { val name: String = "gen_ai.server.request.duration" val description: String = "Generative AI server request duration such as time-to-last byte or last output token" val unit: String = "s" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { @@ -382,7 +382,7 @@ object GenAiExperimentalMetrics { List( ), Requirement.required, - Stability.experimental + Stability.development ) /** The name of the GenAI model a request is being made to. @@ -397,8 +397,8 @@ object GenAiExperimentalMetrics { "-", "4", ), - Requirement.required, - Stability.experimental + Requirement.conditionallyRequired("If available."), + Stability.development ) /** The name of the model that generated the response. @@ -410,7 +410,7 @@ object GenAiExperimentalMetrics { "gpt-4-0613", ), Requirement.recommended, - Stability.experimental + Stability.development ) /** The Generative AI product as identified by the client or server instrumentation.
@@ -434,7 +434,7 @@ object GenAiExperimentalMetrics { "i", ), Requirement.required, - Stability.experimental + Stability.development ) /** GenAI server address.
@@ -500,7 +500,7 @@ object GenAiExperimentalMetrics { val name: String = "gen_ai.server.time_per_output_token" val description: String = "Time per output token generated after the first token for successful responses" val unit: String = "s" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { @@ -518,7 +518,7 @@ object GenAiExperimentalMetrics { List( ), Requirement.required, - Stability.experimental + Stability.development ) /** The name of the GenAI model a request is being made to. @@ -533,8 +533,8 @@ object GenAiExperimentalMetrics { "-", "4", ), - Requirement.required, - Stability.experimental + Requirement.conditionallyRequired("If available."), + Stability.development ) /** The name of the model that generated the response. @@ -546,7 +546,7 @@ object GenAiExperimentalMetrics { "gpt-4-0613", ), Requirement.recommended, - Stability.experimental + Stability.development ) /** The Generative AI product as identified by the client or server instrumentation.
@@ -570,7 +570,7 @@ object GenAiExperimentalMetrics { "i", ), Requirement.required, - Stability.experimental + Stability.development ) /** GenAI server address.
@@ -635,7 +635,7 @@ object GenAiExperimentalMetrics { val name: String = "gen_ai.server.time_to_first_token" val description: String = "Time to generate first token for successful responses" val unit: String = "s" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { @@ -653,7 +653,7 @@ object GenAiExperimentalMetrics { List( ), Requirement.required, - Stability.experimental + Stability.development ) /** The name of the GenAI model a request is being made to. @@ -668,8 +668,8 @@ object GenAiExperimentalMetrics { "-", "4", ), - Requirement.required, - Stability.experimental + Requirement.conditionallyRequired("If available."), + Stability.development ) /** The name of the model that generated the response. @@ -681,7 +681,7 @@ object GenAiExperimentalMetrics { "gpt-4-0613", ), Requirement.recommended, - Stability.experimental + Stability.development ) /** The Generative AI product as identified by the client or server instrumentation.
@@ -705,7 +705,7 @@ object GenAiExperimentalMetrics { "i", ), Requirement.required, - Stability.experimental + Stability.development ) /** GenAI server address.
diff --git a/semconv/metrics/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/metrics/HttpExperimentalMetrics.scala b/semconv/metrics/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/metrics/HttpExperimentalMetrics.scala index 20ee07ebd..deeebf73e 100644 --- a/semconv/metrics/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/metrics/HttpExperimentalMetrics.scala +++ b/semconv/metrics/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/metrics/HttpExperimentalMetrics.scala @@ -48,7 +48,7 @@ object HttpExperimentalMetrics { val name: String = "http.client.active_requests" val description: String = "Number of active HTTP requests." val unit: String = "{request}" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { @@ -147,7 +147,7 @@ object HttpExperimentalMetrics { "/users?id={id}", ), Requirement.conditionallyRequired("If available."), - Stability.experimental + Stability.development ) val specs: List[AttributeSpec[_]] = @@ -192,7 +192,7 @@ object HttpExperimentalMetrics { val name: String = "http.client.connection.duration" val description: String = "The duration of the successfully established outbound HTTP connections." val unit: String = "s" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { @@ -304,7 +304,7 @@ object HttpExperimentalMetrics { val name: String = "http.client.open_connections" val description: String = "Number of outbound HTTP connections that are currently active or idle on the client." val unit: String = "{connection}" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { @@ -319,7 +319,7 @@ object HttpExperimentalMetrics { "idle", ), Requirement.required, - Stability.experimental + Stability.development ) /** Peer address of the network connection - IP address or Unix domain socket name. @@ -450,7 +450,7 @@ object HttpExperimentalMetrics { val name: String = "http.client.request.body.size" val description: String = "Size of HTTP client request bodies." val unit: String = "By" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { @@ -523,7 +523,7 @@ object HttpExperimentalMetrics { Stability.stable ) - /** OSI application layer or non-OSI equivalent.
+ /** OSI application layer or non-OSI equivalent.
* @note *
The value SHOULD be normalized to lowercase. */ @@ -622,7 +622,7 @@ object HttpExperimentalMetrics { "/users?id={id}", ), Requirement.conditionallyRequired("If available."), - Stability.experimental + Stability.development ) val specs: List[AttributeSpec[_]] = @@ -730,7 +730,7 @@ object HttpExperimentalMetrics { Stability.stable ) - /** OSI application layer or non-OSI equivalent.
+ /** OSI application layer or non-OSI equivalent.
* @note *
The value SHOULD be normalized to lowercase. */ @@ -814,6 +814,24 @@ object HttpExperimentalMetrics { Stability.stable ) + /** The low-cardinality template of an absolute path + * reference.
+ * @note + *
The `url.template` MUST have low cardinality. It is not usually available on HTTP clients, but may be + * known by the application or specialized HTTP instrumentation. + */ + val urlTemplate: AttributeSpec[String] = + AttributeSpec( + UrlExperimentalAttributes.UrlTemplate, + List( + "/users/{id}", + "/users/:id", + "/users?id={id}", + ), + Requirement.optIn, + Stability.development + ) + val specs: List[AttributeSpec[_]] = List( errorType, @@ -824,6 +842,7 @@ object HttpExperimentalMetrics { serverAddress, serverPort, urlScheme, + urlTemplate, ) } @@ -849,7 +868,7 @@ object HttpExperimentalMetrics { val name: String = "http.client.response.body.size" val description: String = "Size of HTTP client response bodies." val unit: String = "By" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { @@ -922,7 +941,7 @@ object HttpExperimentalMetrics { Stability.stable ) - /** OSI application layer or non-OSI equivalent.
+ /** OSI application layer or non-OSI equivalent.
* @note *
The value SHOULD be normalized to lowercase. */ @@ -1021,7 +1040,7 @@ object HttpExperimentalMetrics { "/users?id={id}", ), Requirement.conditionallyRequired("If available."), - Stability.experimental + Stability.development ) val specs: List[AttributeSpec[_]] = @@ -1055,7 +1074,7 @@ object HttpExperimentalMetrics { val name: String = "http.server.active_requests" val description: String = "Number of active HTTP server requests." val unit: String = "{request}" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { @@ -1092,7 +1111,7 @@ object HttpExperimentalMetrics { /** Name of the local HTTP server that received the request.
* @note *
See Setting - * `server.address` and `server.port` attributes.
Warning Since this + * `server.address` and `server.port` attributes.Warning Since this * attribute is based on HTTP headers, opting in to it may allow an attacker to trigger cardinality limits, * degrading the usefulness of the metric.*/ @@ -1111,7 +1130,7 @@ object HttpExperimentalMetrics { /** Port of the local HTTP server that received the request.* @note *
See Setting - * `server.address` and `server.port` attributes.
Warning Since this + * `server.address` and `server.port` attributes.Warning Since this * attribute is based on HTTP headers, opting in to it may allow an attacker to trigger cardinality limits, * degrading the usefulness of the metric.*/ @@ -1187,7 +1206,7 @@ object HttpExperimentalMetrics { val name: String = "http.server.request.body.size" val description: String = "Size of HTTP server request bodies." val unit: String = "By" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { @@ -1277,7 +1296,7 @@ object HttpExperimentalMetrics { Stability.stable ) - /** OSI application layer or non-OSI equivalent.+ /** OSI application layer or non-OSI equivalent.
* @note *
The value SHOULD be normalized to lowercase. */ @@ -1314,7 +1333,7 @@ object HttpExperimentalMetrics { /** Name of the local HTTP server that received the request.
* @note *
See Setting - * `server.address` and `server.port` attributes.
Warning Since this + * `server.address` and `server.port` attributes.Warning Since this * attribute is based on HTTP headers, opting in to it may allow an attacker to trigger cardinality limits, * degrading the usefulness of the metric.*/ @@ -1333,7 +1352,7 @@ object HttpExperimentalMetrics { /** Port of the local HTTP server that received the request.* @note *
See Setting - * `server.address` and `server.port` attributes.
Warning Since this + * `server.address` and `server.port` attributes.Warning Since this * attribute is based on HTTP headers, opting in to it may allow an attacker to trigger cardinality limits, * degrading the usefulness of the metric.*/ @@ -1368,6 +1387,23 @@ object HttpExperimentalMetrics { Stability.stable ) + /** Specifies the category of synthetic traffic, such as tests or bots.+ * @note + *
This attribute MAY be derived from the contents of the `user_agent.original` attribute. Components that + * populate the attribute are responsible for determining what they consider to be synthetic bot or test + * traffic. This attribute can either be set for self-identification purposes, or on telemetry detected to be + * generated as a result of a synthetic request. This attribute is useful for distinguishing between genuine + * client traffic and synthetic traffic generated by bots or tests. + */ + val userAgentSyntheticType: AttributeSpec[String] = + AttributeSpec( + UserAgentExperimentalAttributes.UserAgentSyntheticType, + List( + ), + Requirement.optIn, + Stability.development + ) + val specs: List[AttributeSpec[_]] = List( errorType, @@ -1379,6 +1415,7 @@ object HttpExperimentalMetrics { serverAddress, serverPort, urlScheme, + userAgentSyntheticType, ) } @@ -1490,7 +1527,7 @@ object HttpExperimentalMetrics { Stability.stable ) - /** OSI application layer or non-OSI equivalent.
+ /** OSI application layer or non-OSI equivalent.
* @note *
The value SHOULD be normalized to lowercase. */ @@ -1527,7 +1564,7 @@ object HttpExperimentalMetrics { /** Name of the local HTTP server that received the request.
* @note *
See Setting - * `server.address` and `server.port` attributes.
Warning Since this + * `server.address` and `server.port` attributes.Warning Since this * attribute is based on HTTP headers, opting in to it may allow an attacker to trigger cardinality limits, * degrading the usefulness of the metric.*/ @@ -1546,7 +1583,7 @@ object HttpExperimentalMetrics { /** Port of the local HTTP server that received the request.* @note *
See Setting - * `server.address` and `server.port` attributes.
Warning Since this + * `server.address` and `server.port` attributes.Warning Since this * attribute is based on HTTP headers, opting in to it may allow an attacker to trigger cardinality limits, * degrading the usefulness of the metric.*/ @@ -1581,6 +1618,23 @@ object HttpExperimentalMetrics { Stability.stable ) + /** Specifies the category of synthetic traffic, such as tests or bots.+ * @note + *
This attribute MAY be derived from the contents of the `user_agent.original` attribute. Components that + * populate the attribute are responsible for determining what they consider to be synthetic bot or test + * traffic. This attribute can either be set for self-identification purposes, or on telemetry detected to be + * generated as a result of a synthetic request. This attribute is useful for distinguishing between genuine + * client traffic and synthetic traffic generated by bots or tests. + */ + val userAgentSyntheticType: AttributeSpec[String] = + AttributeSpec( + UserAgentExperimentalAttributes.UserAgentSyntheticType, + List( + ), + Requirement.optIn, + Stability.development + ) + val specs: List[AttributeSpec[_]] = List( errorType, @@ -1592,6 +1646,7 @@ object HttpExperimentalMetrics { serverAddress, serverPort, urlScheme, + userAgentSyntheticType, ) } @@ -1617,7 +1672,7 @@ object HttpExperimentalMetrics { val name: String = "http.server.response.body.size" val description: String = "Size of HTTP server response bodies." val unit: String = "By" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { @@ -1707,7 +1762,7 @@ object HttpExperimentalMetrics { Stability.stable ) - /** OSI application layer or non-OSI equivalent.
+ /** OSI application layer or non-OSI equivalent.
* @note *
The value SHOULD be normalized to lowercase. */ @@ -1744,7 +1799,7 @@ object HttpExperimentalMetrics { /** Name of the local HTTP server that received the request.
* @note *
See Setting - * `server.address` and `server.port` attributes.
Warning Since this + * `server.address` and `server.port` attributes.Warning Since this * attribute is based on HTTP headers, opting in to it may allow an attacker to trigger cardinality limits, * degrading the usefulness of the metric.*/ @@ -1763,7 +1818,7 @@ object HttpExperimentalMetrics { /** Port of the local HTTP server that received the request.* @note *
See Setting - * `server.address` and `server.port` attributes.
Warning Since this + * `server.address` and `server.port` attributes.Warning Since this * attribute is based on HTTP headers, opting in to it may allow an attacker to trigger cardinality limits, * degrading the usefulness of the metric.*/ @@ -1798,6 +1853,23 @@ object HttpExperimentalMetrics { Stability.stable ) + /** Specifies the category of synthetic traffic, such as tests or bots.+ * @note + *
This attribute MAY be derived from the contents of the `user_agent.original` attribute. Components that + * populate the attribute are responsible for determining what they consider to be synthetic bot or test + * traffic. This attribute can either be set for self-identification purposes, or on telemetry detected to be + * generated as a result of a synthetic request. This attribute is useful for distinguishing between genuine + * client traffic and synthetic traffic generated by bots or tests. + */ + val userAgentSyntheticType: AttributeSpec[String] = + AttributeSpec( + UserAgentExperimentalAttributes.UserAgentSyntheticType, + List( + ), + Requirement.optIn, + Stability.development + ) + val specs: List[AttributeSpec[_]] = List( errorType, @@ -1809,6 +1881,7 @@ object HttpExperimentalMetrics { serverAddress, serverPort, urlScheme, + userAgentSyntheticType, ) } diff --git a/semconv/metrics/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/metrics/HwExperimentalMetrics.scala b/semconv/metrics/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/metrics/HwExperimentalMetrics.scala index c181d8c05..79d337efc 100644 --- a/semconv/metrics/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/metrics/HwExperimentalMetrics.scala +++ b/semconv/metrics/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/metrics/HwExperimentalMetrics.scala @@ -41,7 +41,7 @@ object HwExperimentalMetrics { val name: String = "hw.energy" val description: String = "Energy consumed by the component" val unit: String = "J" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { @@ -55,7 +55,7 @@ object HwExperimentalMetrics { "win32battery_battery_testsysa33_1", ), Requirement.required, - Stability.experimental + Stability.development ) /** An easily-recognizable name for the hardware component @@ -67,7 +67,7 @@ object HwExperimentalMetrics { "eth0", ), Requirement.recommended, - Stability.experimental + Stability.development ) /** Unique identifier of the parent component (typically the `hw.id` attribute of the enclosure, or disk @@ -80,7 +80,7 @@ object HwExperimentalMetrics { "dellStorage_perc_0", ), Requirement.recommended, - Stability.experimental + Stability.development ) /** Type of the component
@@ -95,7 +95,7 @@ object HwExperimentalMetrics { List( ), Requirement.required, - Stability.experimental + Stability.development ) val specs: List[AttributeSpec[_]] = @@ -139,7 +139,7 @@ object HwExperimentalMetrics { val name: String = "hw.errors" val description: String = "Number of errors encountered by the component" val unit: String = "{error}" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { @@ -172,7 +172,7 @@ object HwExperimentalMetrics { "win32battery_battery_testsysa33_1", ), Requirement.required, - Stability.experimental + Stability.development ) /** An easily-recognizable name for the hardware component @@ -184,7 +184,7 @@ object HwExperimentalMetrics { "eth0", ), Requirement.recommended, - Stability.experimental + Stability.development ) /** Unique identifier of the parent component (typically the `hw.id` attribute of the enclosure, or disk @@ -197,7 +197,7 @@ object HwExperimentalMetrics { "dellStorage_perc_0", ), Requirement.recommended, - Stability.experimental + Stability.development ) /** Type of the component
@@ -212,7 +212,7 @@ object HwExperimentalMetrics { List( ), Requirement.required, - Stability.experimental + Stability.development ) val specs: List[AttributeSpec[_]] = @@ -259,7 +259,7 @@ object HwExperimentalMetrics { val name: String = "hw.power" val description: String = "Instantaneous power consumed by the component" val unit: String = "W" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { @@ -273,7 +273,7 @@ object HwExperimentalMetrics { "win32battery_battery_testsysa33_1", ), Requirement.required, - Stability.experimental + Stability.development ) /** An easily-recognizable name for the hardware component @@ -285,7 +285,7 @@ object HwExperimentalMetrics { "eth0", ), Requirement.recommended, - Stability.experimental + Stability.development ) /** Unique identifier of the parent component (typically the `hw.id` attribute of the enclosure, or disk @@ -298,7 +298,7 @@ object HwExperimentalMetrics { "dellStorage_perc_0", ), Requirement.recommended, - Stability.experimental + Stability.development ) /** Type of the component
@@ -313,7 +313,7 @@ object HwExperimentalMetrics { List( ), Requirement.required, - Stability.experimental + Stability.development ) val specs: List[AttributeSpec[_]] = @@ -363,7 +363,7 @@ object HwExperimentalMetrics { val name: String = "hw.status" val description: String = "Operational status: `1` (true) or `0` (false) for each of the possible states" val unit: String = "1" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { @@ -377,7 +377,7 @@ object HwExperimentalMetrics { "win32battery_battery_testsysa33_1", ), Requirement.required, - Stability.experimental + Stability.development ) /** An easily-recognizable name for the hardware component @@ -389,7 +389,7 @@ object HwExperimentalMetrics { "eth0", ), Requirement.recommended, - Stability.experimental + Stability.development ) /** Unique identifier of the parent component (typically the `hw.id` attribute of the enclosure, or disk @@ -402,7 +402,7 @@ object HwExperimentalMetrics { "dellStorage_perc_0", ), Requirement.recommended, - Stability.experimental + Stability.development ) /** The current state of the component @@ -413,7 +413,7 @@ object HwExperimentalMetrics { List( ), Requirement.required, - Stability.experimental + Stability.development ) /** Type of the component
@@ -428,7 +428,7 @@ object HwExperimentalMetrics { List( ), Requirement.required, - Stability.experimental + Stability.development ) val specs: List[AttributeSpec[_]] = diff --git a/semconv/metrics/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/metrics/JvmExperimentalMetrics.scala b/semconv/metrics/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/metrics/JvmExperimentalMetrics.scala index 031e34c85..04ccda7d5 100644 --- a/semconv/metrics/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/metrics/JvmExperimentalMetrics.scala +++ b/semconv/metrics/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/metrics/JvmExperimentalMetrics.scala @@ -57,7 +57,7 @@ object JvmExperimentalMetrics { val name: String = "jvm.buffer.count" val description: String = "Number of buffers in the pool." val unit: String = "{buffer}" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { @@ -75,7 +75,7 @@ object JvmExperimentalMetrics { "direct", ), Requirement.recommended, - Stability.experimental + Stability.development ) val specs: List[AttributeSpec[_]] = @@ -116,7 +116,7 @@ object JvmExperimentalMetrics { val name: String = "jvm.buffer.memory.limit" val description: String = "Measure of total memory capacity of buffers." val unit: String = "By" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { @@ -134,7 +134,7 @@ object JvmExperimentalMetrics { "direct", ), Requirement.recommended, - Stability.experimental + Stability.development ) val specs: List[AttributeSpec[_]] = @@ -176,7 +176,7 @@ object JvmExperimentalMetrics { val name: String = "jvm.buffer.memory.usage" val description: String = "Deprecated, use `jvm.buffer.memory.used` instead." val unit: String = "By" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { @@ -194,7 +194,7 @@ object JvmExperimentalMetrics { "direct", ), Requirement.recommended, - Stability.experimental + Stability.development ) val specs: List[AttributeSpec[_]] = @@ -235,7 +235,7 @@ object JvmExperimentalMetrics { val name: String = "jvm.buffer.memory.used" val description: String = "Measure of memory used by buffers." val unit: String = "By" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { @@ -253,7 +253,7 @@ object JvmExperimentalMetrics { "direct", ), Requirement.recommended, - Stability.experimental + Stability.development ) val specs: List[AttributeSpec[_]] = @@ -651,7 +651,7 @@ object JvmExperimentalMetrics { val name: String = "jvm.memory.init" val description: String = "Measure of initial memory requested." val unit: String = "By" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { @@ -956,7 +956,7 @@ object JvmExperimentalMetrics { val name: String = "jvm.system.cpu.load_1m" val description: String = "Average CPU load of the whole system for the last minute as reported by the JVM." val unit: String = "{run_queue_item}" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = Nil def create[F[_]: Meter, A: MeasurementValue]: F[Gauge[F, A]] = @@ -995,7 +995,7 @@ object JvmExperimentalMetrics { val name: String = "jvm.system.cpu.utilization" val description: String = "Recent CPU utilization for the whole system as reported by the JVM." val unit: String = "1" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = Nil def create[F[_]: Meter, A: MeasurementValue]: F[Gauge[F, A]] = diff --git a/semconv/metrics/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/metrics/K8sExperimentalMetrics.scala b/semconv/metrics/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/metrics/K8sExperimentalMetrics.scala index 59a2d0296..5b98338a8 100644 --- a/semconv/metrics/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/metrics/K8sExperimentalMetrics.scala +++ b/semconv/metrics/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/metrics/K8sExperimentalMetrics.scala @@ -21,6 +21,7 @@ package metrics import cats.effect.Resource import org.typelevel.otel4s.metrics._ +import org.typelevel.otel4s.semconv.experimental.attributes._ // DO NOT EDIT, this is an Auto-generated file from buildscripts/templates/registry/otel4s/metrics/SemanticMetrics.scala.j2 object K8sExperimentalMetrics { @@ -29,9 +30,15 @@ object K8sExperimentalMetrics { NodeCpuTime, NodeCpuUsage, NodeMemoryUsage, + NodeNetworkErrors, + NodeNetworkIo, + NodeUptime, PodCpuTime, PodCpuUsage, PodMemoryUsage, + PodNetworkErrors, + PodNetworkIo, + PodUptime, ) /** Total CPU time consumed
@@ -43,7 +50,7 @@ object K8sExperimentalMetrics { val name: String = "k8s.node.cpu.time" val description: String = "Total CPU time consumed" val unit: String = "s" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = Nil def create[F[_]: Meter, A: MeasurementValue]: F[Counter[F, A]] = @@ -80,7 +87,7 @@ object K8sExperimentalMetrics { val name: String = "k8s.node.cpu.usage" val description: String = "Node's CPU usage, measured in cpus. Range from 0 to the number of allocatable CPUs" val unit: String = "{cpu}" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = Nil def create[F[_]: Meter, A: MeasurementValue]: F[Gauge[F, A]] = @@ -117,7 +124,184 @@ object K8sExperimentalMetrics { val name: String = "k8s.node.memory.usage" val description: String = "Memory usage of the Node" val unit: String = "By" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development + val attributeSpecs: List[AttributeSpec[_]] = Nil + + def create[F[_]: Meter, A: MeasurementValue]: F[Gauge[F, A]] = + Meter[F] + .gauge[A](name) + .withDescription(description) + .withUnit(unit) + .create + + def createObserver[F[_]: Meter, A: MeasurementValue]: F[ObservableMeasurement[F, A]] = + Meter[F] + .observableGauge[A](name) + .withDescription(description) + .withUnit(unit) + .createObserver + + def createWithCallback[F[_]: Meter, A: MeasurementValue]( + callback: ObservableMeasurement[F, A] => F[Unit] + ): Resource[F, ObservableGauge] = + Meter[F] + .observableGauge[A](name) + .withDescription(description) + .withUnit(unit) + .createWithCallback(callback) + + } + + /** Node network errors + */ + object NodeNetworkErrors extends MetricSpec { + + val name: String = "k8s.node.network.errors" + val description: String = "Node network errors" + val unit: String = "{error}" + val stability: Stability = Stability.development + val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs + + object AttributeSpecs { + + /** The network interface name. + */ + val networkInterfaceName: AttributeSpec[String] = + AttributeSpec( + NetworkExperimentalAttributes.NetworkInterfaceName, + List( + "lo", + "eth0", + ), + Requirement.recommended, + Stability.development + ) + + /** The network IO operation direction. + */ + val networkIoDirection: AttributeSpec[String] = + AttributeSpec( + NetworkExperimentalAttributes.NetworkIoDirection, + List( + "transmit", + ), + Requirement.recommended, + Stability.development + ) + + val specs: List[AttributeSpec[_]] = + List( + networkInterfaceName, + networkIoDirection, + ) + } + + def create[F[_]: Meter, A: MeasurementValue]: F[Counter[F, A]] = + Meter[F] + .counter[A](name) + .withDescription(description) + .withUnit(unit) + .create + + def createObserver[F[_]: Meter, A: MeasurementValue]: F[ObservableMeasurement[F, A]] = + Meter[F] + .observableCounter[A](name) + .withDescription(description) + .withUnit(unit) + .createObserver + + def createWithCallback[F[_]: Meter, A: MeasurementValue]( + callback: ObservableMeasurement[F, A] => F[Unit] + ): Resource[F, ObservableCounter] = + Meter[F] + .observableCounter[A](name) + .withDescription(description) + .withUnit(unit) + .createWithCallback(callback) + + } + + /** Network bytes for the Node + */ + object NodeNetworkIo extends MetricSpec { + + val name: String = "k8s.node.network.io" + val description: String = "Network bytes for the Node" + val unit: String = "By" + val stability: Stability = Stability.development + val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs + + object AttributeSpecs { + + /** The network interface name. + */ + val networkInterfaceName: AttributeSpec[String] = + AttributeSpec( + NetworkExperimentalAttributes.NetworkInterfaceName, + List( + "lo", + "eth0", + ), + Requirement.recommended, + Stability.development + ) + + /** The network IO operation direction. + */ + val networkIoDirection: AttributeSpec[String] = + AttributeSpec( + NetworkExperimentalAttributes.NetworkIoDirection, + List( + "transmit", + ), + Requirement.recommended, + Stability.development + ) + + val specs: List[AttributeSpec[_]] = + List( + networkInterfaceName, + networkIoDirection, + ) + } + + def create[F[_]: Meter, A: MeasurementValue]: F[Counter[F, A]] = + Meter[F] + .counter[A](name) + .withDescription(description) + .withUnit(unit) + .create + + def createObserver[F[_]: Meter, A: MeasurementValue]: F[ObservableMeasurement[F, A]] = + Meter[F] + .observableCounter[A](name) + .withDescription(description) + .withUnit(unit) + .createObserver + + def createWithCallback[F[_]: Meter, A: MeasurementValue]( + callback: ObservableMeasurement[F, A] => F[Unit] + ): Resource[F, ObservableCounter] = + Meter[F] + .observableCounter[A](name) + .withDescription(description) + .withUnit(unit) + .createWithCallback(callback) + + } + + /** The time the Node has been running
+ * @note + *
Instrumentations SHOULD use a gauge with type `double` and measure uptime in seconds as a floating point + * number with the highest precision available. The actual accuracy would depend on the instrumentation and + * operating system. + */ + object NodeUptime extends MetricSpec { + + val name: String = "k8s.node.uptime" + val description: String = "The time the Node has been running" + val unit: String = "s" + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = Nil def create[F[_]: Meter, A: MeasurementValue]: F[Gauge[F, A]] = @@ -154,7 +338,7 @@ object K8sExperimentalMetrics { val name: String = "k8s.pod.cpu.time" val description: String = "Total CPU time consumed" val unit: String = "s" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = Nil def create[F[_]: Meter, A: MeasurementValue]: F[Counter[F, A]] = @@ -191,7 +375,7 @@ object K8sExperimentalMetrics { val name: String = "k8s.pod.cpu.usage" val description: String = "Pod's CPU usage, measured in cpus. Range from 0 to the number of allocatable CPUs" val unit: String = "{cpu}" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = Nil def create[F[_]: Meter, A: MeasurementValue]: F[Gauge[F, A]] = @@ -228,7 +412,184 @@ object K8sExperimentalMetrics { val name: String = "k8s.pod.memory.usage" val description: String = "Memory usage of the Pod" val unit: String = "By" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development + val attributeSpecs: List[AttributeSpec[_]] = Nil + + def create[F[_]: Meter, A: MeasurementValue]: F[Gauge[F, A]] = + Meter[F] + .gauge[A](name) + .withDescription(description) + .withUnit(unit) + .create + + def createObserver[F[_]: Meter, A: MeasurementValue]: F[ObservableMeasurement[F, A]] = + Meter[F] + .observableGauge[A](name) + .withDescription(description) + .withUnit(unit) + .createObserver + + def createWithCallback[F[_]: Meter, A: MeasurementValue]( + callback: ObservableMeasurement[F, A] => F[Unit] + ): Resource[F, ObservableGauge] = + Meter[F] + .observableGauge[A](name) + .withDescription(description) + .withUnit(unit) + .createWithCallback(callback) + + } + + /** Pod network errors + */ + object PodNetworkErrors extends MetricSpec { + + val name: String = "k8s.pod.network.errors" + val description: String = "Pod network errors" + val unit: String = "{error}" + val stability: Stability = Stability.development + val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs + + object AttributeSpecs { + + /** The network interface name. + */ + val networkInterfaceName: AttributeSpec[String] = + AttributeSpec( + NetworkExperimentalAttributes.NetworkInterfaceName, + List( + "lo", + "eth0", + ), + Requirement.recommended, + Stability.development + ) + + /** The network IO operation direction. + */ + val networkIoDirection: AttributeSpec[String] = + AttributeSpec( + NetworkExperimentalAttributes.NetworkIoDirection, + List( + "transmit", + ), + Requirement.recommended, + Stability.development + ) + + val specs: List[AttributeSpec[_]] = + List( + networkInterfaceName, + networkIoDirection, + ) + } + + def create[F[_]: Meter, A: MeasurementValue]: F[Counter[F, A]] = + Meter[F] + .counter[A](name) + .withDescription(description) + .withUnit(unit) + .create + + def createObserver[F[_]: Meter, A: MeasurementValue]: F[ObservableMeasurement[F, A]] = + Meter[F] + .observableCounter[A](name) + .withDescription(description) + .withUnit(unit) + .createObserver + + def createWithCallback[F[_]: Meter, A: MeasurementValue]( + callback: ObservableMeasurement[F, A] => F[Unit] + ): Resource[F, ObservableCounter] = + Meter[F] + .observableCounter[A](name) + .withDescription(description) + .withUnit(unit) + .createWithCallback(callback) + + } + + /** Network bytes for the Pod + */ + object PodNetworkIo extends MetricSpec { + + val name: String = "k8s.pod.network.io" + val description: String = "Network bytes for the Pod" + val unit: String = "By" + val stability: Stability = Stability.development + val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs + + object AttributeSpecs { + + /** The network interface name. + */ + val networkInterfaceName: AttributeSpec[String] = + AttributeSpec( + NetworkExperimentalAttributes.NetworkInterfaceName, + List( + "lo", + "eth0", + ), + Requirement.recommended, + Stability.development + ) + + /** The network IO operation direction. + */ + val networkIoDirection: AttributeSpec[String] = + AttributeSpec( + NetworkExperimentalAttributes.NetworkIoDirection, + List( + "transmit", + ), + Requirement.recommended, + Stability.development + ) + + val specs: List[AttributeSpec[_]] = + List( + networkInterfaceName, + networkIoDirection, + ) + } + + def create[F[_]: Meter, A: MeasurementValue]: F[Counter[F, A]] = + Meter[F] + .counter[A](name) + .withDescription(description) + .withUnit(unit) + .create + + def createObserver[F[_]: Meter, A: MeasurementValue]: F[ObservableMeasurement[F, A]] = + Meter[F] + .observableCounter[A](name) + .withDescription(description) + .withUnit(unit) + .createObserver + + def createWithCallback[F[_]: Meter, A: MeasurementValue]( + callback: ObservableMeasurement[F, A] => F[Unit] + ): Resource[F, ObservableCounter] = + Meter[F] + .observableCounter[A](name) + .withDescription(description) + .withUnit(unit) + .createWithCallback(callback) + + } + + /** The time the Pod has been running
+ * @note + *
Instrumentations SHOULD use a gauge with type `double` and measure uptime in seconds as a floating point + * number with the highest precision available. The actual accuracy would depend on the instrumentation and + * operating system. + */ + object PodUptime extends MetricSpec { + + val name: String = "k8s.pod.uptime" + val description: String = "The time the Pod has been running" + val unit: String = "s" + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = Nil def create[F[_]: Meter, A: MeasurementValue]: F[Gauge[F, A]] = diff --git a/semconv/metrics/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/metrics/MessagingExperimentalMetrics.scala b/semconv/metrics/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/metrics/MessagingExperimentalMetrics.scala index 5772e84be..4bab57af9 100644 --- a/semconv/metrics/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/metrics/MessagingExperimentalMetrics.scala +++ b/semconv/metrics/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/metrics/MessagingExperimentalMetrics.scala @@ -53,7 +53,7 @@ object MessagingExperimentalMetrics { val name: String = "messaging.client.consumed.messages" val description: String = "Number of messages that were delivered to the application." val unit: String = "{message}" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { @@ -67,9 +67,9 @@ object MessagingExperimentalMetrics { * multiple instrumentation libraries and applications should be prepared for `error.type` to have high * cardinality at query time when no additional filters are applied.
If the operation has completed * successfully, instrumentations SHOULD NOT set `error.type`.
If a specific domain defines its own set of - * error identifiers (such as HTTP or gRPC status codes), it's RECOMMENDED to:
+ * error identifiers (such as HTTP or gRPC status codes), it's RECOMMENDED to:
- Use a - * domain-specific attribute
- Set `error.type` to capture all errors, regardless of whether they are defined - * within the domain-specific set or not.
*/ val errorType: AttributeSpec[String] = AttributeSpec( @@ -96,7 +96,7 @@ object MessagingExperimentalMetrics { "indexer", ), Requirement.conditionallyRequired("if applicable."), - Stability.experimental + Stability.development ) /** The message destination name
- Use a domain-specific + * attribute
- Set `error.type` to capture all errors, regardless of whether they are defined within the + * domain-specific set or not.
@@ -114,7 +114,7 @@ object MessagingExperimentalMetrics { Requirement.conditionallyRequired( "if and only if `messaging.destination.name` is known to have low cardinality. Otherwise, `messaging.destination.template` MAY be populated." ), - Stability.experimental + Stability.development ) /** The identifier of the partition messages are sent to or received from, unique within the @@ -127,7 +127,7 @@ object MessagingExperimentalMetrics { "1", ), Requirement.recommended, - Stability.experimental + Stability.development ) /** The name of the destination subscription from which a message is consumed.
@@ -142,7 +142,7 @@ object MessagingExperimentalMetrics { "subscription-a", ), Requirement.conditionallyRequired("if applicable."), - Stability.experimental + Stability.development ) /** Low cardinality representation of the messaging destination name
@@ -158,7 +158,7 @@ object MessagingExperimentalMetrics { "/customers/{customerId}", ), Requirement.conditionallyRequired("if available."), - Stability.experimental + Stability.development ) /** The system-specific name of the messaging operation. @@ -173,7 +173,7 @@ object MessagingExperimentalMetrics { "consume", ), Requirement.required, - Stability.experimental + Stability.development ) /** The messaging system as identified by the client instrumentation.
@@ -188,7 +188,7 @@ object MessagingExperimentalMetrics { List( ), Requirement.required, - Stability.experimental + Stability.development ) /** Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. @@ -276,7 +276,7 @@ object MessagingExperimentalMetrics { val name: String = "messaging.client.operation.duration" val description: String = "Duration of messaging operation initiated by a producer or consumer client." val unit: String = "s" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { @@ -290,9 +290,9 @@ object MessagingExperimentalMetrics { * multiple instrumentation libraries and applications should be prepared for `error.type` to have high * cardinality at query time when no additional filters are applied.
If the operation has completed * successfully, instrumentations SHOULD NOT set `error.type`.
If a specific domain defines its own set of - * error identifiers (such as HTTP or gRPC status codes), it's RECOMMENDED to:
+ * error identifiers (such as HTTP or gRPC status codes), it's RECOMMENDED to:
- Use a - * domain-specific attribute
- Set `error.type` to capture all errors, regardless of whether they are defined - * within the domain-specific set or not.
*/ val errorType: AttributeSpec[String] = AttributeSpec( @@ -319,7 +319,7 @@ object MessagingExperimentalMetrics { "indexer", ), Requirement.conditionallyRequired("if applicable."), - Stability.experimental + Stability.development ) /** The message destination name
- Use a domain-specific + * attribute
- Set `error.type` to capture all errors, regardless of whether they are defined within the + * domain-specific set or not.
@@ -337,7 +337,7 @@ object MessagingExperimentalMetrics { Requirement.conditionallyRequired( "if and only if `messaging.destination.name` is known to have low cardinality. Otherwise, `messaging.destination.template` MAY be populated." ), - Stability.experimental + Stability.development ) /** The identifier of the partition messages are sent to or received from, unique within the @@ -350,7 +350,7 @@ object MessagingExperimentalMetrics { "1", ), Requirement.recommended, - Stability.experimental + Stability.development ) /** The name of the destination subscription from which a message is consumed.
@@ -365,7 +365,7 @@ object MessagingExperimentalMetrics { "subscription-a", ), Requirement.conditionallyRequired("if applicable."), - Stability.experimental + Stability.development ) /** Low cardinality representation of the messaging destination name
@@ -381,7 +381,7 @@ object MessagingExperimentalMetrics { "/customers/{customerId}", ), Requirement.conditionallyRequired("if available."), - Stability.experimental + Stability.development ) /** The system-specific name of the messaging operation. @@ -395,7 +395,7 @@ object MessagingExperimentalMetrics { "ack", ), Requirement.required, - Stability.experimental + Stability.development ) /** A string identifying the type of the messaging operation.
@@ -408,7 +408,7 @@ object MessagingExperimentalMetrics { List( ), Requirement.conditionallyRequired("If applicable."), - Stability.experimental + Stability.development ) /** The messaging system as identified by the client instrumentation.
@@ -423,7 +423,7 @@ object MessagingExperimentalMetrics { List( ), Requirement.required, - Stability.experimental + Stability.development ) /** Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. @@ -495,7 +495,7 @@ object MessagingExperimentalMetrics { val name: String = "messaging.client.published.messages" val description: String = "Deprecated. Use `messaging.client.sent.messages` instead." val unit: String = "{message}" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { @@ -509,9 +509,9 @@ object MessagingExperimentalMetrics { * multiple instrumentation libraries and applications should be prepared for `error.type` to have high * cardinality at query time when no additional filters are applied.
If the operation has completed * successfully, instrumentations SHOULD NOT set `error.type`.
If a specific domain defines its own set of - * error identifiers (such as HTTP or gRPC status codes), it's RECOMMENDED to:
+ * error identifiers (such as HTTP or gRPC status codes), it's RECOMMENDED to:
- Use a - * domain-specific attribute
- Set `error.type` to capture all errors, regardless of whether they are defined - * within the domain-specific set or not.
*/ val errorType: AttributeSpec[String] = AttributeSpec( @@ -540,7 +540,7 @@ object MessagingExperimentalMetrics { Requirement.conditionallyRequired( "if and only if `messaging.destination.name` is known to have low cardinality. Otherwise, `messaging.destination.template` MAY be populated." ), - Stability.experimental + Stability.development ) /** The identifier of the partition messages are sent to or received from, unique within the @@ -553,7 +553,7 @@ object MessagingExperimentalMetrics { "1", ), Requirement.recommended, - Stability.experimental + Stability.development ) /** Low cardinality representation of the messaging destination name
- Use a domain-specific + * attribute
- Set `error.type` to capture all errors, regardless of whether they are defined within the + * domain-specific set or not.
@@ -569,7 +569,7 @@ object MessagingExperimentalMetrics { "/customers/{customerId}", ), Requirement.conditionallyRequired("if available."), - Stability.experimental + Stability.development ) /** The system-specific name of the messaging operation. @@ -583,7 +583,7 @@ object MessagingExperimentalMetrics { "send", ), Requirement.required, - Stability.experimental + Stability.development ) /** The messaging system as identified by the client instrumentation.
@@ -598,7 +598,7 @@ object MessagingExperimentalMetrics { List( ), Requirement.required, - Stability.experimental + Stability.development ) /** Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. @@ -683,7 +683,7 @@ object MessagingExperimentalMetrics { val name: String = "messaging.client.sent.messages" val description: String = "Number of messages producer attempted to send to the broker." val unit: String = "{message}" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { @@ -697,9 +697,9 @@ object MessagingExperimentalMetrics { * multiple instrumentation libraries and applications should be prepared for `error.type` to have high * cardinality at query time when no additional filters are applied.
If the operation has completed * successfully, instrumentations SHOULD NOT set `error.type`.
If a specific domain defines its own set of - * error identifiers (such as HTTP or gRPC status codes), it's RECOMMENDED to:
+ * error identifiers (such as HTTP or gRPC status codes), it's RECOMMENDED to:
- Use a - * domain-specific attribute
- Set `error.type` to capture all errors, regardless of whether they are defined - * within the domain-specific set or not.
*/ val errorType: AttributeSpec[String] = AttributeSpec( @@ -728,7 +728,7 @@ object MessagingExperimentalMetrics { Requirement.conditionallyRequired( "if and only if `messaging.destination.name` is known to have low cardinality. Otherwise, `messaging.destination.template` MAY be populated." ), - Stability.experimental + Stability.development ) /** The identifier of the partition messages are sent to or received from, unique within the @@ -741,7 +741,7 @@ object MessagingExperimentalMetrics { "1", ), Requirement.recommended, - Stability.experimental + Stability.development ) /** Low cardinality representation of the messaging destination name
- Use a domain-specific + * attribute
- Set `error.type` to capture all errors, regardless of whether they are defined within the + * domain-specific set or not.
@@ -757,7 +757,7 @@ object MessagingExperimentalMetrics { "/customers/{customerId}", ), Requirement.conditionallyRequired("if available."), - Stability.experimental + Stability.development ) /** The system-specific name of the messaging operation. @@ -771,7 +771,7 @@ object MessagingExperimentalMetrics { "enqueue", ), Requirement.required, - Stability.experimental + Stability.development ) /** The messaging system as identified by the client instrumentation.
@@ -786,7 +786,7 @@ object MessagingExperimentalMetrics { List( ), Requirement.required, - Stability.experimental + Stability.development ) /** Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. @@ -871,7 +871,7 @@ object MessagingExperimentalMetrics { val name: String = "messaging.process.duration" val description: String = "Duration of processing operation." val unit: String = "s" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { @@ -885,9 +885,9 @@ object MessagingExperimentalMetrics { * multiple instrumentation libraries and applications should be prepared for `error.type` to have high * cardinality at query time when no additional filters are applied.
If the operation has completed * successfully, instrumentations SHOULD NOT set `error.type`.
If a specific domain defines its own set of - * error identifiers (such as HTTP or gRPC status codes), it's RECOMMENDED to:
+ * error identifiers (such as HTTP or gRPC status codes), it's RECOMMENDED to:
- Use a - * domain-specific attribute
- Set `error.type` to capture all errors, regardless of whether they are defined - * within the domain-specific set or not.
*/ val errorType: AttributeSpec[String] = AttributeSpec( @@ -914,7 +914,7 @@ object MessagingExperimentalMetrics { "indexer", ), Requirement.conditionallyRequired("if applicable."), - Stability.experimental + Stability.development ) /** The message destination name
- Use a domain-specific + * attribute
- Set `error.type` to capture all errors, regardless of whether they are defined within the + * domain-specific set or not.
@@ -932,7 +932,7 @@ object MessagingExperimentalMetrics { Requirement.conditionallyRequired( "if and only if `messaging.destination.name` is known to have low cardinality. Otherwise, `messaging.destination.template` MAY be populated." ), - Stability.experimental + Stability.development ) /** The identifier of the partition messages are sent to or received from, unique within the @@ -945,7 +945,7 @@ object MessagingExperimentalMetrics { "1", ), Requirement.recommended, - Stability.experimental + Stability.development ) /** The name of the destination subscription from which a message is consumed.
@@ -960,7 +960,7 @@ object MessagingExperimentalMetrics { "subscription-a", ), Requirement.conditionallyRequired("if applicable."), - Stability.experimental + Stability.development ) /** Low cardinality representation of the messaging destination name
@@ -976,7 +976,7 @@ object MessagingExperimentalMetrics { "/customers/{customerId}", ), Requirement.conditionallyRequired("if available."), - Stability.experimental + Stability.development ) /** The system-specific name of the messaging operation. @@ -990,7 +990,7 @@ object MessagingExperimentalMetrics { "handle", ), Requirement.required, - Stability.experimental + Stability.development ) /** The messaging system as identified by the client instrumentation.
@@ -1005,7 +1005,7 @@ object MessagingExperimentalMetrics { List( ), Requirement.required, - Stability.experimental + Stability.development ) /** Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. @@ -1076,7 +1076,7 @@ object MessagingExperimentalMetrics { val name: String = "messaging.process.messages" val description: String = "Deprecated. Use `messaging.client.consumed.messages` instead." val unit: String = "{message}" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { @@ -1090,9 +1090,9 @@ object MessagingExperimentalMetrics { * multiple instrumentation libraries and applications should be prepared for `error.type` to have high * cardinality at query time when no additional filters are applied.
If the operation has completed * successfully, instrumentations SHOULD NOT set `error.type`.
If a specific domain defines its own set of - * error identifiers (such as HTTP or gRPC status codes), it's RECOMMENDED to:
+ * error identifiers (such as HTTP or gRPC status codes), it's RECOMMENDED to:
- Use a - * domain-specific attribute
- Set `error.type` to capture all errors, regardless of whether they are defined - * within the domain-specific set or not.
*/ val errorType: AttributeSpec[String] = AttributeSpec( @@ -1117,7 +1117,7 @@ object MessagingExperimentalMetrics { "send", ), Requirement.required, - Stability.experimental + Stability.development ) /** Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. @@ -1197,7 +1197,7 @@ object MessagingExperimentalMetrics { val name: String = "messaging.publish.duration" val description: String = "Deprecated. Use `messaging.client.operation.duration` instead." val unit: String = "s" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { @@ -1211,9 +1211,9 @@ object MessagingExperimentalMetrics { * multiple instrumentation libraries and applications should be prepared for `error.type` to have high * cardinality at query time when no additional filters are applied.
- Use a domain-specific + * attribute
- Set `error.type` to capture all errors, regardless of whether they are defined within the + * domain-specific set or not.
If the operation has completed * successfully, instrumentations SHOULD NOT set `error.type`.
If a specific domain defines its own set of - * error identifiers (such as HTTP or gRPC status codes), it's RECOMMENDED to:
+ * error identifiers (such as HTTP or gRPC status codes), it's RECOMMENDED to:
- Use a - * domain-specific attribute
- Set `error.type` to capture all errors, regardless of whether they are defined - * within the domain-specific set or not.
*/ val errorType: AttributeSpec[String] = AttributeSpec( @@ -1238,7 +1238,7 @@ object MessagingExperimentalMetrics { "send", ), Requirement.required, - Stability.experimental + Stability.development ) /** Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. @@ -1303,7 +1303,7 @@ object MessagingExperimentalMetrics { val name: String = "messaging.publish.messages" val description: String = "Deprecated. Use `messaging.client.produced.messages` instead." val unit: String = "{message}" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { @@ -1317,9 +1317,9 @@ object MessagingExperimentalMetrics { * multiple instrumentation libraries and applications should be prepared for `error.type` to have high * cardinality at query time when no additional filters are applied.
- Use a domain-specific + * attribute
- Set `error.type` to capture all errors, regardless of whether they are defined within the + * domain-specific set or not.
If the operation has completed * successfully, instrumentations SHOULD NOT set `error.type`.
If a specific domain defines its own set of - * error identifiers (such as HTTP or gRPC status codes), it's RECOMMENDED to:
+ * error identifiers (such as HTTP or gRPC status codes), it's RECOMMENDED to:
- Use a - * domain-specific attribute
- Set `error.type` to capture all errors, regardless of whether they are defined - * within the domain-specific set or not.
*/ val errorType: AttributeSpec[String] = AttributeSpec( @@ -1344,7 +1344,7 @@ object MessagingExperimentalMetrics { "send", ), Requirement.required, - Stability.experimental + Stability.development ) /** Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. @@ -1424,7 +1424,7 @@ object MessagingExperimentalMetrics { val name: String = "messaging.receive.duration" val description: String = "Deprecated. Use `messaging.client.operation.duration` instead." val unit: String = "s" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { @@ -1438,9 +1438,9 @@ object MessagingExperimentalMetrics { * multiple instrumentation libraries and applications should be prepared for `error.type` to have high * cardinality at query time when no additional filters are applied.
- Use a domain-specific + * attribute
- Set `error.type` to capture all errors, regardless of whether they are defined within the + * domain-specific set or not.
If the operation has completed * successfully, instrumentations SHOULD NOT set `error.type`.
If a specific domain defines its own set of - * error identifiers (such as HTTP or gRPC status codes), it's RECOMMENDED to:
+ * error identifiers (such as HTTP or gRPC status codes), it's RECOMMENDED to:
- Use a - * domain-specific attribute
- Set `error.type` to capture all errors, regardless of whether they are defined - * within the domain-specific set or not.
*/ val errorType: AttributeSpec[String] = AttributeSpec( @@ -1465,7 +1465,7 @@ object MessagingExperimentalMetrics { "send", ), Requirement.required, - Stability.experimental + Stability.development ) /** Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. @@ -1530,7 +1530,7 @@ object MessagingExperimentalMetrics { val name: String = "messaging.receive.messages" val description: String = "Deprecated. Use `messaging.client.consumed.messages` instead." val unit: String = "{message}" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { @@ -1544,9 +1544,9 @@ object MessagingExperimentalMetrics { * multiple instrumentation libraries and applications should be prepared for `error.type` to have high * cardinality at query time when no additional filters are applied.
- Use a domain-specific + * attribute
- Set `error.type` to capture all errors, regardless of whether they are defined within the + * domain-specific set or not.
If the operation has completed * successfully, instrumentations SHOULD NOT set `error.type`.
If a specific domain defines its own set of - * error identifiers (such as HTTP or gRPC status codes), it's RECOMMENDED to:
+ * error identifiers (such as HTTP or gRPC status codes), it's RECOMMENDED to:
- Use a - * domain-specific attribute
- Set `error.type` to capture all errors, regardless of whether they are defined - * within the domain-specific set or not.
*/ val errorType: AttributeSpec[String] = AttributeSpec( @@ -1571,7 +1571,7 @@ object MessagingExperimentalMetrics { "send", ), Requirement.required, - Stability.experimental + Stability.development ) /** Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. diff --git a/semconv/metrics/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/metrics/NodejsExperimentalMetrics.scala b/semconv/metrics/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/metrics/NodejsExperimentalMetrics.scala index 88faa10e9..115ebbb8a 100644 --- a/semconv/metrics/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/metrics/NodejsExperimentalMetrics.scala +++ b/semconv/metrics/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/metrics/NodejsExperimentalMetrics.scala @@ -48,7 +48,7 @@ object NodejsExperimentalMetrics { val name: String = "nodejs.eventloop.delay.max" val description: String = "Event loop maximum delay." val unit: String = "s" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = Nil def create[F[_]: Meter, A: MeasurementValue]: F[Gauge[F, A]] = @@ -86,7 +86,7 @@ object NodejsExperimentalMetrics { val name: String = "nodejs.eventloop.delay.mean" val description: String = "Event loop mean delay." val unit: String = "s" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = Nil def create[F[_]: Meter, A: MeasurementValue]: F[Gauge[F, A]] = @@ -124,7 +124,7 @@ object NodejsExperimentalMetrics { val name: String = "nodejs.eventloop.delay.min" val description: String = "Event loop minimum delay." val unit: String = "s" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = Nil def create[F[_]: Meter, A: MeasurementValue]: F[Gauge[F, A]] = @@ -162,7 +162,7 @@ object NodejsExperimentalMetrics { val name: String = "nodejs.eventloop.delay.p50" val description: String = "Event loop 50 percentile delay." val unit: String = "s" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = Nil def create[F[_]: Meter, A: MeasurementValue]: F[Gauge[F, A]] = @@ -200,7 +200,7 @@ object NodejsExperimentalMetrics { val name: String = "nodejs.eventloop.delay.p90" val description: String = "Event loop 90 percentile delay." val unit: String = "s" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = Nil def create[F[_]: Meter, A: MeasurementValue]: F[Gauge[F, A]] = @@ -238,7 +238,7 @@ object NodejsExperimentalMetrics { val name: String = "nodejs.eventloop.delay.p99" val description: String = "Event loop 99 percentile delay." val unit: String = "s" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = Nil def create[F[_]: Meter, A: MeasurementValue]: F[Gauge[F, A]] = @@ -276,7 +276,7 @@ object NodejsExperimentalMetrics { val name: String = "nodejs.eventloop.delay.stddev" val description: String = "Event loop standard deviation delay." val unit: String = "s" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = Nil def create[F[_]: Meter, A: MeasurementValue]: F[Gauge[F, A]] = @@ -315,7 +315,7 @@ object NodejsExperimentalMetrics { val name: String = "nodejs.eventloop.time" val description: String = "Cumulative duration of time the event loop has been in each state." val unit: String = "s" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { @@ -328,7 +328,7 @@ object NodejsExperimentalMetrics { List( ), Requirement.required, - Stability.experimental + Stability.development ) val specs: List[AttributeSpec[_]] = @@ -373,7 +373,7 @@ object NodejsExperimentalMetrics { val name: String = "nodejs.eventloop.utilization" val description: String = "Event loop utilization." val unit: String = "1" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = Nil def create[F[_]: Meter, A: MeasurementValue]: F[Gauge[F, A]] = diff --git a/semconv/metrics/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/metrics/ProcessExperimentalMetrics.scala b/semconv/metrics/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/metrics/ProcessExperimentalMetrics.scala index 495e000ba..1194a0890 100644 --- a/semconv/metrics/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/metrics/ProcessExperimentalMetrics.scala +++ b/semconv/metrics/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/metrics/ProcessExperimentalMetrics.scala @@ -47,7 +47,7 @@ object ProcessExperimentalMetrics { val name: String = "process.context_switches" val description: String = "Number of times the process has been context switched." val unit: String = "{count}" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { @@ -60,7 +60,7 @@ object ProcessExperimentalMetrics { List( ), Requirement.recommended, - Stability.experimental + Stability.development ) val specs: List[AttributeSpec[_]] = @@ -101,7 +101,7 @@ object ProcessExperimentalMetrics { val name: String = "process.cpu.time" val description: String = "Total CPU seconds broken down by different states." val unit: String = "s" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { @@ -119,7 +119,7 @@ object ProcessExperimentalMetrics { "system", ), Requirement.recommended, - Stability.experimental + Stability.development ) val specs: List[AttributeSpec[_]] = @@ -162,7 +162,7 @@ object ProcessExperimentalMetrics { val description: String = "Difference in process.cpu.time since the last measurement, divided by the elapsed time and number of CPUs available to the process." val unit: String = "1" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { @@ -180,7 +180,7 @@ object ProcessExperimentalMetrics { "system", ), Requirement.recommended, - Stability.experimental + Stability.development ) val specs: List[AttributeSpec[_]] = @@ -221,7 +221,7 @@ object ProcessExperimentalMetrics { val name: String = "process.disk.io" val description: String = "Disk bytes transferred." val unit: String = "By" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { @@ -235,7 +235,7 @@ object ProcessExperimentalMetrics { "read", ), Requirement.recommended, - Stability.experimental + Stability.development ) val specs: List[AttributeSpec[_]] = @@ -276,7 +276,7 @@ object ProcessExperimentalMetrics { val name: String = "process.memory.usage" val description: String = "The amount of physical memory in use." val unit: String = "By" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = Nil def create[F[_]: Meter, A: MeasurementValue]: F[UpDownCounter[F, A]] = @@ -311,7 +311,7 @@ object ProcessExperimentalMetrics { val name: String = "process.memory.virtual" val description: String = "The amount of committed virtual memory." val unit: String = "By" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = Nil def create[F[_]: Meter, A: MeasurementValue]: F[UpDownCounter[F, A]] = @@ -346,7 +346,7 @@ object ProcessExperimentalMetrics { val name: String = "process.network.io" val description: String = "Network bytes transferred." val unit: String = "By" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { @@ -360,7 +360,7 @@ object ProcessExperimentalMetrics { "transmit", ), Requirement.recommended, - Stability.experimental + Stability.development ) val specs: List[AttributeSpec[_]] = @@ -401,7 +401,7 @@ object ProcessExperimentalMetrics { val name: String = "process.open_file_descriptor.count" val description: String = "Number of file descriptors in use by the process." val unit: String = "{count}" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = Nil def create[F[_]: Meter, A: MeasurementValue]: F[UpDownCounter[F, A]] = @@ -436,7 +436,7 @@ object ProcessExperimentalMetrics { val name: String = "process.paging.faults" val description: String = "Number of page faults the process has made." val unit: String = "{fault}" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { @@ -450,7 +450,7 @@ object ProcessExperimentalMetrics { List( ), Requirement.recommended, - Stability.experimental + Stability.development ) val specs: List[AttributeSpec[_]] = @@ -491,7 +491,7 @@ object ProcessExperimentalMetrics { val name: String = "process.thread.count" val description: String = "Process threads count." val unit: String = "{thread}" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = Nil def create[F[_]: Meter, A: MeasurementValue]: F[UpDownCounter[F, A]] = @@ -521,36 +521,37 @@ object ProcessExperimentalMetrics { /** The time the process has been running.
- Use a domain-specific + * attribute
- Set `error.type` to capture all errors, regardless of whether they are defined within the + * domain-specific set or not.
* @note - *
Instrumentations SHOULD use counter with type `double` and measure uptime with at least millisecond - * precision + *
Instrumentations SHOULD use a gauge with type `double` and measure uptime in seconds as a floating point + * number with the highest precision available. The actual accuracy would depend on the instrumentation and + * operating system. */ object Uptime extends MetricSpec { val name: String = "process.uptime" val description: String = "The time the process has been running." val unit: String = "s" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = Nil - def create[F[_]: Meter, A: MeasurementValue]: F[Counter[F, A]] = + def create[F[_]: Meter, A: MeasurementValue]: F[Gauge[F, A]] = Meter[F] - .counter[A](name) + .gauge[A](name) .withDescription(description) .withUnit(unit) .create def createObserver[F[_]: Meter, A: MeasurementValue]: F[ObservableMeasurement[F, A]] = Meter[F] - .observableCounter[A](name) + .observableGauge[A](name) .withDescription(description) .withUnit(unit) .createObserver def createWithCallback[F[_]: Meter, A: MeasurementValue]( callback: ObservableMeasurement[F, A] => F[Unit] - ): Resource[F, ObservableCounter] = + ): Resource[F, ObservableGauge] = Meter[F] - .observableCounter[A](name) + .observableGauge[A](name) .withDescription(description) .withUnit(unit) .createWithCallback(callback) diff --git a/semconv/metrics/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/metrics/RpcExperimentalMetrics.scala b/semconv/metrics/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/metrics/RpcExperimentalMetrics.scala index 5023deee3..578037c28 100644 --- a/semconv/metrics/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/metrics/RpcExperimentalMetrics.scala +++ b/semconv/metrics/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/metrics/RpcExperimentalMetrics.scala @@ -47,7 +47,7 @@ object RpcExperimentalMetrics { val name: String = "rpc.client.duration" val description: String = "Measures the duration of outbound RPC." val unit: String = "ms" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = Nil def create[F[_]: Meter, A: MeasurementValue](boundaries: BucketBoundaries): F[Histogram[F, A]] = @@ -69,7 +69,7 @@ object RpcExperimentalMetrics { val name: String = "rpc.client.request.size" val description: String = "Measures the size of RPC request messages (uncompressed)." val unit: String = "By" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = Nil def create[F[_]: Meter, A: MeasurementValue](boundaries: BucketBoundaries): F[Histogram[F, A]] = @@ -92,7 +92,7 @@ object RpcExperimentalMetrics { val name: String = "rpc.client.requests_per_rpc" val description: String = "Measures the number of messages received per RPC." val unit: String = "{count}" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = Nil def create[F[_]: Meter, A: MeasurementValue](boundaries: BucketBoundaries): F[Histogram[F, A]] = @@ -114,7 +114,7 @@ object RpcExperimentalMetrics { val name: String = "rpc.client.response.size" val description: String = "Measures the size of RPC response messages (uncompressed)." val unit: String = "By" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = Nil def create[F[_]: Meter, A: MeasurementValue](boundaries: BucketBoundaries): F[Histogram[F, A]] = @@ -137,7 +137,7 @@ object RpcExperimentalMetrics { val name: String = "rpc.client.responses_per_rpc" val description: String = "Measures the number of messages sent per RPC." val unit: String = "{count}" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = Nil def create[F[_]: Meter, A: MeasurementValue](boundaries: BucketBoundaries): F[Histogram[F, A]] = @@ -160,7 +160,7 @@ object RpcExperimentalMetrics { val name: String = "rpc.server.duration" val description: String = "Measures the duration of inbound RPC." val unit: String = "ms" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = Nil def create[F[_]: Meter, A: MeasurementValue](boundaries: BucketBoundaries): F[Histogram[F, A]] = @@ -182,7 +182,7 @@ object RpcExperimentalMetrics { val name: String = "rpc.server.request.size" val description: String = "Measures the size of RPC request messages (uncompressed)." val unit: String = "By" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = Nil def create[F[_]: Meter, A: MeasurementValue](boundaries: BucketBoundaries): F[Histogram[F, A]] = @@ -205,7 +205,7 @@ object RpcExperimentalMetrics { val name: String = "rpc.server.requests_per_rpc" val description: String = "Measures the number of messages received per RPC." val unit: String = "{count}" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = Nil def create[F[_]: Meter, A: MeasurementValue](boundaries: BucketBoundaries): F[Histogram[F, A]] = @@ -227,7 +227,7 @@ object RpcExperimentalMetrics { val name: String = "rpc.server.response.size" val description: String = "Measures the size of RPC response messages (uncompressed)." val unit: String = "By" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = Nil def create[F[_]: Meter, A: MeasurementValue](boundaries: BucketBoundaries): F[Histogram[F, A]] = @@ -250,7 +250,7 @@ object RpcExperimentalMetrics { val name: String = "rpc.server.responses_per_rpc" val description: String = "Measures the number of messages sent per RPC." val unit: String = "{count}" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = Nil def create[F[_]: Meter, A: MeasurementValue](boundaries: BucketBoundaries): F[Histogram[F, A]] = diff --git a/semconv/metrics/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/metrics/SystemExperimentalMetrics.scala b/semconv/metrics/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/metrics/SystemExperimentalMetrics.scala index ac001b9fb..01be3bc86 100644 --- a/semconv/metrics/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/metrics/SystemExperimentalMetrics.scala +++ b/semconv/metrics/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/metrics/SystemExperimentalMetrics.scala @@ -59,6 +59,7 @@ object SystemExperimentalMetrics { PagingUtilization, ProcessCount, ProcessCreated, + Uptime, ) /** Reports the current frequency of the CPU in Hz @@ -68,7 +69,7 @@ object SystemExperimentalMetrics { val name: String = "system.cpu.frequency" val description: String = "Reports the current frequency of the CPU in Hz" val unit: String = "{Hz}" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { @@ -82,7 +83,7 @@ object SystemExperimentalMetrics { 1, ), Requirement.recommended, - Stability.experimental + Stability.development ) val specs: List[AttributeSpec[_]] = @@ -124,7 +125,7 @@ object SystemExperimentalMetrics { val description: String = "Reports the number of logical (virtual) processor cores created by the operating system to manage multitasking" val unit: String = "{cpu}" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = Nil def create[F[_]: Meter, A: MeasurementValue]: F[UpDownCounter[F, A]] = @@ -159,7 +160,7 @@ object SystemExperimentalMetrics { val name: String = "system.cpu.physical.count" val description: String = "Reports the number of actual physical processor cores on the hardware" val unit: String = "{cpu}" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = Nil def create[F[_]: Meter, A: MeasurementValue]: F[UpDownCounter[F, A]] = @@ -194,7 +195,7 @@ object SystemExperimentalMetrics { val name: String = "system.cpu.time" val description: String = "Seconds each logical CPU spent on each mode" val unit: String = "s" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { @@ -212,7 +213,7 @@ object SystemExperimentalMetrics { "system", ), Requirement.recommended, - Stability.experimental + Stability.development ) /** The logical CPU number [0..n-1] @@ -224,7 +225,7 @@ object SystemExperimentalMetrics { 1, ), Requirement.recommended, - Stability.experimental + Stability.development ) val specs: List[AttributeSpec[_]] = @@ -267,7 +268,7 @@ object SystemExperimentalMetrics { val description: String = "Difference in system.cpu.time since the last measurement, divided by the elapsed time and number of logical CPUs" val unit: String = "1" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { @@ -285,7 +286,7 @@ object SystemExperimentalMetrics { "system", ), Requirement.recommended, - Stability.experimental + Stability.development ) /** The logical CPU number [0..n-1] @@ -297,7 +298,7 @@ object SystemExperimentalMetrics { 1, ), Requirement.recommended, - Stability.experimental + Stability.development ) val specs: List[AttributeSpec[_]] = @@ -338,7 +339,7 @@ object SystemExperimentalMetrics { val name: String = "system.disk.io" val description: String = "" val unit: String = "By" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { @@ -352,7 +353,7 @@ object SystemExperimentalMetrics { "read", ), Requirement.recommended, - Stability.experimental + Stability.development ) /** The device identifier @@ -364,7 +365,7 @@ object SystemExperimentalMetrics { "(identifier)", ), Requirement.recommended, - Stability.experimental + Stability.development ) val specs: List[AttributeSpec[_]] = @@ -402,7 +403,7 @@ object SystemExperimentalMetrics { /** Time disk spent activated
* @note *
The real elapsed time ("wall clock") used in the I/O path (time from operations running in parallel are not - * counted). Measured as:
- Linux: Field 13 from
- Linux: Field 13 from procfs-diskstats
- Windows: * The complement of "Disk% @@ -413,7 +414,7 @@ object SystemExperimentalMetrics { val name: String = "system.disk.io_time" val description: String = "Time disk spent activated" val unit: String = "s" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { @@ -427,7 +428,7 @@ object SystemExperimentalMetrics { "(identifier)", ), Requirement.recommended, - Stability.experimental + Stability.development ) val specs: List[AttributeSpec[_]] = @@ -468,7 +469,7 @@ object SystemExperimentalMetrics { val name: String = "system.disk.limit" val description: String = "The total storage capacity of the disk" val unit: String = "By" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { @@ -482,7 +483,7 @@ object SystemExperimentalMetrics { "(identifier)", ), Requirement.recommended, - Stability.experimental + Stability.development ) val specs: List[AttributeSpec[_]] = @@ -522,7 +523,7 @@ object SystemExperimentalMetrics { val name: String = "system.disk.merged" val description: String = "" val unit: String = "{operation}" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { @@ -536,7 +537,7 @@ object SystemExperimentalMetrics { "read", ), Requirement.recommended, - Stability.experimental + Stability.development ) /** The device identifier @@ -548,7 +549,7 @@ object SystemExperimentalMetrics { "(identifier)", ), Requirement.recommended, - Stability.experimental + Stability.development ) val specs: List[AttributeSpec[_]] = @@ -586,7 +587,7 @@ object SystemExperimentalMetrics { /** Sum of the time each operation took to complete
* @note *
Because it is the sum of time each request took, parallel-issued requests each contribute to make the count - * grow. Measured as:
*/ @@ -595,7 +596,7 @@ object SystemExperimentalMetrics { val name: String = "system.disk.operation_time" val description: String = "Sum of the time each operation took to complete" val unit: String = "s" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { @@ -609,7 +610,7 @@ object SystemExperimentalMetrics { "read", ), Requirement.recommended, - Stability.experimental + Stability.development ) /** The device identifier @@ -621,7 +622,7 @@ object SystemExperimentalMetrics { "(identifier)", ), Requirement.recommended, - Stability.experimental + Stability.development ) val specs: List[AttributeSpec[_]] = @@ -662,7 +663,7 @@ object SystemExperimentalMetrics { val name: String = "system.disk.operations" val description: String = "" val unit: String = "{operation}" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { @@ -676,7 +677,7 @@ object SystemExperimentalMetrics { "read", ), Requirement.recommended, - Stability.experimental + Stability.development ) /** The device identifier @@ -688,7 +689,7 @@ object SystemExperimentalMetrics { "(identifier)", ), Requirement.recommended, - Stability.experimental + Stability.development ) val specs: List[AttributeSpec[_]] = @@ -730,7 +731,7 @@ object SystemExperimentalMetrics { val name: String = "system.filesystem.limit" val description: String = "The total storage capacity of the filesystem" val unit: String = "By" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { @@ -745,7 +746,7 @@ object SystemExperimentalMetrics { "\network-drive", ), Requirement.recommended, - Stability.experimental + Stability.development ) /** The filesystem mode @@ -757,7 +758,7 @@ object SystemExperimentalMetrics { "rw, ro", ), Requirement.recommended, - Stability.experimental + Stability.development ) /** The filesystem mount path @@ -769,7 +770,7 @@ object SystemExperimentalMetrics { "/mnt/data", ), Requirement.recommended, - Stability.experimental + Stability.development ) /** The filesystem type @@ -781,7 +782,7 @@ object SystemExperimentalMetrics { "ext4", ), Requirement.recommended, - Stability.experimental + Stability.development ) val specs: List[AttributeSpec[_]] = @@ -828,7 +829,7 @@ object SystemExperimentalMetrics { val name: String = "system.filesystem.usage" val description: String = "Reports a filesystem's space usage across different states." val unit: String = "By" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { @@ -843,7 +844,7 @@ object SystemExperimentalMetrics { "\network-drive", ), Requirement.recommended, - Stability.experimental + Stability.development ) /** The filesystem mode @@ -855,7 +856,7 @@ object SystemExperimentalMetrics { "rw, ro", ), Requirement.recommended, - Stability.experimental + Stability.development ) /** The filesystem mount path @@ -867,7 +868,7 @@ object SystemExperimentalMetrics { "/mnt/data", ), Requirement.recommended, - Stability.experimental + Stability.development ) /** The filesystem state @@ -879,7 +880,7 @@ object SystemExperimentalMetrics { "used", ), Requirement.recommended, - Stability.experimental + Stability.development ) /** The filesystem type @@ -891,7 +892,7 @@ object SystemExperimentalMetrics { "ext4", ), Requirement.recommended, - Stability.experimental + Stability.development ) val specs: List[AttributeSpec[_]] = @@ -935,7 +936,7 @@ object SystemExperimentalMetrics { val name: String = "system.filesystem.utilization" val description: String = "" val unit: String = "1" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { @@ -950,7 +951,7 @@ object SystemExperimentalMetrics { "\network-drive", ), Requirement.recommended, - Stability.experimental + Stability.development ) /** The filesystem mode @@ -962,7 +963,7 @@ object SystemExperimentalMetrics { "rw, ro", ), Requirement.recommended, - Stability.experimental + Stability.development ) /** The filesystem mount path @@ -974,7 +975,7 @@ object SystemExperimentalMetrics { "/mnt/data", ), Requirement.recommended, - Stability.experimental + Stability.development ) /** The filesystem state @@ -986,7 +987,7 @@ object SystemExperimentalMetrics { "used", ), Requirement.recommended, - Stability.experimental + Stability.development ) /** The filesystem type @@ -998,7 +999,7 @@ object SystemExperimentalMetrics { "ext4", ), Requirement.recommended, - Stability.experimental + Stability.development ) val specs: List[AttributeSpec[_]] = @@ -1050,7 +1051,7 @@ object SystemExperimentalMetrics { val description: String = "An estimate of how much memory is available for starting new applications, without causing swapping" val unit: String = "By" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = Nil def create[F[_]: Meter, A: MeasurementValue]: F[UpDownCounter[F, A]] = @@ -1092,7 +1093,7 @@ object SystemExperimentalMetrics { val description: String = "Reports the memory used by the Linux kernel for managing caches of frequently used objects." val unit: String = "By" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { @@ -1107,7 +1108,7 @@ object SystemExperimentalMetrics { "unreclaimable", ), Requirement.recommended, - Stability.experimental + Stability.development ) val specs: List[AttributeSpec[_]] = @@ -1150,7 +1151,7 @@ object SystemExperimentalMetrics { val name: String = "system.memory.limit" val description: String = "Total memory available in the system." val unit: String = "By" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = Nil def create[F[_]: Meter, A: MeasurementValue]: F[UpDownCounter[F, A]] = @@ -1188,7 +1189,7 @@ object SystemExperimentalMetrics { val name: String = "system.memory.shared" val description: String = "Shared memory used (mostly by tmpfs)." val unit: String = "By" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = Nil def create[F[_]: Meter, A: MeasurementValue]: F[UpDownCounter[F, A]] = @@ -1226,7 +1227,7 @@ object SystemExperimentalMetrics { val name: String = "system.memory.usage" val description: String = "Reports memory in use by state." val unit: String = "By" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { @@ -1241,7 +1242,7 @@ object SystemExperimentalMetrics { "cached", ), Requirement.recommended, - Stability.experimental + Stability.development ) val specs: List[AttributeSpec[_]] = @@ -1281,7 +1282,7 @@ object SystemExperimentalMetrics { val name: String = "system.memory.utilization" val description: String = "" val unit: String = "1" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { @@ -1296,7 +1297,7 @@ object SystemExperimentalMetrics { "cached", ), Requirement.recommended, - Stability.experimental + Stability.development ) val specs: List[AttributeSpec[_]] = @@ -1336,12 +1337,25 @@ object SystemExperimentalMetrics { val name: String = "system.network.connections" val description: String = "" val unit: String = "{connection}" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { - /** OSI transport layer or OSI transport layer or inter-process communication method.
* @note *
The value SHOULD be normalized to lowercase.
Consider always setting the transport when setting a @@ -1359,18 +1373,6 @@ object SystemExperimentalMetrics { Stability.stable ) - /** The device identifier - */ - val systemDevice: AttributeSpec[String] = - AttributeSpec( - SystemExperimentalAttributes.SystemDevice, - List( - "(identifier)", - ), - Requirement.recommended, - Stability.experimental - ) - /** A stateless protocol MUST NOT set this attribute */ val systemNetworkState: AttributeSpec[String] = @@ -1380,13 +1382,13 @@ object SystemExperimentalMetrics { "close_wait", ), Requirement.recommended, - Stability.experimental + Stability.development ) val specs: List[AttributeSpec[_]] = List( + networkInterfaceName, networkTransport, - systemDevice, systemNetworkState, ) } @@ -1418,7 +1420,7 @@ object SystemExperimentalMetrics { /** Count of packets that are dropped or discarded even though there was no error
* @note - *
Measured as:
- Linux: the `drop` column in `/proc/dev/net` ( Measured as:
.
- Linux: the `drop` column in `/proc/dev/net` (source) *
- Windows: `InDiscards`/`OutDiscards` @@ -1430,39 +1432,40 @@ object SystemExperimentalMetrics { val name: String = "system.network.dropped" val description: String = "Count of packets that are dropped or discarded even though there was no error" val unit: String = "{packet}" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { - /** The network IO operation direction. + /** The network interface name. */ - val networkIoDirection: AttributeSpec[String] = + val networkInterfaceName: AttributeSpec[String] = AttributeSpec( - NetworkExperimentalAttributes.NetworkIoDirection, + NetworkExperimentalAttributes.NetworkInterfaceName, List( - "transmit", + "lo", + "eth0", ), Requirement.recommended, - Stability.experimental + Stability.development ) - /** The device identifier + /** The network IO operation direction. */ - val systemDevice: AttributeSpec[String] = + val networkIoDirection: AttributeSpec[String] = AttributeSpec( - SystemExperimentalAttributes.SystemDevice, + NetworkExperimentalAttributes.NetworkIoDirection, List( - "(identifier)", + "transmit", ), Requirement.recommended, - Stability.experimental + Stability.development ) val specs: List[AttributeSpec[_]] = List( + networkInterfaceName, networkIoDirection, - systemDevice, ) } @@ -1493,7 +1496,7 @@ object SystemExperimentalMetrics { /** Count of network errors detected
* @note - *
Measured as:
- Linux: the `errs` column in `/proc/dev/net` ( Measured as:
.
- Linux: the `errs` column in `/proc/dev/net` (source). *
- Windows: `InErrors`/`OutErrors` @@ -1505,39 +1508,40 @@ object SystemExperimentalMetrics { val name: String = "system.network.errors" val description: String = "Count of network errors detected" val unit: String = "{error}" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { - /** The network IO operation direction. + /** The network interface name. */ - val networkIoDirection: AttributeSpec[String] = + val networkInterfaceName: AttributeSpec[String] = AttributeSpec( - NetworkExperimentalAttributes.NetworkIoDirection, + NetworkExperimentalAttributes.NetworkInterfaceName, List( - "transmit", + "lo", + "eth0", ), Requirement.recommended, - Stability.experimental + Stability.development ) - /** The device identifier + /** The network IO operation direction. */ - val systemDevice: AttributeSpec[String] = + val networkIoDirection: AttributeSpec[String] = AttributeSpec( - SystemExperimentalAttributes.SystemDevice, + NetworkExperimentalAttributes.NetworkIoDirection, List( - "(identifier)", + "transmit", ), Requirement.recommended, - Stability.experimental + Stability.development ) val specs: List[AttributeSpec[_]] = List( + networkInterfaceName, networkIoDirection, - systemDevice, ) } @@ -1572,39 +1576,40 @@ object SystemExperimentalMetrics { val name: String = "system.network.io" val description: String = "" val unit: String = "By" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { - /** The network IO operation direction. + /** The network interface name. */ - val networkIoDirection: AttributeSpec[String] = + val networkInterfaceName: AttributeSpec[String] = AttributeSpec( - NetworkExperimentalAttributes.NetworkIoDirection, + NetworkExperimentalAttributes.NetworkInterfaceName, List( - "transmit", + "lo", + "eth0", ), Requirement.recommended, - Stability.experimental + Stability.development ) - /** The device identifier + /** The network IO operation direction. */ - val systemDevice: AttributeSpec[String] = + val networkIoDirection: AttributeSpec[String] = AttributeSpec( - SystemExperimentalAttributes.SystemDevice, + NetworkExperimentalAttributes.NetworkIoDirection, List( - "(identifier)", + "transmit", ), Requirement.recommended, - Stability.experimental + Stability.development ) val specs: List[AttributeSpec[_]] = List( + networkInterfaceName, networkIoDirection, - systemDevice, ) } @@ -1639,7 +1644,7 @@ object SystemExperimentalMetrics { val name: String = "system.network.packets" val description: String = "" val unit: String = "{packet}" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { @@ -1653,7 +1658,7 @@ object SystemExperimentalMetrics { "transmit", ), Requirement.recommended, - Stability.experimental + Stability.development ) /** The device identifier @@ -1665,7 +1670,7 @@ object SystemExperimentalMetrics { "(identifier)", ), Requirement.recommended, - Stability.experimental + Stability.development ) val specs: List[AttributeSpec[_]] = @@ -1706,7 +1711,7 @@ object SystemExperimentalMetrics { val name: String = "system.paging.faults" val description: String = "" val unit: String = "{fault}" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { @@ -1720,7 +1725,7 @@ object SystemExperimentalMetrics { "minor", ), Requirement.recommended, - Stability.experimental + Stability.development ) val specs: List[AttributeSpec[_]] = @@ -1760,7 +1765,7 @@ object SystemExperimentalMetrics { val name: String = "system.paging.operations" val description: String = "" val unit: String = "{operation}" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { @@ -1774,7 +1779,7 @@ object SystemExperimentalMetrics { "in", ), Requirement.recommended, - Stability.experimental + Stability.development ) /** The memory paging type @@ -1786,7 +1791,7 @@ object SystemExperimentalMetrics { "minor", ), Requirement.recommended, - Stability.experimental + Stability.development ) val specs: List[AttributeSpec[_]] = @@ -1828,11 +1833,23 @@ object SystemExperimentalMetrics { val name: String = "system.paging.usage" val description: String = "Unix swap or windows pagefile usage" val unit: String = "By" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { + /** Unique identifier for the device responsible for managing paging operations. + */ + val systemDevice: AttributeSpec[String] = + AttributeSpec( + SystemExperimentalAttributes.SystemDevice, + List( + "/dev/dm-0", + ), + Requirement.recommended, + Stability.development + ) + /** The memory paging state */ val systemPagingState: AttributeSpec[String] = @@ -1842,11 +1859,12 @@ object SystemExperimentalMetrics { "free", ), Requirement.recommended, - Stability.experimental + Stability.development ) val specs: List[AttributeSpec[_]] = List( + systemDevice, systemPagingState, ) } @@ -1882,11 +1900,23 @@ object SystemExperimentalMetrics { val name: String = "system.paging.utilization" val description: String = "" val unit: String = "1" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { + /** Unique identifier for the device responsible for managing paging operations. + */ + val systemDevice: AttributeSpec[String] = + AttributeSpec( + SystemExperimentalAttributes.SystemDevice, + List( + "/dev/dm-0", + ), + Requirement.recommended, + Stability.development + ) + /** The memory paging state */ val systemPagingState: AttributeSpec[String] = @@ -1896,11 +1926,12 @@ object SystemExperimentalMetrics { "free", ), Requirement.recommended, - Stability.experimental + Stability.development ) val specs: List[AttributeSpec[_]] = List( + systemDevice, systemPagingState, ) } @@ -1937,7 +1968,7 @@ object SystemExperimentalMetrics { val name: String = "system.process.count" val description: String = "Total number of processes in each state" val unit: String = "{process}" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { @@ -1952,7 +1983,7 @@ object SystemExperimentalMetrics { "running", ), Requirement.recommended, - Stability.experimental + Stability.development ) val specs: List[AttributeSpec[_]] = @@ -1993,7 +2024,7 @@ object SystemExperimentalMetrics { val name: String = "system.process.created" val description: String = "Total number of processes created over uptime of the host" val unit: String = "{process}" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = Nil def create[F[_]: Meter, A: MeasurementValue]: F[Counter[F, A]] = @@ -2021,4 +2052,43 @@ object SystemExperimentalMetrics { } + /** The time the system has been running
+ * @note + *
Instrumentations SHOULD use a gauge with type `double` and measure uptime in seconds as a floating point + * number with the highest precision available. The actual accuracy would depend on the instrumentation and + * operating system. + */ + object Uptime extends MetricSpec { + + val name: String = "system.uptime" + val description: String = "The time the system has been running" + val unit: String = "s" + val stability: Stability = Stability.development + val attributeSpecs: List[AttributeSpec[_]] = Nil + + def create[F[_]: Meter, A: MeasurementValue]: F[Gauge[F, A]] = + Meter[F] + .gauge[A](name) + .withDescription(description) + .withUnit(unit) + .create + + def createObserver[F[_]: Meter, A: MeasurementValue]: F[ObservableMeasurement[F, A]] = + Meter[F] + .observableGauge[A](name) + .withDescription(description) + .withUnit(unit) + .createObserver + + def createWithCallback[F[_]: Meter, A: MeasurementValue]( + callback: ObservableMeasurement[F, A] => F[Unit] + ): Resource[F, ObservableGauge] = + Meter[F] + .observableGauge[A](name) + .withDescription(description) + .withUnit(unit) + .createWithCallback(callback) + + } + } diff --git a/semconv/metrics/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/metrics/V8jsExperimentalMetrics.scala b/semconv/metrics/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/metrics/V8jsExperimentalMetrics.scala index 5c38b7fbb..8de159a3d 100644 --- a/semconv/metrics/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/metrics/V8jsExperimentalMetrics.scala +++ b/semconv/metrics/experimental/src/main/scala/org/typelevel/otel4s/semconv/experimental/metrics/V8jsExperimentalMetrics.scala @@ -45,7 +45,7 @@ object V8jsExperimentalMetrics { val name: String = "v8js.gc.duration" val description: String = "Garbage collection duration." val unit: String = "s" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { @@ -58,7 +58,7 @@ object V8jsExperimentalMetrics { List( ), Requirement.required, - Stability.experimental + Stability.development ) val specs: List[AttributeSpec[_]] = @@ -87,7 +87,7 @@ object V8jsExperimentalMetrics { val name: String = "v8js.heap.space.available_size" val description: String = "Heap space available size." val unit: String = "By" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { @@ -103,7 +103,7 @@ object V8jsExperimentalMetrics { List( ), Requirement.required, - Stability.experimental + Stability.development ) val specs: List[AttributeSpec[_]] = @@ -147,7 +147,7 @@ object V8jsExperimentalMetrics { val name: String = "v8js.heap.space.physical_size" val description: String = "Committed size of a heap space." val unit: String = "By" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { @@ -163,7 +163,7 @@ object V8jsExperimentalMetrics { List( ), Requirement.required, - Stability.experimental + Stability.development ) val specs: List[AttributeSpec[_]] = @@ -207,7 +207,7 @@ object V8jsExperimentalMetrics { val name: String = "v8js.memory.heap.limit" val description: String = "Total heap memory size pre-allocated." val unit: String = "By" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { @@ -223,7 +223,7 @@ object V8jsExperimentalMetrics { List( ), Requirement.required, - Stability.experimental + Stability.development ) val specs: List[AttributeSpec[_]] = @@ -267,7 +267,7 @@ object V8jsExperimentalMetrics { val name: String = "v8js.memory.heap.used" val description: String = "Heap Memory size allocated." val unit: String = "By" - val stability: Stability = Stability.experimental + val stability: Stability = Stability.development val attributeSpecs: List[AttributeSpec[_]] = AttributeSpecs.specs object AttributeSpecs { @@ -283,7 +283,7 @@ object V8jsExperimentalMetrics { List( ), Requirement.required, - Stability.experimental + Stability.development ) val specs: List[AttributeSpec[_]] = diff --git a/semconv/metrics/stable/src/main/scala/org/typelevel/otel4s/semconv/Stability.scala b/semconv/metrics/stable/src/main/scala/org/typelevel/otel4s/semconv/Stability.scala index b1a5d1340..bb3c3a086 100644 --- a/semconv/metrics/stable/src/main/scala/org/typelevel/otel4s/semconv/Stability.scala +++ b/semconv/metrics/stable/src/main/scala/org/typelevel/otel4s/semconv/Stability.scala @@ -23,8 +23,8 @@ sealed trait Stability object Stability { def stable: Stability = Stable - def experimental: Stability = Experimental + def development: Stability = Development private case object Stable extends Stability - private case object Experimental extends Stability + private case object Development extends Stability } diff --git a/semconv/metrics/stable/src/main/scala/org/typelevel/otel4s/semconv/metrics/HttpMetrics.scala b/semconv/metrics/stable/src/main/scala/org/typelevel/otel4s/semconv/metrics/HttpMetrics.scala index 63ecb8656..a06604970 100644 --- a/semconv/metrics/stable/src/main/scala/org/typelevel/otel4s/semconv/metrics/HttpMetrics.scala +++ b/semconv/metrics/stable/src/main/scala/org/typelevel/otel4s/semconv/metrics/HttpMetrics.scala @@ -109,7 +109,7 @@ object HttpMetrics { Stability.stable ) - /** OSI application layer or non-OSI equivalent.
+ /** OSI application layer or non-OSI equivalent.
* @note *
The value SHOULD be normalized to lowercase. */ @@ -313,7 +313,7 @@ object HttpMetrics { Stability.stable ) - /** OSI application layer or non-OSI equivalent.
+ /** OSI application layer or non-OSI equivalent.
* @note *
The value SHOULD be normalized to lowercase. */ @@ -350,7 +350,7 @@ object HttpMetrics { /** Name of the local HTTP server that received the request.
* @note *
See Setting - * `server.address` and `server.port` attributes.
Warning Since this + * `server.address` and `server.port` attributesWarning Since this * attribute is based on HTTP headers, opting in to it may allow an attacker to trigger cardinality limits, * degrading the usefulness of the metric.*/ @@ -369,7 +369,7 @@ object HttpMetrics { /** Port of the local HTTP server that received the request.* @note *
See Setting - * `server.address` and `server.port` attributes.
Warning Since this + * `server.address` and `server.port` attributesWarning Since this * attribute is based on HTTP headers, opting in to it may allow an attacker to trigger cardinality limits, * degrading the usefulness of the metric.*/ diff --git a/semconv/stable/src/main/scala/org/typelevel/otel4s/semconv/SchemaUrls.scala b/semconv/stable/src/main/scala/org/typelevel/otel4s/semconv/SchemaUrls.scala index 302fca1b3..774e4388d 100644 --- a/semconv/stable/src/main/scala/org/typelevel/otel4s/semconv/SchemaUrls.scala +++ b/semconv/stable/src/main/scala/org/typelevel/otel4s/semconv/SchemaUrls.scala @@ -18,10 +18,11 @@ package org.typelevel.otel4s.semconv object SchemaUrls { + val V1_29_0: String = "https://opentelemetry.io/schemas/1.29.0" val V1_28_0: String = "https://opentelemetry.io/schemas/1.28.0" val V1_27_0: String = "https://opentelemetry.io/schemas/1.27.0" val V1_26_0: String = "https://opentelemetry.io/schemas/1.26.0" - private[otel4s] val Current: String = V1_28_0 + private[otel4s] val Current: String = V1_29_0 } diff --git a/semconv/stable/src/main/scala/org/typelevel/otel4s/semconv/attributes/ErrorAttributes.scala b/semconv/stable/src/main/scala/org/typelevel/otel4s/semconv/attributes/ErrorAttributes.scala index 1d60259b6..44feb6c8c 100644 --- a/semconv/stable/src/main/scala/org/typelevel/otel4s/semconv/attributes/ErrorAttributes.scala +++ b/semconv/stable/src/main/scala/org/typelevel/otel4s/semconv/attributes/ErrorAttributes.scala @@ -30,7 +30,7 @@ object ErrorAttributes { * instrumentation libraries and applications should be prepared for `error.type` to have high cardinality at query * time when no additional filters are applied.If the operation has completed successfully, instrumentations * SHOULD NOT set `error.type`.
If a specific domain defines its own set of error identifiers (such as HTTP or - * gRPC status codes), it's RECOMMENDED to:
- Use a domain-specific attribute
- Set `error.type` to + * gRPC status codes), it's RECOMMENDED to:
*/ val ErrorType: AttributeKey[String] = diff --git a/semconv/stable/src/main/scala/org/typelevel/otel4s/semconv/attributes/NetworkAttributes.scala b/semconv/stable/src/main/scala/org/typelevel/otel4s/semconv/attributes/NetworkAttributes.scala index 8709a1775..e8e6a0bf9 100644 --- a/semconv/stable/src/main/scala/org/typelevel/otel4s/semconv/attributes/NetworkAttributes.scala +++ b/semconv/stable/src/main/scala/org/typelevel/otel4s/semconv/attributes/NetworkAttributes.scala @@ -41,7 +41,7 @@ object NetworkAttributes { val NetworkPeerPort: AttributeKey[Long] = AttributeKey("network.peer.port") - /** OSI application layer or non-OSI equivalent.
- Use a domain-specific attribute
- Set `error.type` to * capture all errors, regardless of whether they are defined within the domain-specific set or not.
+ /** OSI application layer or non-OSI equivalent.
* @note *
The value SHOULD be normalized to lowercase. */ @@ -57,7 +57,7 @@ object NetworkAttributes { val NetworkProtocolVersion: AttributeKey[String] = AttributeKey("network.protocol.version") - /** OSI transport layer or OSI transport layer or inter-process communication method.
* @note *
The value SHOULD be normalized to lowercase.
Consider always setting the transport when setting a port @@ -67,7 +67,7 @@ object NetworkAttributes { val NetworkTransport: AttributeKey[String] = AttributeKey("network.transport") - /** OSI network layer or non-OSI equivalent.
+ /** OSI network layer or non-OSI equivalent.
* @note *
The value SHOULD be normalized to lowercase. */ diff --git a/semconv/stable/src/main/scala/org/typelevel/otel4s/semconv/attributes/UrlAttributes.scala b/semconv/stable/src/main/scala/org/typelevel/otel4s/semconv/attributes/UrlAttributes.scala index a09c3be8d..54079c7ba 100644 --- a/semconv/stable/src/main/scala/org/typelevel/otel4s/semconv/attributes/UrlAttributes.scala +++ b/semconv/stable/src/main/scala/org/typelevel/otel4s/semconv/attributes/UrlAttributes.scala @@ -30,12 +30,22 @@ object UrlAttributes { * href="https://www.rfc-editor.org/rfc/rfc3986">RFC3986
* @note *
For network calls, URL usually has `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. `url.full` MUST - * NOT contain credentials passed via URL in form of `https://username:password@www.example.com/`. In such case - * username and password SHOULD be redacted and attribute's value SHOULD be - * `https://REDACTED:REDACTED@www.example.com/`. `url.full` SHOULD capture the absolute URL when it is available - * (or can be reconstructed). Sensitive content provided in `url.full` SHOULD be scrubbed when instrumentations can - * identify it. + * fragment is not transmitted over HTTP, but if it is known, it SHOULD be included nevertheless.
`url.full` + * MUST NOT contain credentials passed via URL in form of `https://username:password@www.example.com/`. In such + * case username and password SHOULD be redacted and attribute's value SHOULD be + * `https://REDACTED:REDACTED@www.example.com/`.
`url.full` SHOULD capture the absolute URL when it is + * available (or can be reconstructed).
Sensitive content provided in `url.full` SHOULD be scrubbed when + * instrumentations can identify it.
+ * + * Query string values for the following keys SHOULD be redacted by default and replaced by the value `REDACTED`: + *
This list + * is subject to change over time.
When a query string value is redacted, the query string key SHOULD still be + * preserved, e.g. `https://www.example.com/path?color=blue&sig=REDACTED`. */ val UrlFull: AttributeKey[String] = AttributeKey("url.full") @@ -49,7 +59,17 @@ object UrlAttributes { /** The URI query component
* @note - *
Sensitive content provided in `url.query` SHOULD be scrubbed when instrumentations can identify it. + *
Sensitive content provided in `url.query` SHOULD be scrubbed when instrumentations can identify it.
+ * + * Query string values for the following keys SHOULD be redacted by default and replaced by the value `REDACTED`: + *
This list + * is subject to change over time.
When a query string value is redacted, the query string key SHOULD still be + * preserved, e.g. `q=OpenTelemetry&sig=REDACTED`. */ val UrlQuery: AttributeKey[String] = AttributeKey("url.query")