diff --git a/.typos.toml b/.typos.toml index 9e1a0055b..549668693 100644 --- a/.typos.toml +++ b/.typos.toml @@ -1,5 +1,5 @@ [files] -extend-exclude = ["*.cast", "**/*.yaml", "**/*.svg", "**/allowed-external-types.toml"] +extend-exclude = ["*.cast", "**/*.yaml", "**/*.json", "**/*.svg", "**/allowed-external-types.toml"] [default.extend-words] ratatui = "ratatui" diff --git a/crates/weaver_forge/src/registry.rs b/crates/weaver_forge/src/registry.rs index 3d265a94f..f6bf26c2a 100644 --- a/crates/weaver_forge/src/registry.rs +++ b/crates/weaver_forge/src/registry.rs @@ -351,7 +351,7 @@ mod tests { ], }; - let catalog = Catalog::from_attributes(vec![]); + let catalog = Catalog::default(); // Convert to resolved registry let resolved = ResolvedRegistry::try_from_resolved_registry(®istry, &catalog) diff --git a/crates/weaver_resolved_schema/src/catalog.rs b/crates/weaver_resolved_schema/src/catalog.rs index 28aea7d48..148aa6c07 100644 --- a/crates/weaver_resolved_schema/src/catalog.rs +++ b/crates/weaver_resolved_schema/src/catalog.rs @@ -4,8 +4,7 @@ //! that are shared across multiple signals in the Resolved Telemetry Schema. use crate::attribute::{Attribute, AttributeRef}; -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; +use serde::Serialize; use std::collections::{BTreeMap, HashMap}; use std::fmt::Debug; use weaver_semconv::attribute::{AttributeType, BasicRequirementLevelSpec, RequirementLevel}; @@ -15,13 +14,17 @@ use weaver_semconv::stability::Stability; /// Attribute references are used to refer to attributes in the catalog. /// /// Note : In the future, this catalog could be extended with other entities. -#[derive(Serialize, Deserialize, Debug, Clone, JsonSchema, Default, PartialEq, Eq)] -#[serde(deny_unknown_fields)] +#[derive(Debug, Clone, Default, PartialEq, Eq)] #[must_use] pub struct Catalog { - /// Catalog of attributes used in the schema. - #[serde(default, skip_serializing_if = "Vec::is_empty")] - pub(crate) attributes: Vec, + /// Catalog of attribute definitions and refinements used in the schema. + /// Contains elements with the same attribute key. + /// Use root_attributes for original attribute definitions. + attributes: Vec, + /// Attribute definitions available in this registry (including those + /// from dependencies). Used for cross-registry attribute lookup. + /// Not serialized — populated only for freshly resolved schemas. + root_attributes: HashMap, } /// Statistics on a catalog. @@ -41,31 +44,23 @@ pub struct Stats { } impl Catalog { - /// Creates a catalog from a list of attributes. - pub fn from_attributes(attributes: Vec) -> Self { - Self { attributes } - } - - /// Adds attributes to the catalog and returns a list of attribute references. - #[must_use] - pub fn add_attributes( - &mut self, - attributes: [Attribute; N], - ) -> Vec { - let start_index = self.attributes.len(); - self.attributes.extend(attributes.iter().cloned()); - (start_index..self.attributes.len()) - .map(|i| AttributeRef(i as u32)) - .collect::>() + /// Creates a catalog from a list of attributes and root attribute definitions. + pub fn new( + attributes: Vec, + root_attributes: HashMap, + ) -> Self { + Self { + attributes, + root_attributes, + } } - /// Returns the attribute name from an attribute ref if it exists - /// in the catalog or None if it does not exist. + /// Looks up an attribute by name in the root attribute definitions. #[must_use] - pub fn attribute_name(&self, attribute_ref: &AttributeRef) -> Option<&str> { - self.attributes - .get(attribute_ref.0 as usize) - .map(|attr| attr.name.as_ref()) + pub fn root_attribute(&self, name: &str) -> Option<(&Attribute, &str)> { + self.root_attributes + .get(name) + .map(|(attr, group_id)| (attr, group_id.as_str())) } /// Counts the number of attributes in the catalog. @@ -75,7 +70,7 @@ impl Catalog { } /// Return an iterator over the attributes in the catalog. - pub fn iter(&self) -> impl Iterator { + pub fn attributes(&self) -> impl Iterator { self.attributes.iter() } @@ -140,3 +135,47 @@ impl Catalog { } } } + +#[cfg(test)] +/// Test utilities for building [`Catalog`] instances. +pub mod test_utils { + use super::*; + + /// A builder for constructing a [`Catalog`] in tests. + #[derive(Default)] + pub struct CatalogBuilder { + attributes: Vec, + root_attributes: HashMap, + } + + impl CatalogBuilder { + /// Creates a builder pre-populated with all attributes from an existing catalog. + /// Root attributes are not copied — use [`CatalogBuilder::add`] with a `group_id` for that. + #[must_use] + pub fn from_catalog(catalog: &Catalog) -> Self { + let mut builder = Self::default(); + for attr in catalog.attributes() { + let _ = builder.add(attr.clone(), None); + } + builder + } + + /// Adds an attribute to the catalog. If `group_id` is `Some`, the attribute + /// is also registered as a root definition for cross-registry lookup. + pub fn add(&mut self, attr: Attribute, group_id: Option<&str>) -> AttributeRef { + if let Some(gid) = group_id { + let _ = self + .root_attributes + .insert(attr.name.clone(), (attr.clone(), gid.to_owned())); + } + let idx = self.attributes.len(); + self.attributes.push(attr); + AttributeRef(idx as u32) + } + + /// Builds the [`Catalog`]. + pub fn build(self) -> Catalog { + Catalog::new(self.attributes, self.root_attributes) + } + } +} diff --git a/crates/weaver_resolved_schema/src/lib.rs b/crates/weaver_resolved_schema/src/lib.rs index a0c7f4238..b97f7b6df 100644 --- a/crates/weaver_resolved_schema/src/lib.rs +++ b/crates/weaver_resolved_schema/src/lib.rs @@ -10,7 +10,6 @@ use crate::catalog::Catalog; use crate::instrumentation_library::InstrumentationLibrary; use crate::registry::{Group, Registry}; use crate::resource::Resource; -use schemars::JsonSchema; use serde::Serialize; use std::collections::HashMap; use weaver_semconv::deprecated::Deprecated; @@ -46,8 +45,7 @@ pub(crate) const V2_RESOLVED_FILE_FORMAT: &str = "resolved/2.0.0"; /// A Resolved Telemetry Schema. /// A Resolved Telemetry Schema is self-contained and doesn't contain any /// external references to other schemas or semantic conventions. -#[derive(Debug, JsonSchema)] -#[serde(deny_unknown_fields)] +#[derive(Debug)] pub struct ResolvedTelemetrySchema { /// Version of the file structure. pub file_format: String, @@ -61,14 +59,11 @@ pub struct ResolvedTelemetrySchema { /// and signals. pub catalog: Catalog, /// Resource definition (only for application). - #[serde(skip_serializing_if = "Option::is_none")] pub resource: Option, /// Definition of the instrumentation library for the instrumented application or library. /// Or none if the resolved telemetry schema represents a semantic convention registry. - #[serde(skip_serializing_if = "Option::is_none")] pub instrumentation_library: Option, /// The list of dependencies of the current instrumentation application or library. - #[serde(skip_serializing_if = "Vec::is_empty")] pub dependencies: Vec, /// Definitions for each schema version in this family. /// Note: the ordering of versions is defined according to semver @@ -76,7 +71,6 @@ pub struct ResolvedTelemetrySchema { /// This section is described in more details in the OTEP 0152 and in a dedicated /// section below. /// - #[serde(skip_serializing_if = "Option::is_none")] pub versions: Option, /// The manifest of the registry. pub registry_manifest: Option, @@ -117,7 +111,12 @@ impl ResolvedTelemetrySchema { attrs: [Attribute; N], deprecated: Option, ) { - let attr_refs = self.catalog.add_attributes(attrs); + let mut builder = catalog::test_utils::CatalogBuilder::from_catalog(&self.catalog); + let attr_refs: Vec = attrs + .into_iter() + .map(|a| builder.add(a, Some(group_id))) + .collect(); + self.catalog = builder.build(); self.registry.groups.push(Group { id: group_id.to_owned(), r#type: GroupType::Metric, @@ -161,7 +160,12 @@ impl ResolvedTelemetrySchema { let al = AttributeLineage::new(group_id); lineage.add_attribute_lineage(attr.name.clone(), al); } - let attr_refs: Vec = self.catalog.add_attributes(attrs); + let mut builder = catalog::test_utils::CatalogBuilder::from_catalog(&self.catalog); + let attr_refs: Vec = attrs + .into_iter() + .map(|a| builder.add(a, Some(group_id))) + .collect(); + self.catalog = builder.build(); self.registry.groups.push(Group { id: group_id.to_owned(), r#type: GroupType::AttributeGroup, @@ -525,20 +529,9 @@ impl ResolvedTelemetrySchema { mod tests { use crate::attribute::Attribute; use crate::ResolvedTelemetrySchema; - use schemars::schema_for; - use serde_json::to_string_pretty; use weaver_semconv::deprecated::Deprecated; use weaver_version::schema_changes::{SchemaItemChange, SchemaItemType}; - #[test] - fn test_json_schema_gen() { - // Ensure the JSON schema can be generated for the ResolvedTelemetrySchema - let schema = schema_for!(ResolvedTelemetrySchema); - - // Ensure the schema can be serialized to a string - assert!(to_string_pretty(&schema).is_ok()); - } - #[test] fn no_diff() { let mut prior_schema = ResolvedTelemetrySchema::new("1.0", "", ""); diff --git a/crates/weaver_resolved_schema/src/v2/mod.rs b/crates/weaver_resolved_schema/src/v2/mod.rs index 6e543efeb..13d2df02e 100644 --- a/crates/weaver_resolved_schema/src/v2/mod.rs +++ b/crates/weaver_resolved_schema/src/v2/mod.rs @@ -163,8 +163,7 @@ pub fn convert_v1_to_v2( // When pulling attributes, as we collapse things, we need to filter // to just unique. let attributes: HashSet = c - .attributes - .iter() + .attributes() .cloned() .map(|a| { Attribute { @@ -616,8 +615,8 @@ mod tests { #[test] fn test_convert_span_v1_to_v2() { - let mut v1_catalog = crate::catalog::Catalog::from_attributes(vec![]); - let test_refs = v1_catalog.add_attributes([ + let mut builder = crate::catalog::test_utils::CatalogBuilder::default(); + let ref0 = builder.add( Attribute { name: "test.key".to_owned(), r#type: weaver_semconv::attribute::AttributeType::PrimitiveOrArray( @@ -639,6 +638,9 @@ mod tests { value: None, role: None, }, + None, + ); + let ref1 = builder.add( Attribute { name: "test.key".to_owned(), r#type: weaver_semconv::attribute::AttributeType::PrimitiveOrArray( @@ -660,7 +662,10 @@ mod tests { value: None, role: None, }, - ]); + None, + ); + let test_refs = [ref0, ref1]; + let v1_catalog = builder.build(); let mut refinement_span_lineage = GroupLineage::new(Provenance::new("tmp", "tmp")); refinement_span_lineage.extends("span.my-span"); refinement_span_lineage @@ -746,8 +751,8 @@ mod tests { #[test] fn test_convert_metric_v1_to_v2() { - let mut v1_catalog = crate::catalog::Catalog::from_attributes(vec![]); - let test_refs = v1_catalog.add_attributes([ + let mut builder = crate::catalog::test_utils::CatalogBuilder::default(); + let ref0 = builder.add( Attribute { name: "test.key".to_owned(), r#type: weaver_semconv::attribute::AttributeType::PrimitiveOrArray( @@ -769,6 +774,9 @@ mod tests { value: None, role: None, }, + None, + ); + let ref1 = builder.add( Attribute { name: "test.key".to_owned(), r#type: weaver_semconv::attribute::AttributeType::PrimitiveOrArray( @@ -790,7 +798,10 @@ mod tests { value: None, role: None, }, - ]); + None, + ); + let test_refs = [ref0, ref1]; + let v1_catalog = builder.build(); let mut refinement_metric_lineage = GroupLineage::new(Provenance::new("tmp", "tmp")); refinement_metric_lineage.extends("metric.http"); refinement_metric_lineage @@ -874,28 +885,33 @@ mod tests { #[test] fn test_convert_event_v1_to_v2() { - let mut v1_catalog = crate::catalog::Catalog::from_attributes(vec![]); - let test_refs = v1_catalog.add_attributes([Attribute { - name: "test.key".to_owned(), - r#type: weaver_semconv::attribute::AttributeType::PrimitiveOrArray( - weaver_semconv::attribute::PrimitiveOrArrayTypeSpec::String, - ), - brief: "".to_owned(), - examples: None, - tag: None, - requirement_level: weaver_semconv::attribute::RequirementLevel::Basic( - weaver_semconv::attribute::BasicRequirementLevelSpec::Required, - ), - sampling_relevant: None, - note: "".to_owned(), - stability: Some(Stability::Stable), - deprecated: None, - prefix: false, - tags: None, - annotations: None, - value: None, - role: None, - }]); + let mut builder = crate::catalog::test_utils::CatalogBuilder::default(); + let ref0 = builder.add( + Attribute { + name: "test.key".to_owned(), + r#type: weaver_semconv::attribute::AttributeType::PrimitiveOrArray( + weaver_semconv::attribute::PrimitiveOrArrayTypeSpec::String, + ), + brief: "".to_owned(), + examples: None, + tag: None, + requirement_level: weaver_semconv::attribute::RequirementLevel::Basic( + weaver_semconv::attribute::BasicRequirementLevelSpec::Required, + ), + sampling_relevant: None, + note: "".to_owned(), + stability: Some(Stability::Stable), + deprecated: None, + prefix: false, + tags: None, + annotations: None, + value: None, + role: None, + }, + None, + ); + let test_refs = [ref0]; + let v1_catalog = builder.build(); let v1_registry = crate::registry::Registry { registry_url: "my.schema.url".to_owned(), groups: vec![Group { @@ -934,28 +950,33 @@ mod tests { #[test] fn test_convert_entity_v1_to_v2() { - let mut v1_catalog = crate::catalog::Catalog::from_attributes(vec![]); - let test_refs = v1_catalog.add_attributes([Attribute { - name: "test.key".to_owned(), - r#type: weaver_semconv::attribute::AttributeType::PrimitiveOrArray( - weaver_semconv::attribute::PrimitiveOrArrayTypeSpec::String, - ), - brief: "".to_owned(), - examples: None, - tag: None, - requirement_level: weaver_semconv::attribute::RequirementLevel::Basic( - weaver_semconv::attribute::BasicRequirementLevelSpec::Required, - ), - sampling_relevant: None, - note: "".to_owned(), - stability: Some(Stability::Stable), - deprecated: None, - prefix: false, - tags: None, - annotations: None, - value: None, - role: Some(weaver_semconv::attribute::AttributeRole::Identifying), - }]); + let mut builder = crate::catalog::test_utils::CatalogBuilder::default(); + let ref0 = builder.add( + Attribute { + name: "test.key".to_owned(), + r#type: weaver_semconv::attribute::AttributeType::PrimitiveOrArray( + weaver_semconv::attribute::PrimitiveOrArrayTypeSpec::String, + ), + brief: "".to_owned(), + examples: None, + tag: None, + requirement_level: weaver_semconv::attribute::RequirementLevel::Basic( + weaver_semconv::attribute::BasicRequirementLevelSpec::Required, + ), + sampling_relevant: None, + note: "".to_owned(), + stability: Some(Stability::Stable), + deprecated: None, + prefix: false, + tags: None, + annotations: None, + value: None, + role: Some(weaver_semconv::attribute::AttributeRole::Identifying), + }, + None, + ); + let test_refs = [ref0]; + let v1_catalog = builder.build(); let v1_registry = crate::registry::Registry { registry_url: "my.schema.url".to_owned(), groups: vec![Group { @@ -999,7 +1020,7 @@ mod tests { file_format: V1_RESOLVED_FILE_FORMAT.to_owned(), schema_url: "http://test/schemas/1.0.0".to_owned(), registry_id: "my-registry".to_owned(), - catalog: crate::catalog::Catalog::from_attributes(vec![]), + catalog: crate::catalog::Catalog::default(), registry: crate::registry::Registry { registry_url: "http://another/url/1.0".to_owned(), groups: vec![], diff --git a/crates/weaver_resolver/data/multi-registry/otel_registry/otel_registry.yaml b/crates/weaver_resolver/data/multi-registry/otel_registry/otel_registry.yaml index 277254a61..e7a288a69 100644 --- a/crates/weaver_resolver/data/multi-registry/otel_registry/otel_registry.yaml +++ b/crates/weaver_resolver/data/multi-registry/otel_registry/otel_registry.yaml @@ -9,6 +9,13 @@ groups: stability: stable requirement_level: recommended examples: "Ex" + - id: db.client.metrics + type: attribute_group + brief: DB client metric attributes. + attributes: + - ref: error.type + brief: The type of database error. + - id: otel.unused type: attribute_group brief: Unused attributes from the OTEL Registry. diff --git a/crates/weaver_resolver/data/registry-test-1-single-attr-ref/expected-attribute-catalog.json b/crates/weaver_resolver/data/registry-test-1-single-attr-ref/expected-attribute-catalog.json index f455a0080..02ce96b85 100644 --- a/crates/weaver_resolver/data/registry-test-1-single-attr-ref/expected-attribute-catalog.json +++ b/crates/weaver_resolver/data/registry-test-1-single-attr-ref/expected-attribute-catalog.json @@ -1,30 +1,28 @@ -{ - "attributes": [ - { - "name": "messaging.destination.name", - "type": "string", - "brief": "The message destination name", - "examples": [ - "MyQueue", - "MyTopic" - ], - "requirement_level": "recommended", - "note": "Destination name SHOULD uniquely identify a specific queue, topic or other entity within the broker. If\nthe broker doesn't have such notion, the destination name SHOULD uniquely identify the broker.\n", - "stability": "stable" +[ + { + "name": "messaging.destination.name", + "type": "string", + "brief": "The message destination name", + "examples": [ + "MyQueue", + "MyTopic" + ], + "requirement_level": "recommended", + "note": "Destination name SHOULD uniquely identify a specific queue, topic or other entity within the broker. If\nthe broker doesn't have such notion, the destination name SHOULD uniquely identify the broker.\n", + "stability": "stable" + }, + { + "name": "messaging.destination.name", + "type": "string", + "brief": "The message destination name", + "examples": [ + "MyQueue", + "MyTopic" + ], + "requirement_level": { + "conditionally_required": "if and only if `messaging.destination.name` is known to have low cardinality. Otherwise, `messaging.destination.template` MAY be populated." }, - { - "name": "messaging.destination.name", - "type": "string", - "brief": "The message destination name", - "examples": [ - "MyQueue", - "MyTopic" - ], - "requirement_level": { - "conditionally_required": "if and only if `messaging.destination.name` is known to have low cardinality. Otherwise, `messaging.destination.template` MAY be populated." - }, - "note": "Destination name SHOULD uniquely identify a specific queue, topic or other entity within the broker. If\nthe broker doesn't have such notion, the destination name SHOULD uniquely identify the broker.\n", - "stability": "stable" - } - ] -} \ No newline at end of file + "note": "Destination name SHOULD uniquely identify a specific queue, topic or other entity within the broker. If\nthe broker doesn't have such notion, the destination name SHOULD uniquely identify the broker.\n", + "stability": "stable" + } +] diff --git a/crates/weaver_resolver/data/registry-test-10-prefix-refs/expected-attribute-catalog.json b/crates/weaver_resolver/data/registry-test-10-prefix-refs/expected-attribute-catalog.json index a8a6b4fe0..7dc7bf333 100644 --- a/crates/weaver_resolver/data/registry-test-10-prefix-refs/expected-attribute-catalog.json +++ b/crates/weaver_resolver/data/registry-test-10-prefix-refs/expected-attribute-catalog.json @@ -1,65 +1,63 @@ -{ - "attributes": [ - { - "name": "client.geo.lat", - "type": "string", - "brief": "My own latitude", - "examples": [ - "123.456" - ], - "requirement_level": "recommended", - "stability": "development", - "prefix": true - }, - { - "name": "client.geo.lat", - "type": "string", - "brief": "this is embedded attribute", - "examples": [ - "123.456" - ], - "requirement_level": "recommended", - "stability": "development" - }, - { - "name": "client.id", - "type": "string", - "brief": "some client id\n", - "examples": [ - "a.einstein" - ], - "requirement_level": "recommended", - "stability": "development" - }, - { - "name": "geo.lat", - "type": "string", - "brief": "latitude of the geo coordinates.\n", - "examples": [ - "123.456" - ], - "requirement_level": "recommended", - "stability": "development" - }, - { - "name": "geo.lat", - "type": "string", - "brief": "this is ref attribute", - "examples": [ - "123.456" - ], - "requirement_level": "recommended", - "stability": "development" - }, - { - "name": "geo.lon", - "type": "string", - "brief": "longitude of the geo coordinates.\n", - "examples": [ - "234.456" - ], - "requirement_level": "recommended", - "stability": "development" - } - ] -} \ No newline at end of file +[ + { + "name": "client.geo.lat", + "type": "string", + "brief": "My own latitude", + "examples": [ + "123.456" + ], + "requirement_level": "recommended", + "stability": "development", + "prefix": true + }, + { + "name": "client.geo.lat", + "type": "string", + "brief": "this is embedded attribute", + "examples": [ + "123.456" + ], + "requirement_level": "recommended", + "stability": "development" + }, + { + "name": "client.id", + "type": "string", + "brief": "some client id\n", + "examples": [ + "a.einstein" + ], + "requirement_level": "recommended", + "stability": "development" + }, + { + "name": "geo.lat", + "type": "string", + "brief": "latitude of the geo coordinates.\n", + "examples": [ + "123.456" + ], + "requirement_level": "recommended", + "stability": "development" + }, + { + "name": "geo.lat", + "type": "string", + "brief": "this is ref attribute", + "examples": [ + "123.456" + ], + "requirement_level": "recommended", + "stability": "development" + }, + { + "name": "geo.lon", + "type": "string", + "brief": "longitude of the geo coordinates.\n", + "examples": [ + "234.456" + ], + "requirement_level": "recommended", + "stability": "development" + } +] diff --git a/crates/weaver_resolver/data/registry-test-11-prefix-refs-extends/expected-attribute-catalog.json b/crates/weaver_resolver/data/registry-test-11-prefix-refs-extends/expected-attribute-catalog.json index 32c61f106..5ce6d5d26 100644 --- a/crates/weaver_resolver/data/registry-test-11-prefix-refs-extends/expected-attribute-catalog.json +++ b/crates/weaver_resolver/data/registry-test-11-prefix-refs-extends/expected-attribute-catalog.json @@ -1,85 +1,83 @@ -{ - "attributes": [ - { - "name": "client.geo.lat", - "type": "string", - "brief": "My own latitude", - "examples": [ - "123.456" - ], - "requirement_level": "recommended", - "stability": "development", - "prefix": true - }, - { - "name": "client.geo.lat", - "type": "string", - "brief": "this is embedded attribute", - "examples": [ - "123.456" - ], - "requirement_level": "recommended", - "stability": "development" - }, - { - "name": "client.id", - "type": "string", - "brief": "some client id\n", - "examples": [ - "a.einstein" - ], - "requirement_level": "recommended", - "stability": "development" - }, - { - "name": "geo.country", - "type": "string", - "brief": "country of the geo coordinates.\n", - "examples": [ - "US" - ], - "requirement_level": "recommended", - "stability": "development" - }, - { - "name": "geo.country", - "type": "string", - "brief": "this is ref country attribute", - "examples": [ - "US" - ], - "requirement_level": "recommended", - "stability": "development" - }, - { - "name": "geo.lat", - "type": "string", - "brief": "latitude of the geo coordinates.\n", - "examples": [ - "123.456" - ], - "requirement_level": "recommended", - "stability": "development" - }, - { - "name": "geo.lat", - "type": "string", - "brief": "this is ref attribute", - "examples": [ - "123.456" - ], - "requirement_level": "recommended", - "stability": "development" - }, - { - "name": "geo.lon", - "type": "string", - "brief": "longitude of the geo coordinates.\n", - "examples": [ - "234.456" - ], - "requirement_level": "recommended", - "stability": "development" - } - ] -} \ No newline at end of file +[ + { + "name": "client.geo.lat", + "type": "string", + "brief": "My own latitude", + "examples": [ + "123.456" + ], + "requirement_level": "recommended", + "stability": "development", + "prefix": true + }, + { + "name": "client.geo.lat", + "type": "string", + "brief": "this is embedded attribute", + "examples": [ + "123.456" + ], + "requirement_level": "recommended", + "stability": "development" + }, + { + "name": "client.id", + "type": "string", + "brief": "some client id\n", + "examples": [ + "a.einstein" + ], + "requirement_level": "recommended", + "stability": "development" + }, + { + "name": "geo.country", + "type": "string", + "brief": "country of the geo coordinates.\n", + "examples": [ + "US" + ], + "requirement_level": "recommended", + "stability": "development" + }, + { + "name": "geo.country", + "type": "string", + "brief": "this is ref country attribute", + "examples": [ + "US" + ], + "requirement_level": "recommended", + "stability": "development" + }, + { + "name": "geo.lat", + "type": "string", + "brief": "latitude of the geo coordinates.\n", + "examples": [ + "123.456" + ], + "requirement_level": "recommended", + "stability": "development" + }, + { + "name": "geo.lat", + "type": "string", + "brief": "this is ref attribute", + "examples": [ + "123.456" + ], + "requirement_level": "recommended", + "stability": "development" + }, + { + "name": "geo.lon", + "type": "string", + "brief": "longitude of the geo coordinates.\n", + "examples": [ + "234.456" + ], + "requirement_level": "recommended", + "stability": "development" + } +] diff --git a/crates/weaver_resolver/data/registry-test-14-annotations/expected-attribute-catalog.json b/crates/weaver_resolver/data/registry-test-14-annotations/expected-attribute-catalog.json index 09677c257..54e06451e 100644 --- a/crates/weaver_resolver/data/registry-test-14-annotations/expected-attribute-catalog.json +++ b/crates/weaver_resolver/data/registry-test-14-annotations/expected-attribute-catalog.json @@ -1,85 +1,83 @@ -{ - "attributes": [ - { - "name": "attr1", - "type": "string", - "brief": "Brief", - "examples": "eu-central-1", - "requirement_level": "required", - "note": "Note", - "stability": "stable", - "annotations": { - "code_generation": { - "exclude": true - }, - "complex": { - "key1": "string", - "key2": 234, - "key3": true, - "key4": { - "key4.1": "string", - "key4.2": 234 - }, - "key5": [ - 12, - 45, - 67 - ], - "key6": null +[ + { + "name": "attr1", + "type": "string", + "brief": "Brief", + "examples": "eu-central-1", + "requirement_level": "required", + "note": "Note", + "stability": "stable", + "annotations": { + "code_generation": { + "exclude": true + }, + "complex": { + "key1": "string", + "key2": 234, + "key3": true, + "key4": { + "key4.1": "string", + "key4.2": 234 }, - "privacy_sensitivity": "PII + PHI" - } - }, - { - "name": "attr1", - "type": "string", - "brief": "Brief", - "examples": "eu-central-1", - "requirement_level": "required", - "note": "Note", - "stability": "stable", - "annotations": { - "code_generation": { - "exclude": true + "key5": [ + 12, + 45, + 67 + ], + "key6": null + }, + "privacy_sensitivity": "PII + PHI" + } + }, + { + "name": "attr1", + "type": "string", + "brief": "Brief", + "examples": "eu-central-1", + "requirement_level": "required", + "note": "Note", + "stability": "stable", + "annotations": { + "code_generation": { + "exclude": true + }, + "privacy_sensitivity": "PII" + } + }, + { + "name": "attr2", + "type": { + "members": [ + { + "id": "first", + "value": "first", + "brief": "First", + "stability": "stable" }, - "privacy_sensitivity": "PII" - } - }, - { - "name": "attr2", - "type": { - "members": [ - { - "id": "first", - "value": "first", - "brief": "First", - "stability": "stable" - }, - { - "id": "second", - "value": "second", - "brief": "Second", - "stability": "stable", - "annotations": { - "code_generation": { - "exclude": true - }, - "privacy_sensitivity": "PII + PHI" - } + { + "id": "second", + "value": "second", + "brief": "Second", + "stability": "stable", + "annotations": { + "code_generation": { + "exclude": true + }, + "privacy_sensitivity": "PII + PHI" } - ] + } + ] + }, + "brief": "Brief", + "examples": "eu-central-1", + "requirement_level": "required", + "note": "Note", + "stability": "stable", + "annotations": { + "code_generation": { + "exclude": true }, - "brief": "Brief", - "examples": "eu-central-1", - "requirement_level": "required", - "note": "Note", - "stability": "stable", - "annotations": { - "code_generation": { - "exclude": true - }, - "privacy_sensitivity": "PII" - } + "privacy_sensitivity": "PII" } - ] -} \ No newline at end of file + } +] diff --git a/crates/weaver_resolver/data/registry-test-15-attr-any/expected-attribute-catalog.json b/crates/weaver_resolver/data/registry-test-15-attr-any/expected-attribute-catalog.json index e54473610..b768d8d60 100644 --- a/crates/weaver_resolver/data/registry-test-15-attr-any/expected-attribute-catalog.json +++ b/crates/weaver_resolver/data/registry-test-15-attr-any/expected-attribute-catalog.json @@ -1,29 +1,27 @@ -{ - "attributes": [ - { - "name": "test.any", - "type": "any", - "brief": "any attribute", - "examples": [ - "zero", - 1, - 2.0, - true - ], - "requirement_level": "recommended", - "note": "any attribute.\n", - "stability": "stable" - }, - { - "name": "test.template.any", - "type": "template[any]", - "brief": "template[any] attribute", - "examples": [ - "test.template.any.my-custom-metadata-attribute=[\"zero\", 1, 2.0, true]" - ], - "requirement_level": "recommended", - "note": "template[any] attribute.\n", - "stability": "stable" - } - ] -} \ No newline at end of file +[ + { + "name": "test.any", + "type": "any", + "brief": "any attribute", + "examples": [ + "zero", + 1, + 2.0, + true + ], + "requirement_level": "recommended", + "note": "any attribute.\n", + "stability": "stable" + }, + { + "name": "test.template.any", + "type": "template[any]", + "brief": "template[any] attribute", + "examples": [ + "test.template.any.my-custom-metadata-attribute=[\"zero\", 1, 2.0, true]" + ], + "requirement_level": "recommended", + "note": "template[any] attribute.\n", + "stability": "stable" + } +] diff --git a/crates/weaver_resolver/data/registry-test-2-multi-attr-refs/expected-attribute-catalog.json b/crates/weaver_resolver/data/registry-test-2-multi-attr-refs/expected-attribute-catalog.json index 8b5ecbdf9..e3fc8df7f 100644 --- a/crates/weaver_resolver/data/registry-test-2-multi-attr-refs/expected-attribute-catalog.json +++ b/crates/weaver_resolver/data/registry-test-2-multi-attr-refs/expected-attribute-catalog.json @@ -1,425 +1,423 @@ -{ - "attributes": [ - { - "name": "messaging.batch.message_count", - "type": "int", - "brief": "The number of messages sent, received, or processed in the scope of the batching operation.", - "examples": [ - 0, - 1, - 2 - ], - "requirement_level": "recommended", - "note": "Instrumentations SHOULD NOT set `messaging.batch.message_count` on spans that operate with a single message. When a messaging client library supports both batch and single-message API for the same operation, instrumentations SHOULD use `messaging.batch.message_count` for batching APIs and SHOULD NOT use it for single-message APIs.\n", - "stability": "stable" - }, - { - "name": "messaging.client_id", - "type": "string", - "brief": "A unique identifier for the client that consumes or produces a message.\n", - "examples": [ - "client-5", - "myhost@8742@s8083jm" - ], - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "messaging.destination.anonymous", - "type": "boolean", - "brief": "A boolean that is true if the message destination is anonymous (could be unnamed or have auto-generated name).", - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "messaging.destination.name", - "type": "string", - "brief": "The message destination name", - "examples": [ - "MyQueue", - "MyTopic" - ], - "requirement_level": "recommended", - "note": "Destination name SHOULD uniquely identify a specific queue, topic or other entity within the broker. If\nthe broker doesn't have such notion, the destination name SHOULD uniquely identify the broker.\n", - "stability": "stable" - }, - { - "name": "messaging.destination.name", - "type": "string", - "brief": "The message destination name", - "examples": [ - "MyQueue", - "MyTopic" - ], - "requirement_level": { - "conditionally_required": "if and only if `messaging.destination.name` is known to have low cardinality. Otherwise, `messaging.destination.template` MAY be populated." - }, - "note": "Destination name SHOULD uniquely identify a specific queue, topic or other entity within the broker. If\nthe broker doesn't have such notion, the destination name SHOULD uniquely identify the broker.\n", - "stability": "stable" - }, - { - "name": "messaging.destination.template", - "type": "string", - "brief": "Low cardinality representation of the messaging destination name", - "examples": [ - "/customers/{customerId}" - ], - "requirement_level": "recommended", - "note": "Destination names could be constructed from templates. An example would be a destination name involving a user name or product id. Although the destination name in this case is of high cardinality, the underlying template is of low cardinality and can be effectively used for grouping and aggregation.\n", - "stability": "stable" - }, - { - "name": "messaging.destination.template", - "type": "string", - "brief": "Low cardinality representation of the messaging destination name", - "examples": [ - "/customers/{customerId}" - ], - "requirement_level": { - "conditionally_required": "if available." - }, - "note": "Destination names could be constructed from templates. An example would be a destination name involving a user name or product id. Although the destination name in this case is of high cardinality, the underlying template is of low cardinality and can be effectively used for grouping and aggregation.\n", - "stability": "stable" - }, - { - "name": "messaging.destination.temporary", - "type": "boolean", - "brief": "A boolean that is true if the message destination is temporary and might not exist anymore after messages are processed.", - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "messaging.destination_publish.anonymous", - "type": "boolean", - "brief": "A boolean that is true if the publish message destination is anonymous (could be unnamed or have auto-generated name).", - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "messaging.destination_publish.name", - "type": "string", - "brief": "The name of the original destination the message was published to", - "examples": [ - "MyQueue", - "MyTopic" - ], - "requirement_level": "recommended", - "note": "The name SHOULD uniquely identify a specific queue, topic, or other entity within the broker. If\nthe broker doesn't have such notion, the original destination name SHOULD uniquely identify the broker.\n", - "stability": "stable" +[ + { + "name": "messaging.batch.message_count", + "type": "int", + "brief": "The number of messages sent, received, or processed in the scope of the batching operation.", + "examples": [ + 0, + 1, + 2 + ], + "requirement_level": "recommended", + "note": "Instrumentations SHOULD NOT set `messaging.batch.message_count` on spans that operate with a single message. When a messaging client library supports both batch and single-message API for the same operation, instrumentations SHOULD use `messaging.batch.message_count` for batching APIs and SHOULD NOT use it for single-message APIs.\n", + "stability": "stable" + }, + { + "name": "messaging.client_id", + "type": "string", + "brief": "A unique identifier for the client that consumes or produces a message.\n", + "examples": [ + "client-5", + "myhost@8742@s8083jm" + ], + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "messaging.destination.anonymous", + "type": "boolean", + "brief": "A boolean that is true if the message destination is anonymous (could be unnamed or have auto-generated name).", + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "messaging.destination.name", + "type": "string", + "brief": "The message destination name", + "examples": [ + "MyQueue", + "MyTopic" + ], + "requirement_level": "recommended", + "note": "Destination name SHOULD uniquely identify a specific queue, topic or other entity within the broker. If\nthe broker doesn't have such notion, the destination name SHOULD uniquely identify the broker.\n", + "stability": "stable" + }, + { + "name": "messaging.destination.name", + "type": "string", + "brief": "The message destination name", + "examples": [ + "MyQueue", + "MyTopic" + ], + "requirement_level": { + "conditionally_required": "if and only if `messaging.destination.name` is known to have low cardinality. Otherwise, `messaging.destination.template` MAY be populated." }, - { - "name": "messaging.gcp_pubsub.message.ordering_key", - "type": "string", - "brief": "The ordering key for a given message. If the attribute is not present, the message does not have an ordering key.\n", - "examples": "ordering_key", - "requirement_level": "recommended", - "stability": "stable" + "note": "Destination name SHOULD uniquely identify a specific queue, topic or other entity within the broker. If\nthe broker doesn't have such notion, the destination name SHOULD uniquely identify the broker.\n", + "stability": "stable" + }, + { + "name": "messaging.destination.template", + "type": "string", + "brief": "Low cardinality representation of the messaging destination name", + "examples": [ + "/customers/{customerId}" + ], + "requirement_level": "recommended", + "note": "Destination names could be constructed from templates. An example would be a destination name involving a user name or product id. Although the destination name in this case is of high cardinality, the underlying template is of low cardinality and can be effectively used for grouping and aggregation.\n", + "stability": "stable" + }, + { + "name": "messaging.destination.template", + "type": "string", + "brief": "Low cardinality representation of the messaging destination name", + "examples": [ + "/customers/{customerId}" + ], + "requirement_level": { + "conditionally_required": "if available." }, - { - "name": "messaging.kafka.consumer.group", - "type": "string", - "brief": "Name of the Kafka Consumer Group that is handling the message. Only applies to consumers, not producers.\n", - "examples": "my-group", - "requirement_level": "recommended", - "stability": "stable" + "note": "Destination names could be constructed from templates. An example would be a destination name involving a user name or product id. Although the destination name in this case is of high cardinality, the underlying template is of low cardinality and can be effectively used for grouping and aggregation.\n", + "stability": "stable" + }, + { + "name": "messaging.destination.temporary", + "type": "boolean", + "brief": "A boolean that is true if the message destination is temporary and might not exist anymore after messages are processed.", + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "messaging.destination_publish.anonymous", + "type": "boolean", + "brief": "A boolean that is true if the publish message destination is anonymous (could be unnamed or have auto-generated name).", + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "messaging.destination_publish.name", + "type": "string", + "brief": "The name of the original destination the message was published to", + "examples": [ + "MyQueue", + "MyTopic" + ], + "requirement_level": "recommended", + "note": "The name SHOULD uniquely identify a specific queue, topic, or other entity within the broker. If\nthe broker doesn't have such notion, the original destination name SHOULD uniquely identify the broker.\n", + "stability": "stable" + }, + { + "name": "messaging.gcp_pubsub.message.ordering_key", + "type": "string", + "brief": "The ordering key for a given message. If the attribute is not present, the message does not have an ordering key.\n", + "examples": "ordering_key", + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "messaging.kafka.consumer.group", + "type": "string", + "brief": "Name of the Kafka Consumer Group that is handling the message. Only applies to consumers, not producers.\n", + "examples": "my-group", + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "messaging.kafka.destination.partition", + "type": "int", + "brief": "Partition the message is sent to.\n", + "examples": 2, + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "messaging.kafka.message.key", + "type": "string", + "brief": "Message keys in Kafka are used for grouping alike messages to ensure they're processed on the same partition. They differ from `messaging.message.id` in that they're not unique. If the key is `null`, the attribute MUST NOT be set.\n", + "examples": "myKey", + "requirement_level": "recommended", + "note": "If the key type is not string, it's string representation has to be supplied for the attribute. If the key has no unambiguous, canonical string form, don't include its value.\n", + "stability": "stable" + }, + { + "name": "messaging.kafka.message.offset", + "type": "int", + "brief": "The offset of a record in the corresponding Kafka partition.\n", + "examples": 42, + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "messaging.kafka.message.tombstone", + "type": "boolean", + "brief": "A boolean that is true if the message is a tombstone.", + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "messaging.message.body.size", + "type": "int", + "brief": "The size of the message body in bytes.\n", + "examples": 1439, + "requirement_level": "recommended", + "note": "This can refer to both the compressed or uncompressed body size. If both sizes are known, the uncompressed\nbody size should be used.\n", + "stability": "stable" + }, + { + "name": "messaging.message.conversation_id", + "type": "string", + "brief": "The conversation ID identifying the conversation to which the message belongs, represented as a string. Sometimes called \"Correlation ID\".\n", + "examples": "MyConversationId", + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "messaging.message.envelope.size", + "type": "int", + "brief": "The size of the message body and metadata in bytes.\n", + "examples": 2738, + "requirement_level": "recommended", + "note": "This can refer to both the compressed or uncompressed size. If both sizes are known, the uncompressed\nsize should be used.\n", + "stability": "stable" + }, + { + "name": "messaging.message.id", + "type": "string", + "brief": "A value used by the messaging system as an identifier for the message, represented as a string.", + "examples": "452a7c7c7c7048c2f887f61572b18fc2", + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "messaging.operation", + "type": { + "members": [ + { + "id": "publish", + "value": "publish", + "brief": "One or more messages are provided for publishing to an intermediary. If a single message is published, the context of the \"Publish\" span can be used as the creation context and no \"Create\" span needs to be created.\n", + "stability": "stable" + }, + { + "id": "create", + "value": "create", + "brief": "A message is created. \"Create\" spans always refer to a single message and are used to provide a unique creation context for messages in batch publishing scenarios.\n", + "stability": "stable" + }, + { + "id": "receive", + "value": "receive", + "brief": "One or more messages are requested by a consumer. This operation refers to pull-based scenarios, where consumers explicitly call methods of messaging SDKs to receive messages.\n", + "stability": "stable" + }, + { + "id": "deliver", + "value": "deliver", + "brief": "One or more messages are passed to a consumer. This operation refers to push-based scenarios, where consumer register callbacks which get called by messaging SDKs.\n", + "stability": "stable" + } + ] }, - { - "name": "messaging.kafka.destination.partition", - "type": "int", - "brief": "Partition the message is sent to.\n", - "examples": 2, - "requirement_level": "recommended", - "stability": "stable" + "brief": "A string identifying the kind of messaging operation.\n", + "requirement_level": "recommended", + "note": "If a custom value is used, it MUST be of low cardinality.", + "stability": "stable" + }, + { + "name": "messaging.rabbitmq.destination.routing_key", + "type": "string", + "brief": "RabbitMQ message routing key.\n", + "examples": "myKey", + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "messaging.rocketmq.client_group", + "type": "string", + "brief": "Name of the RocketMQ producer/consumer group that is handling the message. The client type is identified by the SpanKind.\n", + "examples": "myConsumerGroup", + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "messaging.rocketmq.consumption_model", + "type": { + "members": [ + { + "id": "clustering", + "value": "clustering", + "brief": "Clustering consumption model", + "stability": "stable" + }, + { + "id": "broadcasting", + "value": "broadcasting", + "brief": "Broadcasting consumption model", + "stability": "stable" + } + ] }, - { - "name": "messaging.kafka.message.key", - "type": "string", - "brief": "Message keys in Kafka are used for grouping alike messages to ensure they're processed on the same partition. They differ from `messaging.message.id` in that they're not unique. If the key is `null`, the attribute MUST NOT be set.\n", - "examples": "myKey", - "requirement_level": "recommended", - "note": "If the key type is not string, it's string representation has to be supplied for the attribute. If the key has no unambiguous, canonical string form, don't include its value.\n", - "stability": "stable" - }, - { - "name": "messaging.kafka.message.offset", - "type": "int", - "brief": "The offset of a record in the corresponding Kafka partition.\n", - "examples": 42, - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "messaging.kafka.message.tombstone", - "type": "boolean", - "brief": "A boolean that is true if the message is a tombstone.", - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "messaging.message.body.size", - "type": "int", - "brief": "The size of the message body in bytes.\n", - "examples": 1439, - "requirement_level": "recommended", - "note": "This can refer to both the compressed or uncompressed body size. If both sizes are known, the uncompressed\nbody size should be used.\n", - "stability": "stable" - }, - { - "name": "messaging.message.conversation_id", - "type": "string", - "brief": "The conversation ID identifying the conversation to which the message belongs, represented as a string. Sometimes called \"Correlation ID\".\n", - "examples": "MyConversationId", - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "messaging.message.envelope.size", - "type": "int", - "brief": "The size of the message body and metadata in bytes.\n", - "examples": 2738, - "requirement_level": "recommended", - "note": "This can refer to both the compressed or uncompressed size. If both sizes are known, the uncompressed\nsize should be used.\n", - "stability": "stable" - }, - { - "name": "messaging.message.id", - "type": "string", - "brief": "A value used by the messaging system as an identifier for the message, represented as a string.", - "examples": "452a7c7c7c7048c2f887f61572b18fc2", - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "messaging.operation", - "type": { - "members": [ - { - "id": "publish", - "value": "publish", - "brief": "One or more messages are provided for publishing to an intermediary. If a single message is published, the context of the \"Publish\" span can be used as the creation context and no \"Create\" span needs to be created.\n", - "stability": "stable" - }, - { - "id": "create", - "value": "create", - "brief": "A message is created. \"Create\" spans always refer to a single message and are used to provide a unique creation context for messages in batch publishing scenarios.\n", - "stability": "stable" - }, - { - "id": "receive", - "value": "receive", - "brief": "One or more messages are requested by a consumer. This operation refers to pull-based scenarios, where consumers explicitly call methods of messaging SDKs to receive messages.\n", - "stability": "stable" - }, - { - "id": "deliver", - "value": "deliver", - "brief": "One or more messages are passed to a consumer. This operation refers to push-based scenarios, where consumer register callbacks which get called by messaging SDKs.\n", - "stability": "stable" - } - ] - }, - "brief": "A string identifying the kind of messaging operation.\n", - "requirement_level": "recommended", - "note": "If a custom value is used, it MUST be of low cardinality.", - "stability": "stable" - }, - { - "name": "messaging.rabbitmq.destination.routing_key", - "type": "string", - "brief": "RabbitMQ message routing key.\n", - "examples": "myKey", - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "messaging.rocketmq.client_group", - "type": "string", - "brief": "Name of the RocketMQ producer/consumer group that is handling the message. The client type is identified by the SpanKind.\n", - "examples": "myConsumerGroup", - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "messaging.rocketmq.consumption_model", - "type": { - "members": [ - { - "id": "clustering", - "value": "clustering", - "brief": "Clustering consumption model", - "stability": "stable" - }, - { - "id": "broadcasting", - "value": "broadcasting", - "brief": "Broadcasting consumption model", - "stability": "stable" - } - ] - }, - "brief": "Model of message consumption. This only applies to consumer spans.\n", - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "messaging.rocketmq.message.delay_time_level", - "type": "int", - "brief": "The delay time level for delay message, which determines the message delay time.\n", - "examples": 3, - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "messaging.rocketmq.message.delivery_timestamp", - "type": "int", - "brief": "The timestamp in milliseconds that the delay message is expected to be delivered to consumer.\n", - "examples": 1665987217045, - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "messaging.rocketmq.message.group", - "type": "string", - "brief": "It is essential for FIFO message. Messages that belong to the same message group are always processed one by one within the same consumer group.\n", - "examples": "myMessageGroup", - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "messaging.rocketmq.message.keys", - "type": "string[]", - "brief": "Key(s) of message, another way to mark message besides message id.\n", - "examples": [ - [ - "keyA" - ], - [ - "keyB" - ] + "brief": "Model of message consumption. This only applies to consumer spans.\n", + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "messaging.rocketmq.message.delay_time_level", + "type": "int", + "brief": "The delay time level for delay message, which determines the message delay time.\n", + "examples": 3, + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "messaging.rocketmq.message.delivery_timestamp", + "type": "int", + "brief": "The timestamp in milliseconds that the delay message is expected to be delivered to consumer.\n", + "examples": 1665987217045, + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "messaging.rocketmq.message.group", + "type": "string", + "brief": "It is essential for FIFO message. Messages that belong to the same message group are always processed one by one within the same consumer group.\n", + "examples": "myMessageGroup", + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "messaging.rocketmq.message.keys", + "type": "string[]", + "brief": "Key(s) of message, another way to mark message besides message id.\n", + "examples": [ + [ + "keyA" ], - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "messaging.rocketmq.message.tag", - "type": "string", - "brief": "The secondary classifier of message besides topic.\n", - "examples": "tagA", - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "messaging.rocketmq.message.type", - "type": { - "members": [ - { - "id": "normal", - "value": "normal", - "brief": "Normal message", - "stability": "stable" - }, - { - "id": "fifo", - "value": "fifo", - "brief": "FIFO message", - "stability": "stable" - }, - { - "id": "delay", - "value": "delay", - "brief": "Delay message", - "stability": "stable" - }, - { - "id": "transaction", - "value": "transaction", - "brief": "Transaction message", - "stability": "stable" - } - ] - }, - "brief": "Type of message.\n", - "requirement_level": "recommended", - "stability": "stable" + [ + "keyB" + ] + ], + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "messaging.rocketmq.message.tag", + "type": "string", + "brief": "The secondary classifier of message besides topic.\n", + "examples": "tagA", + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "messaging.rocketmq.message.type", + "type": { + "members": [ + { + "id": "normal", + "value": "normal", + "brief": "Normal message", + "stability": "stable" + }, + { + "id": "fifo", + "value": "fifo", + "brief": "FIFO message", + "stability": "stable" + }, + { + "id": "delay", + "value": "delay", + "brief": "Delay message", + "stability": "stable" + }, + { + "id": "transaction", + "value": "transaction", + "brief": "Transaction message", + "stability": "stable" + } + ] }, - { - "name": "messaging.rocketmq.namespace", - "type": "string", - "brief": "Namespace of RocketMQ resources, resources in different namespaces are individual.\n", - "examples": "myNamespace", - "requirement_level": "recommended", - "stability": "stable" + "brief": "Type of message.\n", + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "messaging.rocketmq.namespace", + "type": "string", + "brief": "Namespace of RocketMQ resources, resources in different namespaces are individual.\n", + "examples": "myNamespace", + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "messaging.system", + "type": { + "members": [ + { + "id": "activemq", + "value": "activemq", + "brief": "Apache ActiveMQ", + "stability": "stable" + }, + { + "id": "aws_sqs", + "value": "aws_sqs", + "brief": "Amazon Simple Queue Service (SQS)", + "stability": "stable" + }, + { + "id": "azure_eventgrid", + "value": "azure_eventgrid", + "brief": "Azure Event Grid", + "stability": "stable" + }, + { + "id": "azure_eventhubs", + "value": "azure_eventhubs", + "brief": "Azure Event Hubs", + "stability": "stable" + }, + { + "id": "azure_servicebus", + "value": "azure_servicebus", + "brief": "Azure Service Bus", + "stability": "stable" + }, + { + "id": "gcp_pubsub", + "value": "gcp_pubsub", + "brief": "Google Cloud Pub/Sub", + "stability": "stable" + }, + { + "id": "jms", + "value": "jms", + "brief": "Java Message Service", + "stability": "stable" + }, + { + "id": "kafka", + "value": "kafka", + "brief": "Apache Kafka", + "stability": "stable" + }, + { + "id": "rabbitmq", + "value": "rabbitmq", + "brief": "RabbitMQ", + "stability": "stable" + }, + { + "id": "rocketmq", + "value": "rocketmq", + "brief": "Apache RocketMQ", + "stability": "stable" + } + ] }, - { - "name": "messaging.system", - "type": { - "members": [ - { - "id": "activemq", - "value": "activemq", - "brief": "Apache ActiveMQ", - "stability": "stable" - }, - { - "id": "aws_sqs", - "value": "aws_sqs", - "brief": "Amazon Simple Queue Service (SQS)", - "stability": "stable" - }, - { - "id": "azure_eventgrid", - "value": "azure_eventgrid", - "brief": "Azure Event Grid", - "stability": "stable" - }, - { - "id": "azure_eventhubs", - "value": "azure_eventhubs", - "brief": "Azure Event Hubs", - "stability": "stable" - }, - { - "id": "azure_servicebus", - "value": "azure_servicebus", - "brief": "Azure Service Bus", - "stability": "stable" - }, - { - "id": "gcp_pubsub", - "value": "gcp_pubsub", - "brief": "Google Cloud Pub/Sub", - "stability": "stable" - }, - { - "id": "jms", - "value": "jms", - "brief": "Java Message Service", - "stability": "stable" - }, - { - "id": "kafka", - "value": "kafka", - "brief": "Apache Kafka", - "stability": "stable" - }, - { - "id": "rabbitmq", - "value": "rabbitmq", - "brief": "RabbitMQ", - "stability": "stable" - }, - { - "id": "rocketmq", - "value": "rocketmq", - "brief": "Apache RocketMQ", - "stability": "stable" - } - ] - }, - "brief": "An identifier for the messaging system being used. See below for a list of well-known identifiers.\n", - "requirement_level": "recommended", - "stability": "stable" - } - ] -} \ No newline at end of file + "brief": "An identifier for the messaging system being used. See below for a list of well-known identifiers.\n", + "requirement_level": "recommended", + "stability": "stable" + } +] diff --git a/crates/weaver_resolver/data/registry-test-3-extends/expected-attribute-catalog.json b/crates/weaver_resolver/data/registry-test-3-extends/expected-attribute-catalog.json index f3c429525..58db09f53 100644 --- a/crates/weaver_resolver/data/registry-test-3-extends/expected-attribute-catalog.json +++ b/crates/weaver_resolver/data/registry-test-3-extends/expected-attribute-catalog.json @@ -1,1420 +1,1418 @@ -{ - "attributes": [ - { - "name": "error.type", - "type": { - "members": [ - { - "id": "other", - "value": "_OTHER", - "brief": "A fallback error value to be used when the instrumentation doesn't define a custom value.\n", - "stability": "stable" - } - ] - }, - "brief": "Describes a class of error the operation ended with.\n", - "examples": [ - "amqp:decode-error", - "KAFKA_STORAGE_ERROR", - "channel-error" +[ + { + "name": "error.type", + "type": { + "members": [ + { + "id": "other", + "value": "_OTHER", + "brief": "A fallback error value to be used when the instrumentation doesn't define a custom value.\n", + "stability": "stable" + } + ] + }, + "brief": "Describes a class of error the operation ended with.\n", + "examples": [ + "amqp:decode-error", + "KAFKA_STORAGE_ERROR", + "channel-error" + ], + "requirement_level": { + "conditionally_required": "If and only if the messaging operation has failed." + }, + "note": "The `error.type` SHOULD be predictable and SHOULD have low cardinality.\nInstrumentations SHOULD document the list of errors they report.\n\nThe cardinality of `error.type` within one instrumentation library SHOULD be low.\nTelemetry consumers that aggregate data from multiple instrumentation libraries and applications\nshould be prepared for `error.type` to have high cardinality at query time when no\nadditional filters are applied.\n\nIf the operation has completed successfully, instrumentations SHOULD NOT set `error.type`.\n\nIf a specific domain defines its own set of error identifiers (such as HTTP or gRPC status codes),\nit's RECOMMENDED to:\n\n* Use a domain-specific attribute\n* Set `error.type` to capture all errors, regardless of whether they are defined within the domain-specific set or not\n\nAnd something more.", + "stability": "stable" + }, + { + "name": "error.type", + "type": { + "members": [ + { + "id": "other", + "value": "_OTHER", + "brief": "A fallback error value to be used when the instrumentation doesn't define a custom value.\n", + "stability": "stable" + } + ] + }, + "brief": "Describes a class of error the operation ended with.\n", + "examples": [ + "timeout", + "java.net.UnknownHostException", + "server_certificate_invalid", + "500" + ], + "requirement_level": "recommended", + "note": "The `error.type` SHOULD be predictable and SHOULD have low cardinality.\nInstrumentations SHOULD document the list of errors they report.\n\nThe cardinality of `error.type` within one instrumentation library SHOULD be low.\nTelemetry consumers that aggregate data from multiple instrumentation libraries and applications\nshould be prepared for `error.type` to have high cardinality at query time when no\nadditional filters are applied.\n\nIf the operation has completed successfully, instrumentations SHOULD NOT set `error.type`.\n\nIf a specific domain defines its own set of error identifiers (such as HTTP or gRPC status codes),\nit's RECOMMENDED to:\n\n* Use a domain-specific attribute\n* Set `error.type` to capture all errors, regardless of whether they are defined within the domain-specific set or not\n\nAnd something more.", + "stability": "stable" + }, + { + "name": "error.type", + "type": { + "members": [ + { + "id": "other", + "value": "_OTHER", + "brief": "A fallback error value to be used when the instrumentation doesn't define a custom value.\n", + "stability": "stable" + } + ] + }, + "brief": "Describes a class of error the operation ended with.\n", + "examples": [ + "timeout", + "java.net.UnknownHostException", + "server_certificate_invalid", + "500" + ], + "requirement_level": { + "conditionally_required": "If request has ended with an error." + }, + "note": "If the request fails with an error before response status code was sent or received,\n`error.type` SHOULD be set to exception type (its fully-qualified class name, if applicable)\nor a component-specific low cardinality error identifier.\n\nIf response status code was sent or received and status indicates an error according to [HTTP span status definition](/docs/http/http-spans.md),\n`error.type` SHOULD be set to the status code number (represented as a string), an exception type (if thrown) or a component-specific error identifier.\n\nThe `error.type` value SHOULD be predictable and SHOULD have low cardinality.\nInstrumentations SHOULD document the list of errors they report.\n\nThe cardinality of `error.type` within one instrumentation library SHOULD be low, but\ntelemetry consumers that aggregate data from multiple instrumentation libraries and applications\nshould be prepared for `error.type` to have high cardinality at query time, when no\nadditional filters are applied.\n\nIf the request has completed successfully, instrumentations SHOULD NOT set `error.type`.\n", + "stability": "stable" + }, + { + "name": "http.request.body.size", + "type": "int", + "brief": "The size of the request payload body in bytes. This is the number of bytes transferred excluding headers and is often, but not always, present as the [Content-Length](https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length) header. For requests using transport encoding, this should be the compressed size.\n", + "examples": 3495, + "requirement_level": "recommended", + "stability": "development" + }, + { + "name": "http.request.header", + "type": "template[string[]]", + "brief": "HTTP request headers, `` being the normalized HTTP Header name (lowercase), the value being the header values.\n", + "examples": [ + [ + "application/json" ], - "requirement_level": { - "conditionally_required": "If and only if the messaging operation has failed." - }, - "note": "The `error.type` SHOULD be predictable and SHOULD have low cardinality.\nInstrumentations SHOULD document the list of errors they report.\n\nThe cardinality of `error.type` within one instrumentation library SHOULD be low.\nTelemetry consumers that aggregate data from multiple instrumentation libraries and applications\nshould be prepared for `error.type` to have high cardinality at query time when no\nadditional filters are applied.\n\nIf the operation has completed successfully, instrumentations SHOULD NOT set `error.type`.\n\nIf a specific domain defines its own set of error identifiers (such as HTTP or gRPC status codes),\nit's RECOMMENDED to:\n\n* Use a domain-specific attribute\n* Set `error.type` to capture all errors, regardless of whether they are defined within the domain-specific set or not\n\nAnd something more.", - "stability": "stable" - }, - { - "name": "error.type", - "type": { - "members": [ - { - "id": "other", - "value": "_OTHER", - "brief": "A fallback error value to be used when the instrumentation doesn't define a custom value.\n", - "stability": "stable" - } - ] - }, - "brief": "Describes a class of error the operation ended with.\n", - "examples": [ - "timeout", - "java.net.UnknownHostException", - "server_certificate_invalid", - "500" - ], - "requirement_level": "recommended", - "note": "The `error.type` SHOULD be predictable and SHOULD have low cardinality.\nInstrumentations SHOULD document the list of errors they report.\n\nThe cardinality of `error.type` within one instrumentation library SHOULD be low.\nTelemetry consumers that aggregate data from multiple instrumentation libraries and applications\nshould be prepared for `error.type` to have high cardinality at query time when no\nadditional filters are applied.\n\nIf the operation has completed successfully, instrumentations SHOULD NOT set `error.type`.\n\nIf a specific domain defines its own set of error identifiers (such as HTTP or gRPC status codes),\nit's RECOMMENDED to:\n\n* Use a domain-specific attribute\n* Set `error.type` to capture all errors, regardless of whether they are defined within the domain-specific set or not\n\nAnd something more.", - "stability": "stable" - }, - { - "name": "error.type", - "type": { - "members": [ - { - "id": "other", - "value": "_OTHER", - "brief": "A fallback error value to be used when the instrumentation doesn't define a custom value.\n", - "stability": "stable" - } - ] - }, - "brief": "Describes a class of error the operation ended with.\n", - "examples": [ - "timeout", - "java.net.UnknownHostException", - "server_certificate_invalid", - "500" - ], - "requirement_level": { - "conditionally_required": "If request has ended with an error." - }, - "note": "If the request fails with an error before response status code was sent or received,\n`error.type` SHOULD be set to exception type (its fully-qualified class name, if applicable)\nor a component-specific low cardinality error identifier.\n\nIf response status code was sent or received and status indicates an error according to [HTTP span status definition](/docs/http/http-spans.md),\n`error.type` SHOULD be set to the status code number (represented as a string), an exception type (if thrown) or a component-specific error identifier.\n\nThe `error.type` value SHOULD be predictable and SHOULD have low cardinality.\nInstrumentations SHOULD document the list of errors they report.\n\nThe cardinality of `error.type` within one instrumentation library SHOULD be low, but\ntelemetry consumers that aggregate data from multiple instrumentation libraries and applications\nshould be prepared for `error.type` to have high cardinality at query time, when no\nadditional filters are applied.\n\nIf the request has completed successfully, instrumentations SHOULD NOT set `error.type`.\n", - "stability": "stable" - }, - { - "name": "http.request.body.size", - "type": "int", - "brief": "The size of the request payload body in bytes. This is the number of bytes transferred excluding headers and is often, but not always, present as the [Content-Length](https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length) header. For requests using transport encoding, this should be the compressed size.\n", - "examples": 3495, - "requirement_level": "recommended", - "stability": "development" - }, - { - "name": "http.request.header", - "type": "template[string[]]", - "brief": "HTTP request headers, `` being the normalized HTTP Header name (lowercase), the value being the header values.\n", - "examples": [ - [ - "application/json" - ], - [ - "1.2.3.4", - "1.2.3.5" - ] - ], - "requirement_level": "recommended", - "note": "Instrumentations SHOULD require an explicit configuration of which headers are to be captured. Including all request headers can be a security risk - explicit configuration helps avoid leaking sensitive information.\nThe `User-Agent` header is already captured in the `user_agent.original` attribute. Users MAY explicitly configure instrumentations to capture them even though it is not recommended.\nThe attribute value MUST consist of either multiple header values as an array of strings or a single-item array containing a possibly comma-concatenated string, depending on the way the HTTP library provides access to headers.\n", - "stability": "stable" - }, - { - "name": "http.request.method", - "type": { - "members": [ - { - "id": "connect", - "value": "CONNECT", - "brief": "CONNECT method.", - "stability": "stable" - }, - { - "id": "delete", - "value": "DELETE", - "brief": "DELETE method.", - "stability": "stable" - }, - { - "id": "get", - "value": "GET", - "brief": "GET method.", - "stability": "stable" - }, - { - "id": "head", - "value": "HEAD", - "brief": "HEAD method.", - "stability": "stable" - }, - { - "id": "options", - "value": "OPTIONS", - "brief": "OPTIONS method.", - "stability": "stable" - }, - { - "id": "patch", - "value": "PATCH", - "brief": "PATCH method.", - "stability": "stable" - }, - { - "id": "post", - "value": "POST", - "brief": "POST method.", - "stability": "stable" - }, - { - "id": "put", - "value": "PUT", - "brief": "PUT method.", - "stability": "stable" - }, - { - "id": "trace", - "value": "TRACE", - "brief": "TRACE method.", - "stability": "stable" - }, - { - "id": "other", - "value": "_OTHER", - "brief": "Any HTTP method that the instrumentation has no prior knowledge of.", - "stability": "stable" - } - ] - }, - "brief": "HTTP request method.", - "examples": [ - "GET", - "POST", - "HEAD" - ], - "requirement_level": "required", - "note": "HTTP request method value SHOULD be \"known\" to the instrumentation.\nBy default, this convention defines \"known\" methods as the ones listed in [RFC9110](https://www.rfc-editor.org/rfc/rfc9110.html#name-methods)\nand the PATCH method defined in [RFC5789](https://www.rfc-editor.org/rfc/rfc5789.html).\n\nIf the HTTP request method is not known to instrumentation, it MUST set the `http.request.method` attribute to `_OTHER`.\n\nIf the HTTP instrumentation could end up converting valid HTTP request methods to `_OTHER`, then it MUST provide a way to override\nthe list of known HTTP methods. If this override is done via environment variable, then the environment variable MUST be named\nOTEL_INSTRUMENTATION_HTTP_KNOWN_METHODS and support a comma-separated list of case-sensitive known HTTP methods\n(this list MUST be a full override of the default known method, it is not a list of known methods in addition to the defaults).\n\nHTTP method names are case-sensitive and `http.request.method` attribute value MUST match a known HTTP method name exactly.\nInstrumentations for specific web frameworks that consider HTTP methods to be case insensitive, SHOULD populate a canonical equivalent.\nTracing instrumentations that do so, MUST also set `http.request.method_original` to the original value.\n", - "stability": "stable" - }, - { - "name": "http.request.method", - "type": { - "members": [ - { - "id": "connect", - "value": "CONNECT", - "brief": "CONNECT method.", - "stability": "stable" - }, - { - "id": "delete", - "value": "DELETE", - "brief": "DELETE method.", - "stability": "stable" - }, - { - "id": "get", - "value": "GET", - "brief": "GET method.", - "stability": "stable" - }, - { - "id": "head", - "value": "HEAD", - "brief": "HEAD method.", - "stability": "stable" - }, - { - "id": "options", - "value": "OPTIONS", - "brief": "OPTIONS method.", - "stability": "stable" - }, - { - "id": "patch", - "value": "PATCH", - "brief": "PATCH method.", - "stability": "stable" - }, - { - "id": "post", - "value": "POST", - "brief": "POST method.", - "stability": "stable" - }, - { - "id": "put", - "value": "PUT", - "brief": "PUT method.", - "stability": "stable" - }, - { - "id": "trace", - "value": "TRACE", - "brief": "TRACE method.", - "stability": "stable" - }, - { - "id": "other", - "value": "_OTHER", - "brief": "Any HTTP method that the instrumentation has no prior knowledge of.", - "stability": "stable" - } - ] - }, - "brief": "HTTP request method.", - "examples": [ - "GET", - "POST", - "HEAD" - ], - "requirement_level": "recommended", - "note": "HTTP request method value SHOULD be \"known\" to the instrumentation.\nBy default, this convention defines \"known\" methods as the ones listed in [RFC9110](https://www.rfc-editor.org/rfc/rfc9110.html#name-methods)\nand the PATCH method defined in [RFC5789](https://www.rfc-editor.org/rfc/rfc5789.html).\n\nIf the HTTP request method is not known to instrumentation, it MUST set the `http.request.method` attribute to `_OTHER`.\n\nIf the HTTP instrumentation could end up converting valid HTTP request methods to `_OTHER`, then it MUST provide a way to override\nthe list of known HTTP methods. If this override is done via environment variable, then the environment variable MUST be named\nOTEL_INSTRUMENTATION_HTTP_KNOWN_METHODS and support a comma-separated list of case-sensitive known HTTP methods\n(this list MUST be a full override of the default known method, it is not a list of known methods in addition to the defaults).\n\nHTTP method names are case-sensitive and `http.request.method` attribute value MUST match a known HTTP method name exactly.\nInstrumentations for specific web frameworks that consider HTTP methods to be case insensitive, SHOULD populate a canonical equivalent.\nTracing instrumentations that do so, MUST also set `http.request.method_original` to the original value.\n", - "stability": "stable" - }, - { - "name": "http.request.method_original", - "type": "string", - "brief": "Original HTTP method sent by the client in the request line.", - "examples": [ - "GeT", - "ACL", - "foo" - ], - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "http.request.resend_count", - "type": "int", - "brief": "The ordinal number of request resending attempt (for any reason, including redirects).\n", - "examples": 3, - "requirement_level": "recommended", - "note": "The resend count SHOULD be updated each time an HTTP request gets resent by the client, regardless of what was the cause of the resending (e.g. redirection, authorization failure, 503 Server Unavailable, network issues, or any other).\n", - "stability": "stable" - }, - { - "name": "http.response.body.size", - "type": "int", - "brief": "The size of the response payload body in bytes. This is the number of bytes transferred excluding headers and is often, but not always, present as the [Content-Length](https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length) header. For requests using transport encoding, this should be the compressed size.\n", - "examples": 3495, - "requirement_level": "recommended", - "stability": "development" - }, - { - "name": "http.response.header", - "type": "template[string[]]", - "brief": "HTTP response headers, `` being the normalized HTTP Header name (lowercase), the value being the header values.\n", - "examples": [ - [ - "application/json" - ], - [ - "abc", - "def" - ] - ], - "requirement_level": "recommended", - "note": "Instrumentations SHOULD require an explicit configuration of which headers are to be captured. Including all response headers can be a security risk - explicit configuration helps avoid leaking sensitive information.\nUsers MAY explicitly configure instrumentations to capture them even though it is not recommended.\nThe attribute value MUST consist of either multiple header values as an array of strings or a single-item array containing a possibly comma-concatenated string, depending on the way the HTTP library provides access to headers.\n", - "stability": "stable" - }, - { - "name": "http.response.status_code", - "type": "int", - "brief": "[HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6).", - "examples": [ - 200 - ], - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "http.response.status_code", - "type": "int", - "brief": "[HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6).", - "examples": [ - 200 - ], - "requirement_level": { - "conditionally_required": "If and only if one was received/sent." - }, - "stability": "stable" - }, - { - "name": "http.route", - "type": "string", - "brief": "The matched route, that is, the path template in the format used by the respective server framework.\n", - "examples": [ - "/users/:userID?", - "{controller}/{action}/{id?}" - ], - "requirement_level": "recommended", - "note": "MUST NOT be populated when this is not supported by the HTTP server framework as the route attribute should have low-cardinality and the URI path can NOT substitute it.\nSHOULD include the [application root](/docs/http/http-spans.md#http-server-definitions) if there is one.", - "stability": "stable" - }, - { - "name": "http.route", - "type": "string", - "brief": "The matched route, that is, the path template in the format used by the respective server framework.\n", - "examples": [ - "/users/:userID?", - "{controller}/{action}/{id?}" - ], - "requirement_level": { - "conditionally_required": "If and only if it's available" - }, - "note": "MUST NOT be populated when this is not supported by the HTTP server framework as the route attribute should have low-cardinality and the URI path can NOT substitute it.\nSHOULD include the [application root](/docs/http/http-spans.md#http-server-definitions) if there is one.", - "stability": "stable" - }, - { - "name": "messaging.batch.message_count", - "type": "int", - "brief": "The number of messages sent, received, or processed in the scope of the batching operation.", - "examples": [ - 0, - 1, - 2 - ], - "requirement_level": "recommended", - "note": "Instrumentations SHOULD NOT set `messaging.batch.message_count` on spans that operate with a single message. When a messaging client library supports both batch and single-message API for the same operation, instrumentations SHOULD use `messaging.batch.message_count` for batching APIs and SHOULD NOT use it for single-message APIs.\n", - "stability": "stable" - }, - { - "name": "messaging.client_id", - "type": "string", - "brief": "A unique identifier for the client that consumes or produces a message.\n", - "examples": [ - "client-5", - "myhost@8742@s8083jm" - ], - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "messaging.destination.anonymous", - "type": "boolean", - "brief": "A boolean that is true if the message destination is anonymous (could be unnamed or have auto-generated name).", - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "messaging.destination.name", - "type": "string", - "brief": "The message destination name", - "examples": [ - "MyQueue", - "MyTopic" - ], - "requirement_level": "recommended", - "note": "Destination name SHOULD uniquely identify a specific queue, topic or other entity within the broker. If\nthe broker doesn't have such notion, the destination name SHOULD uniquely identify the broker.\n", - "stability": "stable" - }, - { - "name": "messaging.destination.name", - "type": "string", - "brief": "The message destination name", - "examples": [ - "MyQueue", - "MyTopic" - ], - "requirement_level": { - "conditionally_required": "if and only if `messaging.destination.name` is known to have low cardinality. Otherwise, `messaging.destination.template` MAY be populated." - }, - "note": "Destination name SHOULD uniquely identify a specific queue, topic or other entity within the broker. If\nthe broker doesn't have such notion, the destination name SHOULD uniquely identify the broker.\n", - "stability": "stable" - }, - { - "name": "messaging.destination.template", - "type": "string", - "brief": "Low cardinality representation of the messaging destination name", - "examples": [ - "/customers/{customerId}" - ], - "requirement_level": "recommended", - "note": "Destination names could be constructed from templates. An example would be a destination name involving a user name or product id. Although the destination name in this case is of high cardinality, the underlying template is of low cardinality and can be effectively used for grouping and aggregation.\n", - "stability": "stable" - }, - { - "name": "messaging.destination.template", - "type": "string", - "brief": "Low cardinality representation of the messaging destination name", - "examples": [ - "/customers/{customerId}" - ], - "requirement_level": { - "conditionally_required": "if available." - }, - "note": "Destination names could be constructed from templates. An example would be a destination name involving a user name or product id. Although the destination name in this case is of high cardinality, the underlying template is of low cardinality and can be effectively used for grouping and aggregation.\n", - "stability": "stable" - }, - { - "name": "messaging.destination.temporary", - "type": "boolean", - "brief": "A boolean that is true if the message destination is temporary and might not exist anymore after messages are processed.", - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "messaging.destination_publish.anonymous", - "type": "boolean", - "brief": "A boolean that is true if the publish message destination is anonymous (could be unnamed or have auto-generated name).", - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "messaging.destination_publish.name", - "type": "string", - "brief": "The name of the original destination the message was published to", - "examples": [ - "MyQueue", - "MyTopic" - ], - "requirement_level": "recommended", - "note": "The name SHOULD uniquely identify a specific queue, topic, or other entity within the broker. If\nthe broker doesn't have such notion, the original destination name SHOULD uniquely identify the broker.\n", - "stability": "stable" - }, - { - "name": "messaging.gcp_pubsub.message.ordering_key", - "type": "string", - "brief": "The ordering key for a given message. If the attribute is not present, the message does not have an ordering key.\n", - "examples": "ordering_key", - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "messaging.kafka.consumer.group", - "type": "string", - "brief": "Name of the Kafka Consumer Group that is handling the message. Only applies to consumers, not producers.\n", - "examples": "my-group", - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "messaging.kafka.destination.partition", - "type": "int", - "brief": "Partition the message is sent to.\n", - "examples": 2, - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "messaging.kafka.message.key", - "type": "string", - "brief": "Message keys in Kafka are used for grouping alike messages to ensure they're processed on the same partition. They differ from `messaging.message.id` in that they're not unique. If the key is `null`, the attribute MUST NOT be set.\n", - "examples": "myKey", - "requirement_level": "recommended", - "note": "If the key type is not string, it's string representation has to be supplied for the attribute. If the key has no unambiguous, canonical string form, don't include its value.\n", - "stability": "stable" - }, - { - "name": "messaging.kafka.message.offset", - "type": "int", - "brief": "The offset of a record in the corresponding Kafka partition.\n", - "examples": 42, - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "messaging.kafka.message.tombstone", - "type": "boolean", - "brief": "A boolean that is true if the message is a tombstone.", - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "messaging.message.body.size", - "type": "int", - "brief": "The size of the message body in bytes.\n", - "examples": 1439, - "requirement_level": "recommended", - "note": "This can refer to both the compressed or uncompressed body size. If both sizes are known, the uncompressed\nbody size should be used.\n", - "stability": "stable" - }, - { - "name": "messaging.message.conversation_id", - "type": "string", - "brief": "The conversation ID identifying the conversation to which the message belongs, represented as a string. Sometimes called \"Correlation ID\".\n", - "examples": "MyConversationId", - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "messaging.message.envelope.size", - "type": "int", - "brief": "The size of the message body and metadata in bytes.\n", - "examples": 2738, - "requirement_level": "recommended", - "note": "This can refer to both the compressed or uncompressed size. If both sizes are known, the uncompressed\nsize should be used.\n", - "stability": "stable" - }, - { - "name": "messaging.message.id", - "type": "string", - "brief": "A value used by the messaging system as an identifier for the message, represented as a string.", - "examples": "452a7c7c7c7048c2f887f61572b18fc2", - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "messaging.operation", - "type": { - "members": [ - { - "id": "publish", - "value": "publish", - "brief": "One or more messages are provided for publishing to an intermediary. If a single message is published, the context of the \"Publish\" span can be used as the creation context and no \"Create\" span needs to be created.\n", - "stability": "stable" - }, - { - "id": "create", - "value": "create", - "brief": "A message is created. \"Create\" spans always refer to a single message and are used to provide a unique creation context for messages in batch publishing scenarios.\n", - "stability": "stable" - }, - { - "id": "receive", - "value": "receive", - "brief": "One or more messages are requested by a consumer. This operation refers to pull-based scenarios, where consumers explicitly call methods of messaging SDKs to receive messages.\n", - "stability": "stable" - }, - { - "id": "deliver", - "value": "deliver", - "brief": "One or more messages are passed to a consumer. This operation refers to push-based scenarios, where consumer register callbacks which get called by messaging SDKs.\n", - "stability": "stable" - } - ] - }, - "brief": "A string identifying the kind of messaging operation.\n", - "requirement_level": "recommended", - "note": "If a custom value is used, it MUST be of low cardinality.", - "stability": "stable" - }, - { - "name": "messaging.rabbitmq.destination.routing_key", - "type": "string", - "brief": "RabbitMQ message routing key.\n", - "examples": "myKey", - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "messaging.rocketmq.client_group", - "type": "string", - "brief": "Name of the RocketMQ producer/consumer group that is handling the message. The client type is identified by the SpanKind.\n", - "examples": "myConsumerGroup", - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "messaging.rocketmq.consumption_model", - "type": { - "members": [ - { - "id": "clustering", - "value": "clustering", - "brief": "Clustering consumption model", - "stability": "stable" - }, - { - "id": "broadcasting", - "value": "broadcasting", - "brief": "Broadcasting consumption model", - "stability": "stable" - } - ] - }, - "brief": "Model of message consumption. This only applies to consumer spans.\n", - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "messaging.rocketmq.message.delay_time_level", - "type": "int", - "brief": "The delay time level for delay message, which determines the message delay time.\n", - "examples": 3, - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "messaging.rocketmq.message.delivery_timestamp", - "type": "int", - "brief": "The timestamp in milliseconds that the delay message is expected to be delivered to consumer.\n", - "examples": 1665987217045, - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "messaging.rocketmq.message.group", - "type": "string", - "brief": "It is essential for FIFO message. Messages that belong to the same message group are always processed one by one within the same consumer group.\n", - "examples": "myMessageGroup", - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "messaging.rocketmq.message.keys", - "type": "string[]", - "brief": "Key(s) of message, another way to mark message besides message id.\n", - "examples": [ - [ - "keyA" - ], - [ - "keyB" - ] - ], - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "messaging.rocketmq.message.tag", - "type": "string", - "brief": "The secondary classifier of message besides topic.\n", - "examples": "tagA", - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "messaging.rocketmq.message.type", - "type": { - "members": [ - { - "id": "normal", - "value": "normal", - "brief": "Normal message", - "stability": "stable" - }, - { - "id": "fifo", - "value": "fifo", - "brief": "FIFO message", - "stability": "stable" - }, - { - "id": "delay", - "value": "delay", - "brief": "Delay message", - "stability": "stable" - }, - { - "id": "transaction", - "value": "transaction", - "brief": "Transaction message", - "stability": "stable" - } - ] - }, - "brief": "Type of message.\n", - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "messaging.rocketmq.namespace", - "type": "string", - "brief": "Namespace of RocketMQ resources, resources in different namespaces are individual.\n", - "examples": "myNamespace", - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "messaging.system", - "type": { - "members": [ - { - "id": "activemq", - "value": "activemq", - "brief": "Apache ActiveMQ", - "stability": "stable" - }, - { - "id": "aws_sqs", - "value": "aws_sqs", - "brief": "Amazon Simple Queue Service (SQS)", - "stability": "stable" - }, - { - "id": "azure_eventgrid", - "value": "azure_eventgrid", - "brief": "Azure Event Grid", - "stability": "stable" - }, - { - "id": "azure_eventhubs", - "value": "azure_eventhubs", - "brief": "Azure Event Hubs", - "stability": "stable" - }, - { - "id": "azure_servicebus", - "value": "azure_servicebus", - "brief": "Azure Service Bus", - "stability": "stable" - }, - { - "id": "gcp_pubsub", - "value": "gcp_pubsub", - "brief": "Google Cloud Pub/Sub", - "stability": "stable" - }, - { - "id": "jms", - "value": "jms", - "brief": "Java Message Service", - "stability": "stable" - }, - { - "id": "kafka", - "value": "kafka", - "brief": "Apache Kafka", - "stability": "stable" - }, - { - "id": "rabbitmq", - "value": "rabbitmq", - "brief": "RabbitMQ", - "stability": "stable" - }, - { - "id": "rocketmq", - "value": "rocketmq", - "brief": "Apache RocketMQ", - "stability": "stable" - } - ] - }, - "brief": "An identifier for the messaging system being used. See below for a list of well-known identifiers.\n", - "requirement_level": "required", - "stability": "stable" - }, - { - "name": "messaging.system", - "type": { - "members": [ - { - "id": "activemq", - "value": "activemq", - "brief": "Apache ActiveMQ", - "stability": "stable" - }, - { - "id": "aws_sqs", - "value": "aws_sqs", - "brief": "Amazon Simple Queue Service (SQS)", - "stability": "stable" - }, - { - "id": "azure_eventgrid", - "value": "azure_eventgrid", - "brief": "Azure Event Grid", - "stability": "stable" - }, - { - "id": "azure_eventhubs", - "value": "azure_eventhubs", - "brief": "Azure Event Hubs", - "stability": "stable" - }, - { - "id": "azure_servicebus", - "value": "azure_servicebus", - "brief": "Azure Service Bus", - "stability": "stable" - }, - { - "id": "gcp_pubsub", - "value": "gcp_pubsub", - "brief": "Google Cloud Pub/Sub", - "stability": "stable" - }, - { - "id": "jms", - "value": "jms", - "brief": "Java Message Service", - "stability": "stable" - }, - { - "id": "kafka", - "value": "kafka", - "brief": "Apache Kafka", - "stability": "stable" - }, - { - "id": "rabbitmq", - "value": "rabbitmq", - "brief": "RabbitMQ", - "stability": "stable" - }, - { - "id": "rocketmq", - "value": "rocketmq", - "brief": "Apache RocketMQ", - "stability": "stable" - } - ] - }, - "brief": "An identifier for the messaging system being used. See below for a list of well-known identifiers.\n", - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "network.carrier.icc", - "type": "string", - "brief": "The ISO 3166-1 alpha-2 2-character country code associated with the mobile carrier network.", - "examples": "DE", - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "network.carrier.mcc", - "type": "string", - "brief": "The mobile carrier country code.", - "examples": "310", - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "network.carrier.mnc", - "type": "string", - "brief": "The mobile carrier network code.", - "examples": "001", - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "network.carrier.name", - "type": "string", - "brief": "The name of the mobile carrier.", - "examples": "sprint", - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "network.connection.subtype", - "type": { - "members": [ - { - "id": "gprs", - "value": "gprs", - "brief": "GPRS", - "stability": "stable" - }, - { - "id": "edge", - "value": "edge", - "brief": "EDGE", - "stability": "stable" - }, - { - "id": "umts", - "value": "umts", - "brief": "UMTS", - "stability": "stable" - }, - { - "id": "cdma", - "value": "cdma", - "brief": "CDMA", - "stability": "stable" - }, - { - "id": "evdo_0", - "value": "evdo_0", - "brief": "EVDO Rel. 0", - "stability": "stable" - }, - { - "id": "evdo_a", - "value": "evdo_a", - "brief": "EVDO Rev. A", - "stability": "stable" - }, - { - "id": "cdma2000_1xrtt", - "value": "cdma2000_1xrtt", - "brief": "CDMA2000 1XRTT", - "stability": "stable" - }, - { - "id": "hsdpa", - "value": "hsdpa", - "brief": "HSDPA", - "stability": "stable" - }, - { - "id": "hsupa", - "value": "hsupa", - "brief": "HSUPA", - "stability": "stable" - }, - { - "id": "hspa", - "value": "hspa", - "brief": "HSPA", - "stability": "stable" - }, - { - "id": "iden", - "value": "iden", - "brief": "IDEN", - "stability": "stable" - }, - { - "id": "evdo_b", - "value": "evdo_b", - "brief": "EVDO Rev. B", - "stability": "stable" - }, - { - "id": "lte", - "value": "lte", - "brief": "LTE", - "stability": "stable" - }, - { - "id": "ehrpd", - "value": "ehrpd", - "brief": "EHRPD", - "stability": "stable" - }, - { - "id": "hspap", - "value": "hspap", - "brief": "HSPAP", - "stability": "stable" - }, - { - "id": "gsm", - "value": "gsm", - "brief": "GSM", - "stability": "stable" - }, - { - "id": "td_scdma", - "value": "td_scdma", - "brief": "TD-SCDMA", - "stability": "stable" - }, - { - "id": "iwlan", - "value": "iwlan", - "brief": "IWLAN", - "stability": "stable" - }, - { - "id": "nr", - "value": "nr", - "brief": "5G NR (New Radio)", - "stability": "stable" - }, - { - "id": "nrnsa", - "value": "nrnsa", - "brief": "5G NRNSA (New Radio Non-Standalone)", - "stability": "stable" - }, - { - "id": "lte_ca", - "value": "lte_ca", - "brief": "LTE CA", - "stability": "stable" - } - ] - }, - "brief": "This describes more details regarding the connection.type. It may be the type of cell technology connection, but it could be used for describing details about a wifi connection.", - "examples": "LTE", - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "network.connection.type", - "type": { - "members": [ - { - "id": "wifi", - "value": "wifi", - "stability": "stable" - }, - { - "id": "wired", - "value": "wired", - "stability": "stable" - }, - { - "id": "cell", - "value": "cell", - "stability": "stable" - }, - { - "id": "unavailable", - "value": "unavailable", - "stability": "stable" - }, - { - "id": "unknown", - "value": "unknown", - "stability": "stable" - } - ] - }, - "brief": "The internet connection type.", - "examples": "wifi", - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "network.io.direction", - "type": { - "members": [ - { - "id": "transmit", - "value": "transmit", - "stability": "stable" - }, - { - "id": "receive", - "value": "receive", - "stability": "stable" - } - ] - }, - "brief": "The network IO operation direction.", - "examples": [ - "transmit" - ], - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "network.local.address", - "type": "string", - "brief": "Local address of the network connection - IP address or Unix domain socket name.", - "examples": [ - "10.1.2.80", - "/tmp/my.sock" - ], - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "network.local.port", - "type": "int", - "brief": "Local port number of the network connection.", - "examples": [ - 65123 + [ + "1.2.3.4", + "1.2.3.5" + ] + ], + "requirement_level": "recommended", + "note": "Instrumentations SHOULD require an explicit configuration of which headers are to be captured. Including all request headers can be a security risk - explicit configuration helps avoid leaking sensitive information.\nThe `User-Agent` header is already captured in the `user_agent.original` attribute. Users MAY explicitly configure instrumentations to capture them even though it is not recommended.\nThe attribute value MUST consist of either multiple header values as an array of strings or a single-item array containing a possibly comma-concatenated string, depending on the way the HTTP library provides access to headers.\n", + "stability": "stable" + }, + { + "name": "http.request.method", + "type": { + "members": [ + { + "id": "connect", + "value": "CONNECT", + "brief": "CONNECT method.", + "stability": "stable" + }, + { + "id": "delete", + "value": "DELETE", + "brief": "DELETE method.", + "stability": "stable" + }, + { + "id": "get", + "value": "GET", + "brief": "GET method.", + "stability": "stable" + }, + { + "id": "head", + "value": "HEAD", + "brief": "HEAD method.", + "stability": "stable" + }, + { + "id": "options", + "value": "OPTIONS", + "brief": "OPTIONS method.", + "stability": "stable" + }, + { + "id": "patch", + "value": "PATCH", + "brief": "PATCH method.", + "stability": "stable" + }, + { + "id": "post", + "value": "POST", + "brief": "POST method.", + "stability": "stable" + }, + { + "id": "put", + "value": "PUT", + "brief": "PUT method.", + "stability": "stable" + }, + { + "id": "trace", + "value": "TRACE", + "brief": "TRACE method.", + "stability": "stable" + }, + { + "id": "other", + "value": "_OTHER", + "brief": "Any HTTP method that the instrumentation has no prior knowledge of.", + "stability": "stable" + } + ] + }, + "brief": "HTTP request method.", + "examples": [ + "GET", + "POST", + "HEAD" + ], + "requirement_level": "required", + "note": "HTTP request method value SHOULD be \"known\" to the instrumentation.\nBy default, this convention defines \"known\" methods as the ones listed in [RFC9110](https://www.rfc-editor.org/rfc/rfc9110.html#name-methods)\nand the PATCH method defined in [RFC5789](https://www.rfc-editor.org/rfc/rfc5789.html).\n\nIf the HTTP request method is not known to instrumentation, it MUST set the `http.request.method` attribute to `_OTHER`.\n\nIf the HTTP instrumentation could end up converting valid HTTP request methods to `_OTHER`, then it MUST provide a way to override\nthe list of known HTTP methods. If this override is done via environment variable, then the environment variable MUST be named\nOTEL_INSTRUMENTATION_HTTP_KNOWN_METHODS and support a comma-separated list of case-sensitive known HTTP methods\n(this list MUST be a full override of the default known method, it is not a list of known methods in addition to the defaults).\n\nHTTP method names are case-sensitive and `http.request.method` attribute value MUST match a known HTTP method name exactly.\nInstrumentations for specific web frameworks that consider HTTP methods to be case insensitive, SHOULD populate a canonical equivalent.\nTracing instrumentations that do so, MUST also set `http.request.method_original` to the original value.\n", + "stability": "stable" + }, + { + "name": "http.request.method", + "type": { + "members": [ + { + "id": "connect", + "value": "CONNECT", + "brief": "CONNECT method.", + "stability": "stable" + }, + { + "id": "delete", + "value": "DELETE", + "brief": "DELETE method.", + "stability": "stable" + }, + { + "id": "get", + "value": "GET", + "brief": "GET method.", + "stability": "stable" + }, + { + "id": "head", + "value": "HEAD", + "brief": "HEAD method.", + "stability": "stable" + }, + { + "id": "options", + "value": "OPTIONS", + "brief": "OPTIONS method.", + "stability": "stable" + }, + { + "id": "patch", + "value": "PATCH", + "brief": "PATCH method.", + "stability": "stable" + }, + { + "id": "post", + "value": "POST", + "brief": "POST method.", + "stability": "stable" + }, + { + "id": "put", + "value": "PUT", + "brief": "PUT method.", + "stability": "stable" + }, + { + "id": "trace", + "value": "TRACE", + "brief": "TRACE method.", + "stability": "stable" + }, + { + "id": "other", + "value": "_OTHER", + "brief": "Any HTTP method that the instrumentation has no prior knowledge of.", + "stability": "stable" + } + ] + }, + "brief": "HTTP request method.", + "examples": [ + "GET", + "POST", + "HEAD" + ], + "requirement_level": "recommended", + "note": "HTTP request method value SHOULD be \"known\" to the instrumentation.\nBy default, this convention defines \"known\" methods as the ones listed in [RFC9110](https://www.rfc-editor.org/rfc/rfc9110.html#name-methods)\nand the PATCH method defined in [RFC5789](https://www.rfc-editor.org/rfc/rfc5789.html).\n\nIf the HTTP request method is not known to instrumentation, it MUST set the `http.request.method` attribute to `_OTHER`.\n\nIf the HTTP instrumentation could end up converting valid HTTP request methods to `_OTHER`, then it MUST provide a way to override\nthe list of known HTTP methods. If this override is done via environment variable, then the environment variable MUST be named\nOTEL_INSTRUMENTATION_HTTP_KNOWN_METHODS and support a comma-separated list of case-sensitive known HTTP methods\n(this list MUST be a full override of the default known method, it is not a list of known methods in addition to the defaults).\n\nHTTP method names are case-sensitive and `http.request.method` attribute value MUST match a known HTTP method name exactly.\nInstrumentations for specific web frameworks that consider HTTP methods to be case insensitive, SHOULD populate a canonical equivalent.\nTracing instrumentations that do so, MUST also set `http.request.method_original` to the original value.\n", + "stability": "stable" + }, + { + "name": "http.request.method_original", + "type": "string", + "brief": "Original HTTP method sent by the client in the request line.", + "examples": [ + "GeT", + "ACL", + "foo" + ], + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "http.request.resend_count", + "type": "int", + "brief": "The ordinal number of request resending attempt (for any reason, including redirects).\n", + "examples": 3, + "requirement_level": "recommended", + "note": "The resend count SHOULD be updated each time an HTTP request gets resent by the client, regardless of what was the cause of the resending (e.g. redirection, authorization failure, 503 Server Unavailable, network issues, or any other).\n", + "stability": "stable" + }, + { + "name": "http.response.body.size", + "type": "int", + "brief": "The size of the response payload body in bytes. This is the number of bytes transferred excluding headers and is often, but not always, present as the [Content-Length](https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length) header. For requests using transport encoding, this should be the compressed size.\n", + "examples": 3495, + "requirement_level": "recommended", + "stability": "development" + }, + { + "name": "http.response.header", + "type": "template[string[]]", + "brief": "HTTP response headers, `` being the normalized HTTP Header name (lowercase), the value being the header values.\n", + "examples": [ + [ + "application/json" ], - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "network.peer.address", - "type": "string", - "brief": "Peer address of the network connection - IP address or Unix domain socket name.", - "examples": [ - "10.1.2.80", - "/tmp/my.sock" - ], - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "network.peer.port", - "type": "int", - "brief": "Peer port number of the network connection.", - "examples": [ - 65123 - ], - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "network.protocol.name", - "type": "string", - "brief": "[OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent.", - "examples": [ - "amqp", - "http", - "mqtt" - ], - "requirement_level": "recommended", - "note": "The value SHOULD be normalized to lowercase.", - "stability": "stable" - }, - { - "name": "network.protocol.name", - "type": "string", - "brief": "[OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent.", - "examples": [ - "amqp", - "mqtt" - ], - "tag": "connection-level", - "requirement_level": "recommended", - "note": "The value SHOULD be normalized to lowercase.", - "stability": "stable" - }, - { - "name": "network.protocol.name", - "type": "string", - "brief": "[OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent.", - "examples": [ - "http", - "spdy" - ], - "requirement_level": { - "conditionally_required": "If not `http` and `network.protocol.version` is set." - }, - "note": "The value SHOULD be normalized to lowercase.", - "stability": "stable" - }, - { - "name": "network.protocol.version", - "type": "string", - "brief": "Version of the protocol specified in `network.protocol.name`.", - "examples": "3.1.1", - "requirement_level": "recommended", - "note": "`network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`.\n", - "stability": "stable" - }, - { - "name": "network.protocol.version", - "type": "string", - "brief": "Version of the protocol specified in `network.protocol.name`.", - "examples": "3.1.1", - "tag": "connection-level", - "requirement_level": "recommended", - "note": "`network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`.\n", - "stability": "stable" - }, - { - "name": "network.protocol.version", - "type": "string", - "brief": "Version of the protocol specified in `network.protocol.name`.", - "examples": [ - "1.0", - "1.1", - "2", - "3" - ], - "requirement_level": "recommended", - "note": "`network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`.\n", - "stability": "stable" - }, - { - "name": "network.transport", - "type": { - "members": [ - { - "id": "tcp", - "value": "tcp", - "brief": "TCP", - "stability": "stable" - }, - { - "id": "udp", - "value": "udp", - "brief": "UDP", - "stability": "stable" - }, - { - "id": "pipe", - "value": "pipe", - "brief": "Named or anonymous pipe.", - "stability": "stable" - }, - { - "id": "unix", - "value": "unix", - "brief": "Unix domain socket", - "stability": "stable" - } - ] - }, - "brief": "[OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication).\n", - "examples": [ - "tcp", - "udp" - ], - "requirement_level": "recommended", - "note": "The value SHOULD be normalized to lowercase.\n\nConsider always setting the transport when setting a port number, since\na port number is ambiguous without knowing the transport. For example\ndifferent processes could be listening on TCP port 12345 and UDP port 12345.\n", - "stability": "stable" - }, - { - "name": "network.type", - "type": { - "members": [ - { - "id": "ipv4", - "value": "ipv4", - "brief": "IPv4", - "stability": "stable" - }, - { - "id": "ipv6", - "value": "ipv6", - "brief": "IPv6", - "stability": "stable" - } - ] - }, - "brief": "[OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent.", - "examples": [ - "ipv4", - "ipv6" - ], - "requirement_level": "recommended", - "note": "The value SHOULD be normalized to lowercase.", - "stability": "stable" - }, - { - "name": "server.address", - "type": "string", - "brief": "Host identifier of the [\"URI origin\"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to.\n", - "examples": [ - "example.com", - "10.1.2.80", - "/tmp/my.sock" - ], - "requirement_level": "required", - "note": "If an HTTP client request is explicitly made to an IP address, e.g. `http://x.x.x.x:8080`, then `server.address` SHOULD be the IP address `x.x.x.x`. A DNS lookup SHOULD NOT be used.\n", - "stability": "stable" - }, - { - "name": "server.address", - "type": "string", - "brief": "Name of the local HTTP server that received the request.\n", - "examples": [ - "example.com", - "10.1.2.80", - "/tmp/my.sock" - ], - "requirement_level": "recommended", - "note": "See [Setting `server.address` and `server.port` attributes](/docs/http/http-spans.md#setting-serveraddress-and-serverport-attributes).\n", - "stability": "stable" - }, - { - "name": "server.address", - "type": "string", - "brief": "Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name.", - "examples": [ - "example.com", - "10.1.2.80", - "/tmp/my.sock" - ], - "requirement_level": "recommended", - "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.\n", - "stability": "stable" - }, - { - "name": "server.address", - "type": "string", - "brief": "Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name.", - "examples": [ - "example.com", - "10.1.2.80", - "/tmp/my.sock" - ], - "requirement_level": { - "conditionally_required": "If available." - }, - "note": "This should be the IP/hostname of the broker (or other network-level peer) this specific message is sent to/received from.\n", - "stability": "stable" - }, - { - "name": "server.port", - "type": "int", - "brief": "Port identifier of the [\"URI origin\"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to.\n", - "examples": [ - 80, - 8080, - 443 - ], - "requirement_level": "required", - "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.\n", - "stability": "stable" - }, - { - "name": "server.port", - "type": "int", - "brief": "Port of the local HTTP server that received the request.\n", - "examples": [ - 80, - 8080, - 443 - ], - "requirement_level": { - "conditionally_required": "If `server.address` is set." - }, - "note": "See [Setting `server.address` and `server.port` attributes](/docs/http/http-spans.md#setting-serveraddress-and-serverport-attributes).\n", - "stability": "stable" - }, - { - "name": "server.port", - "type": "int", - "brief": "Server port number.", - "examples": [ - 80, - 8080, - 443 - ], - "requirement_level": "recommended", - "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.\n", - "stability": "stable" - }, - { - "name": "url.fragment", - "type": "string", - "brief": "The [URI fragment](https://www.rfc-editor.org/rfc/rfc3986#section-3.5) component", - "examples": [ - "SemConv" - ], - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "url.full", - "type": "string", - "brief": "Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986)", - "examples": [ - "https://www.foo.bar/search?q=OpenTelemetry#SemConv", - "//localhost" - ], - "requirement_level": "recommended", - "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.\n`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/`.\n`url.full` SHOULD capture the absolute URL when it is available (or can be reconstructed) and SHOULD NOT be validated or modified except for sanitizing purposes.\n", - "stability": "stable" - }, - { - "name": "url.path", - "type": "string", - "brief": "The [URI path](https://www.rfc-editor.org/rfc/rfc3986#section-3.3) component", - "examples": [ - "/search" - ], - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "url.query", - "type": "string", - "brief": "The [URI query](https://www.rfc-editor.org/rfc/rfc3986#section-3.4) component", - "examples": [ - "q=OpenTelemetry" - ], - "requirement_level": "recommended", - "note": "Sensitive content provided in query string SHOULD be scrubbed when instrumentations can identify it.", - "stability": "stable" - }, - { - "name": "url.scheme", - "type": "string", - "brief": "The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol.", - "examples": [ - "http", - "https" - ], - "requirement_level": "required", - "note": "The scheme of the original client request, if known (e.g. from [Forwarded#proto](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded#proto), [X-Forwarded-Proto](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-Proto), or a similar header). Otherwise, the scheme of the immediate peer request.", - "stability": "stable" - }, - { - "name": "url.scheme", - "type": "string", - "brief": "The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol.", - "examples": [ - "http", - "https" - ], - "requirement_level": "opt_in", - "stability": "stable" - }, - { - "name": "url.scheme", - "type": "string", - "brief": "The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol.", - "examples": [ - "https", - "ftp", - "telnet" + [ + "abc", + "def" + ] + ], + "requirement_level": "recommended", + "note": "Instrumentations SHOULD require an explicit configuration of which headers are to be captured. Including all response headers can be a security risk - explicit configuration helps avoid leaking sensitive information.\nUsers MAY explicitly configure instrumentations to capture them even though it is not recommended.\nThe attribute value MUST consist of either multiple header values as an array of strings or a single-item array containing a possibly comma-concatenated string, depending on the way the HTTP library provides access to headers.\n", + "stability": "stable" + }, + { + "name": "http.response.status_code", + "type": "int", + "brief": "[HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6).", + "examples": [ + 200 + ], + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "http.response.status_code", + "type": "int", + "brief": "[HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6).", + "examples": [ + 200 + ], + "requirement_level": { + "conditionally_required": "If and only if one was received/sent." + }, + "stability": "stable" + }, + { + "name": "http.route", + "type": "string", + "brief": "The matched route, that is, the path template in the format used by the respective server framework.\n", + "examples": [ + "/users/:userID?", + "{controller}/{action}/{id?}" + ], + "requirement_level": "recommended", + "note": "MUST NOT be populated when this is not supported by the HTTP server framework as the route attribute should have low-cardinality and the URI path can NOT substitute it.\nSHOULD include the [application root](/docs/http/http-spans.md#http-server-definitions) if there is one.", + "stability": "stable" + }, + { + "name": "http.route", + "type": "string", + "brief": "The matched route, that is, the path template in the format used by the respective server framework.\n", + "examples": [ + "/users/:userID?", + "{controller}/{action}/{id?}" + ], + "requirement_level": { + "conditionally_required": "If and only if it's available" + }, + "note": "MUST NOT be populated when this is not supported by the HTTP server framework as the route attribute should have low-cardinality and the URI path can NOT substitute it.\nSHOULD include the [application root](/docs/http/http-spans.md#http-server-definitions) if there is one.", + "stability": "stable" + }, + { + "name": "messaging.batch.message_count", + "type": "int", + "brief": "The number of messages sent, received, or processed in the scope of the batching operation.", + "examples": [ + 0, + 1, + 2 + ], + "requirement_level": "recommended", + "note": "Instrumentations SHOULD NOT set `messaging.batch.message_count` on spans that operate with a single message. When a messaging client library supports both batch and single-message API for the same operation, instrumentations SHOULD use `messaging.batch.message_count` for batching APIs and SHOULD NOT use it for single-message APIs.\n", + "stability": "stable" + }, + { + "name": "messaging.client_id", + "type": "string", + "brief": "A unique identifier for the client that consumes or produces a message.\n", + "examples": [ + "client-5", + "myhost@8742@s8083jm" + ], + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "messaging.destination.anonymous", + "type": "boolean", + "brief": "A boolean that is true if the message destination is anonymous (could be unnamed or have auto-generated name).", + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "messaging.destination.name", + "type": "string", + "brief": "The message destination name", + "examples": [ + "MyQueue", + "MyTopic" + ], + "requirement_level": "recommended", + "note": "Destination name SHOULD uniquely identify a specific queue, topic or other entity within the broker. If\nthe broker doesn't have such notion, the destination name SHOULD uniquely identify the broker.\n", + "stability": "stable" + }, + { + "name": "messaging.destination.name", + "type": "string", + "brief": "The message destination name", + "examples": [ + "MyQueue", + "MyTopic" + ], + "requirement_level": { + "conditionally_required": "if and only if `messaging.destination.name` is known to have low cardinality. Otherwise, `messaging.destination.template` MAY be populated." + }, + "note": "Destination name SHOULD uniquely identify a specific queue, topic or other entity within the broker. If\nthe broker doesn't have such notion, the destination name SHOULD uniquely identify the broker.\n", + "stability": "stable" + }, + { + "name": "messaging.destination.template", + "type": "string", + "brief": "Low cardinality representation of the messaging destination name", + "examples": [ + "/customers/{customerId}" + ], + "requirement_level": "recommended", + "note": "Destination names could be constructed from templates. An example would be a destination name involving a user name or product id. Although the destination name in this case is of high cardinality, the underlying template is of low cardinality and can be effectively used for grouping and aggregation.\n", + "stability": "stable" + }, + { + "name": "messaging.destination.template", + "type": "string", + "brief": "Low cardinality representation of the messaging destination name", + "examples": [ + "/customers/{customerId}" + ], + "requirement_level": { + "conditionally_required": "if available." + }, + "note": "Destination names could be constructed from templates. An example would be a destination name involving a user name or product id. Although the destination name in this case is of high cardinality, the underlying template is of low cardinality and can be effectively used for grouping and aggregation.\n", + "stability": "stable" + }, + { + "name": "messaging.destination.temporary", + "type": "boolean", + "brief": "A boolean that is true if the message destination is temporary and might not exist anymore after messages are processed.", + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "messaging.destination_publish.anonymous", + "type": "boolean", + "brief": "A boolean that is true if the publish message destination is anonymous (could be unnamed or have auto-generated name).", + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "messaging.destination_publish.name", + "type": "string", + "brief": "The name of the original destination the message was published to", + "examples": [ + "MyQueue", + "MyTopic" + ], + "requirement_level": "recommended", + "note": "The name SHOULD uniquely identify a specific queue, topic, or other entity within the broker. If\nthe broker doesn't have such notion, the original destination name SHOULD uniquely identify the broker.\n", + "stability": "stable" + }, + { + "name": "messaging.gcp_pubsub.message.ordering_key", + "type": "string", + "brief": "The ordering key for a given message. If the attribute is not present, the message does not have an ordering key.\n", + "examples": "ordering_key", + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "messaging.kafka.consumer.group", + "type": "string", + "brief": "Name of the Kafka Consumer Group that is handling the message. Only applies to consumers, not producers.\n", + "examples": "my-group", + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "messaging.kafka.destination.partition", + "type": "int", + "brief": "Partition the message is sent to.\n", + "examples": 2, + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "messaging.kafka.message.key", + "type": "string", + "brief": "Message keys in Kafka are used for grouping alike messages to ensure they're processed on the same partition. They differ from `messaging.message.id` in that they're not unique. If the key is `null`, the attribute MUST NOT be set.\n", + "examples": "myKey", + "requirement_level": "recommended", + "note": "If the key type is not string, it's string representation has to be supplied for the attribute. If the key has no unambiguous, canonical string form, don't include its value.\n", + "stability": "stable" + }, + { + "name": "messaging.kafka.message.offset", + "type": "int", + "brief": "The offset of a record in the corresponding Kafka partition.\n", + "examples": 42, + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "messaging.kafka.message.tombstone", + "type": "boolean", + "brief": "A boolean that is true if the message is a tombstone.", + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "messaging.message.body.size", + "type": "int", + "brief": "The size of the message body in bytes.\n", + "examples": 1439, + "requirement_level": "recommended", + "note": "This can refer to both the compressed or uncompressed body size. If both sizes are known, the uncompressed\nbody size should be used.\n", + "stability": "stable" + }, + { + "name": "messaging.message.conversation_id", + "type": "string", + "brief": "The conversation ID identifying the conversation to which the message belongs, represented as a string. Sometimes called \"Correlation ID\".\n", + "examples": "MyConversationId", + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "messaging.message.envelope.size", + "type": "int", + "brief": "The size of the message body and metadata in bytes.\n", + "examples": 2738, + "requirement_level": "recommended", + "note": "This can refer to both the compressed or uncompressed size. If both sizes are known, the uncompressed\nsize should be used.\n", + "stability": "stable" + }, + { + "name": "messaging.message.id", + "type": "string", + "brief": "A value used by the messaging system as an identifier for the message, represented as a string.", + "examples": "452a7c7c7c7048c2f887f61572b18fc2", + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "messaging.operation", + "type": { + "members": [ + { + "id": "publish", + "value": "publish", + "brief": "One or more messages are provided for publishing to an intermediary. If a single message is published, the context of the \"Publish\" span can be used as the creation context and no \"Create\" span needs to be created.\n", + "stability": "stable" + }, + { + "id": "create", + "value": "create", + "brief": "A message is created. \"Create\" spans always refer to a single message and are used to provide a unique creation context for messages in batch publishing scenarios.\n", + "stability": "stable" + }, + { + "id": "receive", + "value": "receive", + "brief": "One or more messages are requested by a consumer. This operation refers to pull-based scenarios, where consumers explicitly call methods of messaging SDKs to receive messages.\n", + "stability": "stable" + }, + { + "id": "deliver", + "value": "deliver", + "brief": "One or more messages are passed to a consumer. This operation refers to push-based scenarios, where consumer register callbacks which get called by messaging SDKs.\n", + "stability": "stable" + } + ] + }, + "brief": "A string identifying the kind of messaging operation.\n", + "requirement_level": "recommended", + "note": "If a custom value is used, it MUST be of low cardinality.", + "stability": "stable" + }, + { + "name": "messaging.rabbitmq.destination.routing_key", + "type": "string", + "brief": "RabbitMQ message routing key.\n", + "examples": "myKey", + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "messaging.rocketmq.client_group", + "type": "string", + "brief": "Name of the RocketMQ producer/consumer group that is handling the message. The client type is identified by the SpanKind.\n", + "examples": "myConsumerGroup", + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "messaging.rocketmq.consumption_model", + "type": { + "members": [ + { + "id": "clustering", + "value": "clustering", + "brief": "Clustering consumption model", + "stability": "stable" + }, + { + "id": "broadcasting", + "value": "broadcasting", + "brief": "Broadcasting consumption model", + "stability": "stable" + } + ] + }, + "brief": "Model of message consumption. This only applies to consumer spans.\n", + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "messaging.rocketmq.message.delay_time_level", + "type": "int", + "brief": "The delay time level for delay message, which determines the message delay time.\n", + "examples": 3, + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "messaging.rocketmq.message.delivery_timestamp", + "type": "int", + "brief": "The timestamp in milliseconds that the delay message is expected to be delivered to consumer.\n", + "examples": 1665987217045, + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "messaging.rocketmq.message.group", + "type": "string", + "brief": "It is essential for FIFO message. Messages that belong to the same message group are always processed one by one within the same consumer group.\n", + "examples": "myMessageGroup", + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "messaging.rocketmq.message.keys", + "type": "string[]", + "brief": "Key(s) of message, another way to mark message besides message id.\n", + "examples": [ + [ + "keyA" ], - "requirement_level": "recommended", - "stability": "stable" - } - ] -} \ No newline at end of file + [ + "keyB" + ] + ], + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "messaging.rocketmq.message.tag", + "type": "string", + "brief": "The secondary classifier of message besides topic.\n", + "examples": "tagA", + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "messaging.rocketmq.message.type", + "type": { + "members": [ + { + "id": "normal", + "value": "normal", + "brief": "Normal message", + "stability": "stable" + }, + { + "id": "fifo", + "value": "fifo", + "brief": "FIFO message", + "stability": "stable" + }, + { + "id": "delay", + "value": "delay", + "brief": "Delay message", + "stability": "stable" + }, + { + "id": "transaction", + "value": "transaction", + "brief": "Transaction message", + "stability": "stable" + } + ] + }, + "brief": "Type of message.\n", + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "messaging.rocketmq.namespace", + "type": "string", + "brief": "Namespace of RocketMQ resources, resources in different namespaces are individual.\n", + "examples": "myNamespace", + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "messaging.system", + "type": { + "members": [ + { + "id": "activemq", + "value": "activemq", + "brief": "Apache ActiveMQ", + "stability": "stable" + }, + { + "id": "aws_sqs", + "value": "aws_sqs", + "brief": "Amazon Simple Queue Service (SQS)", + "stability": "stable" + }, + { + "id": "azure_eventgrid", + "value": "azure_eventgrid", + "brief": "Azure Event Grid", + "stability": "stable" + }, + { + "id": "azure_eventhubs", + "value": "azure_eventhubs", + "brief": "Azure Event Hubs", + "stability": "stable" + }, + { + "id": "azure_servicebus", + "value": "azure_servicebus", + "brief": "Azure Service Bus", + "stability": "stable" + }, + { + "id": "gcp_pubsub", + "value": "gcp_pubsub", + "brief": "Google Cloud Pub/Sub", + "stability": "stable" + }, + { + "id": "jms", + "value": "jms", + "brief": "Java Message Service", + "stability": "stable" + }, + { + "id": "kafka", + "value": "kafka", + "brief": "Apache Kafka", + "stability": "stable" + }, + { + "id": "rabbitmq", + "value": "rabbitmq", + "brief": "RabbitMQ", + "stability": "stable" + }, + { + "id": "rocketmq", + "value": "rocketmq", + "brief": "Apache RocketMQ", + "stability": "stable" + } + ] + }, + "brief": "An identifier for the messaging system being used. See below for a list of well-known identifiers.\n", + "requirement_level": "required", + "stability": "stable" + }, + { + "name": "messaging.system", + "type": { + "members": [ + { + "id": "activemq", + "value": "activemq", + "brief": "Apache ActiveMQ", + "stability": "stable" + }, + { + "id": "aws_sqs", + "value": "aws_sqs", + "brief": "Amazon Simple Queue Service (SQS)", + "stability": "stable" + }, + { + "id": "azure_eventgrid", + "value": "azure_eventgrid", + "brief": "Azure Event Grid", + "stability": "stable" + }, + { + "id": "azure_eventhubs", + "value": "azure_eventhubs", + "brief": "Azure Event Hubs", + "stability": "stable" + }, + { + "id": "azure_servicebus", + "value": "azure_servicebus", + "brief": "Azure Service Bus", + "stability": "stable" + }, + { + "id": "gcp_pubsub", + "value": "gcp_pubsub", + "brief": "Google Cloud Pub/Sub", + "stability": "stable" + }, + { + "id": "jms", + "value": "jms", + "brief": "Java Message Service", + "stability": "stable" + }, + { + "id": "kafka", + "value": "kafka", + "brief": "Apache Kafka", + "stability": "stable" + }, + { + "id": "rabbitmq", + "value": "rabbitmq", + "brief": "RabbitMQ", + "stability": "stable" + }, + { + "id": "rocketmq", + "value": "rocketmq", + "brief": "Apache RocketMQ", + "stability": "stable" + } + ] + }, + "brief": "An identifier for the messaging system being used. See below for a list of well-known identifiers.\n", + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "network.carrier.icc", + "type": "string", + "brief": "The ISO 3166-1 alpha-2 2-character country code associated with the mobile carrier network.", + "examples": "DE", + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "network.carrier.mcc", + "type": "string", + "brief": "The mobile carrier country code.", + "examples": "310", + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "network.carrier.mnc", + "type": "string", + "brief": "The mobile carrier network code.", + "examples": "001", + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "network.carrier.name", + "type": "string", + "brief": "The name of the mobile carrier.", + "examples": "sprint", + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "network.connection.subtype", + "type": { + "members": [ + { + "id": "gprs", + "value": "gprs", + "brief": "GPRS", + "stability": "stable" + }, + { + "id": "edge", + "value": "edge", + "brief": "EDGE", + "stability": "stable" + }, + { + "id": "umts", + "value": "umts", + "brief": "UMTS", + "stability": "stable" + }, + { + "id": "cdma", + "value": "cdma", + "brief": "CDMA", + "stability": "stable" + }, + { + "id": "evdo_0", + "value": "evdo_0", + "brief": "EVDO Rel. 0", + "stability": "stable" + }, + { + "id": "evdo_a", + "value": "evdo_a", + "brief": "EVDO Rev. A", + "stability": "stable" + }, + { + "id": "cdma2000_1xrtt", + "value": "cdma2000_1xrtt", + "brief": "CDMA2000 1XRTT", + "stability": "stable" + }, + { + "id": "hsdpa", + "value": "hsdpa", + "brief": "HSDPA", + "stability": "stable" + }, + { + "id": "hsupa", + "value": "hsupa", + "brief": "HSUPA", + "stability": "stable" + }, + { + "id": "hspa", + "value": "hspa", + "brief": "HSPA", + "stability": "stable" + }, + { + "id": "iden", + "value": "iden", + "brief": "IDEN", + "stability": "stable" + }, + { + "id": "evdo_b", + "value": "evdo_b", + "brief": "EVDO Rev. B", + "stability": "stable" + }, + { + "id": "lte", + "value": "lte", + "brief": "LTE", + "stability": "stable" + }, + { + "id": "ehrpd", + "value": "ehrpd", + "brief": "EHRPD", + "stability": "stable" + }, + { + "id": "hspap", + "value": "hspap", + "brief": "HSPAP", + "stability": "stable" + }, + { + "id": "gsm", + "value": "gsm", + "brief": "GSM", + "stability": "stable" + }, + { + "id": "td_scdma", + "value": "td_scdma", + "brief": "TD-SCDMA", + "stability": "stable" + }, + { + "id": "iwlan", + "value": "iwlan", + "brief": "IWLAN", + "stability": "stable" + }, + { + "id": "nr", + "value": "nr", + "brief": "5G NR (New Radio)", + "stability": "stable" + }, + { + "id": "nrnsa", + "value": "nrnsa", + "brief": "5G NRNSA (New Radio Non-Standalone)", + "stability": "stable" + }, + { + "id": "lte_ca", + "value": "lte_ca", + "brief": "LTE CA", + "stability": "stable" + } + ] + }, + "brief": "This describes more details regarding the connection.type. It may be the type of cell technology connection, but it could be used for describing details about a wifi connection.", + "examples": "LTE", + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "network.connection.type", + "type": { + "members": [ + { + "id": "wifi", + "value": "wifi", + "stability": "stable" + }, + { + "id": "wired", + "value": "wired", + "stability": "stable" + }, + { + "id": "cell", + "value": "cell", + "stability": "stable" + }, + { + "id": "unavailable", + "value": "unavailable", + "stability": "stable" + }, + { + "id": "unknown", + "value": "unknown", + "stability": "stable" + } + ] + }, + "brief": "The internet connection type.", + "examples": "wifi", + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "network.io.direction", + "type": { + "members": [ + { + "id": "transmit", + "value": "transmit", + "stability": "stable" + }, + { + "id": "receive", + "value": "receive", + "stability": "stable" + } + ] + }, + "brief": "The network IO operation direction.", + "examples": [ + "transmit" + ], + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "network.local.address", + "type": "string", + "brief": "Local address of the network connection - IP address or Unix domain socket name.", + "examples": [ + "10.1.2.80", + "/tmp/my.sock" + ], + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "network.local.port", + "type": "int", + "brief": "Local port number of the network connection.", + "examples": [ + 65123 + ], + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "network.peer.address", + "type": "string", + "brief": "Peer address of the network connection - IP address or Unix domain socket name.", + "examples": [ + "10.1.2.80", + "/tmp/my.sock" + ], + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "network.peer.port", + "type": "int", + "brief": "Peer port number of the network connection.", + "examples": [ + 65123 + ], + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "network.protocol.name", + "type": "string", + "brief": "[OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent.", + "examples": [ + "amqp", + "http", + "mqtt" + ], + "requirement_level": "recommended", + "note": "The value SHOULD be normalized to lowercase.", + "stability": "stable" + }, + { + "name": "network.protocol.name", + "type": "string", + "brief": "[OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent.", + "examples": [ + "amqp", + "mqtt" + ], + "tag": "connection-level", + "requirement_level": "recommended", + "note": "The value SHOULD be normalized to lowercase.", + "stability": "stable" + }, + { + "name": "network.protocol.name", + "type": "string", + "brief": "[OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent.", + "examples": [ + "http", + "spdy" + ], + "requirement_level": { + "conditionally_required": "If not `http` and `network.protocol.version` is set." + }, + "note": "The value SHOULD be normalized to lowercase.", + "stability": "stable" + }, + { + "name": "network.protocol.version", + "type": "string", + "brief": "Version of the protocol specified in `network.protocol.name`.", + "examples": "3.1.1", + "requirement_level": "recommended", + "note": "`network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`.\n", + "stability": "stable" + }, + { + "name": "network.protocol.version", + "type": "string", + "brief": "Version of the protocol specified in `network.protocol.name`.", + "examples": "3.1.1", + "tag": "connection-level", + "requirement_level": "recommended", + "note": "`network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`.\n", + "stability": "stable" + }, + { + "name": "network.protocol.version", + "type": "string", + "brief": "Version of the protocol specified in `network.protocol.name`.", + "examples": [ + "1.0", + "1.1", + "2", + "3" + ], + "requirement_level": "recommended", + "note": "`network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`.\n", + "stability": "stable" + }, + { + "name": "network.transport", + "type": { + "members": [ + { + "id": "tcp", + "value": "tcp", + "brief": "TCP", + "stability": "stable" + }, + { + "id": "udp", + "value": "udp", + "brief": "UDP", + "stability": "stable" + }, + { + "id": "pipe", + "value": "pipe", + "brief": "Named or anonymous pipe.", + "stability": "stable" + }, + { + "id": "unix", + "value": "unix", + "brief": "Unix domain socket", + "stability": "stable" + } + ] + }, + "brief": "[OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication).\n", + "examples": [ + "tcp", + "udp" + ], + "requirement_level": "recommended", + "note": "The value SHOULD be normalized to lowercase.\n\nConsider always setting the transport when setting a port number, since\na port number is ambiguous without knowing the transport. For example\ndifferent processes could be listening on TCP port 12345 and UDP port 12345.\n", + "stability": "stable" + }, + { + "name": "network.type", + "type": { + "members": [ + { + "id": "ipv4", + "value": "ipv4", + "brief": "IPv4", + "stability": "stable" + }, + { + "id": "ipv6", + "value": "ipv6", + "brief": "IPv6", + "stability": "stable" + } + ] + }, + "brief": "[OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent.", + "examples": [ + "ipv4", + "ipv6" + ], + "requirement_level": "recommended", + "note": "The value SHOULD be normalized to lowercase.", + "stability": "stable" + }, + { + "name": "server.address", + "type": "string", + "brief": "Host identifier of the [\"URI origin\"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to.\n", + "examples": [ + "example.com", + "10.1.2.80", + "/tmp/my.sock" + ], + "requirement_level": "required", + "note": "If an HTTP client request is explicitly made to an IP address, e.g. `http://x.x.x.x:8080`, then `server.address` SHOULD be the IP address `x.x.x.x`. A DNS lookup SHOULD NOT be used.\n", + "stability": "stable" + }, + { + "name": "server.address", + "type": "string", + "brief": "Name of the local HTTP server that received the request.\n", + "examples": [ + "example.com", + "10.1.2.80", + "/tmp/my.sock" + ], + "requirement_level": "recommended", + "note": "See [Setting `server.address` and `server.port` attributes](/docs/http/http-spans.md#setting-serveraddress-and-serverport-attributes).\n", + "stability": "stable" + }, + { + "name": "server.address", + "type": "string", + "brief": "Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name.", + "examples": [ + "example.com", + "10.1.2.80", + "/tmp/my.sock" + ], + "requirement_level": "recommended", + "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.\n", + "stability": "stable" + }, + { + "name": "server.address", + "type": "string", + "brief": "Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name.", + "examples": [ + "example.com", + "10.1.2.80", + "/tmp/my.sock" + ], + "requirement_level": { + "conditionally_required": "If available." + }, + "note": "This should be the IP/hostname of the broker (or other network-level peer) this specific message is sent to/received from.\n", + "stability": "stable" + }, + { + "name": "server.port", + "type": "int", + "brief": "Port identifier of the [\"URI origin\"](https://www.rfc-editor.org/rfc/rfc9110.html#name-uri-origin) HTTP request is sent to.\n", + "examples": [ + 80, + 8080, + 443 + ], + "requirement_level": "required", + "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.\n", + "stability": "stable" + }, + { + "name": "server.port", + "type": "int", + "brief": "Port of the local HTTP server that received the request.\n", + "examples": [ + 80, + 8080, + 443 + ], + "requirement_level": { + "conditionally_required": "If `server.address` is set." + }, + "note": "See [Setting `server.address` and `server.port` attributes](/docs/http/http-spans.md#setting-serveraddress-and-serverport-attributes).\n", + "stability": "stable" + }, + { + "name": "server.port", + "type": "int", + "brief": "Server port number.", + "examples": [ + 80, + 8080, + 443 + ], + "requirement_level": "recommended", + "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.\n", + "stability": "stable" + }, + { + "name": "url.fragment", + "type": "string", + "brief": "The [URI fragment](https://www.rfc-editor.org/rfc/rfc3986#section-3.5) component", + "examples": [ + "SemConv" + ], + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "url.full", + "type": "string", + "brief": "Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986)", + "examples": [ + "https://www.foo.bar/search?q=OpenTelemetry#SemConv", + "//localhost" + ], + "requirement_level": "recommended", + "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.\n`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/`.\n`url.full` SHOULD capture the absolute URL when it is available (or can be reconstructed) and SHOULD NOT be validated or modified except for sanitizing purposes.\n", + "stability": "stable" + }, + { + "name": "url.path", + "type": "string", + "brief": "The [URI path](https://www.rfc-editor.org/rfc/rfc3986#section-3.3) component", + "examples": [ + "/search" + ], + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "url.query", + "type": "string", + "brief": "The [URI query](https://www.rfc-editor.org/rfc/rfc3986#section-3.4) component", + "examples": [ + "q=OpenTelemetry" + ], + "requirement_level": "recommended", + "note": "Sensitive content provided in query string SHOULD be scrubbed when instrumentations can identify it.", + "stability": "stable" + }, + { + "name": "url.scheme", + "type": "string", + "brief": "The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol.", + "examples": [ + "http", + "https" + ], + "requirement_level": "required", + "note": "The scheme of the original client request, if known (e.g. from [Forwarded#proto](https://developer.mozilla.org/docs/Web/HTTP/Headers/Forwarded#proto), [X-Forwarded-Proto](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Forwarded-Proto), or a similar header). Otherwise, the scheme of the immediate peer request.", + "stability": "stable" + }, + { + "name": "url.scheme", + "type": "string", + "brief": "The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol.", + "examples": [ + "http", + "https" + ], + "requirement_level": "opt_in", + "stability": "stable" + }, + { + "name": "url.scheme", + "type": "string", + "brief": "The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol.", + "examples": [ + "https", + "ftp", + "telnet" + ], + "requirement_level": "recommended", + "stability": "stable" + } +] diff --git a/crates/weaver_resolver/data/registry-test-4-events/expected-attribute-catalog.json b/crates/weaver_resolver/data/registry-test-4-events/expected-attribute-catalog.json index a0806005b..6c7c7d9bc 100644 --- a/crates/weaver_resolver/data/registry-test-4-events/expected-attribute-catalog.json +++ b/crates/weaver_resolver/data/registry-test-4-events/expected-attribute-catalog.json @@ -1,321 +1,319 @@ -{ - "attributes": [ - { - "name": "android.state", - "type": { - "members": [ - { - "id": "created", - "value": "created", - "brief": "Any time before Activity.onResume() or, if the app has no Activity, Context.startService() has been called in the app for the first time.\n", - "stability": "stable" - }, - { - "id": "background", - "value": "background", - "brief": "Any time after Activity.onPause() or, if the app has no Activity, Context.stopService() has been called when the app was in the foreground state.\n", - "stability": "stable" - }, - { - "id": "foreground", - "value": "foreground", - "brief": "Any time after Activity.onResume() or, if the app has no Activity, Context.startService() has been called when the app was in either the created or background states.", - "stability": "stable" - } - ] - }, - "brief": "This attribute represents the state the application has transitioned into at the occurrence of the event.\n", - "requirement_level": "required", - "note": "The Android lifecycle states are defined in [Activity lifecycle callbacks](https://developer.android.com/guide/components/activities/activity-lifecycle#lc), and from which the `OS identifiers` are derived.\n", - "stability": "stable" +[ + { + "name": "android.state", + "type": { + "members": [ + { + "id": "created", + "value": "created", + "brief": "Any time before Activity.onResume() or, if the app has no Activity, Context.startService() has been called in the app for the first time.\n", + "stability": "stable" + }, + { + "id": "background", + "value": "background", + "brief": "Any time after Activity.onPause() or, if the app has no Activity, Context.stopService() has been called when the app was in the foreground state.\n", + "stability": "stable" + }, + { + "id": "foreground", + "value": "foreground", + "brief": "Any time after Activity.onResume() or, if the app has no Activity, Context.startService() has been called when the app was in either the created or background states.", + "stability": "stable" + } + ] }, - { - "name": "browser.brands", - "type": "string[]", - "brief": "Array of brand name and version separated by a space", - "examples": [ - [ - " Not A;Brand 99", - "Chromium 99", - "Chrome 99" - ] - ], - "requirement_level": "recommended", - "note": "This value is intended to be taken from the [UA client hints API](https://wicg.github.io/ua-client-hints/#interface) (`navigator.userAgentData.brands`).\n", - "stability": "stable" + "brief": "This attribute represents the state the application has transitioned into at the occurrence of the event.\n", + "requirement_level": "required", + "note": "The Android lifecycle states are defined in [Activity lifecycle callbacks](https://developer.android.com/guide/components/activities/activity-lifecycle#lc), and from which the `OS identifiers` are derived.\n", + "stability": "stable" + }, + { + "name": "browser.brands", + "type": "string[]", + "brief": "Array of brand name and version separated by a space", + "examples": [ + [ + " Not A;Brand 99", + "Chromium 99", + "Chrome 99" + ] + ], + "requirement_level": "recommended", + "note": "This value is intended to be taken from the [UA client hints API](https://wicg.github.io/ua-client-hints/#interface) (`navigator.userAgentData.brands`).\n", + "stability": "stable" + }, + { + "name": "browser.language", + "type": "string", + "brief": "Preferred language of the user using the browser", + "examples": [ + "en", + "en-US", + "en-AU", + "fr", + "fr-FR" + ], + "requirement_level": "recommended", + "note": "This value is intended to be taken from the Navigator API `navigator.language`.\n", + "stability": "stable" + }, + { + "name": "browser.mobile", + "type": "boolean", + "brief": "A boolean that is true if the browser is running on a mobile device", + "requirement_level": "recommended", + "note": "This value is intended to be taken from the [UA client hints API](https://wicg.github.io/ua-client-hints/#interface) (`navigator.userAgentData.mobile`). If unavailable, this attribute SHOULD be left unset.\n", + "stability": "stable" + }, + { + "name": "browser.platform", + "type": "string", + "brief": "The platform on which the browser is running", + "examples": [ + "Windows", + "macOS", + "Android", + "iOS", + "Linux" + ], + "requirement_level": "recommended", + "note": "This value is intended to be taken from the [UA client hints API](https://wicg.github.io/ua-client-hints/#interface) (`navigator.userAgentData.platform`). \n", + "stability": "stable" + }, + { + "name": "client.address", + "type": "string", + "brief": "Test Client address ....", + "examples": [ + "client.example.com", + "10.1.2.80", + "/tmp/my.sock" + ], + "requirement_level": "recommended", + "note": "Test client address note\n", + "stability": "stable" + }, + { + "name": "client.name", + "type": "string", + "brief": "The name of the client that reported the exception.\n", + "examples": [ + "myclient" + ], + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "client.port", + "type": "int", + "brief": "Client port number.", + "examples": [ + 65123 + ], + "requirement_level": "recommended", + "note": "Test client port", + "stability": "stable" + }, + { + "name": "exception.escaped", + "type": "boolean", + "brief": "SHOULD be set to true if the exception event is recorded at a point where it is known that the exception is escaping the scope of the span.\n", + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "exception.message", + "type": "string", + "brief": "The exception message.", + "examples": [ + "Division by zero", + "Can't convert 'int' object to str implicitly" + ], + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "exception.message", + "type": "string", + "brief": "The exception message.", + "examples": [ + "Division by zero", + "Can't convert 'int' object to str implicitly" + ], + "requirement_level": { + "conditionally_required": "Required if `exception.type` is not set, recommended otherwise." }, - { - "name": "browser.language", - "type": "string", - "brief": "Preferred language of the user using the browser", - "examples": [ - "en", - "en-US", - "en-AU", - "fr", - "fr-FR" - ], - "requirement_level": "recommended", - "note": "This value is intended to be taken from the Navigator API `navigator.language`.\n", - "stability": "stable" + "stability": "stable" + }, + { + "name": "exception.stacktrace", + "type": "string", + "brief": ".", + "examples": "Exception in thread \"main\" java.lang.RuntimeException: Test exception\\n", + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "exception.type", + "type": "string", + "brief": "The type of the exception (its fully-qualified class name, if applicable).\n", + "examples": [ + "java.net.ConnectException", + "OSError" + ], + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "exception.type", + "type": "string", + "brief": "The type of the exception (its fully-qualified class name, if applicable).\n", + "examples": [ + "java.net.ConnectException", + "OSError" + ], + "requirement_level": { + "conditionally_required": "Required if `exception.message` is not set, recommended otherwise." }, - { - "name": "browser.mobile", - "type": "boolean", - "brief": "A boolean that is true if the browser is running on a mobile device", - "requirement_level": "recommended", - "note": "This value is intended to be taken from the [UA client hints API](https://wicg.github.io/ua-client-hints/#interface) (`navigator.userAgentData.mobile`). If unavailable, this attribute SHOULD be left unset.\n", - "stability": "stable" + "stability": "stable" + }, + { + "name": "feature_flag.key", + "type": "string", + "brief": "The unique identifier of the feature flag.", + "examples": [ + "logo-color" + ], + "requirement_level": "required", + "stability": "stable" + }, + { + "name": "feature_flag.provider_name", + "type": "string", + "brief": "The name of the service provider that performs the flag evaluation.", + "examples": [ + "Flag Manager" + ], + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "feature_flag.variant", + "type": "string", + "brief": "SHOULD be a semantic identifier for a value. If one is unavailable, a stringified version of the value can be used.\n", + "examples": [ + "red", + "true", + "on" + ], + "requirement_level": "recommended", + "note": "A semantic identifier, commonly referred to as a variant, provides a means\nfor referring to a value without including the value itself. This can\nprovide additional context for understanding the meaning behind a value.\nFor example, the variant `red` maybe be used for the value `#c05543`.\n\nA stringified version of the value can be used in situations where a\nsemantic identifier is unavailable. String representation of the value\nshould be determined by the implementer.", + "stability": "stable" + }, + { + "name": "ios.state", + "type": { + "members": [ + { + "id": "active", + "value": "active", + "brief": "The app has become `active`. Associated with UIKit notification `applicationDidBecomeActive`.\n", + "stability": "stable" + }, + { + "id": "inactive", + "value": "inactive", + "brief": "The app is now `inactive`. Associated with UIKit notification `applicationWillResignActive`.\n", + "stability": "stable" + }, + { + "id": "background", + "value": "background", + "brief": "The app is now in the background. This value is associated with UIKit notification `applicationDidEnterBackground`.\n", + "stability": "stable" + }, + { + "id": "foreground", + "value": "foreground", + "brief": "The app is now in the foreground. This value is associated with UIKit notification `applicationWillEnterForeground`.\n", + "stability": "stable" + }, + { + "id": "terminate", + "value": "terminate", + "brief": "The app is about to terminate. Associated with UIKit notification `applicationWillTerminate`.\n", + "stability": "stable" + } + ] }, - { - "name": "browser.platform", - "type": "string", - "brief": "The platform on which the browser is running", - "examples": [ - "Windows", - "macOS", - "Android", - "iOS", - "Linux" - ], - "requirement_level": "recommended", - "note": "This value is intended to be taken from the [UA client hints API](https://wicg.github.io/ua-client-hints/#interface) (`navigator.userAgentData.platform`). \n", - "stability": "stable" + "brief": "This attribute represents the state the application has transitioned into at the occurrence of the event.\n", + "requirement_level": "required", + "note": "The iOS lifecycle states are defined in the [UIApplicationDelegate documentation](https://developer.apple.com/documentation/uikit/uiapplicationdelegate#1656902), and from which the `OS terminology` column values are derived.\n", + "stability": "stable" + }, + { + "name": "test_attr.event.attr", + "type": "string", + "brief": "Just making sure the referenced attributes are defined", + "examples": "some value", + "requirement_level": "recommended", + "note": "Test value.", + "stability": "stable" + }, + { + "name": "test_attr.event.attr", + "type": "string", + "brief": "Just making sure the referenced attributes are defined", + "examples": "some value", + "requirement_level": { + "conditionally_required": "if and only if corresponding event is enabled" }, - { - "name": "client.address", - "type": "string", - "brief": "Test Client address ....", - "examples": [ - "client.example.com", - "10.1.2.80", - "/tmp/my.sock" - ], - "requirement_level": "recommended", - "note": "Test client address note\n", - "stability": "stable" + "note": "test attribute\n", + "stability": "stable" + }, + { + "name": "test_attr.http.url", + "type": "string", + "brief": "The Url", + "examples": [ + "https://example.com" + ], + "requirement_level": "recommended", + "note": "Test url value.", + "stability": "stable" + }, + { + "name": "test_attr.platform", + "type": "string", + "brief": "The browser platform", + "examples": [ + "Windows", + "macOS", + "Android" + ], + "requirement_level": "recommended", + "note": "Test value.", + "stability": "stable" + }, + { + "name": "test_attr.session.id", + "type": "string", + "brief": "The session id", + "examples": "127836abcdef98", + "requirement_level": "recommended", + "note": "Test value.", + "stability": "stable" + }, + { + "name": "test_attr.session.id", + "type": "string", + "brief": "The session id", + "examples": "127836abcdef98", + "requirement_level": { + "conditionally_required": "if and only if corresponding event is enabled" }, - { - "name": "client.name", - "type": "string", - "brief": "The name of the client that reported the exception.\n", - "examples": [ - "myclient" - ], - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "client.port", - "type": "int", - "brief": "Client port number.", - "examples": [ - 65123 - ], - "requirement_level": "recommended", - "note": "Test client port", - "stability": "stable" - }, - { - "name": "exception.escaped", - "type": "boolean", - "brief": "SHOULD be set to true if the exception event is recorded at a point where it is known that the exception is escaping the scope of the span.\n", - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "exception.message", - "type": "string", - "brief": "The exception message.", - "examples": [ - "Division by zero", - "Can't convert 'int' object to str implicitly" - ], - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "exception.message", - "type": "string", - "brief": "The exception message.", - "examples": [ - "Division by zero", - "Can't convert 'int' object to str implicitly" - ], - "requirement_level": { - "conditionally_required": "Required if `exception.type` is not set, recommended otherwise." - }, - "stability": "stable" - }, - { - "name": "exception.stacktrace", - "type": "string", - "brief": ".", - "examples": "Exception in thread \"main\" java.lang.RuntimeException: Test exception\\n", - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "exception.type", - "type": "string", - "brief": "The type of the exception (its fully-qualified class name, if applicable).\n", - "examples": [ - "java.net.ConnectException", - "OSError" - ], - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "exception.type", - "type": "string", - "brief": "The type of the exception (its fully-qualified class name, if applicable).\n", - "examples": [ - "java.net.ConnectException", - "OSError" - ], - "requirement_level": { - "conditionally_required": "Required if `exception.message` is not set, recommended otherwise." - }, - "stability": "stable" - }, - { - "name": "feature_flag.key", - "type": "string", - "brief": "The unique identifier of the feature flag.", - "examples": [ - "logo-color" - ], - "requirement_level": "required", - "stability": "stable" - }, - { - "name": "feature_flag.provider_name", - "type": "string", - "brief": "The name of the service provider that performs the flag evaluation.", - "examples": [ - "Flag Manager" - ], - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "feature_flag.variant", - "type": "string", - "brief": "SHOULD be a semantic identifier for a value. If one is unavailable, a stringified version of the value can be used.\n", - "examples": [ - "red", - "true", - "on" - ], - "requirement_level": "recommended", - "note": "A semantic identifier, commonly referred to as a variant, provides a means\nfor referring to a value without including the value itself. This can\nprovide additional context for understanding the meaning behind a value.\nFor example, the variant `red` maybe be used for the value `#c05543`.\n\nA stringified version of the value can be used in situations where a\nsemantic identifier is unavailable. String representation of the value\nshould be determined by the implementer.", - "stability": "stable" - }, - { - "name": "ios.state", - "type": { - "members": [ - { - "id": "active", - "value": "active", - "brief": "The app has become `active`. Associated with UIKit notification `applicationDidBecomeActive`.\n", - "stability": "stable" - }, - { - "id": "inactive", - "value": "inactive", - "brief": "The app is now `inactive`. Associated with UIKit notification `applicationWillResignActive`.\n", - "stability": "stable" - }, - { - "id": "background", - "value": "background", - "brief": "The app is now in the background. This value is associated with UIKit notification `applicationDidEnterBackground`.\n", - "stability": "stable" - }, - { - "id": "foreground", - "value": "foreground", - "brief": "The app is now in the foreground. This value is associated with UIKit notification `applicationWillEnterForeground`.\n", - "stability": "stable" - }, - { - "id": "terminate", - "value": "terminate", - "brief": "The app is about to terminate. Associated with UIKit notification `applicationWillTerminate`.\n", - "stability": "stable" - } - ] - }, - "brief": "This attribute represents the state the application has transitioned into at the occurrence of the event.\n", - "requirement_level": "required", - "note": "The iOS lifecycle states are defined in the [UIApplicationDelegate documentation](https://developer.apple.com/documentation/uikit/uiapplicationdelegate#1656902), and from which the `OS terminology` column values are derived.\n", - "stability": "stable" - }, - { - "name": "test_attr.event.attr", - "type": "string", - "brief": "Just making sure the referenced attributes are defined", - "examples": "some value", - "requirement_level": "recommended", - "note": "Test value.", - "stability": "stable" - }, - { - "name": "test_attr.event.attr", - "type": "string", - "brief": "Just making sure the referenced attributes are defined", - "examples": "some value", - "requirement_level": { - "conditionally_required": "if and only if corresponding event is enabled" - }, - "note": "test attribute\n", - "stability": "stable" - }, - { - "name": "test_attr.http.url", - "type": "string", - "brief": "The Url", - "examples": [ - "https://example.com" - ], - "requirement_level": "recommended", - "note": "Test url value.", - "stability": "stable" - }, - { - "name": "test_attr.platform", - "type": "string", - "brief": "The browser platform", - "examples": [ - "Windows", - "macOS", - "Android" - ], - "requirement_level": "recommended", - "note": "Test value.", - "stability": "stable" - }, - { - "name": "test_attr.session.id", - "type": "string", - "brief": "The session id", - "examples": "127836abcdef98", - "requirement_level": "recommended", - "note": "Test value.", - "stability": "stable" - }, - { - "name": "test_attr.session.id", - "type": "string", - "brief": "The session id", - "examples": "127836abcdef98", - "requirement_level": { - "conditionally_required": "if and only if corresponding event is enabled" - }, - "note": "Another test attribute\n", - "stability": "stable" - } - ] -} \ No newline at end of file + "note": "Another test attribute\n", + "stability": "stable" + } +] diff --git a/crates/weaver_resolver/data/registry-test-5-metrics/expected-attribute-catalog.json b/crates/weaver_resolver/data/registry-test-5-metrics/expected-attribute-catalog.json index 8a60a4f77..32bb344ba 100644 --- a/crates/weaver_resolver/data/registry-test-5-metrics/expected-attribute-catalog.json +++ b/crates/weaver_resolver/data/registry-test-5-metrics/expected-attribute-catalog.json @@ -1,105 +1,103 @@ -{ - "attributes": [ - { - "name": "faas.invoked_name", - "type": "string", - "brief": "The name of the invoked function.\n", - "examples": "my-function", - "requirement_level": "required", - "note": "SHOULD be equal to the `faas.name` resource attribute of the invoked function.\n", - "stability": "stable" +[ + { + "name": "faas.invoked_name", + "type": "string", + "brief": "The name of the invoked function.\n", + "examples": "my-function", + "requirement_level": "required", + "note": "SHOULD be equal to the `faas.name` resource attribute of the invoked function.\n", + "stability": "stable" + }, + { + "name": "faas.invoked_provider", + "type": { + "members": [ + { + "id": "alibaba_cloud", + "value": "alibaba_cloud", + "brief": "Alibaba Cloud", + "stability": "stable" + }, + { + "id": "aws", + "value": "aws", + "brief": "Amazon Web Services", + "stability": "stable" + }, + { + "id": "azure", + "value": "azure", + "brief": "Microsoft Azure", + "stability": "stable" + }, + { + "id": "gcp", + "value": "gcp", + "brief": "Google Cloud Platform", + "stability": "stable" + }, + { + "id": "tencent_cloud", + "value": "tencent_cloud", + "brief": "Tencent Cloud", + "stability": "stable" + } + ] }, - { - "name": "faas.invoked_provider", - "type": { - "members": [ - { - "id": "alibaba_cloud", - "value": "alibaba_cloud", - "brief": "Alibaba Cloud", - "stability": "stable" - }, - { - "id": "aws", - "value": "aws", - "brief": "Amazon Web Services", - "stability": "stable" - }, - { - "id": "azure", - "value": "azure", - "brief": "Microsoft Azure", - "stability": "stable" - }, - { - "id": "gcp", - "value": "gcp", - "brief": "Google Cloud Platform", - "stability": "stable" - }, - { - "id": "tencent_cloud", - "value": "tencent_cloud", - "brief": "Tencent Cloud", - "stability": "stable" - } - ] - }, - "brief": "The cloud provider of the invoked function.\n", - "requirement_level": "required", - "note": "SHOULD be equal to the `cloud.provider` resource attribute of the invoked function.\n", - "stability": "stable" + "brief": "The cloud provider of the invoked function.\n", + "requirement_level": "required", + "note": "SHOULD be equal to the `cloud.provider` resource attribute of the invoked function.\n", + "stability": "stable" + }, + { + "name": "faas.invoked_region", + "type": "string", + "brief": "The cloud region of the invoked function.\n", + "examples": "eu-central-1", + "requirement_level": { + "conditionally_required": "For some cloud providers, like AWS or GCP, the region in which a function is hosted is essential to uniquely identify the function and also part of its endpoint. Since it's part of the endpoint being called, the region is always known to clients. In these cases, `faas.invoked_region` MUST be set accordingly. If the region is unknown to the client or not required for identifying the invoked function, setting `faas.invoked_region` is optional.\n" }, - { - "name": "faas.invoked_region", - "type": "string", - "brief": "The cloud region of the invoked function.\n", - "examples": "eu-central-1", - "requirement_level": { - "conditionally_required": "For some cloud providers, like AWS or GCP, the region in which a function is hosted is essential to uniquely identify the function and also part of its endpoint. Since it's part of the endpoint being called, the region is always known to clients. In these cases, `faas.invoked_region` MUST be set accordingly. If the region is unknown to the client or not required for identifying the invoked function, setting `faas.invoked_region` is optional.\n" - }, - "note": "SHOULD be equal to the `cloud.region` resource attribute of the invoked function.\n", - "stability": "stable" + "note": "SHOULD be equal to the `cloud.region` resource attribute of the invoked function.\n", + "stability": "stable" + }, + { + "name": "faas.trigger", + "type": { + "members": [ + { + "id": "datasource", + "value": "datasource", + "brief": "A response to some data source operation such as a database or filesystem read/write", + "stability": "stable" + }, + { + "id": "http", + "value": "http", + "brief": "To provide an answer to an inbound HTTP request", + "stability": "stable" + }, + { + "id": "pubsub", + "value": "pubsub", + "brief": "A function is set to be executed when messages are sent to a messaging system", + "stability": "stable" + }, + { + "id": "timer", + "value": "timer", + "brief": "A function is scheduled to be executed regularly", + "stability": "stable" + }, + { + "id": "other", + "value": "other", + "brief": "If none of the others apply", + "stability": "stable" + } + ] }, - { - "name": "faas.trigger", - "type": { - "members": [ - { - "id": "datasource", - "value": "datasource", - "brief": "A response to some data source operation such as a database or filesystem read/write", - "stability": "stable" - }, - { - "id": "http", - "value": "http", - "brief": "To provide an answer to an inbound HTTP request", - "stability": "stable" - }, - { - "id": "pubsub", - "value": "pubsub", - "brief": "A function is set to be executed when messages are sent to a messaging system", - "stability": "stable" - }, - { - "id": "timer", - "value": "timer", - "brief": "A function is scheduled to be executed regularly", - "stability": "stable" - }, - { - "id": "other", - "value": "other", - "brief": "If none of the others apply", - "stability": "stable" - } - ] - }, - "brief": "Type of the trigger which caused this function invocation.", - "requirement_level": "recommended", - "stability": "stable" - } - ] -} \ No newline at end of file + "brief": "Type of the trigger which caused this function invocation.", + "requirement_level": "recommended", + "stability": "stable" + } +] diff --git a/crates/weaver_resolver/data/registry-test-6-resources/expected-attribute-catalog.json b/crates/weaver_resolver/data/registry-test-6-resources/expected-attribute-catalog.json index bd025f313..b875ff6f1 100644 --- a/crates/weaver_resolver/data/registry-test-6-resources/expected-attribute-catalog.json +++ b/crates/weaver_resolver/data/registry-test-6-resources/expected-attribute-catalog.json @@ -1,80 +1,78 @@ -{ - "attributes": [ - { - "name": "browser.brands", - "type": "string[]", - "brief": "Array of brand name and version separated by a space", - "examples": [ - [ - "Not A;Brand 99" - ], - [ - "Chromium 99" - ], - [ - "Chrome 99" - ] +[ + { + "name": "browser.brands", + "type": "string[]", + "brief": "Array of brand name and version separated by a space", + "examples": [ + [ + "Not A;Brand 99" ], - "requirement_level": "recommended", - "note": "This value is intended to be taken from the [UA client hints API](https://wicg.github.io/ua-client-hints/#interface) (`navigator.userAgentData.brands`).\n", - "stability": "stable" - }, - { - "name": "browser.language", - "type": "string", - "brief": "Preferred language of the user using the browser", - "examples": [ - "en", - "en-US", - "fr", - "fr-FR" + [ + "Chromium 99" ], - "requirement_level": "recommended", - "note": "This value is intended to be taken from the Navigator API `navigator.language`.\n", - "stability": "stable" - }, - { - "name": "browser.mobile", - "type": "boolean", - "brief": "A boolean that is true if the browser is running on a mobile device", - "requirement_level": "recommended", - "note": "This value is intended to be taken from the [UA client hints API](https://wicg.github.io/ua-client-hints/#interface) (`navigator.userAgentData.mobile`). If unavailable, this attribute SHOULD be left unset.\n", - "stability": "stable" - }, - { - "name": "browser.platform", - "type": "string", - "brief": "The platform on which the browser is running", - "examples": [ - "Windows", - "macOS", - "Android" - ], - "requirement_level": "recommended", - "note": "This value is intended to be taken from the [UA client hints API](https://wicg.github.io/ua-client-hints/#interface) (`navigator.userAgentData.platform`). If unavailable, the legacy `navigator.platform` API SHOULD NOT be used instead and this attribute SHOULD be left unset in order for the values to be consistent.\nThe list of possible values is defined in the [W3C User-Agent Client Hints specification](https://wicg.github.io/ua-client-hints/#sec-ch-ua-platform). Note that some (but not all) of these values can overlap with values in the [`os.type` and `os.name` attributes](./os.md). However, for consistency, the values in the `browser.platform` attribute should capture the exact value that the user agent provides.\n", - "stability": "stable" - }, - { - "name": "user_agent.original", - "type": "string", - "brief": "Full user-agent string provided by the browser", - "examples": [ - "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36" - ], - "requirement_level": "recommended", - "note": "The user-agent value SHOULD be provided only from browsers that do not have a mechanism to retrieve brands and platform individually from the User-Agent Client Hints API. To retrieve the value, the legacy `navigator.userAgent` API can be used.\n", - "stability": "stable" - }, - { - "name": "user_agent.original", - "type": "string", - "brief": "Value of the [HTTP User-Agent](https://www.rfc-editor.org/rfc/rfc9110.html#field.user-agent) header sent by the client.\n", - "examples": [ - "CERN-LineMode/2.15 libwww/2.17b3", - "Mozilla/5.0 (iPhone; CPU iPhone OS 14_7_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.2 Mobile/15E148 Safari/604.1" - ], - "requirement_level": "recommended", - "stability": "stable" - } - ] -} \ No newline at end of file + [ + "Chrome 99" + ] + ], + "requirement_level": "recommended", + "note": "This value is intended to be taken from the [UA client hints API](https://wicg.github.io/ua-client-hints/#interface) (`navigator.userAgentData.brands`).\n", + "stability": "stable" + }, + { + "name": "browser.language", + "type": "string", + "brief": "Preferred language of the user using the browser", + "examples": [ + "en", + "en-US", + "fr", + "fr-FR" + ], + "requirement_level": "recommended", + "note": "This value is intended to be taken from the Navigator API `navigator.language`.\n", + "stability": "stable" + }, + { + "name": "browser.mobile", + "type": "boolean", + "brief": "A boolean that is true if the browser is running on a mobile device", + "requirement_level": "recommended", + "note": "This value is intended to be taken from the [UA client hints API](https://wicg.github.io/ua-client-hints/#interface) (`navigator.userAgentData.mobile`). If unavailable, this attribute SHOULD be left unset.\n", + "stability": "stable" + }, + { + "name": "browser.platform", + "type": "string", + "brief": "The platform on which the browser is running", + "examples": [ + "Windows", + "macOS", + "Android" + ], + "requirement_level": "recommended", + "note": "This value is intended to be taken from the [UA client hints API](https://wicg.github.io/ua-client-hints/#interface) (`navigator.userAgentData.platform`). If unavailable, the legacy `navigator.platform` API SHOULD NOT be used instead and this attribute SHOULD be left unset in order for the values to be consistent.\nThe list of possible values is defined in the [W3C User-Agent Client Hints specification](https://wicg.github.io/ua-client-hints/#sec-ch-ua-platform). Note that some (but not all) of these values can overlap with values in the [`os.type` and `os.name` attributes](./os.md). However, for consistency, the values in the `browser.platform` attribute should capture the exact value that the user agent provides.\n", + "stability": "stable" + }, + { + "name": "user_agent.original", + "type": "string", + "brief": "Full user-agent string provided by the browser", + "examples": [ + "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36" + ], + "requirement_level": "recommended", + "note": "The user-agent value SHOULD be provided only from browsers that do not have a mechanism to retrieve brands and platform individually from the User-Agent Client Hints API. To retrieve the value, the legacy `navigator.userAgent` API can be used.\n", + "stability": "stable" + }, + { + "name": "user_agent.original", + "type": "string", + "brief": "Value of the [HTTP User-Agent](https://www.rfc-editor.org/rfc/rfc9110.html#field.user-agent) header sent by the client.\n", + "examples": [ + "CERN-LineMode/2.15 libwww/2.17b3", + "Mozilla/5.0 (iPhone; CPU iPhone OS 14_7_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.2 Mobile/15E148 Safari/604.1" + ], + "requirement_level": "recommended", + "stability": "stable" + } +] diff --git a/crates/weaver_resolver/data/registry-test-7-spans/expected-attribute-catalog.json b/crates/weaver_resolver/data/registry-test-7-spans/expected-attribute-catalog.json index 8885bda66..1a48df333 100644 --- a/crates/weaver_resolver/data/registry-test-7-spans/expected-attribute-catalog.json +++ b/crates/weaver_resolver/data/registry-test-7-spans/expected-attribute-catalog.json @@ -1,2554 +1,2552 @@ -{ - "attributes": [ - { - "name": "db.cassandra.consistency_level", - "type": { - "members": [ - { - "id": "all", - "value": "all", - "stability": "stable" - }, - { - "id": "each_quorum", - "value": "each_quorum", - "stability": "stable" - }, - { - "id": "quorum", - "value": "quorum", - "stability": "stable" - }, - { - "id": "local_quorum", - "value": "local_quorum", - "stability": "stable" - }, - { - "id": "one", - "value": "one", - "stability": "stable" - }, - { - "id": "two", - "value": "two", - "stability": "stable" - }, - { - "id": "three", - "value": "three", - "stability": "stable" - }, - { - "id": "local_one", - "value": "local_one", - "stability": "stable" - }, - { - "id": "any", - "value": "any", - "stability": "stable" - }, - { - "id": "serial", - "value": "serial", - "stability": "stable" - }, - { - "id": "local_serial", - "value": "local_serial", - "stability": "stable" - } - ] - }, - "brief": "The consistency level of the query. Based on consistency values from [CQL](https://docs.datastax.com/en/cassandra-oss/3.0/cassandra/dml/dmlConfigConsistency.html).\n", - "tag": "call-level-tech-specific-cassandra", - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "db.cassandra.consistency_level", - "type": { - "members": [ - { - "id": "all", - "value": "all", - "stability": "stable" - }, - { - "id": "each_quorum", - "value": "each_quorum", - "stability": "stable" - }, - { - "id": "quorum", - "value": "quorum", - "stability": "stable" - }, - { - "id": "local_quorum", - "value": "local_quorum", - "stability": "stable" - }, - { - "id": "one", - "value": "one", - "stability": "stable" - }, - { - "id": "two", - "value": "two", - "stability": "stable" - }, - { - "id": "three", - "value": "three", - "stability": "stable" - }, - { - "id": "local_one", - "value": "local_one", - "stability": "stable" - }, - { - "id": "any", - "value": "any", - "stability": "stable" - }, - { - "id": "serial", - "value": "serial", - "stability": "stable" - }, - { - "id": "local_serial", - "value": "local_serial", - "stability": "stable" - } - ] - }, - "brief": "The consistency level of the query. Based on consistency values from [CQL](https://docs.datastax.com/en/cassandra-oss/3.0/cassandra/dml/dmlConfigConsistency.html).\n", - "tag": "tech-specific-cassandra", - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "db.cassandra.coordinator.dc", - "type": "string", - "brief": "The data center of the coordinating node for a query.\n", - "examples": "us-west-2", - "tag": "call-level-tech-specific-cassandra", - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "db.cassandra.coordinator.dc", - "type": "string", - "brief": "The data center of the coordinating node for a query.\n", - "examples": "us-west-2", - "tag": "tech-specific-cassandra", - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "db.cassandra.coordinator.id", - "type": "string", - "brief": "The ID of the coordinating node for a query.\n", - "examples": "be13faa2-8574-4d71-926d-27f16cf8a7af", - "tag": "call-level-tech-specific-cassandra", - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "db.cassandra.coordinator.id", - "type": "string", - "brief": "The ID of the coordinating node for a query.\n", - "examples": "be13faa2-8574-4d71-926d-27f16cf8a7af", - "tag": "tech-specific-cassandra", - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "db.cassandra.idempotence", - "type": "boolean", - "brief": "Whether or not the query is idempotent.\n", - "tag": "call-level-tech-specific-cassandra", - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "db.cassandra.idempotence", - "type": "boolean", - "brief": "Whether or not the query is idempotent.\n", - "tag": "tech-specific-cassandra", - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "db.cassandra.page_size", - "type": "int", - "brief": "The fetch size used for paging, i.e. how many rows will be returned at once.\n", - "examples": [ - 5000 - ], - "tag": "call-level-tech-specific-cassandra", - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "db.cassandra.page_size", - "type": "int", - "brief": "The fetch size used for paging, i.e. how many rows will be returned at once.\n", - "examples": [ - 5000 - ], - "tag": "tech-specific-cassandra", - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "db.cassandra.speculative_execution_count", - "type": "int", - "brief": "The number of times a query was speculatively executed. Not set or `0` if the query was not executed speculatively.\n", - "examples": [ - 0, - 2 - ], - "tag": "call-level-tech-specific-cassandra", - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "db.cassandra.speculative_execution_count", - "type": "int", - "brief": "The number of times a query was speculatively executed. Not set or `0` if the query was not executed speculatively.\n", - "examples": [ - 0, - 2 - ], - "tag": "tech-specific-cassandra", - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "db.cassandra.table", - "type": "string", - "brief": "The name of the primary Cassandra table that the operation is acting upon, including the keyspace name (if applicable).", - "examples": "mytable", - "tag": "call-level-tech-specific-cassandra", - "requirement_level": "recommended", - "note": "This mirrors the db.sql.table attribute but references cassandra rather than sql. It is not recommended to attempt any client-side parsing of `db.statement` just to get this property, but it should be set if it is provided by the library being instrumented. If the operation is acting upon an anonymous table, or more than one table, this value MUST NOT be set.\n", - "stability": "stable" - }, - { - "name": "db.cassandra.table", - "type": "string", - "brief": "The name of the primary Cassandra table that the operation is acting upon, including the keyspace name (if applicable).", - "examples": "mytable", - "tag": "tech-specific-cassandra", - "requirement_level": "recommended", - "note": "This mirrors the db.sql.table attribute but references cassandra rather than sql. It is not recommended to attempt any client-side parsing of `db.statement` just to get this property, but it should be set if it is provided by the library being instrumented. If the operation is acting upon an anonymous table, or more than one table, this value MUST NOT be set.\n", - "stability": "stable" - }, - { - "name": "db.connection_string", - "type": "string", - "brief": "The connection string used to connect to the database. It is recommended to remove embedded credentials.\n", - "examples": "Server=(localdb)\\v11.0;Integrated Security=true;", - "tag": "connection-level", - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "db.connection_string", - "type": "string", - "brief": "The connection string used to connect to the database. It is recommended to remove embedded credentials.\n", - "examples": "Server=(localdb)\\v11.0;Integrated Security=true;", - "tag": "db-generic", - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "db.cosmosdb.client_id", - "type": "string", - "brief": "Unique Cosmos client instance id.", - "examples": "3ba4827d-4422-483f-b59f-85b74211c11d", - "tag": "call-level-tech-specific", - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "db.cosmosdb.client_id", - "type": "string", - "brief": "Unique Cosmos client instance id.", - "examples": "3ba4827d-4422-483f-b59f-85b74211c11d", - "tag": "tech-specific-cosmosdb", - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "db.cosmosdb.connection_mode", - "type": { - "members": [ - { - "id": "gateway", - "value": "gateway", - "brief": "Gateway (HTTP) connections mode", - "stability": "stable" - }, - { - "id": "direct", - "value": "direct", - "brief": "Direct connection.", - "stability": "stable" - } - ] - }, - "brief": "Cosmos client connection mode.", - "tag": "call-level-tech-specific", - "requirement_level": { - "conditionally_required": "if not `direct` (or pick gw as default)" - }, - "stability": "stable" - }, - { - "name": "db.cosmosdb.connection_mode", - "type": { - "members": [ - { - "id": "gateway", - "value": "gateway", - "brief": "Gateway (HTTP) connections mode", - "stability": "stable" - }, - { - "id": "direct", - "value": "direct", - "brief": "Direct connection.", - "stability": "stable" - } - ] - }, - "brief": "Cosmos client connection mode.", - "tag": "tech-specific-cosmosdb", - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "db.cosmosdb.container", - "type": "string", - "brief": "Cosmos DB container name.", - "examples": "anystring", - "tag": "call-level-tech-specific", - "requirement_level": { - "conditionally_required": "if available" - }, - "stability": "stable" - }, - { - "name": "db.cosmosdb.container", - "type": "string", - "brief": "Cosmos DB container name.", - "examples": "anystring", - "tag": "tech-specific-cosmosdb", - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "db.cosmosdb.operation_type", - "type": { - "members": [ - { - "id": "invalid", - "value": "Invalid", - "stability": "stable" - }, - { - "id": "create", - "value": "Create", - "stability": "stable" - }, - { - "id": "patch", - "value": "Patch", - "stability": "stable" - }, - { - "id": "read", - "value": "Read", - "stability": "stable" - }, - { - "id": "read_feed", - "value": "ReadFeed", - "stability": "stable" - }, - { - "id": "delete", - "value": "Delete", - "stability": "stable" - }, - { - "id": "replace", - "value": "Replace", - "stability": "stable" - }, - { - "id": "execute", - "value": "Execute", - "stability": "stable" - }, - { - "id": "query", - "value": "Query", - "stability": "stable" - }, - { - "id": "head", - "value": "Head", - "stability": "stable" - }, - { - "id": "head_feed", - "value": "HeadFeed", - "stability": "stable" - }, - { - "id": "upsert", - "value": "Upsert", - "stability": "stable" - }, - { - "id": "batch", - "value": "Batch", - "stability": "stable" - }, - { - "id": "query_plan", - "value": "QueryPlan", - "stability": "stable" - }, - { - "id": "execute_javascript", - "value": "ExecuteJavaScript", - "stability": "stable" - } - ] - }, - "brief": "CosmosDB Operation Type.", - "tag": "call-level-tech-specific", - "requirement_level": { - "conditionally_required": "when performing one of the operations in this list" - }, - "stability": "stable" - }, - { - "name": "db.cosmosdb.operation_type", - "type": { - "members": [ - { - "id": "invalid", - "value": "Invalid", - "stability": "stable" - }, - { - "id": "create", - "value": "Create", - "stability": "stable" - }, - { - "id": "patch", - "value": "Patch", - "stability": "stable" - }, - { - "id": "read", - "value": "Read", - "stability": "stable" - }, - { - "id": "read_feed", - "value": "ReadFeed", - "stability": "stable" - }, - { - "id": "delete", - "value": "Delete", - "stability": "stable" - }, - { - "id": "replace", - "value": "Replace", - "stability": "stable" - }, - { - "id": "execute", - "value": "Execute", - "stability": "stable" - }, - { - "id": "query", - "value": "Query", - "stability": "stable" - }, - { - "id": "head", - "value": "Head", - "stability": "stable" - }, - { - "id": "head_feed", - "value": "HeadFeed", - "stability": "stable" - }, - { - "id": "upsert", - "value": "Upsert", - "stability": "stable" - }, - { - "id": "batch", - "value": "Batch", - "stability": "stable" - }, - { - "id": "query_plan", - "value": "QueryPlan", - "stability": "stable" - }, - { - "id": "execute_javascript", - "value": "ExecuteJavaScript", - "stability": "stable" - } - ] - }, - "brief": "CosmosDB Operation Type.", - "tag": "tech-specific-cosmosdb", - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "db.cosmosdb.request_charge", - "type": "double", - "brief": "RU consumed for that operation", - "examples": [ - 46.18, - 1.0 - ], - "tag": "call-level-tech-specific", - "requirement_level": { - "conditionally_required": "when available" - }, - "stability": "stable" - }, - { - "name": "db.cosmosdb.request_charge", - "type": "double", - "brief": "RU consumed for that operation", - "examples": [ - 46.18, - 1.0 - ], - "tag": "tech-specific-cosmosdb", - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "db.cosmosdb.request_content_length", - "type": "int", - "brief": "Request payload size in bytes", - "tag": "call-level-tech-specific", - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "db.cosmosdb.request_content_length", - "type": "int", - "brief": "Request payload size in bytes", - "tag": "tech-specific-cosmosdb", - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "db.cosmosdb.status_code", - "type": "int", - "brief": "Cosmos DB status code.", - "examples": [ - 200, - 201 - ], - "tag": "call-level-tech-specific", - "requirement_level": { - "conditionally_required": "if response was received" - }, - "stability": "stable" - }, - { - "name": "db.cosmosdb.status_code", - "type": "int", - "brief": "Cosmos DB status code.", - "examples": [ - 200, - 201 - ], - "tag": "tech-specific-cosmosdb", - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "db.cosmosdb.sub_status_code", - "type": "int", - "brief": "Cosmos DB sub status code.", - "examples": [ - 1000, - 1002 - ], - "tag": "call-level-tech-specific", - "requirement_level": { - "conditionally_required": "when response was received and contained sub-code." - }, - "stability": "stable" - }, - { - "name": "db.cosmosdb.sub_status_code", - "type": "int", - "brief": "Cosmos DB sub status code.", - "examples": [ - 1000, - 1002 - ], - "tag": "tech-specific-cosmosdb", - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "db.elasticsearch.cluster.name", - "type": "string", - "brief": "Represents the identifier of an Elasticsearch cluster.\n", - "examples": [ - "e9106fc68e3044f0b1475b04bf4ffd5f" - ], - "tag": "call-level-tech-specific", - "requirement_level": { - "recommended": "When communicating with an Elastic Cloud deployment, this should be collected from the \"X-Found-Handling-Cluster\" HTTP response header.\n" - }, - "stability": "stable" - }, - { - "name": "db.elasticsearch.cluster.name", - "type": "string", - "brief": "Represents the identifier of an Elasticsearch cluster.\n", - "examples": [ - "e9106fc68e3044f0b1475b04bf4ffd5f" - ], - "tag": "tech-specific-elasticsearch", - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "db.elasticsearch.node.name", - "type": "string", - "brief": "Represents the human-readable identifier of the node/instance to which a request was routed.\n", - "examples": [ - "instance-0000000001" - ], - "tag": "call-level-tech-specific", - "requirement_level": { - "recommended": "When communicating with an Elastic Cloud deployment, this should be collected from the \"X-Found-Handling-Instance\" HTTP response header.\n" - }, - "stability": "stable" - }, - { - "name": "db.elasticsearch.node.name", - "type": "string", - "brief": "Represents the human-readable identifier of the node/instance to which a request was routed.\n", - "examples": [ - "instance-0000000001" - ], - "tag": "tech-specific-elasticsearch", - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "db.elasticsearch.path_parts", - "type": "template[string]", - "brief": "A dynamic value in the url path.\n", - "examples": [ - "db.elasticsearch.path_parts.index=test-index", - "db.elasticsearch.path_parts.doc_id=123" - ], - "tag": "call-level-tech-specific", - "requirement_level": { - "conditionally_required": "when the url has dynamic values" - }, - "note": "Many Elasticsearch url paths allow dynamic values. These SHOULD be recorded in span attributes in the format `db.elasticsearch.path_parts.`, where `` is the url path part name. The implementation SHOULD reference the [elasticsearch schema](https://raw.githubusercontent.com/elastic/elasticsearch-specification/main/output/schema/schema.json) in order to map the path part values to their names.\n", - "stability": "stable" - }, - { - "name": "db.elasticsearch.path_parts", - "type": "template[string]", - "brief": "A dynamic value in the url path.\n", - "examples": [ - "db.elasticsearch.path_parts.index=test-index", - "db.elasticsearch.path_parts.doc_id=123" - ], - "tag": "tech-specific-elasticsearch", - "requirement_level": "recommended", - "note": "Many Elasticsearch url paths allow dynamic values. These SHOULD be recorded in span attributes in the format `db.elasticsearch.path_parts.`, where `` is the url path part name. The implementation SHOULD reference the [elasticsearch schema](https://raw.githubusercontent.com/elastic/elasticsearch-specification/main/output/schema/schema.json) in order to map the path part values to their names.\n", - "stability": "stable" - }, - { - "name": "db.instance.id", - "type": "string", - "brief": "An identifier (address, unique name, or any other identifier) of the database instance that is executing queries or mutations on the current connection. This is useful in cases where the database is running in a clustered environment and the instrumentation is able to record the node executing the query. The client may obtain this value in databases like MySQL using queries like `select @@hostname`.\n", - "examples": "mysql-e26b99z.example.com", - "tag": "connection-level", - "requirement_level": { - "recommended": "If different from the `server.address`" - }, - "stability": "stable" - }, - { - "name": "db.instance.id", - "type": "string", - "brief": "An identifier (address, unique name, or any other identifier) of the database instance that is executing queries or mutations on the current connection. This is useful in cases where the database is running in a clustered environment and the instrumentation is able to record the node executing the query. The client may obtain this value in databases like MySQL using queries like `select @@hostname`.\n", - "examples": "mysql-e26b99z.example.com", - "tag": "db-generic", - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "db.jdbc.driver_classname", - "type": "string", - "brief": "The fully-qualified class name of the [Java Database Connectivity (JDBC)](https://docs.oracle.com/javase/8/docs/technotes/guides/jdbc/) driver used to connect.\n", - "examples": [ - "org.postgresql.Driver", - "com.microsoft.sqlserver.jdbc.SQLServerDriver" - ], - "tag": "connection-level-tech-specific", - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "db.jdbc.driver_classname", - "type": "string", - "brief": "The fully-qualified class name of the [Java Database Connectivity (JDBC)](https://docs.oracle.com/javase/8/docs/technotes/guides/jdbc/) driver used to connect.\n", - "examples": [ - "org.postgresql.Driver", - "com.microsoft.sqlserver.jdbc.SQLServerDriver" - ], - "tag": "tech-specific-jdbc", - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "db.mongodb.collection", - "type": "string", - "brief": "The MongoDB collection being accessed within the database stated in `db.name`.\n", - "examples": [ - "customers", - "products" - ], - "tag": "call-level-tech-specific", - "requirement_level": "required", - "stability": "stable" - }, - { - "name": "db.mongodb.collection", - "type": "string", - "brief": "The MongoDB collection being accessed within the database stated in `db.name`.\n", - "examples": [ - "customers", - "products" - ], - "tag": "tech-specific-mongodb", - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "db.mssql.instance_name", - "type": "string", - "brief": "The Microsoft SQL Server [instance name](https://docs.microsoft.com/sql/connect/jdbc/building-the-connection-url?view=sql-server-ver15) connecting to. This name is used to determine the port of a named instance.\n", - "examples": "MSSQLSERVER", - "tag": "connection-level-tech-specific", - "requirement_level": "recommended", - "note": "If setting a `db.mssql.instance_name`, `server.port` is no longer required (but still recommended if non-standard).\n", - "stability": "stable" - }, - { - "name": "db.mssql.instance_name", - "type": "string", - "brief": "The Microsoft SQL Server [instance name](https://docs.microsoft.com/sql/connect/jdbc/building-the-connection-url?view=sql-server-ver15) connecting to. This name is used to determine the port of a named instance.\n", - "examples": "MSSQLSERVER", - "tag": "tech-specific-mssql", - "requirement_level": "recommended", - "note": "If setting a `db.mssql.instance_name`, `server.port` is no longer required (but still recommended if non-standard).\n", - "stability": "stable" - }, - { - "name": "db.name", - "type": "string", - "brief": "The HBase namespace.\n", - "examples": [ - "mynamespace" - ], - "tag": "call-level-tech-specific", - "requirement_level": { - "conditionally_required": "If applicable." - }, - "note": "For HBase the `db.name` should be set to the HBase namespace.", - "stability": "stable" - }, - { - "name": "db.name", - "type": "string", - "brief": "The keyspace name in Cassandra.\n", - "examples": [ - "mykeyspace" - ], - "tag": "call-level-tech-specific-cassandra", - "requirement_level": { - "conditionally_required": "If applicable." - }, - "note": "For Cassandra the `db.name` should be set to the Cassandra keyspace name.", - "stability": "stable" - }, - { - "name": "db.name", - "type": "string", - "brief": "This attribute is used to report the name of the database being accessed. For commands that switch the database, this should be set to the target database (even if the command fails).\n", - "examples": [ - "customers", - "main" - ], - "tag": "call-level", - "requirement_level": { - "conditionally_required": "If applicable." - }, - "note": "In some SQL databases, the database name to be used is called \"schema name\". In case there are multiple layers that could be considered for database name (e.g. Oracle instance name and schema name), the database name to be used is the more specific layer (e.g. Oracle schema name).\n", - "stability": "stable" - }, - { - "name": "db.name", - "type": "string", - "brief": "This attribute is used to report the name of the database being accessed. For commands that switch the database, this should be set to the target database (even if the command fails).\n", - "examples": [ - "customers", - "main" - ], - "tag": "db-generic", - "requirement_level": "recommended", - "note": "In some SQL databases, the database name to be used is called \"schema name\". In case there are multiple layers that could be considered for database name (e.g. Oracle instance name and schema name), the database name to be used is the more specific layer (e.g. Oracle schema name).\n", - "stability": "stable" - }, - { - "name": "db.operation", - "type": "string", - "brief": "The HTTP method + the target REST route.\n", - "examples": [ - "GET /{db}/{docid}" - ], - "tag": "call-level-tech-specific", - "requirement_level": { - "conditionally_required": "If `db.statement` is not applicable." - }, - "note": "In **CouchDB**, `db.operation` should be set to the HTTP method + the target REST route according to the API reference documentation. For example, when retrieving a document, `db.operation` would be set to (literally, i.e., without replacing the placeholders with concrete values): [`GET /{db}/{docid}`](http://docs.couchdb.org/en/stable/api/document/common.html#get--db-docid).\n", - "stability": "stable" - }, - { - "name": "db.operation", - "type": "string", - "brief": "The endpoint identifier for the request.", - "examples": [ - "search", - "ml.close_job", - "cat.aliases" - ], - "tag": "call-level-tech-specific", - "requirement_level": "required", - "note": "When setting this to an SQL keyword, it is not recommended to attempt any client-side parsing of `db.statement` just to get this property, but it should be set if the operation name is provided by the library being instrumented. If the SQL statement has an ambiguous operation, or performs more than one operation, this value may be omitted.\n", - "stability": "stable" - }, - { - "name": "db.operation", - "type": "string", - "brief": "The name of the operation being executed, e.g. the [MongoDB command name](https://docs.mongodb.com/manual/reference/command/#database-operations) such as `findAndModify`, or the SQL keyword.\n", - "examples": [ - "findAndModify", - "HMSET", - "SELECT" - ], - "tag": "call-level", - "requirement_level": { - "conditionally_required": "If `db.statement` is not applicable." - }, - "note": "When setting this to an SQL keyword, it is not recommended to attempt any client-side parsing of `db.statement` just to get this property, but it should be set if the operation name is provided by the library being instrumented. If the SQL statement has an ambiguous operation, or performs more than one operation, this value may be omitted.\n", - "stability": "stable" - }, - { - "name": "db.operation", - "type": "string", - "brief": "The name of the operation being executed, e.g. the [MongoDB command name](https://docs.mongodb.com/manual/reference/command/#database-operations) such as `findAndModify`, or the SQL keyword.\n", - "examples": [ - "findAndModify", - "HMSET", - "SELECT" - ], - "tag": "db-generic", - "requirement_level": "recommended", - "note": "When setting this to an SQL keyword, it is not recommended to attempt any client-side parsing of `db.statement` just to get this property, but it should be set if the operation name is provided by the library being instrumented. If the SQL statement has an ambiguous operation, or performs more than one operation, this value may be omitted.\n", - "stability": "stable" - }, - { - "name": "db.redis.database_index", - "type": "int", - "brief": "The index of the database being accessed as used in the [`SELECT` command](https://redis.io/commands/select), provided as an integer. To be used instead of the generic `db.name` attribute.\n", - "examples": [ - 0, - 1, - 15 - ], - "tag": "call-level-tech-specific", - "requirement_level": { - "conditionally_required": "If other than the default database (`0`)." - }, - "stability": "stable" - }, - { - "name": "db.redis.database_index", - "type": "int", - "brief": "The index of the database being accessed as used in the [`SELECT` command](https://redis.io/commands/select), provided as an integer. To be used instead of the generic `db.name` attribute.\n", - "examples": [ - 0, - 1, - 15 - ], - "tag": "tech-specific-redis", - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "db.sql.table", - "type": "string", - "brief": "The name of the primary table that the operation is acting upon, including the database name (if applicable).", - "examples": [ - "public.users", - "customers" - ], - "tag": "call-level-tech-specific", - "requirement_level": "recommended", - "note": "It is not recommended to attempt any client-side parsing of `db.statement` just to get this property, but it should be set if it is provided by the library being instrumented. If the operation is acting upon an anonymous table, or more than one table, this value MUST NOT be set.\n", - "stability": "stable" - }, - { - "name": "db.sql.table", - "type": "string", - "brief": "The name of the primary table that the operation is acting upon, including the database name (if applicable).", - "examples": [ - "public.users", - "customers" - ], - "tag": "tech-specific-sql", - "requirement_level": "recommended", - "note": "It is not recommended to attempt any client-side parsing of `db.statement` just to get this property, but it should be set if it is provided by the library being instrumented. If the operation is acting upon an anonymous table, or more than one table, this value MUST NOT be set.\n", - "stability": "stable" - }, - { - "name": "db.statement", - "type": "string", - "brief": "The database statement being executed.\n", - "examples": [ - "SELECT * FROM wuser_table", - "SET mykey \"WuValue\"" - ], - "tag": "call-level", - "requirement_level": { - "recommended": "Should be collected by default only if there is sanitization that excludes sensitive information.\n" - }, - "stability": "stable" - }, - { - "name": "db.statement", - "type": "string", - "brief": "The database statement being executed.\n", - "examples": [ - "SELECT * FROM wuser_table", - "SET mykey \"WuValue\"" - ], - "tag": "db-generic", - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "db.statement", - "type": "string", - "brief": "The full syntax of the Redis CLI command.\n", - "examples": [ - "HMSET myhash field1 'Hello' field2 'World'" - ], - "tag": "call-level-tech-specific", - "requirement_level": { - "recommended": "Should be collected by default only if there is sanitization that excludes sensitive information.\n" - }, - "note": "For **Redis**, the value provided for `db.statement` SHOULD correspond to the syntax of the Redis CLI. If, for example, the [`HMSET` command](https://redis.io/commands/hmset) is invoked, `\"HMSET myhash field1 'Hello' field2 'World'\"` would be a suitable value for `db.statement`.\n", - "stability": "stable" - }, - { - "name": "db.statement", - "type": "string", - "brief": "The request body for a [search-type query](https://www.elastic.co/guide/en/elasticsearch/reference/current/search.html), as a json string.", - "examples": [ - "\"{\\\"query\\\":{\\\"term\\\":{\\\"user.id\\\":\\\"kimchy\\\"}}}\"" - ], - "tag": "call-level-tech-specific", - "requirement_level": { - "recommended": "Should be collected by default for search-type queries and only if there is sanitization that excludes sensitive information.\n" - }, - "stability": "stable" - }, - { - "name": "db.system", - "type": { - "members": [ - { - "id": "other_sql", - "value": "other_sql", - "brief": "Some other SQL database. Fallback only. See notes.", - "stability": "stable" - }, - { - "id": "mssql", - "value": "mssql", - "brief": "Microsoft SQL Server", - "stability": "stable" - }, - { - "id": "mssqlcompact", - "value": "mssqlcompact", - "brief": "Microsoft SQL Server Compact", - "stability": "stable" - }, - { - "id": "mysql", - "value": "mysql", - "brief": "MySQL", - "stability": "stable" - }, - { - "id": "oracle", - "value": "oracle", - "brief": "Oracle Database", - "stability": "stable" - }, - { - "id": "db2", - "value": "db2", - "brief": "IBM Db2", - "stability": "stable" - }, - { - "id": "postgresql", - "value": "postgresql", - "brief": "PostgreSQL", - "stability": "stable" - }, - { - "id": "redshift", - "value": "redshift", - "brief": "Amazon Redshift", - "stability": "stable" - }, - { - "id": "hive", - "value": "hive", - "brief": "Apache Hive", - "stability": "stable" - }, - { - "id": "cloudscape", - "value": "cloudscape", - "brief": "Cloudscape", - "stability": "stable" - }, - { - "id": "hsqldb", - "value": "hsqldb", - "brief": "HyperSQL DataBase", - "stability": "stable" - }, - { - "id": "progress", - "value": "progress", - "brief": "Progress Database", - "stability": "stable" - }, - { - "id": "maxdb", - "value": "maxdb", - "brief": "SAP MaxDB", - "stability": "stable" - }, - { - "id": "hanadb", - "value": "hanadb", - "brief": "SAP HANA", - "stability": "stable" - }, - { - "id": "ingres", - "value": "ingres", - "brief": "Ingres", - "stability": "stable" - }, - { - "id": "firstsql", - "value": "firstsql", - "brief": "FirstSQL", - "stability": "stable" - }, - { - "id": "edb", - "value": "edb", - "brief": "EnterpriseDB", - "stability": "stable" - }, - { - "id": "cache", - "value": "cache", - "brief": "InterSystems Caché", - "stability": "stable" - }, - { - "id": "adabas", - "value": "adabas", - "brief": "Adabas (Adaptable Database System)", - "stability": "stable" - }, - { - "id": "firebird", - "value": "firebird", - "brief": "Firebird", - "stability": "stable" - }, - { - "id": "derby", - "value": "derby", - "brief": "Apache Derby", - "stability": "stable" - }, - { - "id": "filemaker", - "value": "filemaker", - "brief": "FileMaker", - "stability": "stable" - }, - { - "id": "informix", - "value": "informix", - "brief": "Informix", - "stability": "stable" - }, - { - "id": "instantdb", - "value": "instantdb", - "brief": "InstantDB", - "stability": "stable" - }, - { - "id": "interbase", - "value": "interbase", - "brief": "InterBase", - "stability": "stable" - }, - { - "id": "mariadb", - "value": "mariadb", - "brief": "MariaDB", - "stability": "stable" - }, - { - "id": "netezza", - "value": "netezza", - "brief": "Netezza", - "stability": "stable" - }, - { - "id": "pervasive", - "value": "pervasive", - "brief": "Pervasive PSQL", - "stability": "stable" - }, - { - "id": "pointbase", - "value": "pointbase", - "brief": "PointBase", - "stability": "stable" - }, - { - "id": "sqlite", - "value": "sqlite", - "brief": "SQLite", - "stability": "stable" - }, - { - "id": "sybase", - "value": "sybase", - "brief": "Sybase", - "stability": "stable" - }, - { - "id": "teradata", - "value": "teradata", - "brief": "Teradata", - "stability": "stable" - }, - { - "id": "vertica", - "value": "vertica", - "brief": "Vertica", - "stability": "stable" - }, - { - "id": "h2", - "value": "h2", - "brief": "H2", - "stability": "stable" - }, - { - "id": "coldfusion", - "value": "coldfusion", - "brief": "ColdFusion IMQ", - "stability": "stable" - }, - { - "id": "cassandra", - "value": "cassandra", - "brief": "Apache Cassandra", - "stability": "stable" - }, - { - "id": "hbase", - "value": "hbase", - "brief": "Apache HBase", - "stability": "stable" - }, - { - "id": "mongodb", - "value": "mongodb", - "brief": "MongoDB", - "stability": "stable" - }, - { - "id": "redis", - "value": "redis", - "brief": "Redis", - "stability": "stable" - }, - { - "id": "couchbase", - "value": "couchbase", - "brief": "Couchbase", - "stability": "stable" - }, - { - "id": "couchdb", - "value": "couchdb", - "brief": "CouchDB", - "stability": "stable" - }, - { - "id": "cosmosdb", - "value": "cosmosdb", - "brief": "Microsoft Azure Cosmos DB", - "stability": "stable" - }, - { - "id": "dynamodb", - "value": "dynamodb", - "brief": "Amazon DynamoDB", - "stability": "stable" - }, - { - "id": "neo4j", - "value": "neo4j", - "brief": "Neo4j", - "stability": "stable" - }, - { - "id": "geode", - "value": "geode", - "brief": "Apache Geode", - "stability": "stable" - }, - { - "id": "elasticsearch", - "value": "elasticsearch", - "brief": "Elasticsearch", - "stability": "stable" - }, - { - "id": "memcached", - "value": "memcached", - "brief": "Memcached", - "stability": "stable" - }, - { - "id": "cockroachdb", - "value": "cockroachdb", - "brief": "CockroachDB", - "stability": "stable" - }, - { - "id": "opensearch", - "value": "opensearch", - "brief": "OpenSearch", - "stability": "stable" - }, - { - "id": "clickhouse", - "value": "clickhouse", - "brief": "ClickHouse", - "stability": "stable" - }, - { - "id": "spanner", - "value": "spanner", - "brief": "Cloud Spanner", - "stability": "stable" - }, - { - "id": "trino", - "value": "trino", - "brief": "Trino", - "stability": "stable" - } - ] - }, - "brief": "An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers.", - "tag": "connection-level", - "requirement_level": "required", - "stability": "stable" - }, - { - "name": "db.system", - "type": { - "members": [ - { - "id": "other_sql", - "value": "other_sql", - "brief": "Some other SQL database. Fallback only. See notes.", - "stability": "stable" - }, - { - "id": "mssql", - "value": "mssql", - "brief": "Microsoft SQL Server", - "stability": "stable" - }, - { - "id": "mssqlcompact", - "value": "mssqlcompact", - "brief": "Microsoft SQL Server Compact", - "stability": "stable" - }, - { - "id": "mysql", - "value": "mysql", - "brief": "MySQL", - "stability": "stable" - }, - { - "id": "oracle", - "value": "oracle", - "brief": "Oracle Database", - "stability": "stable" - }, - { - "id": "db2", - "value": "db2", - "brief": "IBM Db2", - "stability": "stable" - }, - { - "id": "postgresql", - "value": "postgresql", - "brief": "PostgreSQL", - "stability": "stable" - }, - { - "id": "redshift", - "value": "redshift", - "brief": "Amazon Redshift", - "stability": "stable" - }, - { - "id": "hive", - "value": "hive", - "brief": "Apache Hive", - "stability": "stable" - }, - { - "id": "cloudscape", - "value": "cloudscape", - "brief": "Cloudscape", - "stability": "stable" - }, - { - "id": "hsqldb", - "value": "hsqldb", - "brief": "HyperSQL DataBase", - "stability": "stable" - }, - { - "id": "progress", - "value": "progress", - "brief": "Progress Database", - "stability": "stable" - }, - { - "id": "maxdb", - "value": "maxdb", - "brief": "SAP MaxDB", - "stability": "stable" - }, - { - "id": "hanadb", - "value": "hanadb", - "brief": "SAP HANA", - "stability": "stable" - }, - { - "id": "ingres", - "value": "ingres", - "brief": "Ingres", - "stability": "stable" - }, - { - "id": "firstsql", - "value": "firstsql", - "brief": "FirstSQL", - "stability": "stable" - }, - { - "id": "edb", - "value": "edb", - "brief": "EnterpriseDB", - "stability": "stable" - }, - { - "id": "cache", - "value": "cache", - "brief": "InterSystems Caché", - "stability": "stable" - }, - { - "id": "adabas", - "value": "adabas", - "brief": "Adabas (Adaptable Database System)", - "stability": "stable" - }, - { - "id": "firebird", - "value": "firebird", - "brief": "Firebird", - "stability": "stable" - }, - { - "id": "derby", - "value": "derby", - "brief": "Apache Derby", - "stability": "stable" - }, - { - "id": "filemaker", - "value": "filemaker", - "brief": "FileMaker", - "stability": "stable" - }, - { - "id": "informix", - "value": "informix", - "brief": "Informix", - "stability": "stable" - }, - { - "id": "instantdb", - "value": "instantdb", - "brief": "InstantDB", - "stability": "stable" - }, - { - "id": "interbase", - "value": "interbase", - "brief": "InterBase", - "stability": "stable" - }, - { - "id": "mariadb", - "value": "mariadb", - "brief": "MariaDB", - "stability": "stable" - }, - { - "id": "netezza", - "value": "netezza", - "brief": "Netezza", - "stability": "stable" - }, - { - "id": "pervasive", - "value": "pervasive", - "brief": "Pervasive PSQL", - "stability": "stable" - }, - { - "id": "pointbase", - "value": "pointbase", - "brief": "PointBase", - "stability": "stable" - }, - { - "id": "sqlite", - "value": "sqlite", - "brief": "SQLite", - "stability": "stable" - }, - { - "id": "sybase", - "value": "sybase", - "brief": "Sybase", - "stability": "stable" - }, - { - "id": "teradata", - "value": "teradata", - "brief": "Teradata", - "stability": "stable" - }, - { - "id": "vertica", - "value": "vertica", - "brief": "Vertica", - "stability": "stable" - }, - { - "id": "h2", - "value": "h2", - "brief": "H2", - "stability": "stable" - }, - { - "id": "coldfusion", - "value": "coldfusion", - "brief": "ColdFusion IMQ", - "stability": "stable" - }, - { - "id": "cassandra", - "value": "cassandra", - "brief": "Apache Cassandra", - "stability": "stable" - }, - { - "id": "hbase", - "value": "hbase", - "brief": "Apache HBase", - "stability": "stable" - }, - { - "id": "mongodb", - "value": "mongodb", - "brief": "MongoDB", - "stability": "stable" - }, - { - "id": "redis", - "value": "redis", - "brief": "Redis", - "stability": "stable" - }, - { - "id": "couchbase", - "value": "couchbase", - "brief": "Couchbase", - "stability": "stable" - }, - { - "id": "couchdb", - "value": "couchdb", - "brief": "CouchDB", - "stability": "stable" - }, - { - "id": "cosmosdb", - "value": "cosmosdb", - "brief": "Microsoft Azure Cosmos DB", - "stability": "stable" - }, - { - "id": "dynamodb", - "value": "dynamodb", - "brief": "Amazon DynamoDB", - "stability": "stable" - }, - { - "id": "neo4j", - "value": "neo4j", - "brief": "Neo4j", - "stability": "stable" - }, - { - "id": "geode", - "value": "geode", - "brief": "Apache Geode", - "stability": "stable" - }, - { - "id": "elasticsearch", - "value": "elasticsearch", - "brief": "Elasticsearch", - "stability": "stable" - }, - { - "id": "memcached", - "value": "memcached", - "brief": "Memcached", - "stability": "stable" - }, - { - "id": "cockroachdb", - "value": "cockroachdb", - "brief": "CockroachDB", - "stability": "stable" - }, - { - "id": "opensearch", - "value": "opensearch", - "brief": "OpenSearch", - "stability": "stable" - }, - { - "id": "clickhouse", - "value": "clickhouse", - "brief": "ClickHouse", - "stability": "stable" - }, - { - "id": "spanner", - "value": "spanner", - "brief": "Cloud Spanner", - "stability": "stable" - }, - { - "id": "trino", - "value": "trino", - "brief": "Trino", - "stability": "stable" - } - ] - }, - "brief": "An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers.", - "tag": "db-generic", - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "db.user", - "type": "string", - "brief": "Username for accessing the database.\n", - "examples": [ - "readonly_user", - "reporting_user" - ], - "tag": "connection-level", - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "db.user", - "type": "string", - "brief": "Username for accessing the database.\n", - "examples": [ - "readonly_user", - "reporting_user" - ], - "tag": "db-generic", - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "http.request.body.size", - "type": "int", - "brief": "The size of the request payload body in bytes. This is the number of bytes transferred excluding headers and is often, but not always, present as the [Content-Length](https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length) header. For requests using transport encoding, this should be the compressed size.\n", - "examples": 3495, - "requirement_level": "recommended", - "stability": "development" - }, - { - "name": "http.request.header", - "type": "template[string[]]", - "brief": "HTTP request headers, `` being the normalized HTTP Header name (lowercase), the value being the header values.\n", - "examples": [ - [ - "application/json" - ], - [ - "1.2.3.4", - "1.2.3.5" - ] - ], - "requirement_level": "recommended", - "note": "Instrumentations SHOULD require an explicit configuration of which headers are to be captured. Including all request headers can be a security risk - explicit configuration helps avoid leaking sensitive information.\nThe `User-Agent` header is already captured in the `user_agent.original` attribute. Users MAY explicitly configure instrumentations to capture them even though it is not recommended.\nThe attribute value MUST consist of either multiple header values as an array of strings or a single-item array containing a possibly comma-concatenated string, depending on the way the HTTP library provides access to headers.\n", - "stability": "stable" - }, - { - "name": "http.request.method", - "type": { - "members": [ - { - "id": "connect", - "value": "CONNECT", - "brief": "CONNECT method.", - "stability": "stable" - }, - { - "id": "delete", - "value": "DELETE", - "brief": "DELETE method.", - "stability": "stable" - }, - { - "id": "get", - "value": "GET", - "brief": "GET method.", - "stability": "stable" - }, - { - "id": "head", - "value": "HEAD", - "brief": "HEAD method.", - "stability": "stable" - }, - { - "id": "options", - "value": "OPTIONS", - "brief": "OPTIONS method.", - "stability": "stable" - }, - { - "id": "patch", - "value": "PATCH", - "brief": "PATCH method.", - "stability": "stable" - }, - { - "id": "post", - "value": "POST", - "brief": "POST method.", - "stability": "stable" - }, - { - "id": "put", - "value": "PUT", - "brief": "PUT method.", - "stability": "stable" - }, - { - "id": "trace", - "value": "TRACE", - "brief": "TRACE method.", - "stability": "stable" - }, - { - "id": "other", - "value": "_OTHER", - "brief": "Any HTTP method that the instrumentation has no prior knowledge of.", - "stability": "stable" - } - ] - }, - "brief": "HTTP request method.", - "examples": [ - "GET", - "POST", - "HEAD" - ], - "requirement_level": "recommended", - "note": "HTTP request method value SHOULD be \"known\" to the instrumentation.\nBy default, this convention defines \"known\" methods as the ones listed in [RFC9110](https://www.rfc-editor.org/rfc/rfc9110.html#name-methods)\nand the PATCH method defined in [RFC5789](https://www.rfc-editor.org/rfc/rfc5789.html).\n\nIf the HTTP request method is not known to instrumentation, it MUST set the `http.request.method` attribute to `_OTHER`.\n\nIf the HTTP instrumentation could end up converting valid HTTP request methods to `_OTHER`, then it MUST provide a way to override\nthe list of known HTTP methods. If this override is done via environment variable, then the environment variable MUST be named\nOTEL_INSTRUMENTATION_HTTP_KNOWN_METHODS and support a comma-separated list of case-sensitive known HTTP methods\n(this list MUST be a full override of the default known method, it is not a list of known methods in addition to the defaults).\n\nHTTP method names are case-sensitive and `http.request.method` attribute value MUST match a known HTTP method name exactly.\nInstrumentations for specific web frameworks that consider HTTP methods to be case insensitive, SHOULD populate a canonical equivalent.\nTracing instrumentations that do so, MUST also set `http.request.method_original` to the original value.\n", - "stability": "stable" - }, - { - "name": "http.request.method", - "type": { - "members": [ - { - "id": "connect", - "value": "CONNECT", - "brief": "CONNECT method.", - "stability": "stable" - }, - { - "id": "delete", - "value": "DELETE", - "brief": "DELETE method.", - "stability": "stable" - }, - { - "id": "get", - "value": "GET", - "brief": "GET method.", - "stability": "stable" - }, - { - "id": "head", - "value": "HEAD", - "brief": "HEAD method.", - "stability": "stable" - }, - { - "id": "options", - "value": "OPTIONS", - "brief": "OPTIONS method.", - "stability": "stable" - }, - { - "id": "patch", - "value": "PATCH", - "brief": "PATCH method.", - "stability": "stable" - }, - { - "id": "post", - "value": "POST", - "brief": "POST method.", - "stability": "stable" - }, - { - "id": "put", - "value": "PUT", - "brief": "PUT method.", - "stability": "stable" - }, - { - "id": "trace", - "value": "TRACE", - "brief": "TRACE method.", - "stability": "stable" - }, - { - "id": "other", - "value": "_OTHER", - "brief": "Any HTTP method that the instrumentation has no prior knowledge of.", - "stability": "stable" - } - ] - }, - "brief": "HTTP request method.", - "examples": [ - "GET", - "POST", - "HEAD" - ], - "tag": "call-level-tech-specific", - "requirement_level": "required", - "note": "HTTP request method value SHOULD be \"known\" to the instrumentation.\nBy default, this convention defines \"known\" methods as the ones listed in [RFC9110](https://www.rfc-editor.org/rfc/rfc9110.html#name-methods)\nand the PATCH method defined in [RFC5789](https://www.rfc-editor.org/rfc/rfc5789.html).\n\nIf the HTTP request method is not known to instrumentation, it MUST set the `http.request.method` attribute to `_OTHER`.\n\nIf the HTTP instrumentation could end up converting valid HTTP request methods to `_OTHER`, then it MUST provide a way to override\nthe list of known HTTP methods. If this override is done via environment variable, then the environment variable MUST be named\nOTEL_INSTRUMENTATION_HTTP_KNOWN_METHODS and support a comma-separated list of case-sensitive known HTTP methods\n(this list MUST be a full override of the default known method, it is not a list of known methods in addition to the defaults).\n\nHTTP method names are case-sensitive and `http.request.method` attribute value MUST match a known HTTP method name exactly.\nInstrumentations for specific web frameworks that consider HTTP methods to be case insensitive, SHOULD populate a canonical equivalent.\nTracing instrumentations that do so, MUST also set `http.request.method_original` to the original value.\n", - "stability": "stable" - }, - { - "name": "http.request.method_original", - "type": "string", - "brief": "Original HTTP method sent by the client in the request line.", - "examples": [ - "GeT", - "ACL", - "foo" - ], - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "http.request.resend_count", - "type": "int", - "brief": "The ordinal number of request resending attempt (for any reason, including redirects).\n", - "examples": 3, - "requirement_level": "recommended", - "note": "The resend count SHOULD be updated each time an HTTP request gets resent by the client, regardless of what was the cause of the resending (e.g. redirection, authorization failure, 503 Server Unavailable, network issues, or any other).\n", - "stability": "stable" - }, - { - "name": "http.response.body.size", - "type": "int", - "brief": "The size of the response payload body in bytes. This is the number of bytes transferred excluding headers and is often, but not always, present as the [Content-Length](https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length) header. For requests using transport encoding, this should be the compressed size.\n", - "examples": 3495, - "requirement_level": "recommended", - "stability": "development" - }, - { - "name": "http.response.header", - "type": "template[string[]]", - "brief": "HTTP response headers, `` being the normalized HTTP Header name (lowercase), the value being the header values.\n", - "examples": [ - [ - "application/json" - ], - [ - "abc", - "def" - ] - ], - "requirement_level": "recommended", - "note": "Instrumentations SHOULD require an explicit configuration of which headers are to be captured. Including all response headers can be a security risk - explicit configuration helps avoid leaking sensitive information.\nUsers MAY explicitly configure instrumentations to capture them even though it is not recommended.\nThe attribute value MUST consist of either multiple header values as an array of strings or a single-item array containing a possibly comma-concatenated string, depending on the way the HTTP library provides access to headers.\n", - "stability": "stable" - }, - { - "name": "http.response.status_code", - "type": "int", - "brief": "[HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6).", - "examples": [ - 200 - ], - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "http.route", - "type": "string", - "brief": "The matched route, that is, the path template in the format used by the respective server framework.\n", - "examples": [ - "/users/:userID?", - "{controller}/{action}/{id?}" - ], - "requirement_level": "recommended", - "note": "MUST NOT be populated when this is not supported by the HTTP server framework as the route attribute should have low-cardinality and the URI path can NOT substitute it.\nSHOULD include the [application root](/docs/http/http-spans.md#http-server-definitions) if there is one.", - "stability": "stable" - }, - { - "name": "network.carrier.icc", - "type": "string", - "brief": "The ISO 3166-1 alpha-2 2-character country code associated with the mobile carrier network.", - "examples": "DE", - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "network.carrier.mcc", - "type": "string", - "brief": "The mobile carrier country code.", - "examples": "310", - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "network.carrier.mnc", - "type": "string", - "brief": "The mobile carrier network code.", - "examples": "001", - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "network.carrier.name", - "type": "string", - "brief": "The name of the mobile carrier.", - "examples": "sprint", - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "network.connection.subtype", - "type": { - "members": [ - { - "id": "gprs", - "value": "gprs", - "brief": "GPRS", - "stability": "stable" - }, - { - "id": "edge", - "value": "edge", - "brief": "EDGE", - "stability": "stable" - }, - { - "id": "umts", - "value": "umts", - "brief": "UMTS", - "stability": "stable" - }, - { - "id": "cdma", - "value": "cdma", - "brief": "CDMA", - "stability": "stable" - }, - { - "id": "evdo_0", - "value": "evdo_0", - "brief": "EVDO Rel. 0", - "stability": "stable" - }, - { - "id": "evdo_a", - "value": "evdo_a", - "brief": "EVDO Rev. A", - "stability": "stable" - }, - { - "id": "cdma2000_1xrtt", - "value": "cdma2000_1xrtt", - "brief": "CDMA2000 1XRTT", - "stability": "stable" - }, - { - "id": "hsdpa", - "value": "hsdpa", - "brief": "HSDPA", - "stability": "stable" - }, - { - "id": "hsupa", - "value": "hsupa", - "brief": "HSUPA", - "stability": "stable" - }, - { - "id": "hspa", - "value": "hspa", - "brief": "HSPA", - "stability": "stable" - }, - { - "id": "iden", - "value": "iden", - "brief": "IDEN", - "stability": "stable" - }, - { - "id": "evdo_b", - "value": "evdo_b", - "brief": "EVDO Rev. B", - "stability": "stable" - }, - { - "id": "lte", - "value": "lte", - "brief": "LTE", - "stability": "stable" - }, - { - "id": "ehrpd", - "value": "ehrpd", - "brief": "EHRPD", - "stability": "stable" - }, - { - "id": "hspap", - "value": "hspap", - "brief": "HSPAP", - "stability": "stable" - }, - { - "id": "gsm", - "value": "gsm", - "brief": "GSM", - "stability": "stable" - }, - { - "id": "td_scdma", - "value": "td_scdma", - "brief": "TD-SCDMA", - "stability": "stable" - }, - { - "id": "iwlan", - "value": "iwlan", - "brief": "IWLAN", - "stability": "stable" - }, - { - "id": "nr", - "value": "nr", - "brief": "5G NR (New Radio)", - "stability": "stable" - }, - { - "id": "nrnsa", - "value": "nrnsa", - "brief": "5G NRNSA (New Radio Non-Standalone)", - "stability": "stable" - }, - { - "id": "lte_ca", - "value": "lte_ca", - "brief": "LTE CA", - "stability": "stable" - } - ] - }, - "brief": "This describes more details regarding the connection.type. It may be the type of cell technology connection, but it could be used for describing details about a wifi connection.", - "examples": "LTE", - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "network.connection.type", - "type": { - "members": [ - { - "id": "wifi", - "value": "wifi", - "stability": "stable" - }, - { - "id": "wired", - "value": "wired", - "stability": "stable" - }, - { - "id": "cell", - "value": "cell", - "stability": "stable" - }, - { - "id": "unavailable", - "value": "unavailable", - "stability": "stable" - }, - { - "id": "unknown", - "value": "unknown", - "stability": "stable" - } - ] - }, - "brief": "The internet connection type.", - "examples": "wifi", - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "network.io.direction", - "type": { - "members": [ - { - "id": "transmit", - "value": "transmit", - "stability": "stable" - }, - { - "id": "receive", - "value": "receive", - "stability": "stable" - } - ] - }, - "brief": "The network IO operation direction.", - "examples": [ - "transmit" - ], - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "network.local.address", - "type": "string", - "brief": "Local address of the network connection - IP address or Unix domain socket name.", - "examples": [ - "10.1.2.80", - "/tmp/my.sock" - ], - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "network.local.port", - "type": "int", - "brief": "Local port number of the network connection.", - "examples": [ - 65123 - ], - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "network.peer.address", - "type": "string", - "brief": "Peer address of the network connection - IP address or Unix domain socket name.", - "examples": [ - "10.1.2.80", - "/tmp/my.sock" - ], - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "network.peer.address", - "type": "string", - "brief": "Peer address of the network connection - IP address or Unix domain socket name.", - "examples": [ - "10.1.2.80", - "/tmp/my.sock" - ], - "tag": "connection-level", - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "network.peer.port", - "type": "int", - "brief": "Peer port number of the network connection.", - "examples": [ - 65123 - ], - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "network.peer.port", - "type": "int", - "brief": "Peer port number of the network connection.", - "examples": [ - 65123 - ], - "tag": "connection-level", - "requirement_level": { - "recommended": "If `network.peer.address` is set." - }, - "stability": "stable" - }, - { - "name": "network.protocol.name", - "type": "string", - "brief": "[OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent.", - "examples": [ - "amqp", - "http", - "mqtt" - ], - "requirement_level": "recommended", - "note": "The value SHOULD be normalized to lowercase.", - "stability": "stable" - }, - { - "name": "network.protocol.version", - "type": "string", - "brief": "Version of the protocol specified in `network.protocol.name`.", - "examples": "3.1.1", - "requirement_level": "recommended", - "note": "`network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`.\n", - "stability": "stable" - }, - { - "name": "network.transport", - "type": { - "members": [ - { - "id": "tcp", - "value": "tcp", - "brief": "TCP", - "stability": "stable" - }, - { - "id": "udp", - "value": "udp", - "brief": "UDP", - "stability": "stable" - }, - { - "id": "pipe", - "value": "pipe", - "brief": "Named or anonymous pipe.", - "stability": "stable" - }, - { - "id": "unix", - "value": "unix", - "brief": "Unix domain socket", - "stability": "stable" - } - ] - }, - "brief": "[OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication).\n", - "examples": [ - "tcp", - "udp" - ], - "requirement_level": "recommended", - "note": "The value SHOULD be normalized to lowercase.\n\nConsider always setting the transport when setting a port number, since\na port number is ambiguous without knowing the transport. For example\ndifferent processes could be listening on TCP port 12345 and UDP port 12345.\n", - "stability": "stable" - }, - { - "name": "network.transport", - "type": { - "members": [ - { - "id": "tcp", - "value": "tcp", - "brief": "TCP", - "stability": "stable" - }, - { - "id": "udp", - "value": "udp", - "brief": "UDP", - "stability": "stable" - }, - { - "id": "pipe", - "value": "pipe", - "brief": "Named or anonymous pipe.", - "stability": "stable" - }, - { - "id": "unix", - "value": "unix", - "brief": "Unix domain socket", - "stability": "stable" - } - ] - }, - "brief": "[OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication).\n", - "examples": [ - "tcp", - "udp" - ], - "tag": "connection-level", - "requirement_level": "recommended", - "note": "The value SHOULD be normalized to lowercase.\n\nConsider always setting the transport when setting a port number, since\na port number is ambiguous without knowing the transport. For example\ndifferent processes could be listening on TCP port 12345 and UDP port 12345.\n", - "stability": "stable" - }, - { - "name": "network.type", - "type": { - "members": [ - { - "id": "ipv4", - "value": "ipv4", - "brief": "IPv4", - "stability": "stable" - }, - { - "id": "ipv6", - "value": "ipv6", - "brief": "IPv6", - "stability": "stable" - } - ] - }, - "brief": "[OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent.", - "examples": [ - "ipv4", - "ipv6" - ], - "requirement_level": "recommended", - "note": "The value SHOULD be normalized to lowercase.", - "stability": "stable" - }, - { - "name": "network.type", - "type": { - "members": [ - { - "id": "ipv4", - "value": "ipv4", - "brief": "IPv4", - "stability": "stable" - }, - { - "id": "ipv6", - "value": "ipv6", - "brief": "IPv6", - "stability": "stable" - } - ] - }, - "brief": "[OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent.", - "examples": [ - "ipv4", - "ipv6" - ], - "tag": "connection-level", - "requirement_level": "recommended", - "note": "The value SHOULD be normalized to lowercase.", - "stability": "stable" - }, - { - "name": "server.address", - "type": "string", - "brief": "Name of the database host.\n", - "examples": [ - "example.com", - "10.1.2.80", - "/tmp/my.sock" - ], - "tag": "call-level-tech-specific", - "requirement_level": "recommended", - "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.\n", - "stability": "stable" - }, - { - "name": "server.address", - "type": "string", - "brief": "Name of the database host.\n", - "examples": [ - "example.com", - "10.1.2.80", - "/tmp/my.sock" - ], - "tag": "connection-level", - "requirement_level": "recommended", - "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.\n", - "stability": "stable" - }, - { - "name": "server.address", - "type": "string", - "brief": "Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name.", - "examples": [ - "example.com", - "10.1.2.80", - "/tmp/my.sock" - ], - "requirement_level": "recommended", - "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.\n", - "stability": "stable" - }, - { - "name": "server.port", - "type": "int", - "brief": "Server port number.", - "examples": [ - 80, - 8080, - 443 - ], - "requirement_level": "recommended", - "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.\n", - "stability": "stable" - }, - { - "name": "server.port", - "type": "int", - "brief": "Server port number.", - "examples": [ - 80, - 8080, - 443 - ], - "tag": "call-level-tech-specific", - "requirement_level": { - "conditionally_required": "If using a port other than the default port for this DBMS and if `server.address` is set." - }, - "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.\n", - "stability": "stable" - }, - { - "name": "server.port", - "type": "int", - "brief": "Server port number.", - "examples": [ - 80, - 8080, - 443 - ], - "tag": "connection-level", - "requirement_level": { - "conditionally_required": "If using a port other than the default port for this DBMS and if `server.address` is set." - }, - "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.\n", - "stability": "stable" - }, - { - "name": "url.fragment", - "type": "string", - "brief": "The [URI fragment](https://www.rfc-editor.org/rfc/rfc3986#section-3.5) component", - "examples": [ - "SemConv" - ], - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "url.full", - "type": "string", - "brief": "Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986)", - "examples": [ - "https://localhost:9200/index/_search?q=user.id:kimchy" - ], - "tag": "call-level-tech-specific", - "requirement_level": "required", - "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.\n`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/`.\n`url.full` SHOULD capture the absolute URL when it is available (or can be reconstructed) and SHOULD NOT be validated or modified except for sanitizing purposes.\n", - "stability": "stable" - }, - { - "name": "url.full", - "type": "string", - "brief": "Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986)", - "examples": [ - "https://www.foo.bar/search?q=OpenTelemetry#SemConv", - "//localhost" - ], - "requirement_level": "recommended", - "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.\n`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/`.\n`url.full` SHOULD capture the absolute URL when it is available (or can be reconstructed) and SHOULD NOT be validated or modified except for sanitizing purposes.\n", - "stability": "stable" - }, - { - "name": "url.path", - "type": "string", - "brief": "The [URI path](https://www.rfc-editor.org/rfc/rfc3986#section-3.3) component", - "examples": [ - "/search" - ], - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "url.query", - "type": "string", - "brief": "The [URI query](https://www.rfc-editor.org/rfc/rfc3986#section-3.4) component", - "examples": [ - "q=OpenTelemetry" - ], - "requirement_level": "recommended", - "note": "Sensitive content provided in query string SHOULD be scrubbed when instrumentations can identify it.", - "stability": "stable" - }, - { - "name": "url.scheme", - "type": "string", - "brief": "The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol.", - "examples": [ - "https", - "ftp", - "telnet" - ], - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "user_agent.original", - "type": "string", - "brief": "Full user-agent string is generated by Cosmos DB SDK", - "examples": [ - "cosmos-netstandard-sdk/3.23.0\\|3.23.1\\|1\\|X64\\|Linux 5.4.0-1098-azure 104 18\\|.NET Core 3.1.32\\|S\\|" - ], - "tag": "call-level-tech-specific", - "requirement_level": "recommended", - "note": "The user-agent value is generated by SDK which is a combination of
`sdk_version` : Current version of SDK. e.g. 'cosmos-netstandard-sdk/3.23.0'
`direct_pkg_version` : Direct package version used by Cosmos DB SDK. e.g. '3.23.1'
`number_of_client_instances` : Number of cosmos client instances created by the application. e.g. '1'
`type_of_machine_architecture` : Machine architecture. e.g. 'X64'
`operating_system` : Operating System. e.g. 'Linux 5.4.0-1098-azure 104 18'
`runtime_framework` : Runtime Framework. e.g. '.NET Core 3.1.32'
`failover_information` : Generated key to determine if region failover enabled.\n Format Reg-{D (Disabled discovery)}-S(application region)|L(List of preferred regions)|N(None, user did not configure it).\n Default value is \"NS\".\n", - "stability": "stable" - }, - { - "name": "user_agent.original", - "type": "string", - "brief": "Value of the [HTTP User-Agent](https://www.rfc-editor.org/rfc/rfc9110.html#field.user-agent) header sent by the client.\n", - "examples": [ - "CERN-LineMode/2.15 libwww/2.17b3", - "Mozilla/5.0 (iPhone; CPU iPhone OS 14_7_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.2 Mobile/15E148 Safari/604.1" - ], - "requirement_level": "recommended", - "stability": "stable" - } - ] -} \ No newline at end of file +[ + { + "name": "db.cassandra.consistency_level", + "type": { + "members": [ + { + "id": "all", + "value": "all", + "stability": "stable" + }, + { + "id": "each_quorum", + "value": "each_quorum", + "stability": "stable" + }, + { + "id": "quorum", + "value": "quorum", + "stability": "stable" + }, + { + "id": "local_quorum", + "value": "local_quorum", + "stability": "stable" + }, + { + "id": "one", + "value": "one", + "stability": "stable" + }, + { + "id": "two", + "value": "two", + "stability": "stable" + }, + { + "id": "three", + "value": "three", + "stability": "stable" + }, + { + "id": "local_one", + "value": "local_one", + "stability": "stable" + }, + { + "id": "any", + "value": "any", + "stability": "stable" + }, + { + "id": "serial", + "value": "serial", + "stability": "stable" + }, + { + "id": "local_serial", + "value": "local_serial", + "stability": "stable" + } + ] + }, + "brief": "The consistency level of the query. Based on consistency values from [CQL](https://docs.datastax.com/en/cassandra-oss/3.0/cassandra/dml/dmlConfigConsistency.html).\n", + "tag": "call-level-tech-specific-cassandra", + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "db.cassandra.consistency_level", + "type": { + "members": [ + { + "id": "all", + "value": "all", + "stability": "stable" + }, + { + "id": "each_quorum", + "value": "each_quorum", + "stability": "stable" + }, + { + "id": "quorum", + "value": "quorum", + "stability": "stable" + }, + { + "id": "local_quorum", + "value": "local_quorum", + "stability": "stable" + }, + { + "id": "one", + "value": "one", + "stability": "stable" + }, + { + "id": "two", + "value": "two", + "stability": "stable" + }, + { + "id": "three", + "value": "three", + "stability": "stable" + }, + { + "id": "local_one", + "value": "local_one", + "stability": "stable" + }, + { + "id": "any", + "value": "any", + "stability": "stable" + }, + { + "id": "serial", + "value": "serial", + "stability": "stable" + }, + { + "id": "local_serial", + "value": "local_serial", + "stability": "stable" + } + ] + }, + "brief": "The consistency level of the query. Based on consistency values from [CQL](https://docs.datastax.com/en/cassandra-oss/3.0/cassandra/dml/dmlConfigConsistency.html).\n", + "tag": "tech-specific-cassandra", + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "db.cassandra.coordinator.dc", + "type": "string", + "brief": "The data center of the coordinating node for a query.\n", + "examples": "us-west-2", + "tag": "call-level-tech-specific-cassandra", + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "db.cassandra.coordinator.dc", + "type": "string", + "brief": "The data center of the coordinating node for a query.\n", + "examples": "us-west-2", + "tag": "tech-specific-cassandra", + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "db.cassandra.coordinator.id", + "type": "string", + "brief": "The ID of the coordinating node for a query.\n", + "examples": "be13faa2-8574-4d71-926d-27f16cf8a7af", + "tag": "call-level-tech-specific-cassandra", + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "db.cassandra.coordinator.id", + "type": "string", + "brief": "The ID of the coordinating node for a query.\n", + "examples": "be13faa2-8574-4d71-926d-27f16cf8a7af", + "tag": "tech-specific-cassandra", + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "db.cassandra.idempotence", + "type": "boolean", + "brief": "Whether or not the query is idempotent.\n", + "tag": "call-level-tech-specific-cassandra", + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "db.cassandra.idempotence", + "type": "boolean", + "brief": "Whether or not the query is idempotent.\n", + "tag": "tech-specific-cassandra", + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "db.cassandra.page_size", + "type": "int", + "brief": "The fetch size used for paging, i.e. how many rows will be returned at once.\n", + "examples": [ + 5000 + ], + "tag": "call-level-tech-specific-cassandra", + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "db.cassandra.page_size", + "type": "int", + "brief": "The fetch size used for paging, i.e. how many rows will be returned at once.\n", + "examples": [ + 5000 + ], + "tag": "tech-specific-cassandra", + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "db.cassandra.speculative_execution_count", + "type": "int", + "brief": "The number of times a query was speculatively executed. Not set or `0` if the query was not executed speculatively.\n", + "examples": [ + 0, + 2 + ], + "tag": "call-level-tech-specific-cassandra", + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "db.cassandra.speculative_execution_count", + "type": "int", + "brief": "The number of times a query was speculatively executed. Not set or `0` if the query was not executed speculatively.\n", + "examples": [ + 0, + 2 + ], + "tag": "tech-specific-cassandra", + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "db.cassandra.table", + "type": "string", + "brief": "The name of the primary Cassandra table that the operation is acting upon, including the keyspace name (if applicable).", + "examples": "mytable", + "tag": "call-level-tech-specific-cassandra", + "requirement_level": "recommended", + "note": "This mirrors the db.sql.table attribute but references cassandra rather than sql. It is not recommended to attempt any client-side parsing of `db.statement` just to get this property, but it should be set if it is provided by the library being instrumented. If the operation is acting upon an anonymous table, or more than one table, this value MUST NOT be set.\n", + "stability": "stable" + }, + { + "name": "db.cassandra.table", + "type": "string", + "brief": "The name of the primary Cassandra table that the operation is acting upon, including the keyspace name (if applicable).", + "examples": "mytable", + "tag": "tech-specific-cassandra", + "requirement_level": "recommended", + "note": "This mirrors the db.sql.table attribute but references cassandra rather than sql. It is not recommended to attempt any client-side parsing of `db.statement` just to get this property, but it should be set if it is provided by the library being instrumented. If the operation is acting upon an anonymous table, or more than one table, this value MUST NOT be set.\n", + "stability": "stable" + }, + { + "name": "db.connection_string", + "type": "string", + "brief": "The connection string used to connect to the database. It is recommended to remove embedded credentials.\n", + "examples": "Server=(localdb)\\v11.0;Integrated Security=true;", + "tag": "connection-level", + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "db.connection_string", + "type": "string", + "brief": "The connection string used to connect to the database. It is recommended to remove embedded credentials.\n", + "examples": "Server=(localdb)\\v11.0;Integrated Security=true;", + "tag": "db-generic", + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "db.cosmosdb.client_id", + "type": "string", + "brief": "Unique Cosmos client instance id.", + "examples": "3ba4827d-4422-483f-b59f-85b74211c11d", + "tag": "call-level-tech-specific", + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "db.cosmosdb.client_id", + "type": "string", + "brief": "Unique Cosmos client instance id.", + "examples": "3ba4827d-4422-483f-b59f-85b74211c11d", + "tag": "tech-specific-cosmosdb", + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "db.cosmosdb.connection_mode", + "type": { + "members": [ + { + "id": "gateway", + "value": "gateway", + "brief": "Gateway (HTTP) connections mode", + "stability": "stable" + }, + { + "id": "direct", + "value": "direct", + "brief": "Direct connection.", + "stability": "stable" + } + ] + }, + "brief": "Cosmos client connection mode.", + "tag": "call-level-tech-specific", + "requirement_level": { + "conditionally_required": "if not `direct` (or pick gw as default)" + }, + "stability": "stable" + }, + { + "name": "db.cosmosdb.connection_mode", + "type": { + "members": [ + { + "id": "gateway", + "value": "gateway", + "brief": "Gateway (HTTP) connections mode", + "stability": "stable" + }, + { + "id": "direct", + "value": "direct", + "brief": "Direct connection.", + "stability": "stable" + } + ] + }, + "brief": "Cosmos client connection mode.", + "tag": "tech-specific-cosmosdb", + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "db.cosmosdb.container", + "type": "string", + "brief": "Cosmos DB container name.", + "examples": "anystring", + "tag": "call-level-tech-specific", + "requirement_level": { + "conditionally_required": "if available" + }, + "stability": "stable" + }, + { + "name": "db.cosmosdb.container", + "type": "string", + "brief": "Cosmos DB container name.", + "examples": "anystring", + "tag": "tech-specific-cosmosdb", + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "db.cosmosdb.operation_type", + "type": { + "members": [ + { + "id": "invalid", + "value": "Invalid", + "stability": "stable" + }, + { + "id": "create", + "value": "Create", + "stability": "stable" + }, + { + "id": "patch", + "value": "Patch", + "stability": "stable" + }, + { + "id": "read", + "value": "Read", + "stability": "stable" + }, + { + "id": "read_feed", + "value": "ReadFeed", + "stability": "stable" + }, + { + "id": "delete", + "value": "Delete", + "stability": "stable" + }, + { + "id": "replace", + "value": "Replace", + "stability": "stable" + }, + { + "id": "execute", + "value": "Execute", + "stability": "stable" + }, + { + "id": "query", + "value": "Query", + "stability": "stable" + }, + { + "id": "head", + "value": "Head", + "stability": "stable" + }, + { + "id": "head_feed", + "value": "HeadFeed", + "stability": "stable" + }, + { + "id": "upsert", + "value": "Upsert", + "stability": "stable" + }, + { + "id": "batch", + "value": "Batch", + "stability": "stable" + }, + { + "id": "query_plan", + "value": "QueryPlan", + "stability": "stable" + }, + { + "id": "execute_javascript", + "value": "ExecuteJavaScript", + "stability": "stable" + } + ] + }, + "brief": "CosmosDB Operation Type.", + "tag": "call-level-tech-specific", + "requirement_level": { + "conditionally_required": "when performing one of the operations in this list" + }, + "stability": "stable" + }, + { + "name": "db.cosmosdb.operation_type", + "type": { + "members": [ + { + "id": "invalid", + "value": "Invalid", + "stability": "stable" + }, + { + "id": "create", + "value": "Create", + "stability": "stable" + }, + { + "id": "patch", + "value": "Patch", + "stability": "stable" + }, + { + "id": "read", + "value": "Read", + "stability": "stable" + }, + { + "id": "read_feed", + "value": "ReadFeed", + "stability": "stable" + }, + { + "id": "delete", + "value": "Delete", + "stability": "stable" + }, + { + "id": "replace", + "value": "Replace", + "stability": "stable" + }, + { + "id": "execute", + "value": "Execute", + "stability": "stable" + }, + { + "id": "query", + "value": "Query", + "stability": "stable" + }, + { + "id": "head", + "value": "Head", + "stability": "stable" + }, + { + "id": "head_feed", + "value": "HeadFeed", + "stability": "stable" + }, + { + "id": "upsert", + "value": "Upsert", + "stability": "stable" + }, + { + "id": "batch", + "value": "Batch", + "stability": "stable" + }, + { + "id": "query_plan", + "value": "QueryPlan", + "stability": "stable" + }, + { + "id": "execute_javascript", + "value": "ExecuteJavaScript", + "stability": "stable" + } + ] + }, + "brief": "CosmosDB Operation Type.", + "tag": "tech-specific-cosmosdb", + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "db.cosmosdb.request_charge", + "type": "double", + "brief": "RU consumed for that operation", + "examples": [ + 46.18, + 1.0 + ], + "tag": "call-level-tech-specific", + "requirement_level": { + "conditionally_required": "when available" + }, + "stability": "stable" + }, + { + "name": "db.cosmosdb.request_charge", + "type": "double", + "brief": "RU consumed for that operation", + "examples": [ + 46.18, + 1.0 + ], + "tag": "tech-specific-cosmosdb", + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "db.cosmosdb.request_content_length", + "type": "int", + "brief": "Request payload size in bytes", + "tag": "call-level-tech-specific", + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "db.cosmosdb.request_content_length", + "type": "int", + "brief": "Request payload size in bytes", + "tag": "tech-specific-cosmosdb", + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "db.cosmosdb.status_code", + "type": "int", + "brief": "Cosmos DB status code.", + "examples": [ + 200, + 201 + ], + "tag": "call-level-tech-specific", + "requirement_level": { + "conditionally_required": "if response was received" + }, + "stability": "stable" + }, + { + "name": "db.cosmosdb.status_code", + "type": "int", + "brief": "Cosmos DB status code.", + "examples": [ + 200, + 201 + ], + "tag": "tech-specific-cosmosdb", + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "db.cosmosdb.sub_status_code", + "type": "int", + "brief": "Cosmos DB sub status code.", + "examples": [ + 1000, + 1002 + ], + "tag": "call-level-tech-specific", + "requirement_level": { + "conditionally_required": "when response was received and contained sub-code." + }, + "stability": "stable" + }, + { + "name": "db.cosmosdb.sub_status_code", + "type": "int", + "brief": "Cosmos DB sub status code.", + "examples": [ + 1000, + 1002 + ], + "tag": "tech-specific-cosmosdb", + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "db.elasticsearch.cluster.name", + "type": "string", + "brief": "Represents the identifier of an Elasticsearch cluster.\n", + "examples": [ + "e9106fc68e3044f0b1475b04bf4ffd5f" + ], + "tag": "call-level-tech-specific", + "requirement_level": { + "recommended": "When communicating with an Elastic Cloud deployment, this should be collected from the \"X-Found-Handling-Cluster\" HTTP response header.\n" + }, + "stability": "stable" + }, + { + "name": "db.elasticsearch.cluster.name", + "type": "string", + "brief": "Represents the identifier of an Elasticsearch cluster.\n", + "examples": [ + "e9106fc68e3044f0b1475b04bf4ffd5f" + ], + "tag": "tech-specific-elasticsearch", + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "db.elasticsearch.node.name", + "type": "string", + "brief": "Represents the human-readable identifier of the node/instance to which a request was routed.\n", + "examples": [ + "instance-0000000001" + ], + "tag": "call-level-tech-specific", + "requirement_level": { + "recommended": "When communicating with an Elastic Cloud deployment, this should be collected from the \"X-Found-Handling-Instance\" HTTP response header.\n" + }, + "stability": "stable" + }, + { + "name": "db.elasticsearch.node.name", + "type": "string", + "brief": "Represents the human-readable identifier of the node/instance to which a request was routed.\n", + "examples": [ + "instance-0000000001" + ], + "tag": "tech-specific-elasticsearch", + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "db.elasticsearch.path_parts", + "type": "template[string]", + "brief": "A dynamic value in the url path.\n", + "examples": [ + "db.elasticsearch.path_parts.index=test-index", + "db.elasticsearch.path_parts.doc_id=123" + ], + "tag": "call-level-tech-specific", + "requirement_level": { + "conditionally_required": "when the url has dynamic values" + }, + "note": "Many Elasticsearch url paths allow dynamic values. These SHOULD be recorded in span attributes in the format `db.elasticsearch.path_parts.`, where `` is the url path part name. The implementation SHOULD reference the [elasticsearch schema](https://raw.githubusercontent.com/elastic/elasticsearch-specification/main/output/schema/schema.json) in order to map the path part values to their names.\n", + "stability": "stable" + }, + { + "name": "db.elasticsearch.path_parts", + "type": "template[string]", + "brief": "A dynamic value in the url path.\n", + "examples": [ + "db.elasticsearch.path_parts.index=test-index", + "db.elasticsearch.path_parts.doc_id=123" + ], + "tag": "tech-specific-elasticsearch", + "requirement_level": "recommended", + "note": "Many Elasticsearch url paths allow dynamic values. These SHOULD be recorded in span attributes in the format `db.elasticsearch.path_parts.`, where `` is the url path part name. The implementation SHOULD reference the [elasticsearch schema](https://raw.githubusercontent.com/elastic/elasticsearch-specification/main/output/schema/schema.json) in order to map the path part values to their names.\n", + "stability": "stable" + }, + { + "name": "db.instance.id", + "type": "string", + "brief": "An identifier (address, unique name, or any other identifier) of the database instance that is executing queries or mutations on the current connection. This is useful in cases where the database is running in a clustered environment and the instrumentation is able to record the node executing the query. The client may obtain this value in databases like MySQL using queries like `select @@hostname`.\n", + "examples": "mysql-e26b99z.example.com", + "tag": "connection-level", + "requirement_level": { + "recommended": "If different from the `server.address`" + }, + "stability": "stable" + }, + { + "name": "db.instance.id", + "type": "string", + "brief": "An identifier (address, unique name, or any other identifier) of the database instance that is executing queries or mutations on the current connection. This is useful in cases where the database is running in a clustered environment and the instrumentation is able to record the node executing the query. The client may obtain this value in databases like MySQL using queries like `select @@hostname`.\n", + "examples": "mysql-e26b99z.example.com", + "tag": "db-generic", + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "db.jdbc.driver_classname", + "type": "string", + "brief": "The fully-qualified class name of the [Java Database Connectivity (JDBC)](https://docs.oracle.com/javase/8/docs/technotes/guides/jdbc/) driver used to connect.\n", + "examples": [ + "org.postgresql.Driver", + "com.microsoft.sqlserver.jdbc.SQLServerDriver" + ], + "tag": "connection-level-tech-specific", + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "db.jdbc.driver_classname", + "type": "string", + "brief": "The fully-qualified class name of the [Java Database Connectivity (JDBC)](https://docs.oracle.com/javase/8/docs/technotes/guides/jdbc/) driver used to connect.\n", + "examples": [ + "org.postgresql.Driver", + "com.microsoft.sqlserver.jdbc.SQLServerDriver" + ], + "tag": "tech-specific-jdbc", + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "db.mongodb.collection", + "type": "string", + "brief": "The MongoDB collection being accessed within the database stated in `db.name`.\n", + "examples": [ + "customers", + "products" + ], + "tag": "call-level-tech-specific", + "requirement_level": "required", + "stability": "stable" + }, + { + "name": "db.mongodb.collection", + "type": "string", + "brief": "The MongoDB collection being accessed within the database stated in `db.name`.\n", + "examples": [ + "customers", + "products" + ], + "tag": "tech-specific-mongodb", + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "db.mssql.instance_name", + "type": "string", + "brief": "The Microsoft SQL Server [instance name](https://docs.microsoft.com/sql/connect/jdbc/building-the-connection-url?view=sql-server-ver15) connecting to. This name is used to determine the port of a named instance.\n", + "examples": "MSSQLSERVER", + "tag": "connection-level-tech-specific", + "requirement_level": "recommended", + "note": "If setting a `db.mssql.instance_name`, `server.port` is no longer required (but still recommended if non-standard).\n", + "stability": "stable" + }, + { + "name": "db.mssql.instance_name", + "type": "string", + "brief": "The Microsoft SQL Server [instance name](https://docs.microsoft.com/sql/connect/jdbc/building-the-connection-url?view=sql-server-ver15) connecting to. This name is used to determine the port of a named instance.\n", + "examples": "MSSQLSERVER", + "tag": "tech-specific-mssql", + "requirement_level": "recommended", + "note": "If setting a `db.mssql.instance_name`, `server.port` is no longer required (but still recommended if non-standard).\n", + "stability": "stable" + }, + { + "name": "db.name", + "type": "string", + "brief": "The HBase namespace.\n", + "examples": [ + "mynamespace" + ], + "tag": "call-level-tech-specific", + "requirement_level": { + "conditionally_required": "If applicable." + }, + "note": "For HBase the `db.name` should be set to the HBase namespace.", + "stability": "stable" + }, + { + "name": "db.name", + "type": "string", + "brief": "The keyspace name in Cassandra.\n", + "examples": [ + "mykeyspace" + ], + "tag": "call-level-tech-specific-cassandra", + "requirement_level": { + "conditionally_required": "If applicable." + }, + "note": "For Cassandra the `db.name` should be set to the Cassandra keyspace name.", + "stability": "stable" + }, + { + "name": "db.name", + "type": "string", + "brief": "This attribute is used to report the name of the database being accessed. For commands that switch the database, this should be set to the target database (even if the command fails).\n", + "examples": [ + "customers", + "main" + ], + "tag": "call-level", + "requirement_level": { + "conditionally_required": "If applicable." + }, + "note": "In some SQL databases, the database name to be used is called \"schema name\". In case there are multiple layers that could be considered for database name (e.g. Oracle instance name and schema name), the database name to be used is the more specific layer (e.g. Oracle schema name).\n", + "stability": "stable" + }, + { + "name": "db.name", + "type": "string", + "brief": "This attribute is used to report the name of the database being accessed. For commands that switch the database, this should be set to the target database (even if the command fails).\n", + "examples": [ + "customers", + "main" + ], + "tag": "db-generic", + "requirement_level": "recommended", + "note": "In some SQL databases, the database name to be used is called \"schema name\". In case there are multiple layers that could be considered for database name (e.g. Oracle instance name and schema name), the database name to be used is the more specific layer (e.g. Oracle schema name).\n", + "stability": "stable" + }, + { + "name": "db.operation", + "type": "string", + "brief": "The HTTP method + the target REST route.\n", + "examples": [ + "GET /{db}/{docid}" + ], + "tag": "call-level-tech-specific", + "requirement_level": { + "conditionally_required": "If `db.statement` is not applicable." + }, + "note": "In **CouchDB**, `db.operation` should be set to the HTTP method + the target REST route according to the API reference documentation. For example, when retrieving a document, `db.operation` would be set to (literally, i.e., without replacing the placeholders with concrete values): [`GET /{db}/{docid}`](http://docs.couchdb.org/en/stable/api/document/common.html#get--db-docid).\n", + "stability": "stable" + }, + { + "name": "db.operation", + "type": "string", + "brief": "The endpoint identifier for the request.", + "examples": [ + "search", + "ml.close_job", + "cat.aliases" + ], + "tag": "call-level-tech-specific", + "requirement_level": "required", + "note": "When setting this to an SQL keyword, it is not recommended to attempt any client-side parsing of `db.statement` just to get this property, but it should be set if the operation name is provided by the library being instrumented. If the SQL statement has an ambiguous operation, or performs more than one operation, this value may be omitted.\n", + "stability": "stable" + }, + { + "name": "db.operation", + "type": "string", + "brief": "The name of the operation being executed, e.g. the [MongoDB command name](https://docs.mongodb.com/manual/reference/command/#database-operations) such as `findAndModify`, or the SQL keyword.\n", + "examples": [ + "findAndModify", + "HMSET", + "SELECT" + ], + "tag": "call-level", + "requirement_level": { + "conditionally_required": "If `db.statement` is not applicable." + }, + "note": "When setting this to an SQL keyword, it is not recommended to attempt any client-side parsing of `db.statement` just to get this property, but it should be set if the operation name is provided by the library being instrumented. If the SQL statement has an ambiguous operation, or performs more than one operation, this value may be omitted.\n", + "stability": "stable" + }, + { + "name": "db.operation", + "type": "string", + "brief": "The name of the operation being executed, e.g. the [MongoDB command name](https://docs.mongodb.com/manual/reference/command/#database-operations) such as `findAndModify`, or the SQL keyword.\n", + "examples": [ + "findAndModify", + "HMSET", + "SELECT" + ], + "tag": "db-generic", + "requirement_level": "recommended", + "note": "When setting this to an SQL keyword, it is not recommended to attempt any client-side parsing of `db.statement` just to get this property, but it should be set if the operation name is provided by the library being instrumented. If the SQL statement has an ambiguous operation, or performs more than one operation, this value may be omitted.\n", + "stability": "stable" + }, + { + "name": "db.redis.database_index", + "type": "int", + "brief": "The index of the database being accessed as used in the [`SELECT` command](https://redis.io/commands/select), provided as an integer. To be used instead of the generic `db.name` attribute.\n", + "examples": [ + 0, + 1, + 15 + ], + "tag": "call-level-tech-specific", + "requirement_level": { + "conditionally_required": "If other than the default database (`0`)." + }, + "stability": "stable" + }, + { + "name": "db.redis.database_index", + "type": "int", + "brief": "The index of the database being accessed as used in the [`SELECT` command](https://redis.io/commands/select), provided as an integer. To be used instead of the generic `db.name` attribute.\n", + "examples": [ + 0, + 1, + 15 + ], + "tag": "tech-specific-redis", + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "db.sql.table", + "type": "string", + "brief": "The name of the primary table that the operation is acting upon, including the database name (if applicable).", + "examples": [ + "public.users", + "customers" + ], + "tag": "call-level-tech-specific", + "requirement_level": "recommended", + "note": "It is not recommended to attempt any client-side parsing of `db.statement` just to get this property, but it should be set if it is provided by the library being instrumented. If the operation is acting upon an anonymous table, or more than one table, this value MUST NOT be set.\n", + "stability": "stable" + }, + { + "name": "db.sql.table", + "type": "string", + "brief": "The name of the primary table that the operation is acting upon, including the database name (if applicable).", + "examples": [ + "public.users", + "customers" + ], + "tag": "tech-specific-sql", + "requirement_level": "recommended", + "note": "It is not recommended to attempt any client-side parsing of `db.statement` just to get this property, but it should be set if it is provided by the library being instrumented. If the operation is acting upon an anonymous table, or more than one table, this value MUST NOT be set.\n", + "stability": "stable" + }, + { + "name": "db.statement", + "type": "string", + "brief": "The database statement being executed.\n", + "examples": [ + "SELECT * FROM wuser_table", + "SET mykey \"WuValue\"" + ], + "tag": "call-level", + "requirement_level": { + "recommended": "Should be collected by default only if there is sanitization that excludes sensitive information.\n" + }, + "stability": "stable" + }, + { + "name": "db.statement", + "type": "string", + "brief": "The database statement being executed.\n", + "examples": [ + "SELECT * FROM wuser_table", + "SET mykey \"WuValue\"" + ], + "tag": "db-generic", + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "db.statement", + "type": "string", + "brief": "The full syntax of the Redis CLI command.\n", + "examples": [ + "HMSET myhash field1 'Hello' field2 'World'" + ], + "tag": "call-level-tech-specific", + "requirement_level": { + "recommended": "Should be collected by default only if there is sanitization that excludes sensitive information.\n" + }, + "note": "For **Redis**, the value provided for `db.statement` SHOULD correspond to the syntax of the Redis CLI. If, for example, the [`HMSET` command](https://redis.io/commands/hmset) is invoked, `\"HMSET myhash field1 'Hello' field2 'World'\"` would be a suitable value for `db.statement`.\n", + "stability": "stable" + }, + { + "name": "db.statement", + "type": "string", + "brief": "The request body for a [search-type query](https://www.elastic.co/guide/en/elasticsearch/reference/current/search.html), as a json string.", + "examples": [ + "\"{\\\"query\\\":{\\\"term\\\":{\\\"user.id\\\":\\\"kimchy\\\"}}}\"" + ], + "tag": "call-level-tech-specific", + "requirement_level": { + "recommended": "Should be collected by default for search-type queries and only if there is sanitization that excludes sensitive information.\n" + }, + "stability": "stable" + }, + { + "name": "db.system", + "type": { + "members": [ + { + "id": "other_sql", + "value": "other_sql", + "brief": "Some other SQL database. Fallback only. See notes.", + "stability": "stable" + }, + { + "id": "mssql", + "value": "mssql", + "brief": "Microsoft SQL Server", + "stability": "stable" + }, + { + "id": "mssqlcompact", + "value": "mssqlcompact", + "brief": "Microsoft SQL Server Compact", + "stability": "stable" + }, + { + "id": "mysql", + "value": "mysql", + "brief": "MySQL", + "stability": "stable" + }, + { + "id": "oracle", + "value": "oracle", + "brief": "Oracle Database", + "stability": "stable" + }, + { + "id": "db2", + "value": "db2", + "brief": "IBM Db2", + "stability": "stable" + }, + { + "id": "postgresql", + "value": "postgresql", + "brief": "PostgreSQL", + "stability": "stable" + }, + { + "id": "redshift", + "value": "redshift", + "brief": "Amazon Redshift", + "stability": "stable" + }, + { + "id": "hive", + "value": "hive", + "brief": "Apache Hive", + "stability": "stable" + }, + { + "id": "cloudscape", + "value": "cloudscape", + "brief": "Cloudscape", + "stability": "stable" + }, + { + "id": "hsqldb", + "value": "hsqldb", + "brief": "HyperSQL DataBase", + "stability": "stable" + }, + { + "id": "progress", + "value": "progress", + "brief": "Progress Database", + "stability": "stable" + }, + { + "id": "maxdb", + "value": "maxdb", + "brief": "SAP MaxDB", + "stability": "stable" + }, + { + "id": "hanadb", + "value": "hanadb", + "brief": "SAP HANA", + "stability": "stable" + }, + { + "id": "ingres", + "value": "ingres", + "brief": "Ingres", + "stability": "stable" + }, + { + "id": "firstsql", + "value": "firstsql", + "brief": "FirstSQL", + "stability": "stable" + }, + { + "id": "edb", + "value": "edb", + "brief": "EnterpriseDB", + "stability": "stable" + }, + { + "id": "cache", + "value": "cache", + "brief": "InterSystems Cach\u00e9", + "stability": "stable" + }, + { + "id": "adabas", + "value": "adabas", + "brief": "Adabas (Adaptable Database System)", + "stability": "stable" + }, + { + "id": "firebird", + "value": "firebird", + "brief": "Firebird", + "stability": "stable" + }, + { + "id": "derby", + "value": "derby", + "brief": "Apache Derby", + "stability": "stable" + }, + { + "id": "filemaker", + "value": "filemaker", + "brief": "FileMaker", + "stability": "stable" + }, + { + "id": "informix", + "value": "informix", + "brief": "Informix", + "stability": "stable" + }, + { + "id": "instantdb", + "value": "instantdb", + "brief": "InstantDB", + "stability": "stable" + }, + { + "id": "interbase", + "value": "interbase", + "brief": "InterBase", + "stability": "stable" + }, + { + "id": "mariadb", + "value": "mariadb", + "brief": "MariaDB", + "stability": "stable" + }, + { + "id": "netezza", + "value": "netezza", + "brief": "Netezza", + "stability": "stable" + }, + { + "id": "pervasive", + "value": "pervasive", + "brief": "Pervasive PSQL", + "stability": "stable" + }, + { + "id": "pointbase", + "value": "pointbase", + "brief": "PointBase", + "stability": "stable" + }, + { + "id": "sqlite", + "value": "sqlite", + "brief": "SQLite", + "stability": "stable" + }, + { + "id": "sybase", + "value": "sybase", + "brief": "Sybase", + "stability": "stable" + }, + { + "id": "teradata", + "value": "teradata", + "brief": "Teradata", + "stability": "stable" + }, + { + "id": "vertica", + "value": "vertica", + "brief": "Vertica", + "stability": "stable" + }, + { + "id": "h2", + "value": "h2", + "brief": "H2", + "stability": "stable" + }, + { + "id": "coldfusion", + "value": "coldfusion", + "brief": "ColdFusion IMQ", + "stability": "stable" + }, + { + "id": "cassandra", + "value": "cassandra", + "brief": "Apache Cassandra", + "stability": "stable" + }, + { + "id": "hbase", + "value": "hbase", + "brief": "Apache HBase", + "stability": "stable" + }, + { + "id": "mongodb", + "value": "mongodb", + "brief": "MongoDB", + "stability": "stable" + }, + { + "id": "redis", + "value": "redis", + "brief": "Redis", + "stability": "stable" + }, + { + "id": "couchbase", + "value": "couchbase", + "brief": "Couchbase", + "stability": "stable" + }, + { + "id": "couchdb", + "value": "couchdb", + "brief": "CouchDB", + "stability": "stable" + }, + { + "id": "cosmosdb", + "value": "cosmosdb", + "brief": "Microsoft Azure Cosmos DB", + "stability": "stable" + }, + { + "id": "dynamodb", + "value": "dynamodb", + "brief": "Amazon DynamoDB", + "stability": "stable" + }, + { + "id": "neo4j", + "value": "neo4j", + "brief": "Neo4j", + "stability": "stable" + }, + { + "id": "geode", + "value": "geode", + "brief": "Apache Geode", + "stability": "stable" + }, + { + "id": "elasticsearch", + "value": "elasticsearch", + "brief": "Elasticsearch", + "stability": "stable" + }, + { + "id": "memcached", + "value": "memcached", + "brief": "Memcached", + "stability": "stable" + }, + { + "id": "cockroachdb", + "value": "cockroachdb", + "brief": "CockroachDB", + "stability": "stable" + }, + { + "id": "opensearch", + "value": "opensearch", + "brief": "OpenSearch", + "stability": "stable" + }, + { + "id": "clickhouse", + "value": "clickhouse", + "brief": "ClickHouse", + "stability": "stable" + }, + { + "id": "spanner", + "value": "spanner", + "brief": "Cloud Spanner", + "stability": "stable" + }, + { + "id": "trino", + "value": "trino", + "brief": "Trino", + "stability": "stable" + } + ] + }, + "brief": "An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers.", + "tag": "connection-level", + "requirement_level": "required", + "stability": "stable" + }, + { + "name": "db.system", + "type": { + "members": [ + { + "id": "other_sql", + "value": "other_sql", + "brief": "Some other SQL database. Fallback only. See notes.", + "stability": "stable" + }, + { + "id": "mssql", + "value": "mssql", + "brief": "Microsoft SQL Server", + "stability": "stable" + }, + { + "id": "mssqlcompact", + "value": "mssqlcompact", + "brief": "Microsoft SQL Server Compact", + "stability": "stable" + }, + { + "id": "mysql", + "value": "mysql", + "brief": "MySQL", + "stability": "stable" + }, + { + "id": "oracle", + "value": "oracle", + "brief": "Oracle Database", + "stability": "stable" + }, + { + "id": "db2", + "value": "db2", + "brief": "IBM Db2", + "stability": "stable" + }, + { + "id": "postgresql", + "value": "postgresql", + "brief": "PostgreSQL", + "stability": "stable" + }, + { + "id": "redshift", + "value": "redshift", + "brief": "Amazon Redshift", + "stability": "stable" + }, + { + "id": "hive", + "value": "hive", + "brief": "Apache Hive", + "stability": "stable" + }, + { + "id": "cloudscape", + "value": "cloudscape", + "brief": "Cloudscape", + "stability": "stable" + }, + { + "id": "hsqldb", + "value": "hsqldb", + "brief": "HyperSQL DataBase", + "stability": "stable" + }, + { + "id": "progress", + "value": "progress", + "brief": "Progress Database", + "stability": "stable" + }, + { + "id": "maxdb", + "value": "maxdb", + "brief": "SAP MaxDB", + "stability": "stable" + }, + { + "id": "hanadb", + "value": "hanadb", + "brief": "SAP HANA", + "stability": "stable" + }, + { + "id": "ingres", + "value": "ingres", + "brief": "Ingres", + "stability": "stable" + }, + { + "id": "firstsql", + "value": "firstsql", + "brief": "FirstSQL", + "stability": "stable" + }, + { + "id": "edb", + "value": "edb", + "brief": "EnterpriseDB", + "stability": "stable" + }, + { + "id": "cache", + "value": "cache", + "brief": "InterSystems Cach\u00e9", + "stability": "stable" + }, + { + "id": "adabas", + "value": "adabas", + "brief": "Adabas (Adaptable Database System)", + "stability": "stable" + }, + { + "id": "firebird", + "value": "firebird", + "brief": "Firebird", + "stability": "stable" + }, + { + "id": "derby", + "value": "derby", + "brief": "Apache Derby", + "stability": "stable" + }, + { + "id": "filemaker", + "value": "filemaker", + "brief": "FileMaker", + "stability": "stable" + }, + { + "id": "informix", + "value": "informix", + "brief": "Informix", + "stability": "stable" + }, + { + "id": "instantdb", + "value": "instantdb", + "brief": "InstantDB", + "stability": "stable" + }, + { + "id": "interbase", + "value": "interbase", + "brief": "InterBase", + "stability": "stable" + }, + { + "id": "mariadb", + "value": "mariadb", + "brief": "MariaDB", + "stability": "stable" + }, + { + "id": "netezza", + "value": "netezza", + "brief": "Netezza", + "stability": "stable" + }, + { + "id": "pervasive", + "value": "pervasive", + "brief": "Pervasive PSQL", + "stability": "stable" + }, + { + "id": "pointbase", + "value": "pointbase", + "brief": "PointBase", + "stability": "stable" + }, + { + "id": "sqlite", + "value": "sqlite", + "brief": "SQLite", + "stability": "stable" + }, + { + "id": "sybase", + "value": "sybase", + "brief": "Sybase", + "stability": "stable" + }, + { + "id": "teradata", + "value": "teradata", + "brief": "Teradata", + "stability": "stable" + }, + { + "id": "vertica", + "value": "vertica", + "brief": "Vertica", + "stability": "stable" + }, + { + "id": "h2", + "value": "h2", + "brief": "H2", + "stability": "stable" + }, + { + "id": "coldfusion", + "value": "coldfusion", + "brief": "ColdFusion IMQ", + "stability": "stable" + }, + { + "id": "cassandra", + "value": "cassandra", + "brief": "Apache Cassandra", + "stability": "stable" + }, + { + "id": "hbase", + "value": "hbase", + "brief": "Apache HBase", + "stability": "stable" + }, + { + "id": "mongodb", + "value": "mongodb", + "brief": "MongoDB", + "stability": "stable" + }, + { + "id": "redis", + "value": "redis", + "brief": "Redis", + "stability": "stable" + }, + { + "id": "couchbase", + "value": "couchbase", + "brief": "Couchbase", + "stability": "stable" + }, + { + "id": "couchdb", + "value": "couchdb", + "brief": "CouchDB", + "stability": "stable" + }, + { + "id": "cosmosdb", + "value": "cosmosdb", + "brief": "Microsoft Azure Cosmos DB", + "stability": "stable" + }, + { + "id": "dynamodb", + "value": "dynamodb", + "brief": "Amazon DynamoDB", + "stability": "stable" + }, + { + "id": "neo4j", + "value": "neo4j", + "brief": "Neo4j", + "stability": "stable" + }, + { + "id": "geode", + "value": "geode", + "brief": "Apache Geode", + "stability": "stable" + }, + { + "id": "elasticsearch", + "value": "elasticsearch", + "brief": "Elasticsearch", + "stability": "stable" + }, + { + "id": "memcached", + "value": "memcached", + "brief": "Memcached", + "stability": "stable" + }, + { + "id": "cockroachdb", + "value": "cockroachdb", + "brief": "CockroachDB", + "stability": "stable" + }, + { + "id": "opensearch", + "value": "opensearch", + "brief": "OpenSearch", + "stability": "stable" + }, + { + "id": "clickhouse", + "value": "clickhouse", + "brief": "ClickHouse", + "stability": "stable" + }, + { + "id": "spanner", + "value": "spanner", + "brief": "Cloud Spanner", + "stability": "stable" + }, + { + "id": "trino", + "value": "trino", + "brief": "Trino", + "stability": "stable" + } + ] + }, + "brief": "An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers.", + "tag": "db-generic", + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "db.user", + "type": "string", + "brief": "Username for accessing the database.\n", + "examples": [ + "readonly_user", + "reporting_user" + ], + "tag": "connection-level", + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "db.user", + "type": "string", + "brief": "Username for accessing the database.\n", + "examples": [ + "readonly_user", + "reporting_user" + ], + "tag": "db-generic", + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "http.request.body.size", + "type": "int", + "brief": "The size of the request payload body in bytes. This is the number of bytes transferred excluding headers and is often, but not always, present as the [Content-Length](https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length) header. For requests using transport encoding, this should be the compressed size.\n", + "examples": 3495, + "requirement_level": "recommended", + "stability": "development" + }, + { + "name": "http.request.header", + "type": "template[string[]]", + "brief": "HTTP request headers, `` being the normalized HTTP Header name (lowercase), the value being the header values.\n", + "examples": [ + [ + "application/json" + ], + [ + "1.2.3.4", + "1.2.3.5" + ] + ], + "requirement_level": "recommended", + "note": "Instrumentations SHOULD require an explicit configuration of which headers are to be captured. Including all request headers can be a security risk - explicit configuration helps avoid leaking sensitive information.\nThe `User-Agent` header is already captured in the `user_agent.original` attribute. Users MAY explicitly configure instrumentations to capture them even though it is not recommended.\nThe attribute value MUST consist of either multiple header values as an array of strings or a single-item array containing a possibly comma-concatenated string, depending on the way the HTTP library provides access to headers.\n", + "stability": "stable" + }, + { + "name": "http.request.method", + "type": { + "members": [ + { + "id": "connect", + "value": "CONNECT", + "brief": "CONNECT method.", + "stability": "stable" + }, + { + "id": "delete", + "value": "DELETE", + "brief": "DELETE method.", + "stability": "stable" + }, + { + "id": "get", + "value": "GET", + "brief": "GET method.", + "stability": "stable" + }, + { + "id": "head", + "value": "HEAD", + "brief": "HEAD method.", + "stability": "stable" + }, + { + "id": "options", + "value": "OPTIONS", + "brief": "OPTIONS method.", + "stability": "stable" + }, + { + "id": "patch", + "value": "PATCH", + "brief": "PATCH method.", + "stability": "stable" + }, + { + "id": "post", + "value": "POST", + "brief": "POST method.", + "stability": "stable" + }, + { + "id": "put", + "value": "PUT", + "brief": "PUT method.", + "stability": "stable" + }, + { + "id": "trace", + "value": "TRACE", + "brief": "TRACE method.", + "stability": "stable" + }, + { + "id": "other", + "value": "_OTHER", + "brief": "Any HTTP method that the instrumentation has no prior knowledge of.", + "stability": "stable" + } + ] + }, + "brief": "HTTP request method.", + "examples": [ + "GET", + "POST", + "HEAD" + ], + "requirement_level": "recommended", + "note": "HTTP request method value SHOULD be \"known\" to the instrumentation.\nBy default, this convention defines \"known\" methods as the ones listed in [RFC9110](https://www.rfc-editor.org/rfc/rfc9110.html#name-methods)\nand the PATCH method defined in [RFC5789](https://www.rfc-editor.org/rfc/rfc5789.html).\n\nIf the HTTP request method is not known to instrumentation, it MUST set the `http.request.method` attribute to `_OTHER`.\n\nIf the HTTP instrumentation could end up converting valid HTTP request methods to `_OTHER`, then it MUST provide a way to override\nthe list of known HTTP methods. If this override is done via environment variable, then the environment variable MUST be named\nOTEL_INSTRUMENTATION_HTTP_KNOWN_METHODS and support a comma-separated list of case-sensitive known HTTP methods\n(this list MUST be a full override of the default known method, it is not a list of known methods in addition to the defaults).\n\nHTTP method names are case-sensitive and `http.request.method` attribute value MUST match a known HTTP method name exactly.\nInstrumentations for specific web frameworks that consider HTTP methods to be case insensitive, SHOULD populate a canonical equivalent.\nTracing instrumentations that do so, MUST also set `http.request.method_original` to the original value.\n", + "stability": "stable" + }, + { + "name": "http.request.method", + "type": { + "members": [ + { + "id": "connect", + "value": "CONNECT", + "brief": "CONNECT method.", + "stability": "stable" + }, + { + "id": "delete", + "value": "DELETE", + "brief": "DELETE method.", + "stability": "stable" + }, + { + "id": "get", + "value": "GET", + "brief": "GET method.", + "stability": "stable" + }, + { + "id": "head", + "value": "HEAD", + "brief": "HEAD method.", + "stability": "stable" + }, + { + "id": "options", + "value": "OPTIONS", + "brief": "OPTIONS method.", + "stability": "stable" + }, + { + "id": "patch", + "value": "PATCH", + "brief": "PATCH method.", + "stability": "stable" + }, + { + "id": "post", + "value": "POST", + "brief": "POST method.", + "stability": "stable" + }, + { + "id": "put", + "value": "PUT", + "brief": "PUT method.", + "stability": "stable" + }, + { + "id": "trace", + "value": "TRACE", + "brief": "TRACE method.", + "stability": "stable" + }, + { + "id": "other", + "value": "_OTHER", + "brief": "Any HTTP method that the instrumentation has no prior knowledge of.", + "stability": "stable" + } + ] + }, + "brief": "HTTP request method.", + "examples": [ + "GET", + "POST", + "HEAD" + ], + "tag": "call-level-tech-specific", + "requirement_level": "required", + "note": "HTTP request method value SHOULD be \"known\" to the instrumentation.\nBy default, this convention defines \"known\" methods as the ones listed in [RFC9110](https://www.rfc-editor.org/rfc/rfc9110.html#name-methods)\nand the PATCH method defined in [RFC5789](https://www.rfc-editor.org/rfc/rfc5789.html).\n\nIf the HTTP request method is not known to instrumentation, it MUST set the `http.request.method` attribute to `_OTHER`.\n\nIf the HTTP instrumentation could end up converting valid HTTP request methods to `_OTHER`, then it MUST provide a way to override\nthe list of known HTTP methods. If this override is done via environment variable, then the environment variable MUST be named\nOTEL_INSTRUMENTATION_HTTP_KNOWN_METHODS and support a comma-separated list of case-sensitive known HTTP methods\n(this list MUST be a full override of the default known method, it is not a list of known methods in addition to the defaults).\n\nHTTP method names are case-sensitive and `http.request.method` attribute value MUST match a known HTTP method name exactly.\nInstrumentations for specific web frameworks that consider HTTP methods to be case insensitive, SHOULD populate a canonical equivalent.\nTracing instrumentations that do so, MUST also set `http.request.method_original` to the original value.\n", + "stability": "stable" + }, + { + "name": "http.request.method_original", + "type": "string", + "brief": "Original HTTP method sent by the client in the request line.", + "examples": [ + "GeT", + "ACL", + "foo" + ], + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "http.request.resend_count", + "type": "int", + "brief": "The ordinal number of request resending attempt (for any reason, including redirects).\n", + "examples": 3, + "requirement_level": "recommended", + "note": "The resend count SHOULD be updated each time an HTTP request gets resent by the client, regardless of what was the cause of the resending (e.g. redirection, authorization failure, 503 Server Unavailable, network issues, or any other).\n", + "stability": "stable" + }, + { + "name": "http.response.body.size", + "type": "int", + "brief": "The size of the response payload body in bytes. This is the number of bytes transferred excluding headers and is often, but not always, present as the [Content-Length](https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length) header. For requests using transport encoding, this should be the compressed size.\n", + "examples": 3495, + "requirement_level": "recommended", + "stability": "development" + }, + { + "name": "http.response.header", + "type": "template[string[]]", + "brief": "HTTP response headers, `` being the normalized HTTP Header name (lowercase), the value being the header values.\n", + "examples": [ + [ + "application/json" + ], + [ + "abc", + "def" + ] + ], + "requirement_level": "recommended", + "note": "Instrumentations SHOULD require an explicit configuration of which headers are to be captured. Including all response headers can be a security risk - explicit configuration helps avoid leaking sensitive information.\nUsers MAY explicitly configure instrumentations to capture them even though it is not recommended.\nThe attribute value MUST consist of either multiple header values as an array of strings or a single-item array containing a possibly comma-concatenated string, depending on the way the HTTP library provides access to headers.\n", + "stability": "stable" + }, + { + "name": "http.response.status_code", + "type": "int", + "brief": "[HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6).", + "examples": [ + 200 + ], + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "http.route", + "type": "string", + "brief": "The matched route, that is, the path template in the format used by the respective server framework.\n", + "examples": [ + "/users/:userID?", + "{controller}/{action}/{id?}" + ], + "requirement_level": "recommended", + "note": "MUST NOT be populated when this is not supported by the HTTP server framework as the route attribute should have low-cardinality and the URI path can NOT substitute it.\nSHOULD include the [application root](/docs/http/http-spans.md#http-server-definitions) if there is one.", + "stability": "stable" + }, + { + "name": "network.carrier.icc", + "type": "string", + "brief": "The ISO 3166-1 alpha-2 2-character country code associated with the mobile carrier network.", + "examples": "DE", + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "network.carrier.mcc", + "type": "string", + "brief": "The mobile carrier country code.", + "examples": "310", + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "network.carrier.mnc", + "type": "string", + "brief": "The mobile carrier network code.", + "examples": "001", + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "network.carrier.name", + "type": "string", + "brief": "The name of the mobile carrier.", + "examples": "sprint", + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "network.connection.subtype", + "type": { + "members": [ + { + "id": "gprs", + "value": "gprs", + "brief": "GPRS", + "stability": "stable" + }, + { + "id": "edge", + "value": "edge", + "brief": "EDGE", + "stability": "stable" + }, + { + "id": "umts", + "value": "umts", + "brief": "UMTS", + "stability": "stable" + }, + { + "id": "cdma", + "value": "cdma", + "brief": "CDMA", + "stability": "stable" + }, + { + "id": "evdo_0", + "value": "evdo_0", + "brief": "EVDO Rel. 0", + "stability": "stable" + }, + { + "id": "evdo_a", + "value": "evdo_a", + "brief": "EVDO Rev. A", + "stability": "stable" + }, + { + "id": "cdma2000_1xrtt", + "value": "cdma2000_1xrtt", + "brief": "CDMA2000 1XRTT", + "stability": "stable" + }, + { + "id": "hsdpa", + "value": "hsdpa", + "brief": "HSDPA", + "stability": "stable" + }, + { + "id": "hsupa", + "value": "hsupa", + "brief": "HSUPA", + "stability": "stable" + }, + { + "id": "hspa", + "value": "hspa", + "brief": "HSPA", + "stability": "stable" + }, + { + "id": "iden", + "value": "iden", + "brief": "IDEN", + "stability": "stable" + }, + { + "id": "evdo_b", + "value": "evdo_b", + "brief": "EVDO Rev. B", + "stability": "stable" + }, + { + "id": "lte", + "value": "lte", + "brief": "LTE", + "stability": "stable" + }, + { + "id": "ehrpd", + "value": "ehrpd", + "brief": "EHRPD", + "stability": "stable" + }, + { + "id": "hspap", + "value": "hspap", + "brief": "HSPAP", + "stability": "stable" + }, + { + "id": "gsm", + "value": "gsm", + "brief": "GSM", + "stability": "stable" + }, + { + "id": "td_scdma", + "value": "td_scdma", + "brief": "TD-SCDMA", + "stability": "stable" + }, + { + "id": "iwlan", + "value": "iwlan", + "brief": "IWLAN", + "stability": "stable" + }, + { + "id": "nr", + "value": "nr", + "brief": "5G NR (New Radio)", + "stability": "stable" + }, + { + "id": "nrnsa", + "value": "nrnsa", + "brief": "5G NRNSA (New Radio Non-Standalone)", + "stability": "stable" + }, + { + "id": "lte_ca", + "value": "lte_ca", + "brief": "LTE CA", + "stability": "stable" + } + ] + }, + "brief": "This describes more details regarding the connection.type. It may be the type of cell technology connection, but it could be used for describing details about a wifi connection.", + "examples": "LTE", + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "network.connection.type", + "type": { + "members": [ + { + "id": "wifi", + "value": "wifi", + "stability": "stable" + }, + { + "id": "wired", + "value": "wired", + "stability": "stable" + }, + { + "id": "cell", + "value": "cell", + "stability": "stable" + }, + { + "id": "unavailable", + "value": "unavailable", + "stability": "stable" + }, + { + "id": "unknown", + "value": "unknown", + "stability": "stable" + } + ] + }, + "brief": "The internet connection type.", + "examples": "wifi", + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "network.io.direction", + "type": { + "members": [ + { + "id": "transmit", + "value": "transmit", + "stability": "stable" + }, + { + "id": "receive", + "value": "receive", + "stability": "stable" + } + ] + }, + "brief": "The network IO operation direction.", + "examples": [ + "transmit" + ], + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "network.local.address", + "type": "string", + "brief": "Local address of the network connection - IP address or Unix domain socket name.", + "examples": [ + "10.1.2.80", + "/tmp/my.sock" + ], + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "network.local.port", + "type": "int", + "brief": "Local port number of the network connection.", + "examples": [ + 65123 + ], + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "network.peer.address", + "type": "string", + "brief": "Peer address of the network connection - IP address or Unix domain socket name.", + "examples": [ + "10.1.2.80", + "/tmp/my.sock" + ], + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "network.peer.address", + "type": "string", + "brief": "Peer address of the network connection - IP address or Unix domain socket name.", + "examples": [ + "10.1.2.80", + "/tmp/my.sock" + ], + "tag": "connection-level", + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "network.peer.port", + "type": "int", + "brief": "Peer port number of the network connection.", + "examples": [ + 65123 + ], + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "network.peer.port", + "type": "int", + "brief": "Peer port number of the network connection.", + "examples": [ + 65123 + ], + "tag": "connection-level", + "requirement_level": { + "recommended": "If `network.peer.address` is set." + }, + "stability": "stable" + }, + { + "name": "network.protocol.name", + "type": "string", + "brief": "[OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent.", + "examples": [ + "amqp", + "http", + "mqtt" + ], + "requirement_level": "recommended", + "note": "The value SHOULD be normalized to lowercase.", + "stability": "stable" + }, + { + "name": "network.protocol.version", + "type": "string", + "brief": "Version of the protocol specified in `network.protocol.name`.", + "examples": "3.1.1", + "requirement_level": "recommended", + "note": "`network.protocol.version` refers to the version of the protocol used and might be different from the protocol client's version. If the HTTP client has a version of `0.27.2`, but sends HTTP version `1.1`, this attribute should be set to `1.1`.\n", + "stability": "stable" + }, + { + "name": "network.transport", + "type": { + "members": [ + { + "id": "tcp", + "value": "tcp", + "brief": "TCP", + "stability": "stable" + }, + { + "id": "udp", + "value": "udp", + "brief": "UDP", + "stability": "stable" + }, + { + "id": "pipe", + "value": "pipe", + "brief": "Named or anonymous pipe.", + "stability": "stable" + }, + { + "id": "unix", + "value": "unix", + "brief": "Unix domain socket", + "stability": "stable" + } + ] + }, + "brief": "[OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication).\n", + "examples": [ + "tcp", + "udp" + ], + "requirement_level": "recommended", + "note": "The value SHOULD be normalized to lowercase.\n\nConsider always setting the transport when setting a port number, since\na port number is ambiguous without knowing the transport. For example\ndifferent processes could be listening on TCP port 12345 and UDP port 12345.\n", + "stability": "stable" + }, + { + "name": "network.transport", + "type": { + "members": [ + { + "id": "tcp", + "value": "tcp", + "brief": "TCP", + "stability": "stable" + }, + { + "id": "udp", + "value": "udp", + "brief": "UDP", + "stability": "stable" + }, + { + "id": "pipe", + "value": "pipe", + "brief": "Named or anonymous pipe.", + "stability": "stable" + }, + { + "id": "unix", + "value": "unix", + "brief": "Unix domain socket", + "stability": "stable" + } + ] + }, + "brief": "[OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication).\n", + "examples": [ + "tcp", + "udp" + ], + "tag": "connection-level", + "requirement_level": "recommended", + "note": "The value SHOULD be normalized to lowercase.\n\nConsider always setting the transport when setting a port number, since\na port number is ambiguous without knowing the transport. For example\ndifferent processes could be listening on TCP port 12345 and UDP port 12345.\n", + "stability": "stable" + }, + { + "name": "network.type", + "type": { + "members": [ + { + "id": "ipv4", + "value": "ipv4", + "brief": "IPv4", + "stability": "stable" + }, + { + "id": "ipv6", + "value": "ipv6", + "brief": "IPv6", + "stability": "stable" + } + ] + }, + "brief": "[OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent.", + "examples": [ + "ipv4", + "ipv6" + ], + "requirement_level": "recommended", + "note": "The value SHOULD be normalized to lowercase.", + "stability": "stable" + }, + { + "name": "network.type", + "type": { + "members": [ + { + "id": "ipv4", + "value": "ipv4", + "brief": "IPv4", + "stability": "stable" + }, + { + "id": "ipv6", + "value": "ipv6", + "brief": "IPv6", + "stability": "stable" + } + ] + }, + "brief": "[OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent.", + "examples": [ + "ipv4", + "ipv6" + ], + "tag": "connection-level", + "requirement_level": "recommended", + "note": "The value SHOULD be normalized to lowercase.", + "stability": "stable" + }, + { + "name": "server.address", + "type": "string", + "brief": "Name of the database host.\n", + "examples": [ + "example.com", + "10.1.2.80", + "/tmp/my.sock" + ], + "tag": "call-level-tech-specific", + "requirement_level": "recommended", + "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.\n", + "stability": "stable" + }, + { + "name": "server.address", + "type": "string", + "brief": "Name of the database host.\n", + "examples": [ + "example.com", + "10.1.2.80", + "/tmp/my.sock" + ], + "tag": "connection-level", + "requirement_level": "recommended", + "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.\n", + "stability": "stable" + }, + { + "name": "server.address", + "type": "string", + "brief": "Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name.", + "examples": [ + "example.com", + "10.1.2.80", + "/tmp/my.sock" + ], + "requirement_level": "recommended", + "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.\n", + "stability": "stable" + }, + { + "name": "server.port", + "type": "int", + "brief": "Server port number.", + "examples": [ + 80, + 8080, + 443 + ], + "requirement_level": "recommended", + "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.\n", + "stability": "stable" + }, + { + "name": "server.port", + "type": "int", + "brief": "Server port number.", + "examples": [ + 80, + 8080, + 443 + ], + "tag": "call-level-tech-specific", + "requirement_level": { + "conditionally_required": "If using a port other than the default port for this DBMS and if `server.address` is set." + }, + "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.\n", + "stability": "stable" + }, + { + "name": "server.port", + "type": "int", + "brief": "Server port number.", + "examples": [ + 80, + 8080, + 443 + ], + "tag": "connection-level", + "requirement_level": { + "conditionally_required": "If using a port other than the default port for this DBMS and if `server.address` is set." + }, + "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.\n", + "stability": "stable" + }, + { + "name": "url.fragment", + "type": "string", + "brief": "The [URI fragment](https://www.rfc-editor.org/rfc/rfc3986#section-3.5) component", + "examples": [ + "SemConv" + ], + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "url.full", + "type": "string", + "brief": "Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986)", + "examples": [ + "https://localhost:9200/index/_search?q=user.id:kimchy" + ], + "tag": "call-level-tech-specific", + "requirement_level": "required", + "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.\n`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/`.\n`url.full` SHOULD capture the absolute URL when it is available (or can be reconstructed) and SHOULD NOT be validated or modified except for sanitizing purposes.\n", + "stability": "stable" + }, + { + "name": "url.full", + "type": "string", + "brief": "Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986)", + "examples": [ + "https://www.foo.bar/search?q=OpenTelemetry#SemConv", + "//localhost" + ], + "requirement_level": "recommended", + "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.\n`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/`.\n`url.full` SHOULD capture the absolute URL when it is available (or can be reconstructed) and SHOULD NOT be validated or modified except for sanitizing purposes.\n", + "stability": "stable" + }, + { + "name": "url.path", + "type": "string", + "brief": "The [URI path](https://www.rfc-editor.org/rfc/rfc3986#section-3.3) component", + "examples": [ + "/search" + ], + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "url.query", + "type": "string", + "brief": "The [URI query](https://www.rfc-editor.org/rfc/rfc3986#section-3.4) component", + "examples": [ + "q=OpenTelemetry" + ], + "requirement_level": "recommended", + "note": "Sensitive content provided in query string SHOULD be scrubbed when instrumentations can identify it.", + "stability": "stable" + }, + { + "name": "url.scheme", + "type": "string", + "brief": "The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol.", + "examples": [ + "https", + "ftp", + "telnet" + ], + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "user_agent.original", + "type": "string", + "brief": "Full user-agent string is generated by Cosmos DB SDK", + "examples": [ + "cosmos-netstandard-sdk/3.23.0\\|3.23.1\\|1\\|X64\\|Linux 5.4.0-1098-azure 104 18\\|.NET Core 3.1.32\\|S\\|" + ], + "tag": "call-level-tech-specific", + "requirement_level": "recommended", + "note": "The user-agent value is generated by SDK which is a combination of
`sdk_version` : Current version of SDK. e.g. 'cosmos-netstandard-sdk/3.23.0'
`direct_pkg_version` : Direct package version used by Cosmos DB SDK. e.g. '3.23.1'
`number_of_client_instances` : Number of cosmos client instances created by the application. e.g. '1'
`type_of_machine_architecture` : Machine architecture. e.g. 'X64'
`operating_system` : Operating System. e.g. 'Linux 5.4.0-1098-azure 104 18'
`runtime_framework` : Runtime Framework. e.g. '.NET Core 3.1.32'
`failover_information` : Generated key to determine if region failover enabled.\n Format Reg-{D (Disabled discovery)}-S(application region)|L(List of preferred regions)|N(None, user did not configure it).\n Default value is \"NS\".\n", + "stability": "stable" + }, + { + "name": "user_agent.original", + "type": "string", + "brief": "Value of the [HTTP User-Agent](https://www.rfc-editor.org/rfc/rfc9110.html#field.user-agent) header sent by the client.\n", + "examples": [ + "CERN-LineMode/2.15 libwww/2.17b3", + "Mozilla/5.0 (iPhone; CPU iPhone OS 14_7_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.2 Mobile/15E148 Safari/604.1" + ], + "requirement_level": "recommended", + "stability": "stable" + } +] diff --git a/crates/weaver_resolver/data/registry-test-8-http/expected-attribute-catalog.json b/crates/weaver_resolver/data/registry-test-8-http/expected-attribute-catalog.json index 0c3490c6e..caea872aa 100644 --- a/crates/weaver_resolver/data/registry-test-8-http/expected-attribute-catalog.json +++ b/crates/weaver_resolver/data/registry-test-8-http/expected-attribute-catalog.json @@ -1,72 +1,70 @@ -{ - "attributes": [ - { - "name": "network.protocol.name", - "type": "string", - "brief": "[OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent.", - "examples": [ - "amqp", - "http", - "mqtt" - ], - "requirement_level": "recommended", - "note": "The value SHOULD be normalized to lowercase.", - "stability": "stable" +[ + { + "name": "network.protocol.name", + "type": "string", + "brief": "[OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent.", + "examples": [ + "amqp", + "http", + "mqtt" + ], + "requirement_level": "recommended", + "note": "The value SHOULD be normalized to lowercase.", + "stability": "stable" + }, + { + "name": "network.protocol.name", + "type": "string", + "brief": "[OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent.", + "examples": [ + "http", + "spdy" + ], + "requirement_level": { + "conditionally_required": "If not `http` and `network.protocol.version` is set." }, - { - "name": "network.protocol.name", - "type": "string", - "brief": "[OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent.", - "examples": [ - "http", - "spdy" - ], - "requirement_level": { - "conditionally_required": "If not `http` and `network.protocol.version` is set." - }, - "note": "The value SHOULD be normalized to lowercase.", - "stability": "stable" + "note": "The value SHOULD be normalized to lowercase.", + "stability": "stable" + }, + { + "name": "server.port", + "type": "int", + "brief": "Port of the local HTTP server that received the request.\n", + "examples": [ + 80, + 8080, + 443 + ], + "requirement_level": "opt_in", + "note": "See [Setting `server.address` and `server.port` attributes](/docs/http/http-spans.md#setting-serveraddress-and-serverport-attributes).\n> **Warning**\n> Since this attribute is based on HTTP headers, opting in to it may allow an attacker\n> to trigger cardinality limits, degrading the usefulness of the metric.\n", + "stability": "stable" + }, + { + "name": "server.port", + "type": "int", + "brief": "Port of the local HTTP server that received the request.\n", + "examples": [ + 80, + 8080, + 443 + ], + "requirement_level": { + "conditionally_required": "If `server.address` is set." }, - { - "name": "server.port", - "type": "int", - "brief": "Port of the local HTTP server that received the request.\n", - "examples": [ - 80, - 8080, - 443 - ], - "requirement_level": "opt_in", - "note": "See [Setting `server.address` and `server.port` attributes](/docs/http/http-spans.md#setting-serveraddress-and-serverport-attributes).\n> **Warning**\n> Since this attribute is based on HTTP headers, opting in to it may allow an attacker\n> to trigger cardinality limits, degrading the usefulness of the metric.\n", - "stability": "stable" - }, - { - "name": "server.port", - "type": "int", - "brief": "Port of the local HTTP server that received the request.\n", - "examples": [ - 80, - 8080, - 443 - ], - "requirement_level": { - "conditionally_required": "If `server.address` is set." - }, - "note": "See [Setting `server.address` and `server.port` attributes](/docs/http/http-spans.md#setting-serveraddress-and-serverport-attributes).\n", - "stability": "stable" - }, - { - "name": "server.port", - "type": "int", - "brief": "Server port number.", - "examples": [ - 80, - 8080, - 443 - ], - "requirement_level": "recommended", - "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.\n", - "stability": "stable" - } - ] -} \ No newline at end of file + "note": "See [Setting `server.address` and `server.port` attributes](/docs/http/http-spans.md#setting-serveraddress-and-serverport-attributes).\n", + "stability": "stable" + }, + { + "name": "server.port", + "type": "int", + "brief": "Server port number.", + "examples": [ + 80, + 8080, + 443 + ], + "requirement_level": "recommended", + "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.\n", + "stability": "stable" + } +] diff --git a/crates/weaver_resolver/data/registry-test-9-metric-extends/expected-attribute-catalog.json b/crates/weaver_resolver/data/registry-test-9-metric-extends/expected-attribute-catalog.json index 6a4ade056..48da99fee 100644 --- a/crates/weaver_resolver/data/registry-test-9-metric-extends/expected-attribute-catalog.json +++ b/crates/weaver_resolver/data/registry-test-9-metric-extends/expected-attribute-catalog.json @@ -1,43 +1,41 @@ -{ - "attributes": [ - { - "name": "jvm.memory.pool.name", - "type": "string", - "brief": "Name of the memory pool.", - "examples": [ - "G1 Old Gen", - "G1 Eden space", - "G1 Survivor Space" - ], - "requirement_level": "recommended", - "note": "Pool names are generally obtained via [MemoryPoolMXBean#getName()](https://docs.oracle.com/en/java/javase/11/docs/api/java.management/java/lang/management/MemoryPoolMXBean.html#getName()).\n", - "stability": "stable" +[ + { + "name": "jvm.memory.pool.name", + "type": "string", + "brief": "Name of the memory pool.", + "examples": [ + "G1 Old Gen", + "G1 Eden space", + "G1 Survivor Space" + ], + "requirement_level": "recommended", + "note": "Pool names are generally obtained via [MemoryPoolMXBean#getName()](https://docs.oracle.com/en/java/javase/11/docs/api/java.management/java/lang/management/MemoryPoolMXBean.html#getName()).\n", + "stability": "stable" + }, + { + "name": "jvm.memory.type", + "type": { + "members": [ + { + "id": "heap", + "value": "heap", + "brief": "Heap memory.", + "stability": "stable" + }, + { + "id": "non_heap", + "value": "non_heap", + "brief": "Non-heap memory", + "stability": "stable" + } + ] }, - { - "name": "jvm.memory.type", - "type": { - "members": [ - { - "id": "heap", - "value": "heap", - "brief": "Heap memory.", - "stability": "stable" - }, - { - "id": "non_heap", - "value": "non_heap", - "brief": "Non-heap memory", - "stability": "stable" - } - ] - }, - "brief": "The type of memory.", - "examples": [ - "heap", - "non_heap" - ], - "requirement_level": "recommended", - "stability": "stable" - } - ] -} \ No newline at end of file + "brief": "The type of memory.", + "examples": [ + "heap", + "non_heap" + ], + "requirement_level": "recommended", + "stability": "stable" + } +] diff --git a/crates/weaver_resolver/data/registry-test-lineage-0/expected-attribute-catalog.json b/crates/weaver_resolver/data/registry-test-lineage-0/expected-attribute-catalog.json index b05f31568..dbd8cd7c5 100644 --- a/crates/weaver_resolver/data/registry-test-lineage-0/expected-attribute-catalog.json +++ b/crates/weaver_resolver/data/registry-test-lineage-0/expected-attribute-catalog.json @@ -1,81 +1,79 @@ -{ - "attributes": [ - { - "name": "network.protocol.name", - "type": "string", - "brief": "Network protocol name", - "examples": [ - "http", - "spdy" - ], - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "network.protocol.name2", - "type": "string", - "brief": "Network protocol name", - "examples": [ - "http", - "spdy" - ], - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "network.protocol.version", - "type": "string", - "brief": "Network protocol version", - "examples": [ - "1.0", - "2.0" - ], - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "network.protocol.version", - "type": "string", - "brief": "Network protocol version", - "examples": [ - "1.0", - "2.0" - ], - "requirement_level": "opt_in", - "stability": "stable" - }, - { - "name": "network.type", - "type": "string", - "brief": "Network type", - "examples": [ - "ipv4", - "ipv6" - ], - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "server.port", - "type": "string", - "brief": "Server port", - "examples": [ - "80", - "443" - ], - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "server.port", - "type": "string", - "brief": "Server port", - "examples": [ - "80", - "443" - ], - "requirement_level": "opt_in", - "stability": "stable" - } - ] -} \ No newline at end of file +[ + { + "name": "network.protocol.name", + "type": "string", + "brief": "Network protocol name", + "examples": [ + "http", + "spdy" + ], + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "network.protocol.name2", + "type": "string", + "brief": "Network protocol name", + "examples": [ + "http", + "spdy" + ], + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "network.protocol.version", + "type": "string", + "brief": "Network protocol version", + "examples": [ + "1.0", + "2.0" + ], + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "network.protocol.version", + "type": "string", + "brief": "Network protocol version", + "examples": [ + "1.0", + "2.0" + ], + "requirement_level": "opt_in", + "stability": "stable" + }, + { + "name": "network.type", + "type": "string", + "brief": "Network type", + "examples": [ + "ipv4", + "ipv6" + ], + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "server.port", + "type": "string", + "brief": "Server port", + "examples": [ + "80", + "443" + ], + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "server.port", + "type": "string", + "brief": "Server port", + "examples": [ + "80", + "443" + ], + "requirement_level": "opt_in", + "stability": "stable" + } +] diff --git a/crates/weaver_resolver/data/registry-test-lineage-1/expected-attribute-catalog.json b/crates/weaver_resolver/data/registry-test-lineage-1/expected-attribute-catalog.json index 3890cd13e..10307f6b2 100644 --- a/crates/weaver_resolver/data/registry-test-lineage-1/expected-attribute-catalog.json +++ b/crates/weaver_resolver/data/registry-test-lineage-1/expected-attribute-catalog.json @@ -1,14 +1,12 @@ -{ - "attributes": [ - { - "name": "server.port", - "type": "string", - "brief": "Server port", - "examples": [ - "8080" - ], - "requirement_level": "recommended", - "stability": "stable" - } - ] -} \ No newline at end of file +[ + { + "name": "server.port", + "type": "string", + "brief": "Server port", + "examples": [ + "8080" + ], + "requirement_level": "recommended", + "stability": "stable" + } +] diff --git a/crates/weaver_resolver/data/registry-test-lineage-2/expected-attribute-catalog.json b/crates/weaver_resolver/data/registry-test-lineage-2/expected-attribute-catalog.json index 533171013..a8c0c5d11 100644 --- a/crates/weaver_resolver/data/registry-test-lineage-2/expected-attribute-catalog.json +++ b/crates/weaver_resolver/data/registry-test-lineage-2/expected-attribute-catalog.json @@ -1,106 +1,104 @@ -{ - "attributes": [ - { - "name": "network.protocol.name", - "type": "string", - "brief": "Network protocol name (registry)", - "examples": [ - "http", - "spdy" - ], - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "network.protocol.name", - "type": "string", - "brief": "Network protocol name (registry)", - "examples": [ - "http", - "spdy" - ], - "requirement_level": "opt_in", - "stability": "stable" - }, - { - "name": "network.protocol.name2", - "type": "string", - "brief": "Network protocol name", - "examples": [ - "http", - "spdy" - ], - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "network.protocol.version", - "type": "string", - "brief": "Network protocol version (registry)", - "examples": [ - "1.0", - "2.0" - ], - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "network.protocol.version", - "type": "string", - "brief": "Network protocol version (registry)", - "examples": [ - "1.0", - "2.0" - ], - "requirement_level": "opt_in", - "stability": "stable" - }, - { - "name": "network.type", - "type": "string", - "brief": "Network type (registry)", - "examples": [ - "ipv4", - "ipv6" - ], - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "server.port", - "type": "string", - "brief": "Brief of the top level", - "examples": [ - 80, - 8080, - 443 - ], - "requirement_level": "opt_in", - "stability": "stable" - }, - { - "name": "server.port", - "type": "string", - "brief": "Server port", - "examples": [ - "80", - "8080", - "443" - ], - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "server.port", - "type": "string", - "brief": "Server port", - "examples": [ - "80", - "8080", - "443" - ], - "requirement_level": "opt_in", - "stability": "stable" - } - ] -} \ No newline at end of file +[ + { + "name": "network.protocol.name", + "type": "string", + "brief": "Network protocol name (registry)", + "examples": [ + "http", + "spdy" + ], + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "network.protocol.name", + "type": "string", + "brief": "Network protocol name (registry)", + "examples": [ + "http", + "spdy" + ], + "requirement_level": "opt_in", + "stability": "stable" + }, + { + "name": "network.protocol.name2", + "type": "string", + "brief": "Network protocol name", + "examples": [ + "http", + "spdy" + ], + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "network.protocol.version", + "type": "string", + "brief": "Network protocol version (registry)", + "examples": [ + "1.0", + "2.0" + ], + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "network.protocol.version", + "type": "string", + "brief": "Network protocol version (registry)", + "examples": [ + "1.0", + "2.0" + ], + "requirement_level": "opt_in", + "stability": "stable" + }, + { + "name": "network.type", + "type": "string", + "brief": "Network type (registry)", + "examples": [ + "ipv4", + "ipv6" + ], + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "server.port", + "type": "string", + "brief": "Brief of the top level", + "examples": [ + 80, + 8080, + 443 + ], + "requirement_level": "opt_in", + "stability": "stable" + }, + { + "name": "server.port", + "type": "string", + "brief": "Server port", + "examples": [ + "80", + "8080", + "443" + ], + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "server.port", + "type": "string", + "brief": "Server port", + "examples": [ + "80", + "8080", + "443" + ], + "requirement_level": "opt_in", + "stability": "stable" + } +] diff --git a/crates/weaver_resolver/data/registry-test-lineage-3/expected-attribute-catalog.json b/crates/weaver_resolver/data/registry-test-lineage-3/expected-attribute-catalog.json index 004a42d2c..4f731bceb 100644 --- a/crates/weaver_resolver/data/registry-test-lineage-3/expected-attribute-catalog.json +++ b/crates/weaver_resolver/data/registry-test-lineage-3/expected-attribute-catalog.json @@ -1,35 +1,33 @@ -{ - "attributes": [ - { - "name": "host.id", - "type": "string", - "brief": "Unique identifier for a host", - "examples": [ - "01556-1402034656" - ], - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "host.name", - "type": "string", - "brief": "Name of the host", - "examples": [ - "localhost" - ], - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "host.name", - "type": "string", - "brief": "Name of the host", - "examples": [ - "localhost" - ], - "requirement_level": "recommended", - "stability": "stable", - "role": "descriptive" - } - ] -} \ No newline at end of file +[ + { + "name": "host.id", + "type": "string", + "brief": "Unique identifier for a host", + "examples": [ + "01556-1402034656" + ], + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "host.name", + "type": "string", + "brief": "Name of the host", + "examples": [ + "localhost" + ], + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "host.name", + "type": "string", + "brief": "Name of the host", + "examples": [ + "localhost" + ], + "requirement_level": "recommended", + "stability": "stable", + "role": "descriptive" + } +] diff --git a/crates/weaver_resolver/data/registry-test-published-1/expected-attribute-catalog.json b/crates/weaver_resolver/data/registry-test-published-1/expected-attribute-catalog.json index 0f72b718a..866ceda83 100644 --- a/crates/weaver_resolver/data/registry-test-published-1/expected-attribute-catalog.json +++ b/crates/weaver_resolver/data/registry-test-published-1/expected-attribute-catalog.json @@ -1,29 +1,27 @@ -{ - "attributes": [ - { - "name": "a", - "type": "string", - "brief": "test a", - "requirement_level": "required", - "stability": "stable", - "annotations": {} - }, - { - "name": "a", - "type": "string", - "brief": "test a", - "requirement_level": "required", - "stability": "stable", - "annotations": {}, - "role": "identifying" - }, - { - "name": "a", - "type": "string", - "brief": "test a", - "requirement_level": "recommended", - "stability": "stable", - "annotations": {} - } - ] -} \ No newline at end of file +[ + { + "name": "a", + "type": "string", + "brief": "test a", + "requirement_level": "required", + "stability": "stable", + "annotations": {} + }, + { + "name": "a", + "type": "string", + "brief": "test a", + "requirement_level": "required", + "stability": "stable", + "annotations": {}, + "role": "identifying" + }, + { + "name": "a", + "type": "string", + "brief": "test a", + "requirement_level": "recommended", + "stability": "stable", + "annotations": {} + } +] diff --git a/crates/weaver_resolver/data/registry-test-published-2/expected-attribute-catalog.json b/crates/weaver_resolver/data/registry-test-published-2/expected-attribute-catalog.json index 3dfba8e40..141d509d5 100644 --- a/crates/weaver_resolver/data/registry-test-published-2/expected-attribute-catalog.json +++ b/crates/weaver_resolver/data/registry-test-published-2/expected-attribute-catalog.json @@ -1,34 +1,32 @@ -{ - "attributes": [ - { - "name": "local.attr", - "type": "string", - "brief": "local attribute", - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "local.group.attr", - "type": "string", - "brief": "local group attribute", - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "my.attr.1", - "type": "int", - "brief": "test attr 1", - "requirement_level": "required", - "stability": "stable", - "annotations": {} - }, - { - "name": "my.attr.1", - "type": "int", - "brief": "test attr 1", - "requirement_level": "recommended", - "stability": "stable", - "annotations": {} - } - ] -} +[ + { + "name": "local.attr", + "type": "string", + "brief": "local attribute", + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "local.group.attr", + "type": "string", + "brief": "local group attribute", + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "my.attr.1", + "type": "int", + "brief": "test attr 1", + "requirement_level": "required", + "stability": "stable", + "annotations": {} + }, + { + "name": "my.attr.1", + "type": "int", + "brief": "test attr 1", + "requirement_level": "recommended", + "stability": "stable", + "annotations": {} + } +] diff --git a/crates/weaver_resolver/data/registry-test-v2-1-everything/expected-attribute-catalog.json b/crates/weaver_resolver/data/registry-test-v2-1-everything/expected-attribute-catalog.json index 2bcb90528..4be608992 100644 --- a/crates/weaver_resolver/data/registry-test-v2-1-everything/expected-attribute-catalog.json +++ b/crates/weaver_resolver/data/registry-test-v2-1-everything/expected-attribute-catalog.json @@ -1,57 +1,55 @@ -{ - "attributes": [ - { - "name": "network.protocol.name", - "type": "string", - "brief": "[OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent.", - "examples": [ - "amqp", - "http", - "mqtt" - ], - "requirement_level": "recommended", - "note": "The value SHOULD be normalized to lowercase.", - "stability": "stable" +[ + { + "name": "network.protocol.name", + "type": "string", + "brief": "[OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent.", + "examples": [ + "amqp", + "http", + "mqtt" + ], + "requirement_level": "recommended", + "note": "The value SHOULD be normalized to lowercase.", + "stability": "stable" + }, + { + "name": "network.protocol.name", + "type": "string", + "brief": "[OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent.", + "examples": [ + "http", + "spdy" + ], + "requirement_level": { + "conditionally_required": "If not `http` and `network.protocol.version` is set." }, - { - "name": "network.protocol.name", - "type": "string", - "brief": "[OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent.", - "examples": [ - "http", - "spdy" - ], - "requirement_level": { - "conditionally_required": "If not `http` and `network.protocol.version` is set." - }, - "note": "The value SHOULD be normalized to lowercase.", - "stability": "stable" - }, - { - "name": "server.port", - "type": "int", - "brief": "Server port number.", - "examples": [ - 80, - 8080, - 443 - ], - "requirement_level": "recommended", - "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.\n", - "stability": "stable" - }, - { - "name": "server.port", - "type": "int", - "brief": "Server port number.", - "examples": [ - 80, - 8080, - 443 - ], - "requirement_level": "opt_in", - "note": "See [Setting `server.address` and `server.port` attributes](/docs/http/http-spans.md#setting-serveraddress-and-serverport-attributes).\n> **Warning**\n> Since this attribute is based on HTTP headers, opting in to it may allow an attacker\n> to trigger cardinality limits, degrading the usefulness of the metric.\n", - "stability": "stable" - } - ] -} \ No newline at end of file + "note": "The value SHOULD be normalized to lowercase.", + "stability": "stable" + }, + { + "name": "server.port", + "type": "int", + "brief": "Server port number.", + "examples": [ + 80, + 8080, + 443 + ], + "requirement_level": "recommended", + "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.\n", + "stability": "stable" + }, + { + "name": "server.port", + "type": "int", + "brief": "Server port number.", + "examples": [ + 80, + 8080, + 443 + ], + "requirement_level": "opt_in", + "note": "See [Setting `server.address` and `server.port` attributes](/docs/http/http-spans.md#setting-serveraddress-and-serverport-attributes).\n> **Warning**\n> Since this attribute is based on HTTP headers, opting in to it may allow an attacker\n> to trigger cardinality limits, degrading the usefulness of the metric.\n", + "stability": "stable" + } +] diff --git a/crates/weaver_resolver/data/registry-test-v2-2-multifile/expected-attribute-catalog.json b/crates/weaver_resolver/data/registry-test-v2-2-multifile/expected-attribute-catalog.json index 2bcb90528..4be608992 100644 --- a/crates/weaver_resolver/data/registry-test-v2-2-multifile/expected-attribute-catalog.json +++ b/crates/weaver_resolver/data/registry-test-v2-2-multifile/expected-attribute-catalog.json @@ -1,57 +1,55 @@ -{ - "attributes": [ - { - "name": "network.protocol.name", - "type": "string", - "brief": "[OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent.", - "examples": [ - "amqp", - "http", - "mqtt" - ], - "requirement_level": "recommended", - "note": "The value SHOULD be normalized to lowercase.", - "stability": "stable" +[ + { + "name": "network.protocol.name", + "type": "string", + "brief": "[OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent.", + "examples": [ + "amqp", + "http", + "mqtt" + ], + "requirement_level": "recommended", + "note": "The value SHOULD be normalized to lowercase.", + "stability": "stable" + }, + { + "name": "network.protocol.name", + "type": "string", + "brief": "[OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent.", + "examples": [ + "http", + "spdy" + ], + "requirement_level": { + "conditionally_required": "If not `http` and `network.protocol.version` is set." }, - { - "name": "network.protocol.name", - "type": "string", - "brief": "[OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent.", - "examples": [ - "http", - "spdy" - ], - "requirement_level": { - "conditionally_required": "If not `http` and `network.protocol.version` is set." - }, - "note": "The value SHOULD be normalized to lowercase.", - "stability": "stable" - }, - { - "name": "server.port", - "type": "int", - "brief": "Server port number.", - "examples": [ - 80, - 8080, - 443 - ], - "requirement_level": "recommended", - "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.\n", - "stability": "stable" - }, - { - "name": "server.port", - "type": "int", - "brief": "Server port number.", - "examples": [ - 80, - 8080, - 443 - ], - "requirement_level": "opt_in", - "note": "See [Setting `server.address` and `server.port` attributes](/docs/http/http-spans.md#setting-serveraddress-and-serverport-attributes).\n> **Warning**\n> Since this attribute is based on HTTP headers, opting in to it may allow an attacker\n> to trigger cardinality limits, degrading the usefulness of the metric.\n", - "stability": "stable" - } - ] -} \ No newline at end of file + "note": "The value SHOULD be normalized to lowercase.", + "stability": "stable" + }, + { + "name": "server.port", + "type": "int", + "brief": "Server port number.", + "examples": [ + 80, + 8080, + 443 + ], + "requirement_level": "recommended", + "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.\n", + "stability": "stable" + }, + { + "name": "server.port", + "type": "int", + "brief": "Server port number.", + "examples": [ + 80, + 8080, + 443 + ], + "requirement_level": "opt_in", + "note": "See [Setting `server.address` and `server.port` attributes](/docs/http/http-spans.md#setting-serveraddress-and-serverport-attributes).\n> **Warning**\n> Since this attribute is based on HTTP headers, opting in to it may allow an attacker\n> to trigger cardinality limits, degrading the usefulness of the metric.\n", + "stability": "stable" + } +] diff --git a/crates/weaver_resolver/data/registry-test-v2-3-both-version/expected-attribute-catalog.json b/crates/weaver_resolver/data/registry-test-v2-3-both-version/expected-attribute-catalog.json index 2bcb90528..4be608992 100644 --- a/crates/weaver_resolver/data/registry-test-v2-3-both-version/expected-attribute-catalog.json +++ b/crates/weaver_resolver/data/registry-test-v2-3-both-version/expected-attribute-catalog.json @@ -1,57 +1,55 @@ -{ - "attributes": [ - { - "name": "network.protocol.name", - "type": "string", - "brief": "[OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent.", - "examples": [ - "amqp", - "http", - "mqtt" - ], - "requirement_level": "recommended", - "note": "The value SHOULD be normalized to lowercase.", - "stability": "stable" +[ + { + "name": "network.protocol.name", + "type": "string", + "brief": "[OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent.", + "examples": [ + "amqp", + "http", + "mqtt" + ], + "requirement_level": "recommended", + "note": "The value SHOULD be normalized to lowercase.", + "stability": "stable" + }, + { + "name": "network.protocol.name", + "type": "string", + "brief": "[OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent.", + "examples": [ + "http", + "spdy" + ], + "requirement_level": { + "conditionally_required": "If not `http` and `network.protocol.version` is set." }, - { - "name": "network.protocol.name", - "type": "string", - "brief": "[OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent.", - "examples": [ - "http", - "spdy" - ], - "requirement_level": { - "conditionally_required": "If not `http` and `network.protocol.version` is set." - }, - "note": "The value SHOULD be normalized to lowercase.", - "stability": "stable" - }, - { - "name": "server.port", - "type": "int", - "brief": "Server port number.", - "examples": [ - 80, - 8080, - 443 - ], - "requirement_level": "recommended", - "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.\n", - "stability": "stable" - }, - { - "name": "server.port", - "type": "int", - "brief": "Server port number.", - "examples": [ - 80, - 8080, - 443 - ], - "requirement_level": "opt_in", - "note": "See [Setting `server.address` and `server.port` attributes](/docs/http/http-spans.md#setting-serveraddress-and-serverport-attributes).\n> **Warning**\n> Since this attribute is based on HTTP headers, opting in to it may allow an attacker\n> to trigger cardinality limits, degrading the usefulness of the metric.\n", - "stability": "stable" - } - ] -} \ No newline at end of file + "note": "The value SHOULD be normalized to lowercase.", + "stability": "stable" + }, + { + "name": "server.port", + "type": "int", + "brief": "Server port number.", + "examples": [ + 80, + 8080, + 443 + ], + "requirement_level": "recommended", + "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.\n", + "stability": "stable" + }, + { + "name": "server.port", + "type": "int", + "brief": "Server port number.", + "examples": [ + 80, + 8080, + 443 + ], + "requirement_level": "opt_in", + "note": "See [Setting `server.address` and `server.port` attributes](/docs/http/http-spans.md#setting-serveraddress-and-serverport-attributes).\n> **Warning**\n> Since this attribute is based on HTTP headers, opting in to it may allow an attacker\n> to trigger cardinality limits, degrading the usefulness of the metric.\n", + "stability": "stable" + } +] diff --git a/crates/weaver_resolver/data/registry-test-v2-4-refinements/expected-attribute-catalog.json b/crates/weaver_resolver/data/registry-test-v2-4-refinements/expected-attribute-catalog.json index d474a4883..76e6a2080 100644 --- a/crates/weaver_resolver/data/registry-test-v2-4-refinements/expected-attribute-catalog.json +++ b/crates/weaver_resolver/data/registry-test-v2-4-refinements/expected-attribute-catalog.json @@ -1,34 +1,32 @@ -{ - "attributes": [ - { - "name": "test.attr", - "type": "int", - "brief": "Test attribute", - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "test.attr", - "type": "int", - "brief": "Test attribute", - "requirement_level": "recommended", - "stability": "stable", - "role": "identifying" - }, - { - "name": "test.attr2", - "type": "string", - "brief": "Test attribute 2", - "requirement_level": "recommended", - "stability": "stable" - }, - { - "name": "test.attr2", - "type": "string", - "brief": "Test attribute 2", - "requirement_level": "recommended", - "stability": "stable", - "role": "descriptive" - } - ] -} \ No newline at end of file +[ + { + "name": "test.attr", + "type": "int", + "brief": "Test attribute", + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "test.attr", + "type": "int", + "brief": "Test attribute", + "requirement_level": "recommended", + "stability": "stable", + "role": "identifying" + }, + { + "name": "test.attr2", + "type": "string", + "brief": "Test attribute 2", + "requirement_level": "recommended", + "stability": "stable" + }, + { + "name": "test.attr2", + "type": "string", + "brief": "Test attribute 2", + "requirement_level": "recommended", + "stability": "stable", + "role": "descriptive" + } +] diff --git a/crates/weaver_resolver/data/registry-test-v2-dep/app_registry/manifest.yaml b/crates/weaver_resolver/data/registry-test-v2-dep/app_registry/manifest.yaml new file mode 100644 index 000000000..323ad3a73 --- /dev/null +++ b/crates/weaver_resolver/data/registry-test-v2-dep/app_registry/manifest.yaml @@ -0,0 +1,8 @@ +description: App registry that depends on the consumer V2 package. +schema_url: https://app.example.com/schemas/1.0.0 +dependencies: + - schema_url: https://consumer.example.com/schemas/1.0.0 + # TODO: this only works with definition registry, but not with + # resolved one, because resolved does not know how to get + # attributes from transitive dependencies. + registry_path: data/registry-test-v2-dep/consumer_registry diff --git a/crates/weaver_resolver/data/registry-test-v2-dep/app_registry/registry.yaml b/crates/weaver_resolver/data/registry-test-v2-dep/app_registry/registry.yaml new file mode 100644 index 000000000..b338281e2 --- /dev/null +++ b/crates/weaver_resolver/data/registry-test-v2-dep/app_registry/registry.yaml @@ -0,0 +1,12 @@ +file_format: definition/2 +metrics: + - name: app.request.count + brief: Count of app requests. + instrument: counter + unit: "{request}" + stability: stable + attributes: + - ref: server.address + requirement_level: required + - ref: server.port + requirement_level: recommended diff --git a/crates/weaver_resolver/data/registry-test-v2-dep/consumer_published/manifest.yaml b/crates/weaver_resolver/data/registry-test-v2-dep/consumer_published/manifest.yaml new file mode 100644 index 000000000..aef8cf80e --- /dev/null +++ b/crates/weaver_resolver/data/registry-test-v2-dep/consumer_published/manifest.yaml @@ -0,0 +1,8 @@ +file_format: manifest/2.0.0 +schema_url: https://consumer.example.com/schemas/1.0.0 +description: Consumer registry that depends on the server V2 package. +dependencies: +- schema_url: https://server.example.com/schemas/1.0.0 + registry_path: data/registry-test-v2-dep/published +stability: development +resolved_schema_uri: resolved.yaml diff --git a/crates/weaver_resolver/data/registry-test-v2-dep/consumer_published/resolved.yaml b/crates/weaver_resolver/data/registry-test-v2-dep/consumer_published/resolved.yaml new file mode 100644 index 000000000..73bc1388e --- /dev/null +++ b/crates/weaver_resolver/data/registry-test-v2-dep/consumer_published/resolved.yaml @@ -0,0 +1,75 @@ +file_format: resolved/2.0.0 +schema_url: https://consumer.example.com/schemas/1.0.0 +attribute_catalog: +- key: server.port + type: int + examples: + - 80 + - 443 + brief: The server port used by the consumer. + stability: stable +- key: server.address + type: string + examples: + - example.com + brief: Server address. + stability: stable +- key: server.address + type: string + examples: + - example.com + brief: Yet another description. + stability: stable +registry: + attributes: [] + attribute_groups: [] + spans: [] + metrics: + - name: consumer.request.active + instrument: updowncounter + unit: '{request}' + attributes: + - base: 2 + requirement_level: required + - base: 0 + requirement_level: recommended + brief: Number of active consumer requests. + stability: stable + - name: consumer.request.count + instrument: counter + unit: '{request}' + attributes: + - base: 1 + requirement_level: required + - base: 0 + requirement_level: recommended + brief: Count of consumer requests. + stability: stable + events: [] + entities: [] +refinements: + spans: [] + metrics: + - id: consumer.request.active + name: consumer.request.active + instrument: updowncounter + unit: '{request}' + attributes: + - base: 2 + requirement_level: required + - base: 0 + requirement_level: recommended + brief: Number of active consumer requests. + stability: stable + - id: consumer.request.count + name: consumer.request.count + instrument: counter + unit: '{request}' + attributes: + - base: 1 + requirement_level: required + - base: 0 + requirement_level: recommended + brief: Count of consumer requests. + stability: stable + events: [] diff --git a/crates/weaver_resolver/data/registry-test-v2-dep/consumer_registry/manifest.yaml b/crates/weaver_resolver/data/registry-test-v2-dep/consumer_registry/manifest.yaml new file mode 100644 index 000000000..3d8584717 --- /dev/null +++ b/crates/weaver_resolver/data/registry-test-v2-dep/consumer_registry/manifest.yaml @@ -0,0 +1,5 @@ +description: Consumer registry that depends on the server V2 package. +schema_url: https://consumer.example.com/schemas/1.0.0 +dependencies: + - schema_url: https://server.example.com/schemas/1.0.0 + registry_path: data/registry-test-v2-dep/published \ No newline at end of file diff --git a/crates/weaver_resolver/data/registry-test-v2-dep/consumer_registry/registry.yaml b/crates/weaver_resolver/data/registry-test-v2-dep/consumer_registry/registry.yaml new file mode 100644 index 000000000..7d1d6af07 --- /dev/null +++ b/crates/weaver_resolver/data/registry-test-v2-dep/consumer_registry/registry.yaml @@ -0,0 +1,25 @@ +file_format: definition/2 +metrics: + - name: consumer.request.count + brief: Count of consumer requests. + instrument: counter + unit: "{request}" + stability: stable + attributes: + - ref: server.address + requirement_level: required + - ref: server.port + requirement_level: recommended + brief: The server port used by the consumer. + - name: consumer.request.active + brief: Number of active consumer requests. + instrument: updowncounter + unit: "{request}" + stability: stable + attributes: + - ref: server.address + brief: Yet another description. + requirement_level: required + - ref: server.port + requirement_level: recommended + brief: The server port used by the consumer. diff --git a/crates/weaver_resolver/data/registry-test-v2-dep/published/manifest.yaml b/crates/weaver_resolver/data/registry-test-v2-dep/published/manifest.yaml new file mode 100644 index 000000000..37ccb4895 --- /dev/null +++ b/crates/weaver_resolver/data/registry-test-v2-dep/published/manifest.yaml @@ -0,0 +1,5 @@ +file_format: manifest/2.0.0 +schema_url: https://server.example.com/schemas/1.0.0 +description: Server semantic conventions. +stability: development +resolved_schema_uri: resolved.yaml diff --git a/crates/weaver_resolver/data/registry-test-v2-dep/published/resolved.yaml b/crates/weaver_resolver/data/registry-test-v2-dep/published/resolved.yaml new file mode 100644 index 000000000..9b6e2d4f2 --- /dev/null +++ b/crates/weaver_resolver/data/registry-test-v2-dep/published/resolved.yaml @@ -0,0 +1,57 @@ +file_format: resolved/2.0.0 +schema_url: https://server.example.com/schemas/1.0.0 +attribute_catalog: +- key: server.port + type: int + examples: + - 80 + - 443 + brief: Server port. + stability: stable +- key: server.address + type: string + examples: + - example.com + brief: Different brief + note: Different note + stability: stable +- key: server.address + type: string + examples: + - example.com + brief: Server address. + stability: stable +registry: + attributes: + - 2 + - 0 + attribute_groups: [] + spans: [] + metrics: + - name: server.request.duration + instrument: histogram + unit: s + attributes: + - base: 1 + requirement_level: required + - base: 0 + requirement_level: recommended + brief: Duration of server requests. + stability: stable + events: [] + entities: [] +refinements: + spans: [] + metrics: + - id: server.request.duration + name: server.request.duration + instrument: histogram + unit: s + attributes: + - base: 1 + requirement_level: required + - base: 0 + requirement_level: recommended + brief: Duration of server requests. + stability: stable + events: [] diff --git a/crates/weaver_resolver/src/attribute.rs b/crates/weaver_resolver/src/attribute.rs index 908101c7f..75b2936f7 100644 --- a/crates/weaver_resolver/src/attribute.rs +++ b/crates/weaver_resolver/src/attribute.rs @@ -8,6 +8,7 @@ use serde::Deserialize; use weaver_resolved_schema::attribute::AttributeRef; use weaver_resolved_schema::attribute::{self}; +use weaver_resolved_schema::catalog::Catalog; use weaver_resolved_schema::lineage::{AttributeLineage, GroupLineage}; use weaver_resolved_schema::v2::ResolvedTelemetrySchema as V2Schema; use weaver_resolved_schema::ResolvedTelemetrySchema as V1Schema; @@ -262,6 +263,21 @@ impl AttributeCatalog { } } +impl From for Catalog { + fn from(attr_catalog: AttributeCatalog) -> Self { + let root_attributes = attr_catalog + .root_attributes + .into_iter() + .map(|(k, v)| (k, (v.attribute, v.group_id))) + .collect(); + let mut attributes: Vec<(attribute::Attribute, AttributeRef)> = + attr_catalog.attribute_refs.into_iter().collect(); + attributes.sort_by_key(|(_, attr_ref)| attr_ref.0); + let attributes = attributes.into_iter().map(|(attr, _)| attr).collect(); + Catalog::new(attributes, root_attributes) + } +} + /// Helper trait for abstracting over V1 and V2 schema. trait AttributeLookup { fn lookup_attribute(&self, key: &str) -> Option; @@ -284,45 +300,20 @@ impl AttributeLookup for ResolvedDependency { impl AttributeLookup for V1Schema { fn lookup_attribute(&self, key: &str) -> Option { - // TODO - fast lookup, not a table scan... - // Because of how the algorithm works, we need to looks across - // *all possible* groups for an attribute. - // Note: This *only* works with lineage and breaks otherwise. - let result = self.registry.groups.iter().find_map(|g| { - g.attributes - .iter() - .find_map(|ar| { - self.catalog - .attribute(ar) - .filter(|a| a.name == key) - .and_then(|a| { - let lineage = g - .lineage - .as_ref() - .and_then(|l| l.attribute(&a.name)) - .filter(|al| al.source_group == g.id); - // We defined the attribute. - if lineage.is_none() { - Some(a.clone()) - } else { - // We did not define the attribute. - None - } - }) - }) - .map(|a| AttributeWithGroupId { - attribute: a, - group_id: g.id.to_owned(), - }) - }); - result + self.catalog + .root_attribute(key) + .map(|(attr, group_id)| AttributeWithGroupId { + attribute: attr.clone(), + group_id: group_id.to_owned(), + }) } } impl AttributeLookup for V2Schema { fn lookup_attribute(&self, key: &str) -> Option { let fake_group_id = format!("v2_dependency.{}", self.schema_url.name()); - self.attribute_catalog.iter().find_map(|attr| { + self.registry.attributes.iter().find_map(|attr_ref| { + let attr = self.attribute_catalog.get(attr_ref.0 as usize)?; if attr.key == key { Some(AttributeWithGroupId { attribute: attribute::Attribute { diff --git a/crates/weaver_resolver/src/dependency.rs b/crates/weaver_resolver/src/dependency.rs index 537acc983..c6e722f18 100644 --- a/crates/weaver_resolver/src/dependency.rs +++ b/crates/weaver_resolver/src/dependency.rs @@ -702,7 +702,7 @@ fn build_globset(wildcards: Option<&Vec>) -> Result { panic!("Unexpected attribute name: {}", attr.name); @@ -395,4 +395,121 @@ mod tests { Ok(()) } + + #[test] + fn test_v2_dependency_resolution() -> Result<(), weaver_semconv::Error> { + // Test that a consumer registry can resolve attribute refs from a pre-resolved V2 dependency. + let registry_path = VirtualDirectoryPath::LocalFolder { + path: "data/registry-test-v2-dep/consumer_registry".to_owned(), + }; + + let registry_repo = RegistryRepo::try_new(None, ®istry_path, &mut vec![])?; + let mut diag_msgs = DiagnosticMessages::empty(); + let loaded = SchemaResolver::load_semconv_repository(registry_repo, false) + .capture_non_fatal_errors(&mut diag_msgs) + .expect("Failed to load consumer registry"); + + let resolved = SchemaResolver::resolve(loaded, false); + match resolved { + WResult::Ok(resolved_registry) | WResult::OkWithNFEs(resolved_registry, _) => { + let metrics = resolved_registry.groups(GroupType::Metric); + let metric = metrics + .get("metric.consumer.request.count") + .expect("metric.consumer.request.count not found"); + + assert_eq!(metric.attributes.len(), 2); + + let mut attr_names = HashSet::new(); + for attr_ref in &metric.attributes { + let attr = resolved_registry + .catalog + .attribute(attr_ref) + .expect("Failed to resolve attribute ref"); + _ = attr_names.insert(attr.name.clone()); + match attr.name.as_str() { + "server.address" => { + // requirement_level overridden to required in consumer + assert_eq!( + attr.requirement_level, + RequirementLevel::Basic(BasicRequirementLevelSpec::Required) + ); + assert_eq!(attr.brief, "Server address."); + assert_eq!( + attr.r#type, + weaver_semconv::attribute::AttributeType::PrimitiveOrArray( + weaver_semconv::attribute::PrimitiveOrArrayTypeSpec::String + ) + ); + } + "server.port" => { + // brief overridden locally in consumer + assert_eq!(attr.brief, "The server port used by the consumer."); + // type still comes from the V2 dependency + assert_eq!( + attr.r#type, + weaver_semconv::attribute::AttributeType::PrimitiveOrArray( + weaver_semconv::attribute::PrimitiveOrArrayTypeSpec::Int + ) + ); + } + _ => panic!("Unexpected attribute: {}", attr.name), + } + } + + assert!(attr_names.contains("server.address")); + assert!(attr_names.contains("server.port")); + } + WResult::FatalErr(fatal) => { + panic!("Failed to resolve consumer registry: {fatal}"); + } + } + + Ok(()) + } + + #[test] + fn test_v2_three_layer_dependency_resolution() -> Result<(), weaver_semconv::Error> { + // TODO: this only works with definition registry, but not with + // resolved one, because resolved does not know how to get + // attributes from transitive dependencies. + // Test that briefs are correctly inherited through two levels of V2 dependencies: + // app_registry -> consumer_registry -> published (server definitions) + let registry_path = VirtualDirectoryPath::LocalFolder { + path: "data/registry-test-v2-dep/app_registry".to_owned(), + }; + let registry_repo = RegistryRepo::try_new(None, ®istry_path, &mut vec![])?; + let mut diag_msgs = DiagnosticMessages::empty(); + let loaded = SchemaResolver::load_semconv_repository(registry_repo, false) + .capture_non_fatal_errors(&mut diag_msgs) + .expect("Failed to load app registry"); + + let resolved = SchemaResolver::resolve(loaded, false); + match resolved { + WResult::Ok(resolved_registry) | WResult::OkWithNFEs(resolved_registry, _) => { + let metrics = resolved_registry.groups(GroupType::Metric); + let metric = metrics + .get("metric.app.request.count") + .expect("metric.app.request.count not found"); + assert_eq!(metric.attributes.len(), 2); + for attr_ref in &metric.attributes { + let attr = resolved_registry + .catalog + .attribute(attr_ref) + .expect("Failed to resolve attribute ref"); + match attr.name.as_str() { + // Briefs must come from the original definitions in published/, + // two V2 dependency hops away. + "server.address" => assert_eq!(attr.brief, "Server address."), + "server.port" => assert_eq!(attr.brief, "Server port."), + _ => panic!("Unexpected attribute: {}", attr.name), + } + } + } + WResult::FatalErr(fatal) => { + panic!("Failed to resolve app registry: {fatal}"); + } + } + + Ok(()) + } } diff --git a/crates/weaver_resolver/src/loader.rs b/crates/weaver_resolver/src/loader.rs index 2130816cf..e8da3d4fc 100644 --- a/crates/weaver_resolver/src/loader.rs +++ b/crates/weaver_resolver/src/loader.rs @@ -22,6 +22,7 @@ use crate::Error; const MAX_DEPENDENCY_DEPTH: u32 = 10; /// The result of loading a semantic convention URL prior to resolution. +#[allow(clippy::large_enum_variant)] pub enum LoadedSemconvRegistry { /// The semconv repository was unresolved and needs to be run through resolution. Unresolved { diff --git a/crates/weaver_resolver/src/registry.rs b/crates/weaver_resolver/src/registry.rs index caae94136..945891296 100644 --- a/crates/weaver_resolver/src/registry.rs +++ b/crates/weaver_resolver/src/registry.rs @@ -970,6 +970,7 @@ mod tests { // "registry-test-7-spans", // "registry-test-8-http", // "registry-test-v2-2-multifile", + "registry-test-v2-dep", // tested separately in lib.rs ]; // Iterate over all directories in the data directory and // starting with registry-test-* @@ -1068,7 +1069,8 @@ mod tests { } let observed_schema = schema.expect("Failed to resolve the registry"); - let observed_attr_catalog = observed_schema.catalog; + let observed_attr_catalog: Vec<_> = + observed_schema.catalog.attributes().cloned().collect(); // At this point, the normal behavior of this test is to pass. let mut observed_registry = observed_schema.registry; @@ -1089,18 +1091,17 @@ mod tests { // Load the expected registry and attribute catalog. let expected_attr_catalog_file = format!("{test_dir}/expected-attribute-catalog.json"); - let expected_attr_catalog: weaver_resolved_schema::catalog::Catalog = - serde_json::from_reader( - std::fs::File::open(expected_attr_catalog_file) - .expect("Failed to open expected attribute catalog"), - ) - .expect("Failed to deserialize expected attribute catalog"); + let expected_attr_catalog_attrs: Vec = serde_json::from_reader( + std::fs::File::open(expected_attr_catalog_file) + .expect("Failed to open expected attribute catalog"), + ) + .expect("Failed to deserialize expected attribute catalog"); // Compare values assert_eq!( - observed_attr_catalog, expected_attr_catalog, + observed_attr_catalog, expected_attr_catalog_attrs, "Observed and expected attribute catalogs don't match for `{}`.\nDiff from expected:\n{}", - test_dir, weaver_diff::diff_output(&to_json(&expected_attr_catalog), &to_json(&observed_attr_catalog)) + test_dir, weaver_diff::diff_output(&to_json(&expected_attr_catalog_attrs), &to_json(&observed_attr_catalog)) ); // Check that the resolved registry matches the expected registry. diff --git a/src/registry/search.rs b/src/registry/search.rs index b817a8feb..35da49794 100644 --- a/src/registry/search.rs +++ b/src/registry/search.rs @@ -137,7 +137,7 @@ impl<'a> SearchApp<'a> { fn result_set(&'a self) -> impl Iterator { self.schema .catalog - .iter() + .attributes() .filter(|a| a.name.contains(self.search_string().as_str())) } @@ -366,7 +366,7 @@ fn run_ui(schema: &ResolvedTelemetrySchema) -> Result<(), Error> { fn run_command_line_search(schema: &ResolvedTelemetrySchema, pattern: &str) { let results = schema .catalog() - .iter() + .attributes() .filter(|a| a.name.contains(pattern)) .map(|a| a.name.to_owned()) .join("\n");