From cadc052ab9bb8c60192380626e5893fcc56cad1e Mon Sep 17 00:00:00 2001 From: Laurent Querel Date: Sat, 17 Feb 2024 17:46:15 -0800 Subject: [PATCH 01/20] feat(template): replace tera with minijinja to improve error handling --- crates/weaver_template/README.md | 7 ++++++- crates/weaver_template_engine/Cargo.toml | 11 +++++++++++ crates/weaver_template_engine/README.md | 6 ++++++ .../allowed-external-types.toml | 6 ++++++ crates/weaver_template_engine/src/lib.rs | 15 +++++++++++++++ 5 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 crates/weaver_template_engine/Cargo.toml create mode 100644 crates/weaver_template_engine/README.md create mode 100644 crates/weaver_template_engine/allowed-external-types.toml create mode 100644 crates/weaver_template_engine/src/lib.rs diff --git a/crates/weaver_template/README.md b/crates/weaver_template/README.md index 0c958487..102f07d4 100644 --- a/crates/weaver_template/README.md +++ b/crates/weaver_template/README.md @@ -1,6 +1,11 @@ # Template Engine -Status: **Work-In-Progress** +Status: **Deprecated (see weaver_template_engine)** + +Important Note: Tera doesn't have a good error handling mechanism. Tera2 is +under development to address this issue but doesn't have an ETA yet. So the +plan is to use the crate MiniJinja for the template engine as it has a better +error handling mechanism. This crate extends the `tera` template engine with custom filters and functions. diff --git a/crates/weaver_template_engine/Cargo.toml b/crates/weaver_template_engine/Cargo.toml new file mode 100644 index 00000000..30fee19f --- /dev/null +++ b/crates/weaver_template_engine/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "weaver_template_engine" +version = "0.1.0" +authors.workspace = true +repository.workspace = true +license.workspace = true +publish.workspace = true +edition.workspace = true + +[dependencies] +minijinja = "1.0.12" \ No newline at end of file diff --git a/crates/weaver_template_engine/README.md b/crates/weaver_template_engine/README.md new file mode 100644 index 00000000..2b0348a8 --- /dev/null +++ b/crates/weaver_template_engine/README.md @@ -0,0 +1,6 @@ +# Template Engine + +Status: **Work-In-Progress** + +This crate extends the `MiniJinja` template engine with custom filters and +functions. \ No newline at end of file diff --git a/crates/weaver_template_engine/allowed-external-types.toml b/crates/weaver_template_engine/allowed-external-types.toml new file mode 100644 index 00000000..f186b677 --- /dev/null +++ b/crates/weaver_template_engine/allowed-external-types.toml @@ -0,0 +1,6 @@ +# Copyright The OpenTelemetry Authors +# SPDX-License-Identifier: Apache-2.0 +# This is used with cargo-check-external-types to reduce the surface area of downstream crates from +# the public API. Ideally this can have a few exceptions as possible. +allowed_external_types = [ +] \ No newline at end of file diff --git a/crates/weaver_template_engine/src/lib.rs b/crates/weaver_template_engine/src/lib.rs new file mode 100644 index 00000000..1b036874 --- /dev/null +++ b/crates/weaver_template_engine/src/lib.rs @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: Apache-2.0 + +//! This crate extends the MiniJinja template engine to add helper functions +//! and filters for working with semantic convention registries and telemetry +//! schemas. + +#![deny( +missing_docs, +clippy::print_stdout, +unstable_features, +unused_import_braces, +unused_qualifications, +unused_results, +unused_extern_crates +)] From da3c7d3c5742ffb758595b20985f300c56b1ff30 Mon Sep 17 00:00:00 2001 From: Laurent Querel Date: Mon, 26 Feb 2024 09:00:58 -0800 Subject: [PATCH 02/20] feat(template): start integration of the case converter --- Cargo.lock | 35 ++++ crates/weaver_forge/Cargo.toml | 17 ++ .../README.md | 0 .../allowed-external-types.toml | 0 crates/weaver_forge/src/config.rs | 137 ++++++++++++++++ .../src/extensions/case_converter.rs | 20 +++ crates/weaver_forge/src/extensions/mod.rs | 4 + crates/weaver_forge/src/lib.rs | 155 ++++++++++++++++++ crates/weaver_template_engine/Cargo.toml | 11 -- crates/weaver_template_engine/src/lib.rs | 15 -- 10 files changed, 368 insertions(+), 26 deletions(-) create mode 100644 crates/weaver_forge/Cargo.toml rename crates/{weaver_template_engine => weaver_forge}/README.md (100%) rename crates/{weaver_template_engine => weaver_forge}/allowed-external-types.toml (100%) create mode 100644 crates/weaver_forge/src/config.rs create mode 100644 crates/weaver_forge/src/extensions/case_converter.rs create mode 100644 crates/weaver_forge/src/extensions/mod.rs create mode 100644 crates/weaver_forge/src/lib.rs delete mode 100644 crates/weaver_template_engine/Cargo.toml delete mode 100644 crates/weaver_template_engine/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index cbe24994..3b355b72 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2010,12 +2010,29 @@ dependencies = [ "libc", ] +[[package]] +name = "memo-map" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "374c335b2df19e62d4cb323103473cbc6510980253119180de862d89184f6a83" + [[package]] name = "mime" version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" +[[package]] +name = "minijinja" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fe0ff215195a22884d867b547c70a0c4815cbbcc70991f281dca604b20d10ce" +dependencies = [ + "memo-map", + "self_cell", + "serde", +] + [[package]] name = "minimal-lexical" version = "0.2.1" @@ -2751,6 +2768,12 @@ dependencies = [ "untrusted", ] +[[package]] +name = "self_cell" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58bf37232d3bb9a2c4e641ca2a11d83b5062066f88df7fed36c28772046d65ba" + [[package]] name = "semver" version = "1.0.21" @@ -3795,6 +3818,18 @@ dependencies = [ "thiserror", ] +[[package]] +name = "weaver_forge" +version = "0.1.0" +dependencies = [ + "convert_case", + "minijinja", + "serde", + "serde_yaml", + "thiserror", + "thread_local", +] + [[package]] name = "weaver_logger" version = "0.1.0" diff --git a/crates/weaver_forge/Cargo.toml b/crates/weaver_forge/Cargo.toml new file mode 100644 index 00000000..b99da22e --- /dev/null +++ b/crates/weaver_forge/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "weaver_forge" +version = "0.1.0" +authors.workspace = true +repository.workspace = true +license.workspace = true +publish.workspace = true +edition.workspace = true + +[dependencies] +minijinja = { version = "1.0.12", features = ["loader"] } +thread_local = "1.1.7" +convert_case = "0.6.0" + +thiserror.workspace = true +serde.workspace = true +serde_yaml.workspace = true \ No newline at end of file diff --git a/crates/weaver_template_engine/README.md b/crates/weaver_forge/README.md similarity index 100% rename from crates/weaver_template_engine/README.md rename to crates/weaver_forge/README.md diff --git a/crates/weaver_template_engine/allowed-external-types.toml b/crates/weaver_forge/allowed-external-types.toml similarity index 100% rename from crates/weaver_template_engine/allowed-external-types.toml rename to crates/weaver_forge/allowed-external-types.toml diff --git a/crates/weaver_forge/src/config.rs b/crates/weaver_forge/src/config.rs new file mode 100644 index 00000000..061cc62b --- /dev/null +++ b/crates/weaver_forge/src/config.rs @@ -0,0 +1,137 @@ +// SPDX-License-Identifier: Apache-2.0 + +//! Configuration for the template crate. + +use std::cell::RefCell; +use std::collections::HashMap; +use std::path::Path; + +use convert_case::{Case, Casing}; +use serde::Deserialize; +use thread_local::ThreadLocal; + +use crate::Error; +use crate::Error::InvalidConfigFile; + +/// Case convention for naming of functions and structs. +#[derive(Deserialize, Debug)] +#[allow(clippy::enum_variant_names)] +pub enum CaseConvention { + #[serde(rename = "lowercase")] + LowerCase, + #[serde(rename = "UPPERCASE")] + UpperCase, + #[serde(rename = "PascalCase")] + PascalCase, + #[serde(rename = "camelCase")] + CamelCase, + #[serde(rename = "snake_case")] + SnakeCase, + #[serde(rename = "SCREAMING_SNAKE_CASE")] + ScreamingSnakeCase, + #[serde(rename = "kebab-case")] + KebabCase, + #[serde(rename = "SCREAMING-KEBAB-CASE")] + ScreamingKebabCase, +} + +/// Target specific configuration. +#[derive(Deserialize, Debug, Default)] +pub struct TargetConfig { + /// Case convention used to name a file. + #[serde(default)] + pub file_name: CaseConvention, + /// Case convention used to name a function. + #[serde(default)] + pub function_name: CaseConvention, + /// Case convention used to name a function argument. + #[serde(default)] + pub arg_name: CaseConvention, + /// Case convention used to name a struct. + #[serde(default)] + pub struct_name: CaseConvention, + /// Case convention used to name a struct field. + #[serde(default)] + pub field_name: CaseConvention, + /// Type mapping for target specific types (OTel types -> Target language types). + #[serde(default)] + pub type_mapping: HashMap, +} + +/// Dynamic global configuration. +#[derive(Debug, Default)] +pub struct DynamicGlobalConfig { + /// File name for the current generated code. + pub file_name: ThreadLocal>>, +} + +impl Default for CaseConvention { + /// Default case convention is PascalCase + fn default() -> Self { + CaseConvention::PascalCase + } +} + +impl CaseConvention { + pub fn convert(&self, text: &str) -> String { + let text = text.replace('.', "_"); + match self { + CaseConvention::LowerCase => text.to_case(Case::Lower), + CaseConvention::UpperCase => text.to_case(Case::Upper), + CaseConvention::PascalCase => text.to_case(Case::Pascal), + CaseConvention::CamelCase => text.to_case(Case::Camel), + CaseConvention::SnakeCase => text.to_case(Case::Snake), + CaseConvention::ScreamingSnakeCase => text.to_case(Case::ScreamingSnake), + CaseConvention::KebabCase => text.to_case(Case::Kebab), + CaseConvention::ScreamingKebabCase => text.to_case(Case::Cobol), + } + } +} + +impl TargetConfig { + pub fn try_new(lang_path: &Path) -> Result { + let config_file = lang_path.join("config.yaml"); + if config_file.exists() { + let reader = + std::fs::File::open(config_file.clone()).map_err(|e| InvalidConfigFile { + config_file: config_file.clone(), + error: e.to_string(), + })?; + serde_yaml::from_reader(reader).map_err(|e| InvalidConfigFile { + config_file: config_file.clone(), + error: e.to_string(), + }) + } else { + Ok(TargetConfig::default()) + } + } +} + +impl DynamicGlobalConfig { + /// Set the file name for the current generated code. + /// This method uses a thread local variable to store the file name. + pub fn set(&self, file_name: &str) { + self.file_name + .get_or(|| RefCell::new(None)) + .borrow_mut() + .replace(file_name.to_string()); + } + + /// Get the file name for the current generated code. + /// This method uses a thread local variable to store the file name. + pub fn get(&self) -> Option { + self.file_name + .get_or(|| RefCell::new(None)) + .borrow() + .clone() + } + + /// Reset the file name for the current generated code. + /// This method uses a thread local variable to store the file name. + pub fn reset(&self) { + self.file_name + .get_or(|| RefCell::new(None)) + .borrow_mut() + .take(); + } +} diff --git a/crates/weaver_forge/src/extensions/case_converter.rs b/crates/weaver_forge/src/extensions/case_converter.rs new file mode 100644 index 00000000..a7a13c7f --- /dev/null +++ b/crates/weaver_forge/src/extensions/case_converter.rs @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: Apache-2.0 + +//! Case converter filters used by the template engine. + +use convert_case::{Case, Casing}; + +/// Converts input string to lower case +fn lower_case(input: String) -> String { + input.to_case(Case::Lower) +} + +/// Converts input string to upper case +fn upper_case(input: String) -> String { + input.to_case(Case::Upper) +} + +/// Converts input string to camel case +fn camel_case(input: String) -> String { + input.to_case(Case::Camel) +} diff --git a/crates/weaver_forge/src/extensions/mod.rs b/crates/weaver_forge/src/extensions/mod.rs new file mode 100644 index 00000000..c091caf4 --- /dev/null +++ b/crates/weaver_forge/src/extensions/mod.rs @@ -0,0 +1,4 @@ +// SPDX-License-Identifier: Apache-2.0 + +//! Custom filters used by the template engine. +mod case_converter; \ No newline at end of file diff --git a/crates/weaver_forge/src/lib.rs b/crates/weaver_forge/src/lib.rs new file mode 100644 index 00000000..64c1291e --- /dev/null +++ b/crates/weaver_forge/src/lib.rs @@ -0,0 +1,155 @@ +// SPDX-License-Identifier: Apache-2.0 + +//! This crate extends the MiniJinja template engine to add helper functions +//! and filters for working with semantic convention registries and telemetry +//! schemas. + +#![deny( +missing_docs, +clippy::print_stdout, +unstable_features, +unused_import_braces, +unused_qualifications, +unused_results, +unused_extern_crates +)] + +use std::path::PathBuf; +use std::sync::Arc; + +use minijinja::{Environment, filters, functions, path_loader}; + +use crate::config::{DynamicGlobalConfig, TargetConfig}; +use crate::Error::{InvalidTemplateDir, TargetNotSupported}; + +mod config; +mod extensions; + +/// Errors emitted by this crate. +#[derive(thiserror::Error, Debug)] +pub enum Error { + /// Target not found. + #[error( + "Target `{0}` is not supported. Use the command `targets` to list supported targets." + )] + TargetNotSupported(String), + + /// Invalid template directory. + #[error("Invalid template directory: {0}")] + InvalidTemplateDir(PathBuf), +} + +/// General configuration for the generator. +pub struct GeneratorConfig { + /// Root directory for the templates. + root_dir: PathBuf, +} + +impl Default for GeneratorConfig { + /// Create a new generator configuration with default values. + fn default() -> Self { + Self { + root_dir: PathBuf::from("templates"), + } + } +} + +/// Template engine for generating artifacts from a semantic convention +/// registry and telemetry schema. +pub struct TemplateEngine { + /// Template path + path: PathBuf, + + /// Global configuration + config: Arc, +} + +impl TemplateEngine { + /// Create a new template engine for the given target or return an error if + /// the target does not exist or is not a directory. + pub fn try_new(target: &str, config: GeneratorConfig) -> Result { + // Check if the target is supported. + // A target is supported if a template directory exists for it. + let target_path = config.root_dir.join(target); + + if !target_path.exists() { + return Err(TargetNotSupported(target.to_string())); + } + + let mut env = Environment::new(); + env.set_loader(path_loader(target_path + .to_str() + .ok_or(Err(InvalidTemplateDir(target_path)))? + )); + + let target_config = TargetConfig::try_new(&target_path)?; + + let config = Arc::new(DynamicGlobalConfig::default()); + + // Register custom filters + env.add_filter( + "file_name", + extensions::CaseConverter::new(target_config.file_name, "file_name"), + ); + tera.register_filter( + "function_name", + extensions::CaseConverter::new(target_config.function_name, "function_name"), + ); + tera.register_filter( + "arg_name", + extensions::CaseConverter::new(target_config.arg_name, "arg_name"), + ); + tera.register_filter( + "struct_name", + extensions::CaseConverter::new(target_config.struct_name, "struct_name"), + ); + tera.register_filter( + "field_name", + extensions::CaseConverter::new(target_config.field_name, "field_name"), + ); + tera.register_filter("unique_attributes", extensions::unique_attributes); + tera.register_filter("instrument", extensions::instrument); + tera.register_filter("required", extensions::required); + tera.register_filter("not_required", extensions::not_required); + tera.register_filter("value", extensions::value); + tera.register_filter("with_value", extensions::with_value); + tera.register_filter("without_value", extensions::without_value); + tera.register_filter("with_enum", extensions::with_enum); + tera.register_filter("without_enum", extensions::without_enum); + tera.register_filter("comment", extensions::comment); + tera.register_filter( + "type_mapping", + extensions::TypeMapping { + type_mapping: target_config.type_mapping, + }, + ); + + // Register custom functions + tera.register_function("config", functions::FunctionConfig::new(config.clone())); + + // Register custom testers + tera.register_tester("required", testers::is_required); + tera.register_tester("not_required", testers::is_not_required); + + Ok(Self { + lang_path: target_path, + tera, + config, + }) + } +} + +#[cfg(test)] +mod tests { + use minijinja::{context, Environment}; + + use super::*; + + #[test] + fn test() { + let mut env = Environment::new(); + env.add_template("hello.txt", "Hello {{ name }}!").unwrap(); + let template = env.get_template("hello.txt").unwrap(); + println!("{}", template.render(context! { name => "World" }).unwrap()); + } +} \ No newline at end of file diff --git a/crates/weaver_template_engine/Cargo.toml b/crates/weaver_template_engine/Cargo.toml deleted file mode 100644 index 30fee19f..00000000 --- a/crates/weaver_template_engine/Cargo.toml +++ /dev/null @@ -1,11 +0,0 @@ -[package] -name = "weaver_template_engine" -version = "0.1.0" -authors.workspace = true -repository.workspace = true -license.workspace = true -publish.workspace = true -edition.workspace = true - -[dependencies] -minijinja = "1.0.12" \ No newline at end of file diff --git a/crates/weaver_template_engine/src/lib.rs b/crates/weaver_template_engine/src/lib.rs deleted file mode 100644 index 1b036874..00000000 --- a/crates/weaver_template_engine/src/lib.rs +++ /dev/null @@ -1,15 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 - -//! This crate extends the MiniJinja template engine to add helper functions -//! and filters for working with semantic convention registries and telemetry -//! schemas. - -#![deny( -missing_docs, -clippy::print_stdout, -unstable_features, -unused_import_braces, -unused_qualifications, -unused_results, -unused_extern_crates -)] From 1a10aa4bd6ab344256f454326304af4e3478c9b4 Mon Sep 17 00:00:00 2001 From: Laurent Querel Date: Wed, 28 Feb 2024 08:47:17 -0800 Subject: [PATCH 03/20] feat(template): integrate with minininja --- Cargo.lock | 9 + crates/weaver_forge/Cargo.toml | 12 +- crates/weaver_forge/data/registry-db.yaml | 432 ++++++++++++ crates/weaver_forge/data/registry-http.yaml | 135 ++++ .../weaver_forge/data/registry-network.yaml | 194 ++++++ crates/weaver_forge/data/registry-server.yaml | 28 + crates/weaver_forge/data/registry-url.yaml | 41 ++ .../data/registry-user-agent.yaml | 13 + crates/weaver_forge/data/trace-database.yaml | 263 ++++++++ crates/weaver_forge/src/config.rs | 4 +- .../src/extensions/case_converter.rs | 52 +- crates/weaver_forge/src/extensions/mod.rs | 2 +- crates/weaver_forge/src/lib.rs | 613 ++++++++++++++++-- crates/weaver_semconv/Cargo.toml | 1 + crates/weaver_semconv/src/lib.rs | 43 ++ 15 files changed, 1774 insertions(+), 68 deletions(-) create mode 100644 crates/weaver_forge/data/registry-db.yaml create mode 100644 crates/weaver_forge/data/registry-http.yaml create mode 100644 crates/weaver_forge/data/registry-network.yaml create mode 100644 crates/weaver_forge/data/registry-server.yaml create mode 100644 crates/weaver_forge/data/registry-url.yaml create mode 100644 crates/weaver_forge/data/registry-user-agent.yaml create mode 100644 crates/weaver_forge/data/trace-database.yaml diff --git a/Cargo.lock b/Cargo.lock index 3b355b72..5666bdb9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3823,11 +3823,19 @@ name = "weaver_forge" version = "0.1.0" dependencies = [ "convert_case", + "glob", "minijinja", + "rayon", "serde", "serde_yaml", "thiserror", "thread_local", + "weaver_cache", + "weaver_logger", + "weaver_resolved_schema", + "weaver_resolver", + "weaver_schema", + "weaver_semconv", ] [[package]] @@ -3886,6 +3894,7 @@ dependencies = [ name = "weaver_semconv" version = "0.1.0" dependencies = [ + "glob", "ordered-float", "serde", "serde_yaml", diff --git a/crates/weaver_forge/Cargo.toml b/crates/weaver_forge/Cargo.toml index b99da22e..772d7b78 100644 --- a/crates/weaver_forge/Cargo.toml +++ b/crates/weaver_forge/Cargo.toml @@ -8,10 +8,20 @@ publish.workspace = true edition.workspace = true [dependencies] +weaver_logger = { path = "../weaver_logger" } +weaver_cache = { path = "../weaver_cache" } +weaver_resolver = { path = "../weaver_resolver" } +weaver_schema = { path = "../weaver_schema" } +weaver_resolved_schema = { path = "../weaver_resolved_schema" } +weaver_semconv = { path = "../weaver_semconv" } + minijinja = { version = "1.0.12", features = ["loader"] } thread_local = "1.1.7" convert_case = "0.6.0" +glob = "0.3.1" thiserror.workspace = true serde.workspace = true -serde_yaml.workspace = true \ No newline at end of file +serde_yaml.workspace = true +rayon.workspace = true + diff --git a/crates/weaver_forge/data/registry-db.yaml b/crates/weaver_forge/data/registry-db.yaml new file mode 100644 index 00000000..a17c1046 --- /dev/null +++ b/crates/weaver_forge/data/registry-db.yaml @@ -0,0 +1,432 @@ +groups: + - id: registry.db + prefix: db + type: attribute_group + brief: > + This document defines the attributes used to describe telemetry in the context of databases. + attributes: + - id: cassandra.coordinator.dc + type: string + brief: > + The data center of the coordinating node for a query. + examples: 'us-west-2' + tag: tech-specific-cassandra + - id: cassandra.coordinator.id + type: string + brief: > + The ID of the coordinating node for a query. + examples: 'be13faa2-8574-4d71-926d-27f16cf8a7af' + tag: tech-specific-cassandra + - id: cassandra.consistency_level + 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). + type: + members: + - id: all + value: 'all' + - id: each_quorum + value: 'each_quorum' + - id: quorum + value: 'quorum' + - id: local_quorum + value: 'local_quorum' + - id: one + value: 'one' + - id: two + value: 'two' + - id: three + value: 'three' + - id: local_one + value: 'local_one' + - id: any + value: 'any' + - id: serial + value: 'serial' + - id: local_serial + value: 'local_serial' + tag: tech-specific-cassandra + - id: cassandra.idempotence + type: boolean + brief: > + Whether or not the query is idempotent. + tag: tech-specific-cassandra + - id: cassandra.page_size + type: int + brief: > + The fetch size used for paging, i.e. how many rows will be returned at once. + examples: [5000] + tag: tech-specific-cassandra + - id: 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. + examples: [0, 2] + tag: tech-specific-cassandra + - id: cassandra.table + type: string + brief: The name of the primary Cassandra table that the operation is acting upon, including the keyspace name (if applicable). + 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. + examples: 'mytable' + tag: tech-specific-cassandra + - id: connection_string + type: string + brief: > + The connection string used to connect to the database. + It is recommended to remove embedded credentials. + examples: 'Server=(localdb)\v11.0;Integrated Security=true;' + tag: db-generic + - id: cosmosdb.client_id + type: string + brief: Unique Cosmos client instance id. + examples: '3ba4827d-4422-483f-b59f-85b74211c11d' + tag: tech-specific-cosmosdb + - id: cosmosdb.connection_mode + type: + allow_custom_values: false + members: + - id: gateway + value: 'gateway' + brief: Gateway (HTTP) connections mode + - id: direct + value: 'direct' + brief: Direct connection. + brief: Cosmos client connection mode. + tag: tech-specific-cosmosdb + - id: cosmosdb.container + type: string + brief: Cosmos DB container name. + examples: 'anystring' + tag: tech-specific-cosmosdb + - id: cosmosdb.operation_type + type: + allow_custom_values: true + members: + - id: invalid + value: 'Invalid' + - id: create + value: 'Create' + - id: patch + value: 'Patch' + - id: read + value: 'Read' + - id: read_feed + value: 'ReadFeed' + - id: delete + value: 'Delete' + - id: replace + value: 'Replace' + - id: execute + value: 'Execute' + - id: query + value: 'Query' + - id: head + value: 'Head' + - id: head_feed + value: 'HeadFeed' + - id: upsert + value: 'Upsert' + - id: batch + value: 'Batch' + - id: query_plan + value: 'QueryPlan' + - id: execute_javascript + value: 'ExecuteJavaScript' + brief: CosmosDB Operation Type. + tag: tech-specific-cosmosdb + - id: cosmosdb.request_charge + type: double + brief: RU consumed for that operation + examples: [46.18, 1.0] + tag: tech-specific-cosmosdb + - id: cosmosdb.request_content_length + type: int + brief: Request payload size in bytes + tag: tech-specific-cosmosdb + - id: cosmosdb.status_code + type: int + brief: Cosmos DB status code. + examples: [200, 201] + tag: tech-specific-cosmosdb + - id: cosmosdb.sub_status_code + type: int + brief: Cosmos DB sub status code. + examples: [1000, 1002] + tag: tech-specific-cosmosdb + - id: elasticsearch.cluster.name + type: string + brief: > + Represents the identifier of an Elasticsearch cluster. + examples: ["e9106fc68e3044f0b1475b04bf4ffd5f"] + tag: tech-specific-elasticsearch + - id: elasticsearch.node.name + type: string + brief: > + Represents the human-readable identifier of the node/instance to which a request was routed. + examples: ["instance-0000000001"] + tag: tech-specific-elasticsearch + - id: elasticsearch.path_parts + type: template[string] + brief: > + A dynamic value in the url path. + 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. + examples: ['db.elasticsearch.path_parts.index=test-index', 'db.elasticsearch.path_parts.doc_id=123'] + tag: tech-specific-elasticsearch + - id: 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. + examples: ['org.postgresql.Driver', 'com.microsoft.sqlserver.jdbc.SQLServerDriver'] + tag: tech-specific-jdbc + - id: mongodb.collection + type: string + brief: > + The MongoDB collection being accessed within the database stated in `db.name`. + examples: [ 'customers', 'products' ] + tag: tech-specific-mongodb + - id: mssql.instance_name + type: string + note: > + If setting a `db.mssql.instance_name`, `server.port` is no longer + required (but still recommended if non-standard). + 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. + examples: 'MSSQLSERVER' + tag: tech-specific-mssql + - id: 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). + 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). + examples: [ 'customers', 'main' ] + tag: db-generic + - id: 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. + 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. + examples: ['findAndModify', 'HMSET', 'SELECT'] + tag: db-generic + - id: 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. + examples: [0, 1, 15] + tag: tech-specific-redis + - id: sql.table + type: string + brief: The name of the primary table that the operation is acting upon, including the database name (if applicable). + 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. + examples: ['public.users', 'customers'] + tag: tech-specific-sql + - id: statement + type: string + brief: > + The database statement being executed. + examples: ['SELECT * FROM wuser_table', 'SET mykey "WuValue"'] + tag: db-generic + - id: system + brief: An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. + type: + allow_custom_values: true + members: + - id: other_sql + value: 'other_sql' + brief: 'Some other SQL database. Fallback only. See notes.' + - id: mssql + value: 'mssql' + brief: 'Microsoft SQL Server' + - id: mssqlcompact + value: 'mssqlcompact' + brief: 'Microsoft SQL Server Compact' + - id: mysql + value: 'mysql' + brief: 'MySQL' + - id: oracle + value: 'oracle' + brief: 'Oracle Database' + - id: db2 + value: 'db2' + brief: 'IBM Db2' + - id: postgresql + value: 'postgresql' + brief: 'PostgreSQL' + - id: redshift + value: 'redshift' + brief: 'Amazon Redshift' + - id: hive + value: 'hive' + brief: 'Apache Hive' + - id: cloudscape + value: 'cloudscape' + brief: 'Cloudscape' + - id: hsqldb + value: 'hsqldb' + brief: 'HyperSQL DataBase' + - id: progress + value: 'progress' + brief: 'Progress Database' + - id: maxdb + value: 'maxdb' + brief: 'SAP MaxDB' + - id: hanadb + value: 'hanadb' + brief: 'SAP HANA' + - id: ingres + value: 'ingres' + brief: 'Ingres' + - id: firstsql + value: 'firstsql' + brief: 'FirstSQL' + - id: edb + value: 'edb' + brief: 'EnterpriseDB' + - id: cache + value: 'cache' + brief: 'InterSystems Caché' + - id: adabas + value: 'adabas' + brief: 'Adabas (Adaptable Database System)' + - id: firebird + value: 'firebird' + brief: 'Firebird' + - id: derby + value: 'derby' + brief: 'Apache Derby' + - id: filemaker + value: 'filemaker' + brief: 'FileMaker' + - id: informix + value: 'informix' + brief: 'Informix' + - id: instantdb + value: 'instantdb' + brief: 'InstantDB' + - id: interbase + value: 'interbase' + brief: 'InterBase' + - id: mariadb + value: 'mariadb' + brief: 'MariaDB' + - id: netezza + value: 'netezza' + brief: 'Netezza' + - id: pervasive + value: 'pervasive' + brief: 'Pervasive PSQL' + - id: pointbase + value: 'pointbase' + brief: 'PointBase' + - id: sqlite + value: 'sqlite' + brief: 'SQLite' + - id: sybase + value: 'sybase' + brief: 'Sybase' + - id: teradata + value: 'teradata' + brief: 'Teradata' + - id: vertica + value: 'vertica' + brief: 'Vertica' + - id: h2 + value: 'h2' + brief: 'H2' + - id: coldfusion + value: 'coldfusion' + brief: 'ColdFusion IMQ' + - id: cassandra + value: 'cassandra' + brief: 'Apache Cassandra' + - id: hbase + value: 'hbase' + brief: 'Apache HBase' + - id: mongodb + value: 'mongodb' + brief: 'MongoDB' + - id: redis + value: 'redis' + brief: 'Redis' + - id: couchbase + value: 'couchbase' + brief: 'Couchbase' + - id: couchdb + value: 'couchdb' + brief: 'CouchDB' + - id: cosmosdb + value: 'cosmosdb' + brief: 'Microsoft Azure Cosmos DB' + - id: dynamodb + value: 'dynamodb' + brief: 'Amazon DynamoDB' + - id: neo4j + value: 'neo4j' + brief: 'Neo4j' + - id: geode + value: 'geode' + brief: 'Apache Geode' + - id: elasticsearch + value: 'elasticsearch' + brief: 'Elasticsearch' + - id: memcached + value: 'memcached' + brief: 'Memcached' + - id: cockroachdb + value: 'cockroachdb' + brief: 'CockroachDB' + - id: opensearch + value: 'opensearch' + brief: 'OpenSearch' + - id: clickhouse + value: 'clickhouse' + brief: 'ClickHouse' + - id: spanner + value: 'spanner' + brief: 'Cloud Spanner' + - id: trino + value: 'trino' + brief: 'Trino' + tag: db-generic + - id: user + type: string + brief: > + Username for accessing the database. + examples: ['readonly_user', 'reporting_user'] + tag: db-generic + - id: instance.id + tag: db-generic + 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`. + examples: 'mysql-e26b99z.example.com' diff --git a/crates/weaver_forge/data/registry-http.yaml b/crates/weaver_forge/data/registry-http.yaml new file mode 100644 index 00000000..5ed9a182 --- /dev/null +++ b/crates/weaver_forge/data/registry-http.yaml @@ -0,0 +1,135 @@ +groups: + - id: registry.http + prefix: http + type: attribute_group + brief: 'This document defines semantic convention attributes in the HTTP namespace.' + attributes: + - id: 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. + examples: 3495 + stability: experimental # this should not be marked stable with other HTTP attributes + - id: request.header + stability: stable + type: template[string[]] + brief: > + HTTP request headers, `` being the normalized HTTP Header name (lowercase), the value being the header values. + 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. + + The `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. + + The 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. + examples: ['http.request.header.content-type=["application/json"]', 'http.request.header.x-forwarded-for=["1.2.3.4", "1.2.3.5"]'] + - id: request.method + stability: stable + type: + allow_custom_values: true + members: + - id: connect + value: "CONNECT" + brief: 'CONNECT method.' + - id: delete + value: "DELETE" + brief: 'DELETE method.' + - id: get + value: "GET" + brief: 'GET method.' + - id: head + value: "HEAD" + brief: 'HEAD method.' + - id: options + value: "OPTIONS" + brief: 'OPTIONS method.' + - id: patch + value: "PATCH" + brief: 'PATCH method.' + - id: post + value: "POST" + brief: 'POST method.' + - id: put + value: "PUT" + brief: 'PUT method.' + - id: trace + value: "TRACE" + brief: 'TRACE method.' + - id: other + value: "_OTHER" + brief: 'Any HTTP method that the instrumentation has no prior knowledge of.' + brief: 'HTTP request method.' + examples: ["GET", "POST", "HEAD"] + note: | + HTTP request method value SHOULD be "known" to the instrumentation. + By default, this convention defines "known" methods as the ones listed in [RFC9110](https://www.rfc-editor.org/rfc/rfc9110.html#name-methods) + and the PATCH method defined in [RFC5789](https://www.rfc-editor.org/rfc/rfc5789.html). + + If the HTTP request method is not known to instrumentation, it MUST set the `http.request.method` attribute to `_OTHER`. + + If the HTTP instrumentation could end up converting valid HTTP request methods to `_OTHER`, then it MUST provide a way to override + the list of known HTTP methods. If this override is done via environment variable, then the environment variable MUST be named + OTEL_INSTRUMENTATION_HTTP_KNOWN_METHODS and support a comma-separated list of case-sensitive known HTTP methods + (this list MUST be a full override of the default known method, it is not a list of known methods in addition to the defaults). + + HTTP method names are case-sensitive and `http.request.method` attribute value MUST match a known HTTP method name exactly. + Instrumentations for specific web frameworks that consider HTTP methods to be case insensitive, SHOULD populate a canonical equivalent. + Tracing instrumentations that do so, MUST also set `http.request.method_original` to the original value. + - id: request.method_original + stability: stable + type: string + brief: Original HTTP method sent by the client in the request line. + examples: ["GeT", "ACL", "foo"] + - id: request.resend_count + stability: stable + type: int + brief: > + The ordinal number of request resending attempt (for any reason, including redirects). + 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). + examples: 3 + - id: 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. + examples: 3495 + stability: experimental # this should not be marked stable with other HTTP attributes + - id: response.header + stability: stable + type: template[string[]] + brief: > + HTTP response headers, `` being the normalized HTTP Header name (lowercase), the value being the header values. + 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. + + Users MAY explicitly configure instrumentations to capture them even though it is not recommended. + + The 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. + examples: ['http.response.header.content-type=["application/json"]', 'http.response.header.my-custom-header=["abc", "def"]'] + - id: response.status_code + stability: stable + type: int + brief: '[HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6).' + examples: [200] + - id: route + stability: stable + type: string + brief: > + The matched route, that is, the path template in the format used by the respective server framework. + examples: ['/users/:userID?', '{controller}/{action}/{id?}'] + 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. + + SHOULD include the [application root](/docs/http/http-spans.md#http-server-definitions) if there is one. \ No newline at end of file diff --git a/crates/weaver_forge/data/registry-network.yaml b/crates/weaver_forge/data/registry-network.yaml new file mode 100644 index 00000000..c16763bb --- /dev/null +++ b/crates/weaver_forge/data/registry-network.yaml @@ -0,0 +1,194 @@ +groups: + - id: registry.network + prefix: network + type: attribute_group + brief: > + These attributes may be used for any network related operation. + attributes: + - id: carrier.icc + type: string + brief: "The ISO 3166-1 alpha-2 2-character country code associated with the mobile carrier network." + examples: "DE" + - id: carrier.mcc + type: string + brief: "The mobile carrier country code." + examples: "310" + - id: carrier.mnc + type: string + brief: "The mobile carrier network code." + examples: "001" + - id: carrier.name + type: string + brief: "The name of the mobile carrier." + examples: "sprint" + - id: connection.subtype + type: + allow_custom_values: true + members: + - id: gprs + brief: GPRS + value: "gprs" + - id: edge + brief: EDGE + value: "edge" + - id: umts + brief: UMTS + value: "umts" + - id: cdma + brief: CDMA + value: "cdma" + - id: evdo_0 + brief: EVDO Rel. 0 + value: "evdo_0" + - id: evdo_a + brief: "EVDO Rev. A" + value: "evdo_a" + - id: cdma2000_1xrtt + brief: CDMA2000 1XRTT + value: "cdma2000_1xrtt" + - id: hsdpa + brief: HSDPA + value: "hsdpa" + - id: hsupa + brief: HSUPA + value: "hsupa" + - id: hspa + brief: HSPA + value: "hspa" + - id: iden + brief: IDEN + value: "iden" + - id: evdo_b + brief: "EVDO Rev. B" + value: "evdo_b" + - id: lte + brief: LTE + value: "lte" + - id: ehrpd + brief: EHRPD + value: "ehrpd" + - id: hspap + brief: HSPAP + value: "hspap" + - id: gsm + brief: GSM + value: "gsm" + - id: td_scdma + brief: TD-SCDMA + value: "td_scdma" + - id: iwlan + brief: IWLAN + value: "iwlan" + - id: nr + brief: "5G NR (New Radio)" + value: "nr" + - id: nrnsa + brief: "5G NRNSA (New Radio Non-Standalone)" + value: "nrnsa" + - id: lte_ca + brief: LTE CA + value: "lte_ca" + 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' + - id: connection.type + type: + allow_custom_values: true + members: + - id: wifi + value: "wifi" + - id: wired + value: "wired" + - id: cell + value: "cell" + - id: unavailable + value: "unavailable" + - id: unknown + value: "unknown" + brief: 'The internet connection type.' + examples: 'wifi' + - id: local.address + stability: stable + type: string + brief: Local address of the network connection - IP address or Unix domain socket name. + examples: ['10.1.2.80', '/tmp/my.sock'] + - id: local.port + stability: stable + type: int + brief: Local port number of the network connection. + examples: [65123] + - id: peer.address + stability: stable + type: string + brief: Peer address of the network connection - IP address or Unix domain socket name. + examples: ['10.1.2.80', '/tmp/my.sock'] + - id: peer.port + stability: stable + type: int + brief: Peer port number of the network connection. + examples: [65123] + - id: protocol.name + stability: stable + type: string + brief: '[OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent.' + note: The value SHOULD be normalized to lowercase. + examples: ['amqp', 'http', 'mqtt'] + - id: protocol.version + stability: stable + type: string + brief: Version of the protocol specified in `network.protocol.name`. + examples: '3.1.1' + 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`. + - id: transport + stability: stable + type: + allow_custom_values: true + members: + - id: tcp + value: 'tcp' + brief: "TCP" + - id: udp + value: 'udp' + brief: "UDP" + - id: pipe + value: "pipe" + brief: 'Named or anonymous pipe.' + - id: unix + value: 'unix' + brief: "Unix domain socket" + brief: > + [OSI transport layer](https://osi-model.com/transport-layer/) or + [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). + note: | + The value SHOULD be normalized to lowercase. + + Consider always setting the transport when setting a port number, since + a port number is ambiguous without knowing the transport. For example + different processes could be listening on TCP port 12345 and UDP port 12345. + examples: ['tcp', 'udp'] + - id: type + stability: stable + type: + allow_custom_values: true + members: + - id: ipv4 + value: 'ipv4' + brief: "IPv4" + - id: ipv6 + value: 'ipv6' + brief: "IPv6" + brief: '[OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent.' + note: The value SHOULD be normalized to lowercase. + examples: ['ipv4', 'ipv6'] + - id: io.direction + type: + allow_custom_values: false + members: + - id: transmit + value: 'transmit' + - id: receive + value: 'receive' + brief: "The network IO operation direction." + examples: ["transmit"] \ No newline at end of file diff --git a/crates/weaver_forge/data/registry-server.yaml b/crates/weaver_forge/data/registry-server.yaml new file mode 100644 index 00000000..0523bb0d --- /dev/null +++ b/crates/weaver_forge/data/registry-server.yaml @@ -0,0 +1,28 @@ +groups: + - id: server + prefix: server + type: attribute_group + brief: > + These attributes may be used to describe the server in a connection-based network interaction + where there is one side that initiates the connection (the client is the side that initiates the connection). + This covers all TCP network interactions since TCP is connection-based and one side initiates the + connection (an exception is made for peer-to-peer communication over TCP where the "user-facing" surface of the + protocol / API doesn't expose a clear notion of client and server). + This also covers UDP network interactions where one side initiates the interaction, e.g. QUIC (HTTP/3) and DNS. + attributes: + - id: address + stability: stable + type: string + brief: "Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name." + 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. + examples: ['example.com', '10.1.2.80', '/tmp/my.sock'] + - id: port + stability: stable + type: int + brief: Server port number. + note: > + When observed from the client side, and when communicating through an intermediary, `server.port` SHOULD represent + the server port behind any intermediaries, for example proxies, if it's available. + examples: [80, 8080, 443] \ No newline at end of file diff --git a/crates/weaver_forge/data/registry-url.yaml b/crates/weaver_forge/data/registry-url.yaml new file mode 100644 index 00000000..3042f32c --- /dev/null +++ b/crates/weaver_forge/data/registry-url.yaml @@ -0,0 +1,41 @@ +groups: + - id: registry.url + brief: Attributes describing URL. + type: attribute_group + prefix: url + attributes: + - id: scheme + stability: stable + 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"] + - id: full + stability: stable + type: string + brief: Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986) + note: > + For network calls, URL usually has `scheme://host[:port][path][?query][#fragment]` format, where the fragment + is not transmitted over HTTP, but if it is known, it SHOULD be included nevertheless. + + `url.full` MUST NOT contain credentials passed via URL in form of `https://username:password@www.example.com/`. + In such case username and password SHOULD be redacted and attribute's value SHOULD be `https://REDACTED:REDACTED@www.example.com/`. + + `url.full` SHOULD capture the absolute URL when it is available (or can be reconstructed) + and SHOULD NOT be validated or modified except for sanitizing purposes. + examples: ['https://www.foo.bar/search?q=OpenTelemetry#SemConv', '//localhost'] + - id: path + stability: stable + type: string + brief: 'The [URI path](https://www.rfc-editor.org/rfc/rfc3986#section-3.3) component' + examples: ['/search'] + - id: query + stability: stable + type: string + brief: 'The [URI query](https://www.rfc-editor.org/rfc/rfc3986#section-3.4) component' + examples: ["q=OpenTelemetry"] + note: Sensitive content provided in query string SHOULD be scrubbed when instrumentations can identify it. + - id: fragment + stability: stable + type: string + brief: 'The [URI fragment](https://www.rfc-editor.org/rfc/rfc3986#section-3.5) component' + examples: ["SemConv"] \ No newline at end of file diff --git a/crates/weaver_forge/data/registry-user-agent.yaml b/crates/weaver_forge/data/registry-user-agent.yaml new file mode 100644 index 00000000..3f902d18 --- /dev/null +++ b/crates/weaver_forge/data/registry-user-agent.yaml @@ -0,0 +1,13 @@ +groups: + - id: registry.user_agent + prefix: user_agent + type: attribute_group + brief: "Describes user-agent attributes." + attributes: + - id: original + stability: stable + 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. + 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'] \ No newline at end of file diff --git a/crates/weaver_forge/data/trace-database.yaml b/crates/weaver_forge/data/trace-database.yaml new file mode 100644 index 00000000..2946f80a --- /dev/null +++ b/crates/weaver_forge/data/trace-database.yaml @@ -0,0 +1,263 @@ +groups: + - id: db + type: span + brief: > + This document defines the attributes used to perform database client calls. + span_kind: client + attributes: + - ref: db.system + tag: connection-level + requirement_level: required + + - ref: db.connection_string + tag: connection-level + - ref: db.user + tag: connection-level + - ref: db.jdbc.driver_classname + tag: connection-level-tech-specific + - ref: db.name + tag: call-level + requirement_level: + conditionally_required: If applicable. + - ref: db.statement + tag: call-level + requirement_level: + recommended: > + Should be collected by default only if there is sanitization that excludes sensitive information. + - ref: db.operation + tag: call-level + requirement_level: + conditionally_required: If `db.statement` is not applicable. + - ref: server.address + tag: connection-level + brief: > + Name of the database host. + - ref: server.port + 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. + - ref: network.peer.address + tag: connection-level + - ref: network.peer.port + requirement_level: + recommended: If `network.peer.address` is set. + tag: connection-level + - ref: network.transport + tag: connection-level + - ref: network.type + tag: connection-level + - ref: db.instance.id + tag: connection-level + requirement_level: + recommended: If different from the `server.address` + + - id: db.mssql + type: span + extends: db + brief: > + Connection-level attributes for Microsoft SQL Server + attributes: + - ref: db.mssql.instance_name + tag: connection-level-tech-specific + + - id: db.cassandra + type: span + extends: db + brief: > + Call-level attributes for Cassandra + attributes: + - ref: db.name + tag: call-level-tech-specific-cassandra + brief: > + The keyspace name in Cassandra. + examples: ["mykeyspace"] + note: For Cassandra the `db.name` should be set to the Cassandra keyspace name. + - ref: db.cassandra.page_size + tag: call-level-tech-specific-cassandra + - ref: db.cassandra.consistency_level + tag: call-level-tech-specific-cassandra + - ref: db.cassandra.table + tag: call-level-tech-specific-cassandra + - ref: db.cassandra.idempotence + tag: call-level-tech-specific-cassandra + - ref: db.cassandra.speculative_execution_count + tag: call-level-tech-specific-cassandra + - ref: db.cassandra.coordinator.id + tag: call-level-tech-specific-cassandra + - ref: db.cassandra.coordinator.dc + tag: call-level-tech-specific-cassandra + + - id: db.hbase + type: span + extends: db + brief: > + Call-level attributes for HBase + attributes: + - ref: db.name + tag: call-level-tech-specific + brief: > + The HBase namespace. + examples: ['mynamespace'] + note: For HBase the `db.name` should be set to the HBase namespace. + + - id: db.couchdb + type: span + extends: db + brief: > + Call-level attributes for CouchDB + attributes: + - ref: db.operation + tag: call-level-tech-specific + brief: > + The HTTP method + the target REST route. + examples: ['GET /{db}/{docid}'] + 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). + + - id: db.redis + type: span + extends: db + brief: > + Call-level attributes for Redis + attributes: + - ref: db.redis.database_index + requirement_level: + conditionally_required: If other than the default database (`0`). + tag: call-level-tech-specific + - ref: db.statement + tag: call-level-tech-specific + brief: > + The full syntax of the Redis CLI command. + examples: ["HMSET myhash field1 'Hello' field2 'World'"] + 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`. + + - id: db.mongodb + type: span + extends: db + brief: > + Call-level attributes for MongoDB + attributes: + - ref: db.mongodb.collection + requirement_level: required + tag: call-level-tech-specific + + - id: db.elasticsearch + type: span + extends: db + brief: > + Call-level attributes for Elasticsearch + attributes: + - ref: http.request.method + requirement_level: required + tag: call-level-tech-specific + - ref: db.operation + requirement_level: required + brief: The endpoint identifier for the request. + examples: [ 'search', 'ml.close_job', 'cat.aliases' ] + tag: call-level-tech-specific + - ref: url.full + requirement_level: required + examples: [ 'https://localhost:9200/index/_search?q=user.id:kimchy' ] + tag: call-level-tech-specific + - ref: db.statement + requirement_level: + recommended: > + Should be collected by default for search-type queries and only if there is sanitization that excludes + sensitive information. + 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 + - ref: server.address + tag: call-level-tech-specific + - ref: server.port + tag: call-level-tech-specific + - ref: db.elasticsearch.cluster.name + requirement_level: + recommended: > + When communicating with an Elastic Cloud deployment, this should be collected from the "X-Found-Handling-Cluster" HTTP response header. + tag: call-level-tech-specific + - ref: db.elasticsearch.node.name + requirement_level: + recommended: > + When communicating with an Elastic Cloud deployment, this should be collected from the "X-Found-Handling-Instance" HTTP response header. + tag: call-level-tech-specific + - ref: db.elasticsearch.path_parts + requirement_level: + conditionally_required: when the url has dynamic values + tag: call-level-tech-specific + + - id: db.sql + type: span + extends: 'db' + brief: > + Call-level attributes for SQL databases + attributes: + - ref: db.sql.table + tag: call-level-tech-specific + + - id: db.cosmosdb + type: span + extends: db + prefix: db.cosmosdb + brief: > + Call-level attributes for Cosmos DB. + attributes: + - ref: db.cosmosdb.client_id + tag: call-level-tech-specific + - ref: db.cosmosdb.operation_type + requirement_level: + conditionally_required: when performing one of the operations in this list + tag: call-level-tech-specific + - ref: user_agent.original + brief: 'Full user-agent string is generated by Cosmos DB SDK' + 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. + Format Reg-{D (Disabled discovery)}-S(application region)|L(List of preferred regions)|N(None, user did not configure it). + Default value is "NS". + 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 + - ref: db.cosmosdb.connection_mode + requirement_level: + conditionally_required: if not `direct` (or pick gw as default) + tag: call-level-tech-specific + - ref: db.cosmosdb.container + requirement_level: + conditionally_required: if available + tag: call-level-tech-specific + - ref: db.cosmosdb.request_content_length + tag: call-level-tech-specific + - ref: db.cosmosdb.status_code + requirement_level: + conditionally_required: if response was received + tag: call-level-tech-specific + - ref: db.cosmosdb.sub_status_code + requirement_level: + conditionally_required: when response was received and contained sub-code. + tag: call-level-tech-specific + - ref: db.cosmosdb.request_charge + requirement_level: + conditionally_required: when available + tag: call-level-tech-specific + + - id: db.tech + type: span + brief: "Semantic convention group for specific technologies" + constraints: + - include: 'db.cassandra' + - include: 'db.redis' + - include: 'db.mongodb' + - include: 'db.sql' + - include: 'db.cosmosdb' \ No newline at end of file diff --git a/crates/weaver_forge/src/config.rs b/crates/weaver_forge/src/config.rs index 061cc62b..33e2b5f2 100644 --- a/crates/weaver_forge/src/config.rs +++ b/crates/weaver_forge/src/config.rs @@ -111,7 +111,7 @@ impl DynamicGlobalConfig { /// Set the file name for the current generated code. /// This method uses a thread local variable to store the file name. pub fn set(&self, file_name: &str) { - self.file_name + _ = self.file_name .get_or(|| RefCell::new(None)) .borrow_mut() .replace(file_name.to_string()); @@ -129,7 +129,7 @@ impl DynamicGlobalConfig { /// Reset the file name for the current generated code. /// This method uses a thread local variable to store the file name. pub fn reset(&self) { - self.file_name + _ = self.file_name .get_or(|| RefCell::new(None)) .borrow_mut() .take(); diff --git a/crates/weaver_forge/src/extensions/case_converter.rs b/crates/weaver_forge/src/extensions/case_converter.rs index a7a13c7f..ee1e896e 100644 --- a/crates/weaver_forge/src/extensions/case_converter.rs +++ b/crates/weaver_forge/src/extensions/case_converter.rs @@ -2,19 +2,57 @@ //! Case converter filters used by the template engine. -use convert_case::{Case, Casing}; +use crate::config::CaseConvention; + +pub fn case_converter(case_convention: CaseConvention) -> fn(&str) -> String { + match case_convention { + CaseConvention::LowerCase => lower_case, + CaseConvention::UpperCase => upper_case, + CaseConvention::CamelCase => camel_case, + CaseConvention::PascalCase => pascal_case, + CaseConvention::SnakeCase => snake_case, + CaseConvention::ScreamingSnakeCase => screaming_snake_case, + CaseConvention::KebabCase => kebab_case, + CaseConvention::ScreamingKebabCase => screaming_kebab_case, + } +} /// Converts input string to lower case -fn lower_case(input: String) -> String { - input.to_case(Case::Lower) +fn lower_case(input: &str) -> String { + CaseConvention::LowerCase.convert(input) } /// Converts input string to upper case -fn upper_case(input: String) -> String { - input.to_case(Case::Upper) +fn upper_case(input: &str) -> String { + CaseConvention::UpperCase.convert(input) } /// Converts input string to camel case -fn camel_case(input: String) -> String { - input.to_case(Case::Camel) +fn camel_case(input: &str) -> String { + CaseConvention::CamelCase.convert(input) +} + +/// Converts input string to pascal case +fn pascal_case(input: &str) -> String { + CaseConvention::PascalCase.convert(input) +} + +/// Converts input string to snake case +fn snake_case(input: &str) -> String { + CaseConvention::SnakeCase.convert(input) } + +/// Converts input string to screaming snake case +fn screaming_snake_case(input: &str) -> String { + CaseConvention::ScreamingSnakeCase.convert(input) +} + +/// Converts input string to kebab case +fn kebab_case(input: &str) -> String { + CaseConvention::KebabCase.convert(input) +} + +/// Converts input string to screaming kebab case +fn screaming_kebab_case(input: &str) -> String { + CaseConvention::ScreamingKebabCase.convert(input) +} \ No newline at end of file diff --git a/crates/weaver_forge/src/extensions/mod.rs b/crates/weaver_forge/src/extensions/mod.rs index c091caf4..0e272b59 100644 --- a/crates/weaver_forge/src/extensions/mod.rs +++ b/crates/weaver_forge/src/extensions/mod.rs @@ -1,4 +1,4 @@ // SPDX-License-Identifier: Apache-2.0 //! Custom filters used by the template engine. -mod case_converter; \ No newline at end of file +pub mod case_converter; \ No newline at end of file diff --git a/crates/weaver_forge/src/lib.rs b/crates/weaver_forge/src/lib.rs index 64c1291e..b07cf90f 100644 --- a/crates/weaver_forge/src/lib.rs +++ b/crates/weaver_forge/src/lib.rs @@ -14,13 +14,29 @@ unused_results, unused_extern_crates )] -use std::path::PathBuf; +use std::{fs, process}; +use std::path::{Path, PathBuf}; use std::sync::Arc; +use std::task::Context; -use minijinja::{Environment, filters, functions, path_loader}; +use glob::{glob, Paths}; +use minijinja::{Environment, path_loader}; +use rayon::iter::IntoParallelIterator; +use rayon::iter::ParallelIterator; + +use weaver_cache::Cache; +use weaver_logger::Logger; +use weaver_resolved_schema::registry::Registry; +use weaver_resolver::SchemaResolver; +use weaver_schema::event::Event; +use weaver_schema::metric_group::MetricGroup; +use weaver_schema::span::Span; +use weaver_schema::TelemetrySchema; +use weaver_schema::univariate_metric::UnivariateMetric; use crate::config::{DynamicGlobalConfig, TargetConfig}; -use crate::Error::{InvalidTemplateDir, TargetNotSupported}; +use crate::Error::{InternalError, InvalidTelemetrySchema, InvalidTemplateDir, InvalidTemplateDirectory, InvalidTemplateFile, TargetNotSupported, WriteGeneratedCodeFailed}; +use crate::extensions::case_converter::case_converter; mod config; mod extensions; @@ -28,15 +44,70 @@ mod extensions; /// Errors emitted by this crate. #[derive(thiserror::Error, Debug)] pub enum Error { + /// Invalid config file. + #[error("Invalid config file `{config_file}`: {error}")] + InvalidConfigFile { + /// Config file. + config_file: PathBuf, + /// Error message. + error: String, + }, + /// Target not found. #[error( - "Target `{0}` is not supported. Use the command `targets` to list supported targets." + "Target `{target}` not found in `{root_path}`. Use the command `targets` to list supported targets." )] - TargetNotSupported(String), + TargetNotSupported { + /// Root path. + root_path: String, + /// Target name. + target: String, + }, /// Invalid template directory. #[error("Invalid template directory: {0}")] InvalidTemplateDir(PathBuf), + + /// Invalid telemetry schema. + #[error("Invalid telemetry schema {schema}: {error}")] + InvalidTelemetrySchema { + /// Schema file. + schema: PathBuf, + /// Error message. + error: String, + }, + + /// Invalid template file. + #[error("Invalid template file: {0}")] + InvalidTemplateFile(PathBuf), + + /// Invalid template directory. + #[error("Invalid template directory: {0}")] + InvalidTemplateDirectory(PathBuf), + + /// Internal error. + #[error("Internal error: {0}")] + InternalError(String), + + /// Template file name undefined. + #[error("File name undefined in the template `{template}`. To resolve this, use the function `config(file_name = )` to set the file name.")] + TemplateFileNameUndefined { + /// Template path. + template: PathBuf, + }, + + /// Write generated code failed. + #[error("Writing of the generated code {template} failed: {error}")] + WriteGeneratedCodeFailed { + /// Template path. + template: PathBuf, + /// Error message. + error: String, + }, + + /// A generic container for multiple errors. + #[error("Errors:\n{0:#?}")] + CompoundError(Vec), } /// General configuration for the generator. @@ -54,17 +125,45 @@ impl Default for GeneratorConfig { } } +/// A pair {template, object} to generate code for. +enum TemplateObjectPair<'a> { + Metric { + template: String, + metric: &'a UnivariateMetric, + }, + MetricGroup { + template: String, + metric_group: &'a MetricGroup, + }, + Event { + template: String, + event: &'a Event, + }, + Span { + template: String, + span: &'a Span, + }, + Other { + template: String, + relative_path: PathBuf, + object: &'a TelemetrySchema, + }, +} + /// Template engine for generating artifacts from a semantic convention /// registry and telemetry schema. -pub struct TemplateEngine { +pub struct TemplateEngine<'source> { /// Template path path: PathBuf, /// Global configuration config: Arc, + + /// Engine + engine: Environment<'source>, } -impl TemplateEngine { +impl TemplateEngine<'_> { /// Create a new template engine for the given target or return an error if /// the target does not exist or is not a directory. pub fn try_new(target: &str, config: GeneratorConfig) -> Result { @@ -73,13 +172,16 @@ impl TemplateEngine { let target_path = config.root_dir.join(target); if !target_path.exists() { - return Err(TargetNotSupported(target.to_string())); + return Err(TargetNotSupported { + root_path: config.root_dir.to_string_lossy().to_string(), + target: target.to_string(), + }); } let mut env = Environment::new(); env.set_loader(path_loader(target_path .to_str() - .ok_or(Err(InvalidTemplateDir(target_path)))? + .ok_or(InvalidTemplateDir(target_path.clone()))? )); let target_config = TargetConfig::try_new(&target_path)?; @@ -87,69 +189,466 @@ impl TemplateEngine { let config = Arc::new(DynamicGlobalConfig::default()); // Register custom filters - env.add_filter( - "file_name", - extensions::CaseConverter::new(target_config.file_name, "file_name"), - ); - tera.register_filter( - "function_name", - extensions::CaseConverter::new(target_config.function_name, "function_name"), - ); - tera.register_filter( - "arg_name", - extensions::CaseConverter::new(target_config.arg_name, "arg_name"), - ); - tera.register_filter( - "struct_name", - extensions::CaseConverter::new(target_config.struct_name, "struct_name"), - ); - tera.register_filter( - "field_name", - extensions::CaseConverter::new(target_config.field_name, "field_name"), - ); - tera.register_filter("unique_attributes", extensions::unique_attributes); - tera.register_filter("instrument", extensions::instrument); - tera.register_filter("required", extensions::required); - tera.register_filter("not_required", extensions::not_required); - tera.register_filter("value", extensions::value); - tera.register_filter("with_value", extensions::with_value); - tera.register_filter("without_value", extensions::without_value); - tera.register_filter("with_enum", extensions::with_enum); - tera.register_filter("without_enum", extensions::without_enum); - tera.register_filter("comment", extensions::comment); - tera.register_filter( - "type_mapping", - extensions::TypeMapping { - type_mapping: target_config.type_mapping, - }, - ); + env.add_filter("file_name", case_converter(target_config.file_name)); + env.add_filter("function_name", case_converter(target_config.function_name)); + env.add_filter("arg_name", case_converter(target_config.arg_name)); + env.add_filter("struct_name", case_converter(target_config.struct_name)); + env.add_filter("field_name", case_converter(target_config.field_name)); + // env.add_filter("unique_attributes", extensions::unique_attributes); + // env.add_filter("instrument", extensions::instrument); + // env.add_filter("required", extensions::required); + // env.add_filter("not_required", extensions::not_required); + // env.add_filter("value", extensions::value); + // env.add_filter("with_value", extensions::with_value); + // env.add_filter("without_value", extensions::without_value); + // env.add_filter("with_enum", extensions::with_enum); + // env.add_filter("without_enum", extensions::without_enum); + // env.add_filter("comment", extensions::comment); + // env.add_filter( + // "type_mapping", + // extensions::TypeMapping { + // type_mapping: target_config.type_mapping, + // }, + // ); // Register custom functions - tera.register_function("config", functions::FunctionConfig::new(config.clone())); + // tera.register_function("config", functions::FunctionConfig::new(config.clone())); // Register custom testers - tera.register_tester("required", testers::is_required); - tera.register_tester("not_required", testers::is_not_required); + // tera.register_tester("required", testers::is_required); + // tera.register_tester("not_required", testers::is_not_required); Ok(Self { - lang_path: target_path, - tera, + path: target_path, + engine: env, config, }) } + + /// Generate assets from a semantic convention registry. + pub fn generate_registry( + &self, + log: impl Logger + Clone + Sync, + registry: &Registry, + output_dir: PathBuf, + ) -> Result<(), Error> { + Ok(()) + } + + /// Generate assets from the templates. + pub fn generate( + &self, + log: impl Logger + Clone + Sync, + schema_path: PathBuf, + output_dir: PathBuf, + ) -> Result<(), Error> { + let cache = Cache::try_new().unwrap_or_else(|e| { + _ = log.error(&e.to_string()); + process::exit(1); + }); + + let schema = SchemaResolver::resolve_schema_file(schema_path.clone(), &cache, log.clone()) + .map_err(|e| InvalidTelemetrySchema { + schema: schema_path.clone(), + error: format!("{}", e), + })?; + + // Process recursively all files in the template directory + let mut lang_path = self.path.to_str().unwrap_or_default().to_string(); + let paths = if lang_path.is_empty() { + glob("**/*.tera").map_err(|e| InternalError(e.to_string()))? + } else { + lang_path.push_str("/**/*.tera"); + glob(lang_path.as_str()).map_err(|e| InternalError(e.to_string()))? + }; + + // Build the list of all {template, object} pairs to generate code for + // and process them in parallel. + // All pairs are independent from each other so we can process them in parallel. + self.list_all_templates(&schema, paths)? + .into_par_iter() + .try_for_each(|pair| { + match pair { + TemplateObjectPair::Metric { template, metric } => self.process_metric( + log.clone(), + &template, + &schema_path, + metric, + &output_dir, + ), + TemplateObjectPair::MetricGroup { + template, + metric_group, + } => self.process_metric_group( + log.clone(), + &template, + &schema_path, + metric_group, + &output_dir, + ), + TemplateObjectPair::Event { template, event } => { + self.process_event(log.clone(), &template, &schema_path, event, &output_dir) + } + TemplateObjectPair::Span { template, span } => { + self.process_span(log.clone(), &template, &schema_path, span, &output_dir) + } + TemplateObjectPair::Other { + template, + relative_path, + object, + } => { + // Process other templates + // let context = &Context::from_serialize(object).map_err(|e| { + // InvalidTelemetrySchema { + // schema: schema_path.clone(), + // error: format!("{}", e), + // } + // })?; + // + // log.loading(&format!("Generating file {}", template)); + // let generated_code = self.generate_code(log.clone(), &template, context)?; + // let relative_path = relative_path.to_path_buf(); + // let generated_file = + // Self::save_generated_code(&output_dir, relative_path, generated_code)?; + // log.success(&format!("Generated file {:?}", generated_file)); + Ok(()) + } + } + })?; + + Ok(()) + } + + /// Lists all {template, object} pairs derived from a template directory and a given + /// schema specification. + fn list_all_templates<'a>( + &self, + schema: &'a TelemetrySchema, + paths: Paths, + ) -> Result>, Error> { + let mut templates = Vec::new(); + if let Some(schema_spec) = &schema.schema { + for entry in paths { + if let Ok(tmpl_file_path) = entry { + if tmpl_file_path.is_dir() { + continue; + } + let relative_path = tmpl_file_path.strip_prefix(&self.path).unwrap(); + let tmpl_file = relative_path + .to_str() + .ok_or(InvalidTemplateFile(tmpl_file_path.clone()))?; + + if tmpl_file.ends_with(".macro.tera") { + // Macro files are not templates. + // They are included in other templates. + // So we skip them. + continue; + } + + match tmpl_file_path.file_stem().and_then(|s| s.to_str()) { + Some("metric") => { + if let Some(resource_metrics) = schema_spec.resource_metrics.as_ref() { + for metric in resource_metrics.metrics.iter() { + templates.push(TemplateObjectPair::Metric { + template: tmpl_file.into(), + metric, + }) + } + } + } + Some("metric_group") => { + if let Some(resource_metrics) = schema_spec.resource_metrics.as_ref() { + for metric_group in resource_metrics.metric_groups.iter() { + templates.push(TemplateObjectPair::MetricGroup { + template: tmpl_file.into(), + metric_group, + }) + } + } + } + Some("event") => { + if let Some(events) = schema_spec.resource_events.as_ref() { + for event in events.events.iter() { + templates.push(TemplateObjectPair::Event { + template: tmpl_file.into(), + event, + }) + } + } + } + Some("span") => { + if let Some(spans) = schema_spec.resource_spans.as_ref() { + for span in spans.spans.iter() { + templates.push(TemplateObjectPair::Span { + template: tmpl_file.into(), + span, + }) + } + } + } + _ => { + // Remove the `tera` extension from the relative path + let mut relative_path = relative_path.to_path_buf(); + _ = relative_path.set_extension(""); + + templates.push(TemplateObjectPair::Other { + template: tmpl_file.into(), + relative_path, + object: schema, + }) + } + } + } else { + return Err(InvalidTemplateDirectory(self.path.clone())); + } + } + } + Ok(templates) + } + + /// Generate code. + fn generate_code( + &self, + log: impl Logger, + tmpl_file: &str, + context: &Context, + ) -> Result { + // let generated_code = self.tera.render(tmpl_file, context).unwrap_or_else(|err| { + // log.newline(1); + // log.error(&format!("{}", err)); + // let mut cause = err.source(); + // while let Some(e) = cause { + // log.error(&format!("- caused by: {}", e)); + // cause = e.source(); + // } + // process::exit(1); + // }); + let generated_code = "".to_string(); + + Ok(generated_code) + } + + /// Save the generated code to the output directory. + fn save_generated_code( + output_dir: &Path, + relative_path: PathBuf, + generated_code: String, + ) -> Result { + // Create all intermediary directories if they don't exist + let output_file_path = output_dir.join(relative_path); + if let Some(parent_dir) = output_file_path.parent() { + if let Err(e) = fs::create_dir_all(parent_dir) { + return Err(WriteGeneratedCodeFailed { + template: output_file_path.clone(), + error: format!("{}", e), + }); + } + } + + // Write the generated code to the output directory + fs::write(output_file_path.clone(), generated_code).map_err(|e| { + WriteGeneratedCodeFailed { + template: output_file_path.clone(), + error: format!("{}", e), + } + })?; + + Ok(output_file_path) + } + + /// Process an univariate metric. + fn process_metric( + &self, + log: impl Logger + Clone, + tmpl_file: &str, + schema_path: &Path, + metric: &UnivariateMetric, + output_dir: &Path, + ) -> Result<(), Error> { + // if let UnivariateMetric::Metric { name, .. } = metric { + // let context = &Context::from_serialize(metric).map_err(|e| InvalidTelemetrySchema { + // schema: schema_path.to_path_buf(), + // error: format!("{}", e), + // })?; + // + // // Reset the config + // self.config.reset(); + // + // log.loading(&format!("Generating code for univariate metric `{}`", name)); + // let generated_code = self.generate_code(log.clone(), tmpl_file, context)?; + // + // // Retrieve the file name from the config + // let relative_path = { + // match &self.config.get() { + // None => { + // return Err(TemplateFileNameUndefined { + // template: PathBuf::from(tmpl_file), + // }); + // } + // Some(file_name) => PathBuf::from(file_name.clone()), + // } + // }; + // + // // Save the generated code to the output directory + // let generated_file = + // Self::save_generated_code(output_dir, relative_path, generated_code)?; + // log.success(&format!("Generated file {:?}", generated_file)); + // } + + Ok(()) + } + + /// Process a metric group (multivariate). + fn process_metric_group( + &self, + log: impl Logger + Clone, + tmpl_file: &str, + schema_path: &Path, + metric: &MetricGroup, + output_dir: &Path, + ) -> Result<(), Error> { + // let context = &Context::from_serialize(metric).map_err(|e| InvalidTelemetrySchema { + // schema: schema_path.to_path_buf(), + // error: format!("{}", e), + // })?; + // + // // Reset the config + // self.config.reset(); + // + // log.loading(&format!( + // "Generating code for multivariate metric `{}`", + // metric.name + // )); + // let generated_code = self.generate_code(log.clone(), tmpl_file, context)?; + // + // // Retrieve the file name from the config + // let relative_path = { + // match self.config.get() { + // None => { + // return Err(TemplateFileNameUndefined { + // template: PathBuf::from(tmpl_file), + // }); + // } + // Some(file_name) => PathBuf::from(file_name.clone()), + // } + // }; + // + // // Save the generated code to the output directory + // let generated_file = Self::save_generated_code(output_dir, relative_path, generated_code)?; + // log.success(&format!("Generated file {:?}", generated_file)); + + Ok(()) + } + + /// Process an event. + fn process_event( + &self, + log: impl Logger + Clone, + tmpl_file: &str, + schema_path: &Path, + event: &Event, + output_dir: &Path, + ) -> Result<(), Error> { + // let context = &Context::from_serialize(event).map_err(|e| InvalidTelemetrySchema { + // schema: schema_path.to_path_buf(), + // error: format!("{}", e), + // })?; + // + // // Reset the config + // self.config.reset(); + // + // log.loading(&format!("Generating code for log `{}`", event.event_name)); + // let generated_code = self.generate_code(log.clone(), tmpl_file, context)?; + // + // // Retrieve the file name from the config + // let relative_path = { + // match self.config.get() { + // None => { + // return Err(TemplateFileNameUndefined { + // template: PathBuf::from(tmpl_file), + // }); + // } + // Some(file_name) => PathBuf::from(file_name.clone()), + // } + // }; + // + // // Save the generated code to the output directory + // let generated_file = Self::save_generated_code(output_dir, relative_path, generated_code)?; + // log.success(&format!("Generated file {:?}", generated_file)); + + Ok(()) + } + + /// Process a span. + fn process_span( + &self, + log: impl Logger + Clone, + tmpl_file: &str, + schema_path: &Path, + span: &Span, + output_dir: &Path, + ) -> Result<(), Error> { + // let context = &Context::from_serialize(span).map_err(|e| InvalidTelemetrySchema { + // schema: schema_path.to_path_buf(), + // error: format!("{}", e), + // })?; + // + // // Reset the config + // self.config.reset(); + // + // log.loading(&format!("Generating code for span `{}`", span.span_name)); + // let generated_code = self.generate_code(log.clone(), tmpl_file, context)?; + // + // // Retrieve the file name from the config + // let relative_path = { + // match self.config.get() { + // None => { + // return Err(TemplateFileNameUndefined { + // template: PathBuf::from(tmpl_file), + // }); + // } + // Some(file_name) => PathBuf::from(file_name.clone()), + // } + // }; + // + // // Save the generated code to the output directory + // let generated_file = Self::save_generated_code(output_dir, relative_path, generated_code)?; + // log.success(&format!("Generated file {:?}", generated_file)); + + Ok(()) + } } #[cfg(test)] mod tests { - use minijinja::{context, Environment}; - - use super::*; + use weaver_logger::TestLogger; + use weaver_resolver::attribute::AttributeCatalog; + use weaver_resolver::registry::resolve_semconv_registry; + use weaver_semconv::SemConvRegistry; #[test] fn test() { - let mut env = Environment::new(); - env.add_template("hello.txt", "Hello {{ name }}!").unwrap(); - let template = env.get_template("hello.txt").unwrap(); - println!("{}", template.render(context! { name => "World" }).unwrap()); + let logger = TestLogger::default(); + let engine = super::TemplateEngine::try_new( + "test", + super::GeneratorConfig::default(), + ).expect("Failed to create template engine"); + + let registry = SemConvRegistry::try_from_path("data/*.yaml").expect("Failed to load registry"); + let mut attr_catalog = AttributeCatalog::default(); + let resolved_registry = + resolve_semconv_registry(&mut attr_catalog, "https://127.0.0.1", ®istry) + .expect("Failed to resolve registry"); + + engine.generate_registry( + logger, + &resolved_registry, + "output".into(), + ).expect("Failed to generate registry assets"); + + // let mut env = Environment::new(); + // env.add_template("hello.txt", "Hello {{ name }}!").unwrap(); + // let template = env.get_template("hello.txt").unwrap(); + // println!("{}", template.render(context! { name => "World" }).unwrap()); } } \ No newline at end of file diff --git a/crates/weaver_semconv/Cargo.toml b/crates/weaver_semconv/Cargo.toml index d128d403..d7f4ecfc 100644 --- a/crates/weaver_semconv/Cargo.toml +++ b/crates/weaver_semconv/Cargo.toml @@ -15,3 +15,4 @@ ureq.workspace = true ordered-float.workspace = true validator = { version = "0.16.1", features = ["derive"] } +glob = "0.3.1" \ No newline at end of file diff --git a/crates/weaver_semconv/src/lib.rs b/crates/weaver_semconv/src/lib.rs index 267d3ff5..b9c32316 100644 --- a/crates/weaver_semconv/src/lib.rs +++ b/crates/weaver_semconv/src/lib.rs @@ -20,6 +20,7 @@ use std::collections::{HashMap, HashSet}; use std::fs::File; use std::io::BufReader; use std::path::Path; +use glob::glob; use serde::{Deserialize, Serialize}; use validator::Validate; @@ -36,6 +37,24 @@ pub mod stability; /// An error that can occur while loading a semantic convention registry. #[derive(thiserror::Error, Debug)] pub enum Error { + /// The semantic convention registry path pattern is invalid. + #[error("Invalid semantic convention registry path pattern '{path_pattern:?}'.\n{error}")] + InvalidRegistryPathPattern { + /// The path pattern pointing to the semantic convention registry. + path_pattern: String, + /// The error that occurred. + error: String, + }, + + /// Invalid semantic convention registry asset. + #[error("Invalid semantic convention registry asset (registry=`{path_pattern}`).\n{error}")] + InvalidRegistryAsset { + /// The path pattern pointing to the semantic convention registry. + path_pattern: String, + /// The error that occurred. + error: String, + }, + /// The semantic convention asset was not found. #[error("Semantic convention registry {path_or_url:?} not found\n{error}")] CatalogNotFound { @@ -281,6 +300,30 @@ struct MetricToResolve { } impl SemConvRegistry { + /// Create a new semantic convention registry. + /// + /// # Arguments + /// + /// * `path_pattern` - A glob pattern to load semantic convention registry from files. + /// + /// # Returns + /// + /// A new semantic convention registry. + pub fn try_from_path(path_pattern: &str) -> Result { + let mut registry = SemConvRegistry::default(); + for sc_entry in glob(path_pattern).map_err(|e| Error::InvalidRegistryPathPattern { + path_pattern: path_pattern.to_string(), + error: e.to_string(), + })? { + let path_buf = sc_entry.map_err(|e| Error::InvalidRegistryAsset { + path_pattern: path_pattern.to_string(), + error: e.to_string(), + })?; + registry.load_from_file(path_buf.as_path())?; + } + Ok(registry) + } + /// Load and add a semantic convention file to the semantic convention registry. pub fn load_from_file + Clone>(&mut self, path: P) -> Result<(), Error> { let spec = SemConvSpec::load_from_file(path.clone())?; From e880add751c63174bf9572cb74e3450bae9a7849 Mon Sep 17 00:00:00 2001 From: Laurent Querel Date: Tue, 5 Mar 2024 15:22:13 -0800 Subject: [PATCH 04/20] feature(template): generate registry from templates --- Cargo.lock | 1 + crates/weaver_forge/Cargo.toml | 1 + crates/weaver_forge/src/config.rs | 4 +- crates/weaver_forge/src/lib.rs | 605 ++++++++++++------ .../templates/test/attribute_group.md | 1 + .../templates/test/attribute_groups.md | 1 + crates/weaver_forge/templates/test/event.md | 0 crates/weaver_forge/templates/test/group.md | 8 + crates/weaver_forge/templates/test/groups.md | 0 crates/weaver_forge/templates/test/metric.md | 0 .../templates/test/metric_group.md | 0 .../weaver_forge/templates/test/registry.md | 3 + .../weaver_forge/templates/test/resource.md | 0 crates/weaver_forge/templates/test/scope.md | 0 crates/weaver_forge/templates/test/span.md | 1 + crates/weaver_forge/templates/test/spans.md | 0 .../weaver_forge/templates/test/weaver.yaml | 15 + 17 files changed, 439 insertions(+), 201 deletions(-) create mode 100644 crates/weaver_forge/templates/test/attribute_group.md create mode 100644 crates/weaver_forge/templates/test/attribute_groups.md create mode 100644 crates/weaver_forge/templates/test/event.md create mode 100644 crates/weaver_forge/templates/test/group.md create mode 100644 crates/weaver_forge/templates/test/groups.md create mode 100644 crates/weaver_forge/templates/test/metric.md create mode 100644 crates/weaver_forge/templates/test/metric_group.md create mode 100644 crates/weaver_forge/templates/test/registry.md create mode 100644 crates/weaver_forge/templates/test/resource.md create mode 100644 crates/weaver_forge/templates/test/scope.md create mode 100644 crates/weaver_forge/templates/test/span.md create mode 100644 crates/weaver_forge/templates/test/spans.md create mode 100644 crates/weaver_forge/templates/test/weaver.yaml diff --git a/Cargo.lock b/Cargo.lock index e8c115f2..69b2404b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3819,6 +3819,7 @@ dependencies = [ "minijinja", "rayon", "serde", + "serde_json", "serde_yaml", "thiserror", "thread_local", diff --git a/crates/weaver_forge/Cargo.toml b/crates/weaver_forge/Cargo.toml index 772d7b78..45d3a300 100644 --- a/crates/weaver_forge/Cargo.toml +++ b/crates/weaver_forge/Cargo.toml @@ -23,5 +23,6 @@ glob = "0.3.1" thiserror.workspace = true serde.workspace = true serde_yaml.workspace = true +serde_json.workspace = true rayon.workspace = true diff --git a/crates/weaver_forge/src/config.rs b/crates/weaver_forge/src/config.rs index 33e2b5f2..45e9f2fd 100644 --- a/crates/weaver_forge/src/config.rs +++ b/crates/weaver_forge/src/config.rs @@ -14,7 +14,7 @@ use crate::Error; use crate::Error::InvalidConfigFile; /// Case convention for naming of functions and structs. -#[derive(Deserialize, Debug)] +#[derive(Deserialize, Clone, Debug)] #[allow(clippy::enum_variant_names)] pub enum CaseConvention { #[serde(rename = "lowercase")] @@ -90,7 +90,7 @@ impl CaseConvention { impl TargetConfig { pub fn try_new(lang_path: &Path) -> Result { - let config_file = lang_path.join("config.yaml"); + let config_file = lang_path.join("weaver.yaml"); if config_file.exists() { let reader = std::fs::File::open(config_file.clone()).map_err(|e| InvalidConfigFile { diff --git a/crates/weaver_forge/src/lib.rs b/crates/weaver_forge/src/lib.rs index b07cf90f..b0c164f0 100644 --- a/crates/weaver_forge/src/lib.rs +++ b/crates/weaver_forge/src/lib.rs @@ -21,18 +21,17 @@ use std::task::Context; use glob::{glob, Paths}; use minijinja::{Environment, path_loader}; +use minijinja::filters::abs; use rayon::iter::IntoParallelIterator; use rayon::iter::ParallelIterator; use weaver_cache::Cache; use weaver_logger::Logger; -use weaver_resolved_schema::registry::Registry; +use weaver_resolved_schema::registry::{Group, Registry, TypedGroup}; use weaver_resolver::SchemaResolver; use weaver_schema::event::Event; use weaver_schema::metric_group::MetricGroup; use weaver_schema::span::Span; -use weaver_schema::TelemetrySchema; -use weaver_schema::univariate_metric::UnivariateMetric; use crate::config::{DynamicGlobalConfig, TargetConfig}; use crate::Error::{InternalError, InvalidTelemetrySchema, InvalidTemplateDir, InvalidTemplateDirectory, InvalidTemplateFile, TargetNotSupported, WriteGeneratedCodeFailed}; @@ -78,8 +77,11 @@ pub enum Error { }, /// Invalid template file. - #[error("Invalid template file: {0}")] - InvalidTemplateFile(PathBuf), + #[error("Invalid template file '{template}': {error}")] + InvalidTemplateFile { + template: PathBuf, + error: String, + }, /// Invalid template directory. #[error("Invalid template directory: {0}")] @@ -126,44 +128,39 @@ impl Default for GeneratorConfig { } /// A pair {template, object} to generate code for. +#[derive(Debug)] enum TemplateObjectPair<'a> { - Metric { - template: String, - metric: &'a UnivariateMetric, + Group { + absolute_template_path: PathBuf, + relative_template_path: PathBuf, + group: &'a Group, }, - MetricGroup { - template: String, - metric_group: &'a MetricGroup, + Groups { + absolute_template_path: PathBuf, + relative_template_path: PathBuf, + groups: Vec<&'a Group>, }, - Event { - template: String, - event: &'a Event, - }, - Span { - template: String, - span: &'a Span, - }, - Other { - template: String, - relative_path: PathBuf, - object: &'a TelemetrySchema, + Registry { + absolute_template_path: PathBuf, + relative_template_path: PathBuf, + registry: &'a Registry, }, } /// Template engine for generating artifacts from a semantic convention /// registry and telemetry schema. -pub struct TemplateEngine<'source> { +pub struct TemplateEngine { /// Template path path: PathBuf, + /// Target configuration + target_config: TargetConfig, + /// Global configuration config: Arc, - - /// Engine - engine: Environment<'source>, } -impl TemplateEngine<'_> { +impl TemplateEngine { /// Create a new template engine for the given target or return an error if /// the target does not exist or is not a directory. pub fn try_new(target: &str, config: GeneratorConfig) -> Result { @@ -178,53 +175,16 @@ impl TemplateEngine<'_> { }); } - let mut env = Environment::new(); - env.set_loader(path_loader(target_path - .to_str() - .ok_or(InvalidTemplateDir(target_path.clone()))? - )); - - let target_config = TargetConfig::try_new(&target_path)?; - - let config = Arc::new(DynamicGlobalConfig::default()); - - // Register custom filters - env.add_filter("file_name", case_converter(target_config.file_name)); - env.add_filter("function_name", case_converter(target_config.function_name)); - env.add_filter("arg_name", case_converter(target_config.arg_name)); - env.add_filter("struct_name", case_converter(target_config.struct_name)); - env.add_filter("field_name", case_converter(target_config.field_name)); - // env.add_filter("unique_attributes", extensions::unique_attributes); - // env.add_filter("instrument", extensions::instrument); - // env.add_filter("required", extensions::required); - // env.add_filter("not_required", extensions::not_required); - // env.add_filter("value", extensions::value); - // env.add_filter("with_value", extensions::with_value); - // env.add_filter("without_value", extensions::without_value); - // env.add_filter("with_enum", extensions::with_enum); - // env.add_filter("without_enum", extensions::without_enum); - // env.add_filter("comment", extensions::comment); - // env.add_filter( - // "type_mapping", - // extensions::TypeMapping { - // type_mapping: target_config.type_mapping, - // }, - // ); - - // Register custom functions - // tera.register_function("config", functions::FunctionConfig::new(config.clone())); - - // Register custom testers - // tera.register_tester("required", testers::is_required); - // tera.register_tester("not_required", testers::is_not_required); - Ok(Self { - path: target_path, - engine: env, - config, + path: target_path.clone(), + target_config: TargetConfig::try_new(&target_path)?, + config: Arc::new(DynamicGlobalConfig::default()), }) } + // ToDo Refactor InternalError + // ToDo Use compound error + /// Generate assets from a semantic convention registry. pub fn generate_registry( &self, @@ -232,6 +192,56 @@ impl TemplateEngine<'_> { registry: &Registry, output_dir: PathBuf, ) -> Result<(), Error> { + let cache = Cache::try_new().unwrap_or_else(|e| { + _ = log.error(&e.to_string()); + process::exit(1); + }); + + // Process recursively all files in the template directory + let mut lang_path = self.path.to_str().unwrap_or_default().to_string(); + let paths = if lang_path.is_empty() { + glob("**/*").map_err(|e| InternalError(e.to_string()))? + } else { + lang_path.push_str("/**/*"); + glob(lang_path.as_str()).map_err(|e| InternalError(e.to_string()))? + }; + + // List all {template, object} pairs to run in parallel the template + // engine as all pairs are independent. + self.list_registry_templates(®istry, paths)? + .into_par_iter() + .try_for_each(|pair| { + match pair { + TemplateObjectPair::Group { + absolute_template_path, + relative_template_path, + group + } => { + let ctx: serde_json::Value = serde_json::to_value(group) + .map_err(|e| InternalError(e.to_string()))?; + self.evaluate_template(log.clone(), ctx, absolute_template_path, relative_template_path, &output_dir) + }, + TemplateObjectPair::Groups { + absolute_template_path, + relative_template_path, + groups + } => { + let ctx: serde_json::Value = serde_json::to_value(groups) + .map_err(|e| InternalError(e.to_string()))?; + self.evaluate_template(log.clone(), ctx, absolute_template_path, relative_template_path, &output_dir) + }, + TemplateObjectPair::Registry { + absolute_template_path, + relative_template_path, + registry, + } => { + let ctx: serde_json::Value = serde_json::to_value(registry) + .map_err(|e| InternalError(e.to_string()))?; + self.evaluate_template(log.clone(), ctx, absolute_template_path, relative_template_path, &output_dir) + } + } + })?; + Ok(()) } @@ -265,147 +275,345 @@ impl TemplateEngine<'_> { // Build the list of all {template, object} pairs to generate code for // and process them in parallel. // All pairs are independent from each other so we can process them in parallel. - self.list_all_templates(&schema, paths)? - .into_par_iter() - .try_for_each(|pair| { - match pair { - TemplateObjectPair::Metric { template, metric } => self.process_metric( - log.clone(), - &template, - &schema_path, - metric, - &output_dir, - ), - TemplateObjectPair::MetricGroup { - template, - metric_group, - } => self.process_metric_group( - log.clone(), - &template, - &schema_path, - metric_group, - &output_dir, - ), - TemplateObjectPair::Event { template, event } => { - self.process_event(log.clone(), &template, &schema_path, event, &output_dir) - } - TemplateObjectPair::Span { template, span } => { - self.process_span(log.clone(), &template, &schema_path, span, &output_dir) - } - TemplateObjectPair::Other { - template, - relative_path, - object, - } => { - // Process other templates - // let context = &Context::from_serialize(object).map_err(|e| { - // InvalidTelemetrySchema { - // schema: schema_path.clone(), - // error: format!("{}", e), - // } - // })?; - // - // log.loading(&format!("Generating file {}", template)); - // let generated_code = self.generate_code(log.clone(), &template, context)?; - // let relative_path = relative_path.to_path_buf(); - // let generated_file = - // Self::save_generated_code(&output_dir, relative_path, generated_code)?; - // log.success(&format!("Generated file {:?}", generated_file)); - Ok(()) - } - } - })?; + // self.list_all_templates(&schema, paths)? + // .into_par_iter() + // .try_for_each(|pair| { + // match pair { + // TemplateObjectPair::Metric { template, metric } => self.process_metric( + // log.clone(), + // &template, + // &schema_path, + // metric, + // &output_dir, + // ), + // TemplateObjectPair::MetricGroup { + // template, + // metric_group, + // } => self.process_metric_group( + // log.clone(), + // &template, + // &schema_path, + // metric_group, + // &output_dir, + // ), + // TemplateObjectPair::Event { template, event } => { + // self.process_event(log.clone(), &template, &schema_path, event, &output_dir) + // } + // TemplateObjectPair::Span { template, span } => { + // self.process_span(log.clone(), &template, &schema_path, span, &output_dir) + // } + // TemplateObjectPair::Other { + // template, + // relative_path, + // object, + // } => { + // // Process other templates + // // let context = &Context::from_serialize(object).map_err(|e| { + // // InvalidTelemetrySchema { + // // schema: schema_path.clone(), + // // error: format!("{}", e), + // // } + // // })?; + // // + // // log.loading(&format!("Generating file {}", template)); + // // let generated_code = self.generate_code(log.clone(), &template, context)?; + // // let relative_path = relative_path.to_path_buf(); + // // let generated_file = + // // Self::save_generated_code(&output_dir, relative_path, generated_code)?; + // // log.success(&format!("Generated file {:?}", generated_file)); + // Ok(()) + // } + // } + // })?; Ok(()) } + fn evaluate_template(&self, + log: impl Logger + Clone + Sync, + ctx: serde_json::Value, + absolute_template_path: PathBuf, + relative_template_path: PathBuf, + output_dir: &PathBuf, + ) -> Result<(), Error> { + let template_file_name = absolute_template_path.to_str().ok_or(InvalidTemplateFile{ + template: absolute_template_path.clone(), + error: "".to_string()})?; + let template_source = fs::read_to_string(&absolute_template_path).map_err(|e| InvalidTemplateFile{ + template: absolute_template_path.clone().into(), + error: e.to_string()})?; + let mut engine = self.template_engine(); + + engine.add_template(template_file_name, &template_source).map_err(|e| InternalError(e.to_string()))?; + + _ = log.loading(&format!("Generating file {}", template_file_name)); + let output = engine.get_template(template_file_name).map_err(|e| InternalError(e.to_string()))? + .render(ctx).map_err(|e| InternalError(e.to_string()))?; + let generated_file = + Self::save_generated_code(output_dir, relative_template_path, output)?; + _ = log.success(&format!("Generated file {:?}", generated_file)); + Ok(()) + } + + fn template_engine(&self) -> Environment { + let mut env = Environment::new(); + + // Register custom filters + env.add_filter("file_name", case_converter(self.target_config.file_name.clone())); + env.add_filter("function_name", case_converter(self.target_config.function_name.clone())); + env.add_filter("arg_name", case_converter(self.target_config.arg_name.clone())); + env.add_filter("struct_name", case_converter(self.target_config.struct_name.clone())); + env.add_filter("field_name", case_converter(self.target_config.field_name.clone())); + // env.add_filter("unique_attributes", extensions::unique_attributes); + // env.add_filter("instrument", extensions::instrument); + // env.add_filter("required", extensions::required); + // env.add_filter("not_required", extensions::not_required); + // env.add_filter("value", extensions::value); + // env.add_filter("with_value", extensions::with_value); + // env.add_filter("without_value", extensions::without_value); + // env.add_filter("with_enum", extensions::with_enum); + // env.add_filter("without_enum", extensions::without_enum); + // env.add_filter("comment", extensions::comment); + // env.add_filter( + // "type_mapping", + // extensions::TypeMapping { + // type_mapping: target_config.type_mapping, + // }, + // ); + + // Register custom functions + // tera.register_function("config", functions::FunctionConfig::new(config.clone())); + + // Register custom testers + // tera.register_tester("required", testers::is_required); + // tera.register_tester("not_required", testers::is_not_required); + env + } + /// Lists all {template, object} pairs derived from a template directory and a given - /// schema specification. - fn list_all_templates<'a>( + /// semantic convention registry. + fn list_registry_templates<'a>( &self, - schema: &'a TelemetrySchema, + registry: &'a Registry, paths: Paths, ) -> Result>, Error> { let mut templates = Vec::new(); - if let Some(schema_spec) = &schema.schema { - for entry in paths { - if let Ok(tmpl_file_path) = entry { - if tmpl_file_path.is_dir() { - continue; + + for entry in paths { + if let Ok(tmpl_file_path) = entry { + if tmpl_file_path.is_dir() { + continue; + } + let relative_path = tmpl_file_path + .strip_prefix(&self.path) + .map_err(|e| InvalidTemplateDir(self.path.clone()))?; + let tmpl_file = tmpl_file_path + .to_str() + .ok_or(InvalidTemplateFile{template: tmpl_file_path.clone(), error: "".to_string() })?; + + if tmpl_file.ends_with(".macro.j2") { + // Macro files are not templates. + // They are included in other templates. + // So we skip them. + continue; + } + + if tmpl_file.ends_with("weaver.yaml") { + // Skip weaver configuration file. + continue; + } + + match tmpl_file_path.file_stem().and_then(|s| s.to_str()) { + Some("attribute_group") => { + registry.groups.iter() + .filter(|group| if let TypedGroup::AttributeGroup { .. } = group.typed_group { true } else { false }) + .for_each(|group| { + templates.push(TemplateObjectPair::Group { + absolute_template_path: tmpl_file_path.to_path_buf(), + relative_template_path: relative_path.to_path_buf(), + group, + }) + }); } - let relative_path = tmpl_file_path.strip_prefix(&self.path).unwrap(); - let tmpl_file = relative_path - .to_str() - .ok_or(InvalidTemplateFile(tmpl_file_path.clone()))?; - - if tmpl_file.ends_with(".macro.tera") { - // Macro files are not templates. - // They are included in other templates. - // So we skip them. - continue; + Some("event") => { + registry.groups.iter() + .filter(|group| if let TypedGroup::Event { .. } = group.typed_group { true } else { false }) + .for_each(|group| { + templates.push(TemplateObjectPair::Group { + absolute_template_path: tmpl_file_path.to_path_buf(), + relative_template_path: relative_path.to_path_buf(), + group, + }) + }); } - - match tmpl_file_path.file_stem().and_then(|s| s.to_str()) { - Some("metric") => { - if let Some(resource_metrics) = schema_spec.resource_metrics.as_ref() { - for metric in resource_metrics.metrics.iter() { - templates.push(TemplateObjectPair::Metric { - template: tmpl_file.into(), - metric, - }) - } - } - } - Some("metric_group") => { - if let Some(resource_metrics) = schema_spec.resource_metrics.as_ref() { - for metric_group in resource_metrics.metric_groups.iter() { - templates.push(TemplateObjectPair::MetricGroup { - template: tmpl_file.into(), - metric_group, - }) - } - } - } - Some("event") => { - if let Some(events) = schema_spec.resource_events.as_ref() { - for event in events.events.iter() { - templates.push(TemplateObjectPair::Event { - template: tmpl_file.into(), - event, - }) - } - } - } - Some("span") => { - if let Some(spans) = schema_spec.resource_spans.as_ref() { - for span in spans.spans.iter() { - templates.push(TemplateObjectPair::Span { - template: tmpl_file.into(), - span, - }) - } - } - } - _ => { - // Remove the `tera` extension from the relative path - let mut relative_path = relative_path.to_path_buf(); - _ = relative_path.set_extension(""); - - templates.push(TemplateObjectPair::Other { - template: tmpl_file.into(), - relative_path, - object: schema, - }) - } + Some("group") => { + registry.groups.iter() + .for_each(|group| { + templates.push(TemplateObjectPair::Group { + absolute_template_path: tmpl_file_path.to_path_buf(), + relative_template_path: relative_path.to_path_buf(), + group, + }) + }); + } + Some("metric") => { + registry.groups.iter() + .filter(|group| if let TypedGroup::Metric { .. } = group.typed_group { true } else { false }) + .for_each(|group| { + templates.push(TemplateObjectPair::Group { + absolute_template_path: tmpl_file.into(), + relative_template_path: relative_path.to_path_buf(), + group, + }) + }); + } + Some("metric_group") => { + registry.groups.iter() + .filter(|group| if let TypedGroup::MetricGroup { .. } = group.typed_group { true } else { false }) + .for_each(|group| { + templates.push(TemplateObjectPair::Group { + absolute_template_path: tmpl_file.into(), + relative_template_path: relative_path.to_path_buf(), + group, + }) + }); + } + Some("registry") => { + templates.push(TemplateObjectPair::Registry { + absolute_template_path: tmpl_file.into(), + relative_template_path: relative_path.to_path_buf(), + registry, + }); + } + Some("resource") => { + registry.groups.iter() + .filter(|group| if let TypedGroup::Resource { .. } = group.typed_group { true } else { false }) + .for_each(|group| { + templates.push(TemplateObjectPair::Group { + absolute_template_path: tmpl_file.into(), + relative_template_path: relative_path.to_path_buf(), + group, + }) + }); + } + Some("scope") => { + registry.groups.iter() + .filter(|group| if let TypedGroup::Scope { .. } = group.typed_group { true } else { false }) + .for_each(|group| { + templates.push(TemplateObjectPair::Group { + absolute_template_path: tmpl_file.into(), + relative_template_path: relative_path.to_path_buf(), + group, + }) + }); + } + Some("span") => { + registry.groups.iter() + .filter(|group| if let TypedGroup::Span { .. } = group.typed_group { true } else { false }) + .for_each(|group| { + templates.push(TemplateObjectPair::Group { + absolute_template_path: tmpl_file.into(), + relative_template_path: relative_path.to_path_buf(), + group, + }) + }); + } + Some("attribute_groups") => { + let groups = registry.groups.iter() + .filter(|group| if let TypedGroup::AttributeGroup { .. } = group.typed_group { true } else { false }) + .collect::>(); + templates.push(TemplateObjectPair::Groups { + absolute_template_path: tmpl_file.into(), + relative_template_path: relative_path.to_path_buf(), + groups, + }) + } + Some("events") => { + let groups = registry.groups.iter() + .filter(|group| if let TypedGroup::Event { .. } = group.typed_group { true } else { false }) + .collect::>(); + templates.push(TemplateObjectPair::Groups { + absolute_template_path: tmpl_file.into(), + relative_template_path: relative_path.to_path_buf(), + groups, + }) + } + Some("groups") => { + let groups = registry.groups.iter() + .collect::>(); + templates.push(TemplateObjectPair::Groups { + absolute_template_path: tmpl_file.into(), + relative_template_path: relative_path.to_path_buf(), + groups, + }) + } + Some("metrics") => { + let groups = registry.groups.iter() + .filter(|group| if let TypedGroup::Metric { .. } = group.typed_group { true } else { false }) + .collect::>(); + templates.push(TemplateObjectPair::Groups { + absolute_template_path: tmpl_file.into(), + relative_template_path: relative_path.to_path_buf(), + groups, + }) + } + Some("metric_groups") => { + let groups = registry.groups.iter() + .filter(|group| if let TypedGroup::MetricGroup { .. } = group.typed_group { true } else { false }) + .collect::>(); + templates.push(TemplateObjectPair::Groups { + absolute_template_path: tmpl_file.into(), + relative_template_path: relative_path.to_path_buf(), + groups, + }) + } + Some("resources") => { + let groups = registry.groups.iter() + .filter(|group| if let TypedGroup::Resource { .. } = group.typed_group { true } else { false }) + .collect::>(); + templates.push(TemplateObjectPair::Groups { + absolute_template_path: tmpl_file.into(), + relative_template_path: relative_path.to_path_buf(), + groups, + }) + } + Some("scopes") => { + let groups = registry.groups.iter() + .filter(|group| if let TypedGroup::Scope { .. } = group.typed_group { true } else { false }) + .collect::>(); + templates.push(TemplateObjectPair::Groups { + absolute_template_path: tmpl_file.into(), + relative_template_path: relative_path.to_path_buf(), + groups, + }) + } + Some("spans") => { + let groups = registry.groups.iter() + .filter(|group| if let TypedGroup::Span { .. } = group.typed_group { true } else { false }) + .collect::>(); + templates.push(TemplateObjectPair::Groups { + absolute_template_path: tmpl_file.into(), + relative_template_path: relative_path.to_path_buf(), + groups, + }) + } + _ => { + templates.push(TemplateObjectPair::Registry { + absolute_template_path: tmpl_file.into(), + relative_template_path: relative_path.to_path_buf(), + registry, + }) } - } else { - return Err(InvalidTemplateDirectory(self.path.clone())); } + } else { + return Err(InvalidTemplateDirectory(self.path.clone())); } } + Ok(templates) } + /// Generate code. fn generate_code( &self, @@ -456,13 +664,12 @@ impl TemplateEngine<'_> { Ok(output_file_path) } - /// Process an univariate metric. - fn process_metric( + /// Process a registry group. + fn process_group( &self, log: impl Logger + Clone, - tmpl_file: &str, - schema_path: &Path, - metric: &UnivariateMetric, + tmpl_file: &PathBuf, + group: &Group, output_dir: &Path, ) -> Result<(), Error> { // if let UnivariateMetric::Metric { name, .. } = metric { diff --git a/crates/weaver_forge/templates/test/attribute_group.md b/crates/weaver_forge/templates/test/attribute_group.md new file mode 100644 index 00000000..025b7741 --- /dev/null +++ b/crates/weaver_forge/templates/test/attribute_group.md @@ -0,0 +1 @@ +# Attribute Group `{{ id }}` diff --git a/crates/weaver_forge/templates/test/attribute_groups.md b/crates/weaver_forge/templates/test/attribute_groups.md new file mode 100644 index 00000000..a39a20dd --- /dev/null +++ b/crates/weaver_forge/templates/test/attribute_groups.md @@ -0,0 +1 @@ +# Attribute Groups \ No newline at end of file diff --git a/crates/weaver_forge/templates/test/event.md b/crates/weaver_forge/templates/test/event.md new file mode 100644 index 00000000..e69de29b diff --git a/crates/weaver_forge/templates/test/group.md b/crates/weaver_forge/templates/test/group.md new file mode 100644 index 00000000..1283c831 --- /dev/null +++ b/crates/weaver_forge/templates/test/group.md @@ -0,0 +1,8 @@ +# Group `{{ id }}` + +file name: {{ id | file_name }} +function name: {{ id | function_name }} +arg_name: {{ id | arg_name }} +struct_name: {{ id | struct_name }} +field_name: {{ id | field_name }} + diff --git a/crates/weaver_forge/templates/test/groups.md b/crates/weaver_forge/templates/test/groups.md new file mode 100644 index 00000000..e69de29b diff --git a/crates/weaver_forge/templates/test/metric.md b/crates/weaver_forge/templates/test/metric.md new file mode 100644 index 00000000..e69de29b diff --git a/crates/weaver_forge/templates/test/metric_group.md b/crates/weaver_forge/templates/test/metric_group.md new file mode 100644 index 00000000..e69de29b diff --git a/crates/weaver_forge/templates/test/registry.md b/crates/weaver_forge/templates/test/registry.md new file mode 100644 index 00000000..be6e4d0c --- /dev/null +++ b/crates/weaver_forge/templates/test/registry.md @@ -0,0 +1,3 @@ +# Semantic Convention Registry + +url: {{ registry_url }} \ No newline at end of file diff --git a/crates/weaver_forge/templates/test/resource.md b/crates/weaver_forge/templates/test/resource.md new file mode 100644 index 00000000..e69de29b diff --git a/crates/weaver_forge/templates/test/scope.md b/crates/weaver_forge/templates/test/scope.md new file mode 100644 index 00000000..e69de29b diff --git a/crates/weaver_forge/templates/test/span.md b/crates/weaver_forge/templates/test/span.md new file mode 100644 index 00000000..e093a54d --- /dev/null +++ b/crates/weaver_forge/templates/test/span.md @@ -0,0 +1 @@ +# Span `{{ id }}` \ No newline at end of file diff --git a/crates/weaver_forge/templates/test/spans.md b/crates/weaver_forge/templates/test/spans.md new file mode 100644 index 00000000..e69de29b diff --git a/crates/weaver_forge/templates/test/weaver.yaml b/crates/weaver_forge/templates/test/weaver.yaml new file mode 100644 index 00000000..452e1bf4 --- /dev/null +++ b/crates/weaver_forge/templates/test/weaver.yaml @@ -0,0 +1,15 @@ +file_name: snake_case +function_name: PascalCase +arg_name: camelCase +struct_name: PascalCase +field_name: PascalCase + +type_mapping: + int: int64 + double: double + boolean: bool + string: string + "int[]": "[]int64" + "double[]": "[]double" + "boolean[]": "[]bool" + "string[]": "[]string" \ No newline at end of file From 9121d7f97ae5bca0313bf0eb78c38535cf085d14 Mon Sep 17 00:00:00 2001 From: Laurent Querel Date: Tue, 5 Mar 2024 16:02:32 -0800 Subject: [PATCH 05/20] feature(template): expose template.set_file_name method to dynamically define the file name of the output. --- crates/weaver_forge/src/lib.rs | 50 ++++++++++++++++++--- crates/weaver_forge/templates/test/group.md | 2 + 2 files changed, 47 insertions(+), 5 deletions(-) diff --git a/crates/weaver_forge/src/lib.rs b/crates/weaver_forge/src/lib.rs index b0c164f0..53f5baf1 100644 --- a/crates/weaver_forge/src/lib.rs +++ b/crates/weaver_forge/src/lib.rs @@ -15,13 +15,14 @@ unused_extern_crates )] use std::{fs, process}; +use std::fmt::{Debug, Display, Formatter}; use std::path::{Path, PathBuf}; -use std::sync::Arc; +use std::sync::{Arc, Mutex}; use std::task::Context; use glob::{glob, Paths}; -use minijinja::{Environment, path_loader}; -use minijinja::filters::abs; +use minijinja::{Environment, State, Value}; +use minijinja::value::{from_args, Object}; use rayon::iter::IntoParallelIterator; use rayon::iter::ParallelIterator; @@ -147,6 +148,39 @@ enum TemplateObjectPair<'a> { }, } +/// A template object accessible from the template. +#[derive(Debug, Clone)] +struct TemplateObject { + file_name: Arc>, +} + +impl TemplateObject { + /// Get the file name of the template. + fn file_name(&self) -> PathBuf { + PathBuf::from(self.file_name.lock().unwrap().clone()) + } +} +impl Display for TemplateObject { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + f.write_str(&format!("template file name: {}", self.file_name.lock().unwrap())) + } +} + +impl Object for TemplateObject { + fn call_method(&self, _state: &State, name: &str, args: &[Value]) -> Result { + if name == "set_file_name" { + let (file_name,): (&str,) = from_args(args)?; + *self.file_name.lock().unwrap() = file_name.to_string(); + Ok(Value::from("")) + } else { + Err(minijinja::Error::new( + minijinja::ErrorKind::UnknownMethod, + format!("template has no method named {name}"), + )) + } + } +} + /// Template engine for generating artifacts from a semantic convention /// registry and telemetry schema. pub struct TemplateEngine { @@ -342,28 +376,34 @@ impl TemplateEngine { let template_source = fs::read_to_string(&absolute_template_path).map_err(|e| InvalidTemplateFile{ template: absolute_template_path.clone().into(), error: e.to_string()})?; + let template_object = TemplateObject { + file_name: Arc::new(Mutex::new(relative_template_path.to_str().unwrap_or_default().to_string())), + }; let mut engine = self.template_engine(); + engine.add_global("template", Value::from_object(template_object.clone())); engine.add_template(template_file_name, &template_source).map_err(|e| InternalError(e.to_string()))?; _ = log.loading(&format!("Generating file {}", template_file_name)); let output = engine.get_template(template_file_name).map_err(|e| InternalError(e.to_string()))? .render(ctx).map_err(|e| InternalError(e.to_string()))?; let generated_file = - Self::save_generated_code(output_dir, relative_template_path, output)?; + Self::save_generated_code(output_dir, template_object.file_name(), output)?; _ = log.success(&format!("Generated file {:?}", generated_file)); Ok(()) } + /// Create a new template engine based on the target configuration. fn template_engine(&self) -> Environment { let mut env = Environment::new(); - // Register custom filters + // Register case conversion filters based on the target configuration env.add_filter("file_name", case_converter(self.target_config.file_name.clone())); env.add_filter("function_name", case_converter(self.target_config.function_name.clone())); env.add_filter("arg_name", case_converter(self.target_config.arg_name.clone())); env.add_filter("struct_name", case_converter(self.target_config.struct_name.clone())); env.add_filter("field_name", case_converter(self.target_config.field_name.clone())); + // env.add_filter("unique_attributes", extensions::unique_attributes); // env.add_filter("instrument", extensions::instrument); // env.add_filter("required", extensions::required); diff --git a/crates/weaver_forge/templates/test/group.md b/crates/weaver_forge/templates/test/group.md index 1283c831..116a83cd 100644 --- a/crates/weaver_forge/templates/test/group.md +++ b/crates/weaver_forge/templates/test/group.md @@ -1,3 +1,5 @@ +{%- set file_name = id | file_name -%} +{{- template.set_file_name("group/" ~ file_name ~ ".md") -}} # Group `{{ id }}` file name: {{ id | file_name }} From 7de3e98f80687a64361b65196e139b38bf2adc64 Mon Sep 17 00:00:00 2001 From: Laurent Querel Date: Tue, 5 Mar 2024 17:08:53 -0800 Subject: [PATCH 06/20] feature(template): initialize template engine with a root directory to support include clause. --- crates/weaver_forge/src/config.rs | 40 +-- crates/weaver_forge/src/lib.rs | 411 ++++-------------------------- 2 files changed, 52 insertions(+), 399 deletions(-) diff --git a/crates/weaver_forge/src/config.rs b/crates/weaver_forge/src/config.rs index 45e9f2fd..3aec64bc 100644 --- a/crates/weaver_forge/src/config.rs +++ b/crates/weaver_forge/src/config.rs @@ -2,13 +2,11 @@ //! Configuration for the template crate. -use std::cell::RefCell; use std::collections::HashMap; use std::path::Path; use convert_case::{Case, Casing}; use serde::Deserialize; -use thread_local::ThreadLocal; use crate::Error; use crate::Error::InvalidConfigFile; @@ -58,13 +56,6 @@ pub struct TargetConfig { pub type_mapping: HashMap, } -/// Dynamic global configuration. -#[derive(Debug, Default)] -pub struct DynamicGlobalConfig { - /// File name for the current generated code. - pub file_name: ThreadLocal>>, -} - impl Default for CaseConvention { /// Default case convention is PascalCase fn default() -> Self { @@ -105,33 +96,4 @@ impl TargetConfig { Ok(TargetConfig::default()) } } -} - -impl DynamicGlobalConfig { - /// Set the file name for the current generated code. - /// This method uses a thread local variable to store the file name. - pub fn set(&self, file_name: &str) { - _ = self.file_name - .get_or(|| RefCell::new(None)) - .borrow_mut() - .replace(file_name.to_string()); - } - - /// Get the file name for the current generated code. - /// This method uses a thread local variable to store the file name. - pub fn get(&self) -> Option { - self.file_name - .get_or(|| RefCell::new(None)) - .borrow() - .clone() - } - - /// Reset the file name for the current generated code. - /// This method uses a thread local variable to store the file name. - pub fn reset(&self) { - _ = self.file_name - .get_or(|| RefCell::new(None)) - .borrow_mut() - .take(); - } -} +} \ No newline at end of file diff --git a/crates/weaver_forge/src/lib.rs b/crates/weaver_forge/src/lib.rs index 53f5baf1..86710b27 100644 --- a/crates/weaver_forge/src/lib.rs +++ b/crates/weaver_forge/src/lib.rs @@ -14,28 +14,22 @@ unused_results, unused_extern_crates )] -use std::{fs, process}; use std::fmt::{Debug, Display, Formatter}; +use std::fs; use std::path::{Path, PathBuf}; use std::sync::{Arc, Mutex}; -use std::task::Context; use glob::{glob, Paths}; -use minijinja::{Environment, State, Value}; +use minijinja::{Environment, path_loader, State, Value}; use minijinja::value::{from_args, Object}; use rayon::iter::IntoParallelIterator; use rayon::iter::ParallelIterator; -use weaver_cache::Cache; use weaver_logger::Logger; use weaver_resolved_schema::registry::{Group, Registry, TypedGroup}; -use weaver_resolver::SchemaResolver; -use weaver_schema::event::Event; -use weaver_schema::metric_group::MetricGroup; -use weaver_schema::span::Span; -use crate::config::{DynamicGlobalConfig, TargetConfig}; -use crate::Error::{InternalError, InvalidTelemetrySchema, InvalidTemplateDir, InvalidTemplateDirectory, InvalidTemplateFile, TargetNotSupported, WriteGeneratedCodeFailed}; +use crate::config::TargetConfig; +use crate::Error::{InternalError, InvalidTemplateDir, InvalidTemplateDirectory, InvalidTemplateFile, TargetNotSupported, WriteGeneratedCodeFailed}; use crate::extensions::case_converter::case_converter; mod config; @@ -65,8 +59,11 @@ pub enum Error { }, /// Invalid template directory. - #[error("Invalid template directory: {0}")] - InvalidTemplateDir(PathBuf), + #[error("Invalid template directory {template_dir}: {error}")] + InvalidTemplateDir { + template_dir: PathBuf, + error: String, + }, /// Invalid telemetry schema. #[error("Invalid telemetry schema {schema}: {error}")] @@ -132,18 +129,15 @@ impl Default for GeneratorConfig { #[derive(Debug)] enum TemplateObjectPair<'a> { Group { - absolute_template_path: PathBuf, - relative_template_path: PathBuf, + template_path: PathBuf, group: &'a Group, }, Groups { - absolute_template_path: PathBuf, - relative_template_path: PathBuf, + template_path: PathBuf, groups: Vec<&'a Group>, }, Registry { - absolute_template_path: PathBuf, - relative_template_path: PathBuf, + template_path: PathBuf, registry: &'a Registry, }, } @@ -160,6 +154,7 @@ impl TemplateObject { PathBuf::from(self.file_name.lock().unwrap().clone()) } } + impl Display for TemplateObject { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { f.write_str(&format!("template file name: {}", self.file_name.lock().unwrap())) @@ -169,7 +164,7 @@ impl Display for TemplateObject { impl Object for TemplateObject { fn call_method(&self, _state: &State, name: &str, args: &[Value]) -> Result { if name == "set_file_name" { - let (file_name,): (&str,) = from_args(args)?; + let (file_name, ): (&str, ) = from_args(args)?; *self.file_name.lock().unwrap() = file_name.to_string(); Ok(Value::from("")) } else { @@ -189,9 +184,6 @@ pub struct TemplateEngine { /// Target configuration target_config: TargetConfig, - - /// Global configuration - config: Arc, } impl TemplateEngine { @@ -212,7 +204,6 @@ impl TemplateEngine { Ok(Self { path: target_path.clone(), target_config: TargetConfig::try_new(&target_path)?, - config: Arc::new(DynamicGlobalConfig::default()), }) } @@ -226,11 +217,6 @@ impl TemplateEngine { registry: &Registry, output_dir: PathBuf, ) -> Result<(), Error> { - let cache = Cache::try_new().unwrap_or_else(|e| { - _ = log.error(&e.to_string()); - process::exit(1); - }); - // Process recursively all files in the template directory let mut lang_path = self.path.to_str().unwrap_or_default().to_string(); let paths = if lang_path.is_empty() { @@ -247,31 +233,28 @@ impl TemplateEngine { .try_for_each(|pair| { match pair { TemplateObjectPair::Group { - absolute_template_path, - relative_template_path, + template_path: relative_template_path, group } => { let ctx: serde_json::Value = serde_json::to_value(group) .map_err(|e| InternalError(e.to_string()))?; - self.evaluate_template(log.clone(), ctx, absolute_template_path, relative_template_path, &output_dir) - }, + self.evaluate_template(log.clone(), ctx, relative_template_path, &output_dir) + } TemplateObjectPair::Groups { - absolute_template_path, - relative_template_path, + template_path: relative_template_path, groups } => { let ctx: serde_json::Value = serde_json::to_value(groups) .map_err(|e| InternalError(e.to_string()))?; - self.evaluate_template(log.clone(), ctx, absolute_template_path, relative_template_path, &output_dir) - }, + self.evaluate_template(log.clone(), ctx, relative_template_path, &output_dir) + } TemplateObjectPair::Registry { - absolute_template_path, - relative_template_path, + template_path: relative_template_path, registry, } => { let ctx: serde_json::Value = serde_json::to_value(registry) .map_err(|e| InternalError(e.to_string()))?; - self.evaluate_template(log.clone(), ctx, absolute_template_path, relative_template_path, &output_dir) + self.evaluate_template(log.clone(), ctx, relative_template_path, &output_dir) } } })?; @@ -279,113 +262,25 @@ impl TemplateEngine { Ok(()) } - /// Generate assets from the templates. - pub fn generate( - &self, - log: impl Logger + Clone + Sync, - schema_path: PathBuf, - output_dir: PathBuf, - ) -> Result<(), Error> { - let cache = Cache::try_new().unwrap_or_else(|e| { - _ = log.error(&e.to_string()); - process::exit(1); - }); - - let schema = SchemaResolver::resolve_schema_file(schema_path.clone(), &cache, log.clone()) - .map_err(|e| InvalidTelemetrySchema { - schema: schema_path.clone(), - error: format!("{}", e), - })?; - - // Process recursively all files in the template directory - let mut lang_path = self.path.to_str().unwrap_or_default().to_string(); - let paths = if lang_path.is_empty() { - glob("**/*.tera").map_err(|e| InternalError(e.to_string()))? - } else { - lang_path.push_str("/**/*.tera"); - glob(lang_path.as_str()).map_err(|e| InternalError(e.to_string()))? - }; - - // Build the list of all {template, object} pairs to generate code for - // and process them in parallel. - // All pairs are independent from each other so we can process them in parallel. - // self.list_all_templates(&schema, paths)? - // .into_par_iter() - // .try_for_each(|pair| { - // match pair { - // TemplateObjectPair::Metric { template, metric } => self.process_metric( - // log.clone(), - // &template, - // &schema_path, - // metric, - // &output_dir, - // ), - // TemplateObjectPair::MetricGroup { - // template, - // metric_group, - // } => self.process_metric_group( - // log.clone(), - // &template, - // &schema_path, - // metric_group, - // &output_dir, - // ), - // TemplateObjectPair::Event { template, event } => { - // self.process_event(log.clone(), &template, &schema_path, event, &output_dir) - // } - // TemplateObjectPair::Span { template, span } => { - // self.process_span(log.clone(), &template, &schema_path, span, &output_dir) - // } - // TemplateObjectPair::Other { - // template, - // relative_path, - // object, - // } => { - // // Process other templates - // // let context = &Context::from_serialize(object).map_err(|e| { - // // InvalidTelemetrySchema { - // // schema: schema_path.clone(), - // // error: format!("{}", e), - // // } - // // })?; - // // - // // log.loading(&format!("Generating file {}", template)); - // // let generated_code = self.generate_code(log.clone(), &template, context)?; - // // let relative_path = relative_path.to_path_buf(); - // // let generated_file = - // // Self::save_generated_code(&output_dir, relative_path, generated_code)?; - // // log.success(&format!("Generated file {:?}", generated_file)); - // Ok(()) - // } - // } - // })?; - - Ok(()) - } - fn evaluate_template(&self, log: impl Logger + Clone + Sync, ctx: serde_json::Value, - absolute_template_path: PathBuf, - relative_template_path: PathBuf, + template_path: PathBuf, output_dir: &PathBuf, ) -> Result<(), Error> { - let template_file_name = absolute_template_path.to_str().ok_or(InvalidTemplateFile{ - template: absolute_template_path.clone(), - error: "".to_string()})?; - let template_source = fs::read_to_string(&absolute_template_path).map_err(|e| InvalidTemplateFile{ - template: absolute_template_path.clone().into(), - error: e.to_string()})?; let template_object = TemplateObject { - file_name: Arc::new(Mutex::new(relative_template_path.to_str().unwrap_or_default().to_string())), + file_name: Arc::new(Mutex::new(template_path.to_str().unwrap_or_default().to_string())), }; let mut engine = self.template_engine(); + let template_file = template_path.to_str().ok_or(InvalidTemplateFile { + template: template_path.clone(), + error: "".to_string(), + })?; engine.add_global("template", Value::from_object(template_object.clone())); - engine.add_template(template_file_name, &template_source).map_err(|e| InternalError(e.to_string()))?; - _ = log.loading(&format!("Generating file {}", template_file_name)); - let output = engine.get_template(template_file_name).map_err(|e| InternalError(e.to_string()))? + _ = log.loading(&format!("Generating file {}", template_file)); + let output = engine.get_template(template_file).map_err(|e| InternalError(e.to_string()))? .render(ctx).map_err(|e| InternalError(e.to_string()))?; let generated_file = Self::save_generated_code(output_dir, template_object.file_name(), output)?; @@ -396,6 +291,7 @@ impl TemplateEngine { /// Create a new template engine based on the target configuration. fn template_engine(&self) -> Environment { let mut env = Environment::new(); + env.set_loader(path_loader(&self.path)); // Register case conversion filters based on the target configuration env.add_filter("file_name", case_converter(self.target_config.file_name.clone())); @@ -421,9 +317,6 @@ impl TemplateEngine { // }, // ); - // Register custom functions - // tera.register_function("config", functions::FunctionConfig::new(config.clone())); - // Register custom testers // tera.register_tester("required", testers::is_required); // tera.register_tester("not_required", testers::is_not_required); @@ -446,10 +339,10 @@ impl TemplateEngine { } let relative_path = tmpl_file_path .strip_prefix(&self.path) - .map_err(|e| InvalidTemplateDir(self.path.clone()))?; + .map_err(|e| InvalidTemplateDir { template_dir: self.path.clone(), error: e.to_string() })?; let tmpl_file = tmpl_file_path .to_str() - .ok_or(InvalidTemplateFile{template: tmpl_file_path.clone(), error: "".to_string() })?; + .ok_or(InvalidTemplateFile { template: tmpl_file_path.clone(), error: "".to_string() })?; if tmpl_file.ends_with(".macro.j2") { // Macro files are not templates. @@ -469,8 +362,7 @@ impl TemplateEngine { .filter(|group| if let TypedGroup::AttributeGroup { .. } = group.typed_group { true } else { false }) .for_each(|group| { templates.push(TemplateObjectPair::Group { - absolute_template_path: tmpl_file_path.to_path_buf(), - relative_template_path: relative_path.to_path_buf(), + template_path: relative_path.to_path_buf(), group, }) }); @@ -480,8 +372,7 @@ impl TemplateEngine { .filter(|group| if let TypedGroup::Event { .. } = group.typed_group { true } else { false }) .for_each(|group| { templates.push(TemplateObjectPair::Group { - absolute_template_path: tmpl_file_path.to_path_buf(), - relative_template_path: relative_path.to_path_buf(), + template_path: relative_path.to_path_buf(), group, }) }); @@ -490,8 +381,7 @@ impl TemplateEngine { registry.groups.iter() .for_each(|group| { templates.push(TemplateObjectPair::Group { - absolute_template_path: tmpl_file_path.to_path_buf(), - relative_template_path: relative_path.to_path_buf(), + template_path: relative_path.to_path_buf(), group, }) }); @@ -501,8 +391,7 @@ impl TemplateEngine { .filter(|group| if let TypedGroup::Metric { .. } = group.typed_group { true } else { false }) .for_each(|group| { templates.push(TemplateObjectPair::Group { - absolute_template_path: tmpl_file.into(), - relative_template_path: relative_path.to_path_buf(), + template_path: relative_path.to_path_buf(), group, }) }); @@ -512,16 +401,14 @@ impl TemplateEngine { .filter(|group| if let TypedGroup::MetricGroup { .. } = group.typed_group { true } else { false }) .for_each(|group| { templates.push(TemplateObjectPair::Group { - absolute_template_path: tmpl_file.into(), - relative_template_path: relative_path.to_path_buf(), + template_path: relative_path.to_path_buf(), group, }) }); } Some("registry") => { templates.push(TemplateObjectPair::Registry { - absolute_template_path: tmpl_file.into(), - relative_template_path: relative_path.to_path_buf(), + template_path: relative_path.to_path_buf(), registry, }); } @@ -530,8 +417,7 @@ impl TemplateEngine { .filter(|group| if let TypedGroup::Resource { .. } = group.typed_group { true } else { false }) .for_each(|group| { templates.push(TemplateObjectPair::Group { - absolute_template_path: tmpl_file.into(), - relative_template_path: relative_path.to_path_buf(), + template_path: relative_path.to_path_buf(), group, }) }); @@ -541,8 +427,7 @@ impl TemplateEngine { .filter(|group| if let TypedGroup::Scope { .. } = group.typed_group { true } else { false }) .for_each(|group| { templates.push(TemplateObjectPair::Group { - absolute_template_path: tmpl_file.into(), - relative_template_path: relative_path.to_path_buf(), + template_path: relative_path.to_path_buf(), group, }) }); @@ -552,8 +437,7 @@ impl TemplateEngine { .filter(|group| if let TypedGroup::Span { .. } = group.typed_group { true } else { false }) .for_each(|group| { templates.push(TemplateObjectPair::Group { - absolute_template_path: tmpl_file.into(), - relative_template_path: relative_path.to_path_buf(), + template_path: relative_path.to_path_buf(), group, }) }); @@ -563,8 +447,7 @@ impl TemplateEngine { .filter(|group| if let TypedGroup::AttributeGroup { .. } = group.typed_group { true } else { false }) .collect::>(); templates.push(TemplateObjectPair::Groups { - absolute_template_path: tmpl_file.into(), - relative_template_path: relative_path.to_path_buf(), + template_path: relative_path.to_path_buf(), groups, }) } @@ -573,8 +456,7 @@ impl TemplateEngine { .filter(|group| if let TypedGroup::Event { .. } = group.typed_group { true } else { false }) .collect::>(); templates.push(TemplateObjectPair::Groups { - absolute_template_path: tmpl_file.into(), - relative_template_path: relative_path.to_path_buf(), + template_path: relative_path.to_path_buf(), groups, }) } @@ -582,8 +464,7 @@ impl TemplateEngine { let groups = registry.groups.iter() .collect::>(); templates.push(TemplateObjectPair::Groups { - absolute_template_path: tmpl_file.into(), - relative_template_path: relative_path.to_path_buf(), + template_path: relative_path.to_path_buf(), groups, }) } @@ -592,8 +473,7 @@ impl TemplateEngine { .filter(|group| if let TypedGroup::Metric { .. } = group.typed_group { true } else { false }) .collect::>(); templates.push(TemplateObjectPair::Groups { - absolute_template_path: tmpl_file.into(), - relative_template_path: relative_path.to_path_buf(), + template_path: relative_path.to_path_buf(), groups, }) } @@ -602,8 +482,7 @@ impl TemplateEngine { .filter(|group| if let TypedGroup::MetricGroup { .. } = group.typed_group { true } else { false }) .collect::>(); templates.push(TemplateObjectPair::Groups { - absolute_template_path: tmpl_file.into(), - relative_template_path: relative_path.to_path_buf(), + template_path: relative_path.to_path_buf(), groups, }) } @@ -612,8 +491,7 @@ impl TemplateEngine { .filter(|group| if let TypedGroup::Resource { .. } = group.typed_group { true } else { false }) .collect::>(); templates.push(TemplateObjectPair::Groups { - absolute_template_path: tmpl_file.into(), - relative_template_path: relative_path.to_path_buf(), + template_path: relative_path.to_path_buf(), groups, }) } @@ -622,8 +500,7 @@ impl TemplateEngine { .filter(|group| if let TypedGroup::Scope { .. } = group.typed_group { true } else { false }) .collect::>(); templates.push(TemplateObjectPair::Groups { - absolute_template_path: tmpl_file.into(), - relative_template_path: relative_path.to_path_buf(), + template_path: relative_path.to_path_buf(), groups, }) } @@ -632,15 +509,13 @@ impl TemplateEngine { .filter(|group| if let TypedGroup::Span { .. } = group.typed_group { true } else { false }) .collect::>(); templates.push(TemplateObjectPair::Groups { - absolute_template_path: tmpl_file.into(), - relative_template_path: relative_path.to_path_buf(), + template_path: relative_path.to_path_buf(), groups, }) } _ => { templates.push(TemplateObjectPair::Registry { - absolute_template_path: tmpl_file.into(), - relative_template_path: relative_path.to_path_buf(), + template_path: relative_path.to_path_buf(), registry, }) } @@ -653,29 +528,6 @@ impl TemplateEngine { Ok(templates) } - - /// Generate code. - fn generate_code( - &self, - log: impl Logger, - tmpl_file: &str, - context: &Context, - ) -> Result { - // let generated_code = self.tera.render(tmpl_file, context).unwrap_or_else(|err| { - // log.newline(1); - // log.error(&format!("{}", err)); - // let mut cause = err.source(); - // while let Some(e) = cause { - // log.error(&format!("- caused by: {}", e)); - // cause = e.source(); - // } - // process::exit(1); - // }); - let generated_code = "".to_string(); - - Ok(generated_code) - } - /// Save the generated code to the output directory. fn save_generated_code( output_dir: &Path, @@ -703,167 +555,6 @@ impl TemplateEngine { Ok(output_file_path) } - - /// Process a registry group. - fn process_group( - &self, - log: impl Logger + Clone, - tmpl_file: &PathBuf, - group: &Group, - output_dir: &Path, - ) -> Result<(), Error> { - // if let UnivariateMetric::Metric { name, .. } = metric { - // let context = &Context::from_serialize(metric).map_err(|e| InvalidTelemetrySchema { - // schema: schema_path.to_path_buf(), - // error: format!("{}", e), - // })?; - // - // // Reset the config - // self.config.reset(); - // - // log.loading(&format!("Generating code for univariate metric `{}`", name)); - // let generated_code = self.generate_code(log.clone(), tmpl_file, context)?; - // - // // Retrieve the file name from the config - // let relative_path = { - // match &self.config.get() { - // None => { - // return Err(TemplateFileNameUndefined { - // template: PathBuf::from(tmpl_file), - // }); - // } - // Some(file_name) => PathBuf::from(file_name.clone()), - // } - // }; - // - // // Save the generated code to the output directory - // let generated_file = - // Self::save_generated_code(output_dir, relative_path, generated_code)?; - // log.success(&format!("Generated file {:?}", generated_file)); - // } - - Ok(()) - } - - /// Process a metric group (multivariate). - fn process_metric_group( - &self, - log: impl Logger + Clone, - tmpl_file: &str, - schema_path: &Path, - metric: &MetricGroup, - output_dir: &Path, - ) -> Result<(), Error> { - // let context = &Context::from_serialize(metric).map_err(|e| InvalidTelemetrySchema { - // schema: schema_path.to_path_buf(), - // error: format!("{}", e), - // })?; - // - // // Reset the config - // self.config.reset(); - // - // log.loading(&format!( - // "Generating code for multivariate metric `{}`", - // metric.name - // )); - // let generated_code = self.generate_code(log.clone(), tmpl_file, context)?; - // - // // Retrieve the file name from the config - // let relative_path = { - // match self.config.get() { - // None => { - // return Err(TemplateFileNameUndefined { - // template: PathBuf::from(tmpl_file), - // }); - // } - // Some(file_name) => PathBuf::from(file_name.clone()), - // } - // }; - // - // // Save the generated code to the output directory - // let generated_file = Self::save_generated_code(output_dir, relative_path, generated_code)?; - // log.success(&format!("Generated file {:?}", generated_file)); - - Ok(()) - } - - /// Process an event. - fn process_event( - &self, - log: impl Logger + Clone, - tmpl_file: &str, - schema_path: &Path, - event: &Event, - output_dir: &Path, - ) -> Result<(), Error> { - // let context = &Context::from_serialize(event).map_err(|e| InvalidTelemetrySchema { - // schema: schema_path.to_path_buf(), - // error: format!("{}", e), - // })?; - // - // // Reset the config - // self.config.reset(); - // - // log.loading(&format!("Generating code for log `{}`", event.event_name)); - // let generated_code = self.generate_code(log.clone(), tmpl_file, context)?; - // - // // Retrieve the file name from the config - // let relative_path = { - // match self.config.get() { - // None => { - // return Err(TemplateFileNameUndefined { - // template: PathBuf::from(tmpl_file), - // }); - // } - // Some(file_name) => PathBuf::from(file_name.clone()), - // } - // }; - // - // // Save the generated code to the output directory - // let generated_file = Self::save_generated_code(output_dir, relative_path, generated_code)?; - // log.success(&format!("Generated file {:?}", generated_file)); - - Ok(()) - } - - /// Process a span. - fn process_span( - &self, - log: impl Logger + Clone, - tmpl_file: &str, - schema_path: &Path, - span: &Span, - output_dir: &Path, - ) -> Result<(), Error> { - // let context = &Context::from_serialize(span).map_err(|e| InvalidTelemetrySchema { - // schema: schema_path.to_path_buf(), - // error: format!("{}", e), - // })?; - // - // // Reset the config - // self.config.reset(); - // - // log.loading(&format!("Generating code for span `{}`", span.span_name)); - // let generated_code = self.generate_code(log.clone(), tmpl_file, context)?; - // - // // Retrieve the file name from the config - // let relative_path = { - // match self.config.get() { - // None => { - // return Err(TemplateFileNameUndefined { - // template: PathBuf::from(tmpl_file), - // }); - // } - // Some(file_name) => PathBuf::from(file_name.clone()), - // } - // }; - // - // // Save the generated code to the output directory - // let generated_file = Self::save_generated_code(output_dir, relative_path, generated_code)?; - // log.success(&format!("Generated file {:?}", generated_file)); - - Ok(()) - } } #[cfg(test)] From bd859c17b03269a2d6d770ae817bbe715cfa8b8f Mon Sep 17 00:00:00 2001 From: Laurent Querel Date: Tue, 5 Mar 2024 18:04:43 -0800 Subject: [PATCH 07/20] feature(template): add template syntax configuration --- Cargo.lock | 1 + crates/weaver_forge/Cargo.toml | 2 +- crates/weaver_forge/src/config.rs | 82 +++++++++++++++++++++ crates/weaver_forge/src/lib.rs | 7 +- crates/weaver_forge/templates/test/group.md | 21 ++++-- 5 files changed, 103 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 69b2404b..d03f5984 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2019,6 +2019,7 @@ version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6fe0ff215195a22884d867b547c70a0c4815cbbcc70991f281dca604b20d10ce" dependencies = [ + "aho-corasick", "memo-map", "self_cell", "serde", diff --git a/crates/weaver_forge/Cargo.toml b/crates/weaver_forge/Cargo.toml index 45d3a300..388c8f99 100644 --- a/crates/weaver_forge/Cargo.toml +++ b/crates/weaver_forge/Cargo.toml @@ -15,7 +15,7 @@ weaver_schema = { path = "../weaver_schema" } weaver_resolved_schema = { path = "../weaver_resolved_schema" } weaver_semconv = { path = "../weaver_semconv" } -minijinja = { version = "1.0.12", features = ["loader"] } +minijinja = { version = "1.0.12", features = ["loader", "custom_syntax"] } thread_local = "1.1.7" convert_case = "0.6.0" glob = "0.3.1" diff --git a/crates/weaver_forge/src/config.rs b/crates/weaver_forge/src/config.rs index 3aec64bc..ea2aef38 100644 --- a/crates/weaver_forge/src/config.rs +++ b/crates/weaver_forge/src/config.rs @@ -54,6 +54,88 @@ pub struct TargetConfig { /// Type mapping for target specific types (OTel types -> Target language types). #[serde(default)] pub type_mapping: HashMap, + /// Configuration for the template syntax. + #[serde(default)] + pub template_syntax: TemplateSyntax, +} + +/// Syntax configuration for the template engine. +#[derive(Deserialize, Debug, Clone)] +pub struct TemplateSyntax { + /// The start of a block. + #[serde(default = "default_block_start")] + pub block_start: String, + /// The end of a block. + #[serde(default = "default_block_end")] + pub block_end: String, + /// The start of a variable. + #[serde(default = "default_variable_start")] + pub variable_start: String, + /// The end of a variable. + #[serde(default = "default_variable_end")] + pub variable_end: String, + /// The start of a comment. + #[serde(default = "default_comment_start")] + pub comment_start: String, + /// The end of a comment. + #[serde(default = "default_comment_end")] + pub comment_end: String, +} + +/// Default block start delimiter. +fn default_block_start() -> String { + "{%".to_string() +} + +/// Default block end delimiter. +fn default_block_end() -> String { + "%}".to_string() +} + +/// Default variable start delimiter. +fn default_variable_start() -> String { + "{{".to_string() +} + +/// Default variable end delimiter. +fn default_variable_end() -> String { + "}}".to_string() +} + +/// Default comment start delimiter. +fn default_comment_start() -> String { + "{#".to_string() +} + +/// Default comment end delimiter. +fn default_comment_end() -> String { + "#}".to_string() +} + +impl From for minijinja::Syntax { + fn from(syntax: TemplateSyntax) -> Self { + minijinja::Syntax { + block_start: syntax.block_start.into(), + block_end: syntax.block_end.into(), + variable_start: syntax.variable_start.into(), + variable_end: syntax.variable_end.into(), + comment_start: syntax.comment_start.into(), + comment_end: syntax.comment_end.into(), + } + } +} + +impl Default for TemplateSyntax { + fn default() -> Self { + TemplateSyntax { + block_start: default_block_start(), + block_end: default_block_end(), + variable_start: default_variable_start(), + variable_end: default_variable_end(), + comment_start: default_comment_start(), + comment_end: default_comment_end(), + } + } } impl Default for CaseConvention { diff --git a/crates/weaver_forge/src/lib.rs b/crates/weaver_forge/src/lib.rs index 86710b27..df707096 100644 --- a/crates/weaver_forge/src/lib.rs +++ b/crates/weaver_forge/src/lib.rs @@ -271,7 +271,7 @@ impl TemplateEngine { let template_object = TemplateObject { file_name: Arc::new(Mutex::new(template_path.to_str().unwrap_or_default().to_string())), }; - let mut engine = self.template_engine(); + let mut engine = self.template_engine()?; let template_file = template_path.to_str().ok_or(InvalidTemplateFile { template: template_path.clone(), error: "".to_string(), @@ -289,9 +289,10 @@ impl TemplateEngine { } /// Create a new template engine based on the target configuration. - fn template_engine(&self) -> Environment { + fn template_engine(&self) -> Result { let mut env = Environment::new(); env.set_loader(path_loader(&self.path)); + env.set_syntax(self.target_config.template_syntax.clone().into()).map_err(|e| InternalError(e.to_string()))?; // Register case conversion filters based on the target configuration env.add_filter("file_name", case_converter(self.target_config.file_name.clone())); @@ -320,7 +321,7 @@ impl TemplateEngine { // Register custom testers // tera.register_tester("required", testers::is_required); // tera.register_tester("not_required", testers::is_not_required); - env + Ok(env) } /// Lists all {template, object} pairs derived from a template directory and a given diff --git a/crates/weaver_forge/templates/test/group.md b/crates/weaver_forge/templates/test/group.md index 116a83cd..6b359de1 100644 --- a/crates/weaver_forge/templates/test/group.md +++ b/crates/weaver_forge/templates/test/group.md @@ -1,10 +1,19 @@ {%- set file_name = id | file_name -%} {{- template.set_file_name("group/" ~ file_name ~ ".md") -}} -# Group `{{ id }}` +# {{ typed_group.type }} `{{ id }}` -file name: {{ id | file_name }} -function name: {{ id | function_name }} -arg_name: {{ id | arg_name }} -struct_name: {{ id | struct_name }} -field_name: {{ id | field_name }} +## Brief +{{ brief }} + +## Provenance + +{{- debug() -}} + +{{ lineage.attributes }} + +/* +{%- for key, value in lineage.attributes -%} +{{- key -}} +{%- endfor -%} +*/ From 9a12db23c9844c9b4117fc8d163faee42abde4d2 Mon Sep 17 00:00:00 2001 From: Laurent Querel Date: Wed, 6 Mar 2024 10:15:30 -0800 Subject: [PATCH 08/20] feature(template): generate markdown files describing a registry --- .../weaver_forge/src/extensions/attributes.rs | 9 ++ crates/weaver_forge/src/extensions/mod.rs | 3 +- crates/weaver_forge/src/lib.rs | 86 +++++++---- crates/weaver_forge/src/registry.rs | 133 ++++++++++++++++++ crates/weaver_forge/templates/test/group.md | 33 +++-- .../weaver_resolved_schema/src/attribute.rs | 7 + crates/weaver_resolved_schema/src/catalog.rs | 5 + 7 files changed, 241 insertions(+), 35 deletions(-) create mode 100644 crates/weaver_forge/src/extensions/attributes.rs create mode 100644 crates/weaver_forge/src/registry.rs diff --git a/crates/weaver_forge/src/extensions/attributes.rs b/crates/weaver_forge/src/extensions/attributes.rs new file mode 100644 index 00000000..899c3edf --- /dev/null +++ b/crates/weaver_forge/src/extensions/attributes.rs @@ -0,0 +1,9 @@ +// SPDX-License-Identifier: Apache-2.0 + +//! + +use minijinja::{Error, State, Value}; + +pub fn attributes(_state: &State, v: Value) -> Result { + Ok(v) +} \ No newline at end of file diff --git a/crates/weaver_forge/src/extensions/mod.rs b/crates/weaver_forge/src/extensions/mod.rs index 0e272b59..7907bc94 100644 --- a/crates/weaver_forge/src/extensions/mod.rs +++ b/crates/weaver_forge/src/extensions/mod.rs @@ -1,4 +1,5 @@ // SPDX-License-Identifier: Apache-2.0 //! Custom filters used by the template engine. -pub mod case_converter; \ No newline at end of file +pub mod case_converter; +pub mod attributes; \ No newline at end of file diff --git a/crates/weaver_forge/src/lib.rs b/crates/weaver_forge/src/lib.rs index df707096..fb514415 100644 --- a/crates/weaver_forge/src/lib.rs +++ b/crates/weaver_forge/src/lib.rs @@ -24,16 +24,22 @@ use minijinja::{Environment, path_loader, State, Value}; use minijinja::value::{from_args, Object}; use rayon::iter::IntoParallelIterator; use rayon::iter::ParallelIterator; +use serde::Serialize; use weaver_logger::Logger; -use weaver_resolved_schema::registry::{Group, Registry, TypedGroup}; +use weaver_resolved_schema::attribute::AttributeRef; +use weaver_resolved_schema::catalog::Catalog; +use weaver_resolved_schema::registry::{Registry, TypedGroup}; use crate::config::TargetConfig; use crate::Error::{InternalError, InvalidTemplateDir, InvalidTemplateDirectory, InvalidTemplateFile, TargetNotSupported, WriteGeneratedCodeFailed}; +use crate::extensions::attributes::attributes; use crate::extensions::case_converter::case_converter; +use crate::registry::{TemplateGroup, TemplateRegistry}; mod config; mod extensions; +mod registry; /// Errors emitted by this crate. #[derive(thiserror::Error, Debug)] @@ -105,6 +111,15 @@ pub enum Error { error: String, }, + /// Attribute reference not found in the catalog. + #[error("Attribute reference {attr_ref} (group: {group_id}) not found in the catalog")] + AttributeNotFound { + /// Group id. + group_id: String, + /// Attribute reference. + attr_ref: AttributeRef, + }, + /// A generic container for multiple errors. #[error("Errors:\n{0:#?}")] CompoundError(Vec), @@ -130,15 +145,15 @@ impl Default for GeneratorConfig { enum TemplateObjectPair<'a> { Group { template_path: PathBuf, - group: &'a Group, + group: &'a TemplateGroup, }, Groups { template_path: PathBuf, - groups: Vec<&'a Group>, + groups: Vec<&'a TemplateGroup>, }, Registry { template_path: PathBuf, - registry: &'a Registry, + registry: &'a TemplateRegistry, }, } @@ -186,6 +201,13 @@ pub struct TemplateEngine { target_config: TargetConfig, } +#[derive(Serialize, Debug)] +pub struct Context<'a> { + pub registry: &'a TemplateRegistry, + pub group: Option<&'a TemplateGroup>, + pub groups: Option>, +} + impl TemplateEngine { /// Create a new template engine for the given target or return an error if /// the target does not exist or is not a directory. @@ -215,6 +237,7 @@ impl TemplateEngine { &self, log: impl Logger + Clone + Sync, registry: &Registry, + catalog: &Catalog, output_dir: PathBuf, ) -> Result<(), Error> { // Process recursively all files in the template directory @@ -226,9 +249,12 @@ impl TemplateEngine { glob(lang_path.as_str()).map_err(|e| InternalError(e.to_string()))? }; + let template_registry = TemplateRegistry::try_from_resolved_registry(registry, catalog) + .map_err(|e| InternalError(e.to_string()))?; + // List all {template, object} pairs to run in parallel the template // engine as all pairs are independent. - self.list_registry_templates(®istry, paths)? + self.list_registry_templates(&template_registry, paths)? .into_par_iter() .try_for_each(|pair| { match pair { @@ -236,7 +262,11 @@ impl TemplateEngine { template_path: relative_template_path, group } => { - let ctx: serde_json::Value = serde_json::to_value(group) + let ctx: serde_json::Value = serde_json::to_value(Context { + registry: &template_registry, + group: Some(group), + groups: None, + }) .map_err(|e| InternalError(e.to_string()))?; self.evaluate_template(log.clone(), ctx, relative_template_path, &output_dir) } @@ -244,7 +274,11 @@ impl TemplateEngine { template_path: relative_template_path, groups } => { - let ctx: serde_json::Value = serde_json::to_value(groups) + let ctx: serde_json::Value = serde_json::to_value(Context { + registry: &template_registry, + group: None, + groups: Some(groups), + }) .map_err(|e| InternalError(e.to_string()))?; self.evaluate_template(log.clone(), ctx, relative_template_path, &output_dir) } @@ -252,7 +286,11 @@ impl TemplateEngine { template_path: relative_template_path, registry, } => { - let ctx: serde_json::Value = serde_json::to_value(registry) + let ctx: serde_json::Value = serde_json::to_value(Context { + registry: ®istry, + group: None, + groups: None, + }) .map_err(|e| InternalError(e.to_string()))?; self.evaluate_template(log.clone(), ctx, relative_template_path, &output_dir) } @@ -301,6 +339,8 @@ impl TemplateEngine { env.add_filter("struct_name", case_converter(self.target_config.struct_name.clone())); env.add_filter("field_name", case_converter(self.target_config.field_name.clone())); + env.add_filter("attributes", attributes); + // env.add_filter("unique_attributes", extensions::unique_attributes); // env.add_filter("instrument", extensions::instrument); // env.add_filter("required", extensions::required); @@ -328,7 +368,7 @@ impl TemplateEngine { /// semantic convention registry. fn list_registry_templates<'a>( &self, - registry: &'a Registry, + registry: &'a TemplateRegistry, paths: Paths, ) -> Result>, Error> { let mut templates = Vec::new(); @@ -446,7 +486,7 @@ impl TemplateEngine { Some("attribute_groups") => { let groups = registry.groups.iter() .filter(|group| if let TypedGroup::AttributeGroup { .. } = group.typed_group { true } else { false }) - .collect::>(); + .collect::>(); templates.push(TemplateObjectPair::Groups { template_path: relative_path.to_path_buf(), groups, @@ -455,7 +495,7 @@ impl TemplateEngine { Some("events") => { let groups = registry.groups.iter() .filter(|group| if let TypedGroup::Event { .. } = group.typed_group { true } else { false }) - .collect::>(); + .collect::>(); templates.push(TemplateObjectPair::Groups { template_path: relative_path.to_path_buf(), groups, @@ -463,7 +503,7 @@ impl TemplateEngine { } Some("groups") => { let groups = registry.groups.iter() - .collect::>(); + .collect::>(); templates.push(TemplateObjectPair::Groups { template_path: relative_path.to_path_buf(), groups, @@ -472,7 +512,7 @@ impl TemplateEngine { Some("metrics") => { let groups = registry.groups.iter() .filter(|group| if let TypedGroup::Metric { .. } = group.typed_group { true } else { false }) - .collect::>(); + .collect::>(); templates.push(TemplateObjectPair::Groups { template_path: relative_path.to_path_buf(), groups, @@ -481,7 +521,7 @@ impl TemplateEngine { Some("metric_groups") => { let groups = registry.groups.iter() .filter(|group| if let TypedGroup::MetricGroup { .. } = group.typed_group { true } else { false }) - .collect::>(); + .collect::>(); templates.push(TemplateObjectPair::Groups { template_path: relative_path.to_path_buf(), groups, @@ -490,7 +530,7 @@ impl TemplateEngine { Some("resources") => { let groups = registry.groups.iter() .filter(|group| if let TypedGroup::Resource { .. } = group.typed_group { true } else { false }) - .collect::>(); + .collect::>(); templates.push(TemplateObjectPair::Groups { template_path: relative_path.to_path_buf(), groups, @@ -499,7 +539,7 @@ impl TemplateEngine { Some("scopes") => { let groups = registry.groups.iter() .filter(|group| if let TypedGroup::Scope { .. } = group.typed_group { true } else { false }) - .collect::>(); + .collect::>(); templates.push(TemplateObjectPair::Groups { template_path: relative_path.to_path_buf(), groups, @@ -508,7 +548,7 @@ impl TemplateEngine { Some("spans") => { let groups = registry.groups.iter() .filter(|group| if let TypedGroup::Span { .. } = group.typed_group { true } else { false }) - .collect::>(); + .collect::>(); templates.push(TemplateObjectPair::Groups { template_path: relative_path.to_path_buf(), groups, @@ -561,8 +601,7 @@ impl TemplateEngine { #[cfg(test)] mod tests { use weaver_logger::TestLogger; - use weaver_resolver::attribute::AttributeCatalog; - use weaver_resolver::registry::resolve_semconv_registry; + use weaver_resolver::SchemaResolver; use weaver_semconv::SemConvRegistry; #[test] @@ -573,15 +612,14 @@ mod tests { super::GeneratorConfig::default(), ).expect("Failed to create template engine"); - let registry = SemConvRegistry::try_from_path("data/*.yaml").expect("Failed to load registry"); - let mut attr_catalog = AttributeCatalog::default(); - let resolved_registry = - resolve_semconv_registry(&mut attr_catalog, "https://127.0.0.1", ®istry) + let mut registry = SemConvRegistry::try_from_path("data/*.yaml").expect("Failed to load registry"); + let schema = SchemaResolver::resolve_semantic_convention_registry(&mut registry, logger.clone()) .expect("Failed to resolve registry"); engine.generate_registry( logger, - &resolved_registry, + &schema.registries[0], + &schema.catalog, "output".into(), ).expect("Failed to generate registry assets"); diff --git a/crates/weaver_forge/src/registry.rs b/crates/weaver_forge/src/registry.rs new file mode 100644 index 00000000..f6eaa55d --- /dev/null +++ b/crates/weaver_forge/src/registry.rs @@ -0,0 +1,133 @@ +// SPDX-License-Identifier: Apache-2.0 + +//! Registry used during the evaluation of the templates. References to the +//! catalog are resolved to the actual catalog entries to ease the template +//! evaluation. + +use serde::{Deserialize, Serialize}; +use weaver_resolved_schema::attribute::Attribute; +use weaver_resolved_schema::catalog::{Catalog, Stability}; +use weaver_resolved_schema::lineage::GroupLineage; +use weaver_resolved_schema::registry::{Constraint, Registry, TypedGroup}; +use crate::Error; + +/// A semantic convention registry used in the context of the template engine. +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] +#[serde(deny_unknown_fields)] +pub struct TemplateRegistry { + /// The semantic convention registry url. + #[serde(skip_serializing_if = "String::is_empty")] + pub registry_url: String, + /// A list of semantic convention groups. + pub groups: Vec, +} + +/// Group specification used in the context of the template engine. +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] +pub struct TemplateGroup { + /// The id that uniquely identifies the semantic convention. + pub id: String, + /// The type of the group including the specific fields for each type. + pub typed_group: TypedGroup, + /// A brief description of the semantic convention. + #[serde(skip_serializing_if = "String::is_empty")] + pub brief: String, + /// A more elaborate description of the semantic convention. + /// It defaults to an empty string. + #[serde(default)] + #[serde(skip_serializing_if = "String::is_empty")] + pub note: String, + /// Prefix for the attributes for this semantic convention. + /// It defaults to an empty string. + #[serde(default)] + #[serde(skip_serializing_if = "String::is_empty")] + pub prefix: String, + /// Reference another semantic convention id. It inherits the prefix, + /// constraints, and all attributes defined in the specified semantic + /// convention. + #[serde(skip_serializing_if = "Option::is_none")] + pub extends: Option, + /// Specifies the stability of the semantic convention. + /// Note that, if stability is missing but deprecated is present, it will + /// automatically set the stability to deprecated. If deprecated is + /// present and stability differs from deprecated, this will result in an + /// error. + #[serde(skip_serializing_if = "Option::is_none")] + pub stability: Option, + /// Specifies if the semantic convention is deprecated. The string + /// provided as MUST specify why it's deprecated and/or what + /// to use instead. See also stability. + #[serde(skip_serializing_if = "Option::is_none")] + pub deprecated: Option, + /// Additional constraints. + /// Allow to define additional requirements on the semantic convention. + /// It defaults to an empty list. + #[serde(default)] + #[serde(skip_serializing_if = "Vec::is_empty")] + pub constraints: Vec, + /// List of attributes that belong to the semantic convention. + #[serde(default)] + pub attributes: Vec, + /// The lineage of the group. + #[serde(skip_serializing_if = "Option::is_none")] + pub lineage: Option, +} + +impl TemplateRegistry { + /// Create a new template registry from a resolved registry. + pub fn try_from_resolved_registry( + registry: &Registry, + catalog: &Catalog, + ) -> Result { + let mut errors = Vec::new(); + + let groups = registry + .groups + .iter() + .map(|group| { + let id = group.id.clone(); + let typed_group = group.typed_group.clone(); + let brief = group.brief.clone(); + let note = group.note.clone(); + let prefix = group.prefix.clone(); + let extends = group.extends.clone(); + let stability = group.stability.clone(); + let deprecated = group.deprecated.clone(); + let constraints = group.constraints.clone(); + let attributes = group.attributes.iter().flat_map(|attr_ref| { + let attr = catalog.attribute(attr_ref).map(|a| a.clone()); + if attr.is_none() { + errors.push(Error::AttributeNotFound { + group_id: id.clone(), + attr_ref: *attr_ref, + }); + } + attr + }).collect(); + let lineage = group.lineage.clone(); + TemplateGroup { + id, + typed_group, + brief, + note, + prefix, + extends, + stability, + deprecated, + constraints, + attributes, + lineage, + } + }) + .collect(); + + if !errors.is_empty() { + return Err(Error::CompoundError(errors)) + } + + Ok(Self { + registry_url: registry.registry_url.clone(), + groups, + }) + } +} \ No newline at end of file diff --git a/crates/weaver_forge/templates/test/group.md b/crates/weaver_forge/templates/test/group.md index 6b359de1..8fc37222 100644 --- a/crates/weaver_forge/templates/test/group.md +++ b/crates/weaver_forge/templates/test/group.md @@ -1,19 +1,32 @@ -{%- set file_name = id | file_name -%} +{%- set file_name = group.id | file_name -%} {{- template.set_file_name("group/" ~ file_name ~ ".md") -}} -# {{ typed_group.type }} `{{ id }}` + +# {{ group.typed_group.type }} `{{ group.id }}` ## Brief -{{ brief }} +{{ group.brief }} + +## Attributes + +{%- for attribute in group.attributes %} +### Attribute `{{ attribute.name }}` + +{% if attribute.tag -%} +tag: {{ attribute.tag }} +{%- endif %} + +{{ attribute.brief }} + +{%- endfor %} ## Provenance -{{- debug() -}} +Source: {{ group.lineage.provenance }} + +{{ debug() }} -{{ lineage.attributes }} +{%- for item in group.lineage.attributes -%} +item: {{ group.lineage.attributes[item] }} +{% endfor -%} -/* -{%- for key, value in lineage.attributes -%} -{{- key -}} -{%- endfor -%} -*/ diff --git a/crates/weaver_resolved_schema/src/attribute.rs b/crates/weaver_resolved_schema/src/attribute.rs index fc5a684b..89794eb7 100644 --- a/crates/weaver_resolved_schema/src/attribute.rs +++ b/crates/weaver_resolved_schema/src/attribute.rs @@ -4,6 +4,7 @@ //! Specification of a resolved attribute. +use std::fmt::Display; use crate::catalog::Stability; use crate::tags::Tags; use crate::value::Value; @@ -240,3 +241,9 @@ pub enum RequirementLevel { /// An internal reference to an attribute in the catalog. #[derive(Serialize, Deserialize, Debug, Copy, Clone, Eq, PartialEq, PartialOrd, Ord)] pub struct AttributeRef(pub u32); + +impl Display for AttributeRef { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "AttributeRef({})", self.0) + } +} diff --git a/crates/weaver_resolved_schema/src/catalog.rs b/crates/weaver_resolved_schema/src/catalog.rs index 8e190ff9..93739266 100644 --- a/crates/weaver_resolved_schema/src/catalog.rs +++ b/crates/weaver_resolved_schema/src/catalog.rs @@ -40,4 +40,9 @@ impl Catalog { .get(attribute_ref.0 as usize) .map(|attr| attr.name.as_ref()) } + + /// Returns the attribute from an attribute ref if it exists. + pub fn attribute(&self, attribute_ref: &AttributeRef) -> Option<&Attribute> { + self.attributes.get(attribute_ref.0 as usize) + } } From 89b26ca52cf28d58c4f9c4497dc2e875a800e47f Mon Sep 17 00:00:00 2001 From: Laurent Querel Date: Wed, 6 Mar 2024 11:34:01 -0800 Subject: [PATCH 09/20] feature(template): generate markdown files describing a registry --- Cargo.lock | 240 ++++++------- crates/weaver_forge/Cargo.toml | 3 - .../weaver_forge/allowed-external-types.toml | 4 + crates/weaver_forge/src/config.rs | 2 +- .../weaver_forge/src/extensions/attributes.rs | 2 +- .../src/extensions/case_converter.rs | 4 +- crates/weaver_forge/src/extensions/mod.rs | 2 +- crates/weaver_forge/src/lib.rs | 332 +++++++++++------- crates/weaver_forge/src/registry.rs | 30 +- .../weaver_resolved_schema/src/attribute.rs | 2 +- crates/weaver_resolver/src/attribute.rs | 4 +- crates/weaver_schema/src/attribute.rs | 4 +- crates/weaver_semconv/data/exporter.yaml | 32 ++ crates/weaver_semconv/src/attribute.rs | 4 +- crates/weaver_semconv/src/group.rs | 15 +- crates/weaver_semconv/src/lib.rs | 3 +- docs/images/dependencies.svg | 254 ++++++++------ src/search/semconv/attribute.rs | 16 +- 18 files changed, 552 insertions(+), 401 deletions(-) create mode 100644 crates/weaver_semconv/data/exporter.yaml diff --git a/Cargo.lock b/Cargo.lock index d03f5984..2377f9cb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -19,9 +19,9 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "ahash" -version = "0.8.10" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b79b82693f705137f8fb9b37871d99e4f9a7df12b917eed79c3d3954830a60b" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" dependencies = [ "cfg-if", "once_cell", @@ -109,9 +109,9 @@ dependencies = [ [[package]] name = "arc-swap" -version = "1.6.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bddcadddf5e9015d310179a59bb28c4d4b9920ad0f11e8e14dbadf654890c9a6" +checksum = "7b3d0060af21e8d11a926981cc00c6c1541aa91dd64b9f881985c3da1094425f" [[package]] name = "arrayvec" @@ -127,7 +127,7 @@ checksum = "c980ee35e870bd1a4d2c8294d4c04d0499e67bca1e4b5cefcc693c2fa00caea9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.51", + "syn 2.0.52", ] [[package]] @@ -194,7 +194,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "05efc5cfd9110c8416e471df0e96702d58690178e206e61b7173706673c93706" dependencies = [ "memchr", - "regex-automata 0.4.5", + "regex-automata 0.4.6", "serde", ] @@ -248,10 +248,11 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.88" +version = "1.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02f341c093d19155a6e41631ce5971aac4e9a868262212153124c15fa22d1cdc" +checksum = "a0ba8f7aaa012f30d5b2861462f6708eccd49c3c39863fe083a308035f63d723" dependencies = [ + "jobserver", "libc", ] @@ -269,14 +270,14 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.34" +version = "0.4.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bc015644b92d5890fab7489e49d21f879d5c990186827d42ec511919404f38b" +checksum = "8eaf5903dcbc0a39312feb77df2ff4c76387d591b9fc7b04a238dcf8bb62639a" dependencies = [ "android-tzdata", "iana-time-zone", "num-traits", - "windows-targets 0.52.3", + "windows-targets 0.52.4", ] [[package]] @@ -303,9 +304,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.1" +version = "4.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c918d541ef2913577a0f9566e9ce27cb35b6df072075769e0b26cb5a554520da" +checksum = "b230ab84b0ffdf890d5a10abdbc8b83ae1c4918275daea1ab8801f71536b2651" dependencies = [ "clap_builder", "clap_derive", @@ -313,9 +314,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.1" +version = "4.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f3e7391dad68afb0c2ede1bf619f579a3dc9c2ec67f089baa397123a2f3d1eb" +checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4" dependencies = [ "anstream", "anstyle", @@ -332,7 +333,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.51", + "syn 2.0.52", ] [[package]] @@ -720,12 +721,11 @@ dependencies = [ [[package]] name = "generator" -version = "0.7.6" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5b25e5b3e733153bcab35ee4671b46604b42516163cae442d1601cb716f2ac5" +checksum = "5cc16584ff22b460a382b7feec54b23d2908d858152e5739a120b949293bd74e" dependencies = [ "cc", - "cfg-if", "libc", "log", "rustversion", @@ -1125,7 +1125,7 @@ checksum = "d75e7ab728059f595f6ddc1ad8771b8d6a231971ae493d9d5948ecad366ee8bb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.51", + "syn 2.0.52", ] [[package]] @@ -1284,7 +1284,7 @@ dependencies = [ "gix-utils", "maybe-async", "thiserror", - "winnow 0.6.3", + "winnow 0.6.5", ] [[package]] @@ -1533,7 +1533,7 @@ dependencies = [ "aho-corasick", "bstr", "log", - "regex-automata 0.4.5", + "regex-automata 0.4.6", "regex-syntax 0.8.2", ] @@ -1585,9 +1585,9 @@ checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" [[package]] name = "hermit-abi" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "379dada1584ad501b383485dd706b8afb7a70fcbc7f4da7d780638a5a6124a60" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" [[package]] name = "home" @@ -1606,9 +1606,9 @@ checksum = "e9025058dae765dee5070ec375f591e2ba14638c63feff74f13805a72e523163" [[package]] name = "http" -version = "0.2.11" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8947b1a6fad4393052c7ba1f4cd97bed3e953a95c79c92ad9b051a04611d9fbb" +checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" dependencies = [ "bytes", "fnv", @@ -1702,7 +1702,7 @@ dependencies = [ "iana-time-zone-haiku", "js-sys", "wasm-bindgen", - "windows-core 0.52.0", + "windows-core", ] [[package]] @@ -1750,7 +1750,7 @@ dependencies = [ "globset", "log", "memchr", - "regex-automata 0.4.5", + "regex-automata 0.4.6", "same-file", "walkdir", "winapi-util", @@ -1758,9 +1758,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.2.3" +version = "2.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "233cf39063f058ea2caae4091bf4a3ef70a653afbc026f5c4a4135d114e3c177" +checksum = "7b0b929d511467233429c45a44ac1dcaa21ba0f5ba11e4879e6ed28ddb4f9df4" dependencies = [ "equivalent", "hashbrown", @@ -1824,11 +1824,20 @@ version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" +[[package]] +name = "jobserver" +version = "0.1.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab46a6e9526ddef3ae7f787c06f0f2600639ba80ea3eade3d8e670a2230f51d6" +dependencies = [ + "libc", +] + [[package]] name = "js-sys" -version = "0.3.68" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "406cda4b368d531c842222cf9d2600a9a4acce8d29423695379c6868a143a9ee" +checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" dependencies = [ "wasm-bindgen", ] @@ -1905,9 +1914,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.20" +version = "0.4.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" +checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" [[package]] name = "loom" @@ -1964,7 +1973,7 @@ checksum = "5cf92c10c7e361d6b99666ec1c6f9805b0bea2c3bd8c78dc6fe98ac5bd78db11" dependencies = [ "proc-macro2", "quote", - "syn 2.0.51", + "syn 2.0.52", ] [[package]] @@ -2042,9 +2051,9 @@ dependencies = [ [[package]] name = "mio" -version = "0.8.10" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09" +checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" dependencies = [ "libc", "log", @@ -2220,9 +2229,9 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pest" -version = "2.7.7" +version = "2.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "219c0dcc30b6a27553f9cc242972b67f75b60eb0db71f0b5462f38b058c41546" +checksum = "56f8023d0fb78c8e03784ea1c7f3fa36e68a723138990b8d5a47d916b651e7a8" dependencies = [ "memchr", "thiserror", @@ -2231,9 +2240,9 @@ dependencies = [ [[package]] name = "pest_derive" -version = "2.7.7" +version = "2.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22e1288dbd7786462961e69bfd4df7848c1e37e8b74303dbdab82c3a9cdd2809" +checksum = "b0d24f72393fd16ab6ac5738bc33cdb6a9aa73f8b902e8fe29cf4e67d7dd1026" dependencies = [ "pest", "pest_generator", @@ -2241,22 +2250,22 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.7.7" +version = "2.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1381c29a877c6d34b8c176e734f35d7f7f5b3adaefe940cb4d1bb7af94678e2e" +checksum = "fdc17e2a6c7d0a492f0158d7a4bd66cc17280308bbaff78d5bef566dca35ab80" dependencies = [ "pest", "pest_meta", "proc-macro2", "quote", - "syn 2.0.51", + "syn 2.0.52", ] [[package]] name = "pest_meta" -version = "2.7.7" +version = "2.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0934d6907f148c22a3acbda520c7eed243ad7487a30f51f6ce52b58b7077a8a" +checksum = "934cd7631c050f4674352a6e835d5f6711ffbfb9345c2fc0107155ac495ae293" dependencies = [ "once_cell", "pest", @@ -2520,7 +2529,7 @@ checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.4.5", + "regex-automata 0.4.6", "regex-syntax 0.8.2", ] @@ -2535,9 +2544,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bb987efffd3c6d0d8f5f89510bb458559eab11e4f869acb20bf845e016259cd" +checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" dependencies = [ "aho-corasick", "memchr", @@ -2793,7 +2802,7 @@ checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.51", + "syn 2.0.52", ] [[package]] @@ -3003,7 +3012,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.51", + "syn 2.0.52", ] [[package]] @@ -3025,9 +3034,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.51" +version = "2.0.52" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ab617d94515e94ae53b8406c628598680aa0c9587474ecbe58188f7b345d66c" +checksum = "b699d15b36d1f02c3e7c69f8ffef53de37aefae075d8488d4ba1a7788d574a07" dependencies = [ "proc-macro2", "quote", @@ -3273,7 +3282,7 @@ checksum = "a953cb265bef375dae3de6663da4d3804eee9682ea80d8e2542529b73c531c81" dependencies = [ "proc-macro2", "quote", - "syn 2.0.51", + "syn 2.0.52", ] [[package]] @@ -3399,7 +3408,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.51", + "syn 2.0.52", ] [[package]] @@ -3693,9 +3702,9 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" [[package]] name = "walkdir" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" dependencies = [ "same-file", "winapi-util", @@ -3718,9 +3727,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.91" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1e124130aee3fb58c5bdd6b639a0509486b0338acaaae0c84a5124b0f588b7f" +checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -3728,24 +3737,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.91" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9e7e1900c352b609c8488ad12639a311045f40a35491fb69ba8c12f758af70b" +checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.51", + "syn 2.0.52", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.41" +version = "0.4.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "877b9c3f61ceea0e56331985743b13f3d25c406a7098d45180fb5f09bc19ed97" +checksum = "76bc14366121efc8dbb487ab05bcc9d346b3b5ec0eaa76e46594cabbe51762c0" dependencies = [ "cfg-if", "js-sys", @@ -3755,9 +3764,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.91" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b30af9e2d358182b5c7449424f017eba305ed32a7010509ede96cdc4696c46ed" +checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -3765,22 +3774,22 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.91" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "642f325be6301eb8107a83d12a8ac6c1e1c54345a7ef1a9261962dfefda09e66" +checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.51", + "syn 2.0.52", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.91" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f186bd2dcf04330886ce82d6f33dd75a7bfcf69ecf5763b89fcde53b6ac9838" +checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" [[package]] name = "weaver" @@ -3823,12 +3832,9 @@ dependencies = [ "serde_json", "serde_yaml", "thiserror", - "thread_local", - "weaver_cache", "weaver_logger", "weaver_resolved_schema", "weaver_resolver", - "weaver_schema", "weaver_semconv", ] @@ -3928,9 +3934,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.68" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96565907687f7aceb35bc5fc03770a8a0471d82e479f25832f54a0e3f4b28446" +checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" dependencies = [ "js-sys", "wasm-bindgen", @@ -3984,12 +3990,11 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "windows" -version = "0.53.0" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efc5cf48f83140dcaab716eeaea345f9e93d0018fb81162753a3f76c3397b538" +checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" dependencies = [ - "windows-core 0.53.0", - "windows-targets 0.52.3", + "windows-targets 0.48.5", ] [[package]] @@ -3998,26 +4003,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" dependencies = [ - "windows-targets 0.52.3", -] - -[[package]] -name = "windows-core" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dcc5b895a6377f1ab9fa55acedab1fd5ac0db66ad1e6c7f47e28a22e446a5dd" -dependencies = [ - "windows-result", - "windows-targets 0.52.3", -] - -[[package]] -name = "windows-result" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd19df78e5168dfb0aedc343d1d1b8d422ab2db6756d2dc3fef75035402a3f64" -dependencies = [ - "windows-targets 0.52.3", + "windows-targets 0.52.4", ] [[package]] @@ -4035,7 +4021,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.3", + "windows-targets 0.52.4", ] [[package]] @@ -4055,17 +4041,17 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.3" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d380ba1dc7187569a8a9e91ed34b8ccfc33123bbacb8c0aed2d1ad7f3ef2dc5f" +checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b" dependencies = [ - "windows_aarch64_gnullvm 0.52.3", - "windows_aarch64_msvc 0.52.3", - "windows_i686_gnu 0.52.3", - "windows_i686_msvc 0.52.3", - "windows_x86_64_gnu 0.52.3", - "windows_x86_64_gnullvm 0.52.3", - "windows_x86_64_msvc 0.52.3", + "windows_aarch64_gnullvm 0.52.4", + "windows_aarch64_msvc 0.52.4", + "windows_i686_gnu 0.52.4", + "windows_i686_msvc 0.52.4", + "windows_x86_64_gnu 0.52.4", + "windows_x86_64_gnullvm 0.52.4", + "windows_x86_64_msvc 0.52.4", ] [[package]] @@ -4076,9 +4062,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.3" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68e5dcfb9413f53afd9c8f86e56a7b4d86d9a2fa26090ea2dc9e40fba56c6ec6" +checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9" [[package]] name = "windows_aarch64_msvc" @@ -4088,9 +4074,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" -version = "0.52.3" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8dab469ebbc45798319e69eebf92308e541ce46760b49b18c6b3fe5e8965b30f" +checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675" [[package]] name = "windows_i686_gnu" @@ -4100,9 +4086,9 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" -version = "0.52.3" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a4e9b6a7cac734a8b4138a4e1044eac3404d8326b6c0f939276560687a033fb" +checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3" [[package]] name = "windows_i686_msvc" @@ -4112,9 +4098,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" -version = "0.52.3" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28b0ec9c422ca95ff34a78755cfa6ad4a51371da2a5ace67500cf7ca5f232c58" +checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02" [[package]] name = "windows_x86_64_gnu" @@ -4124,9 +4110,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" -version = "0.52.3" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "704131571ba93e89d7cd43482277d6632589b18ecf4468f591fbae0a8b101614" +checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03" [[package]] name = "windows_x86_64_gnullvm" @@ -4136,9 +4122,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.3" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42079295511643151e98d61c38c0acc444e52dd42ab456f7ccfd5152e8ecf21c" +checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177" [[package]] name = "windows_x86_64_msvc" @@ -4148,9 +4134,9 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" -version = "0.52.3" +version = "0.52.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0770833d60a970638e989b3fa9fd2bb1aaadcf88963d1659fd7d9990196ed2d6" +checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" [[package]] name = "winnow" @@ -4163,9 +4149,9 @@ dependencies = [ [[package]] name = "winnow" -version = "0.6.3" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44e19b97e00a4d3db3cdb9b53c8c5f87151b5689b82cc86c2848cbdcccb2689b" +checksum = "dffa400e67ed5a4dd237983829e66475f0a4a26938c4b04c21baede6262215b8" dependencies = [ "memchr", ] @@ -4197,7 +4183,7 @@ checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.51", + "syn 2.0.52", ] [[package]] diff --git a/crates/weaver_forge/Cargo.toml b/crates/weaver_forge/Cargo.toml index 388c8f99..2374c17d 100644 --- a/crates/weaver_forge/Cargo.toml +++ b/crates/weaver_forge/Cargo.toml @@ -9,14 +9,11 @@ edition.workspace = true [dependencies] weaver_logger = { path = "../weaver_logger" } -weaver_cache = { path = "../weaver_cache" } weaver_resolver = { path = "../weaver_resolver" } -weaver_schema = { path = "../weaver_schema" } weaver_resolved_schema = { path = "../weaver_resolved_schema" } weaver_semconv = { path = "../weaver_semconv" } minijinja = { version = "1.0.12", features = ["loader", "custom_syntax"] } -thread_local = "1.1.7" convert_case = "0.6.0" glob = "0.3.1" diff --git a/crates/weaver_forge/allowed-external-types.toml b/crates/weaver_forge/allowed-external-types.toml index f186b677..658b7951 100644 --- a/crates/weaver_forge/allowed-external-types.toml +++ b/crates/weaver_forge/allowed-external-types.toml @@ -3,4 +3,8 @@ # This is used with cargo-check-external-types to reduce the surface area of downstream crates from # the public API. Ideally this can have a few exceptions as possible. allowed_external_types = [ + "serde::ser::Serialize", + "serde::de::Deserialize", + "weaver_logger::*", + "weaver_resolved_schema::*", ] \ No newline at end of file diff --git a/crates/weaver_forge/src/config.rs b/crates/weaver_forge/src/config.rs index ea2aef38..f21209f2 100644 --- a/crates/weaver_forge/src/config.rs +++ b/crates/weaver_forge/src/config.rs @@ -178,4 +178,4 @@ impl TargetConfig { Ok(TargetConfig::default()) } } -} \ No newline at end of file +} diff --git a/crates/weaver_forge/src/extensions/attributes.rs b/crates/weaver_forge/src/extensions/attributes.rs index 899c3edf..b5e9e70e 100644 --- a/crates/weaver_forge/src/extensions/attributes.rs +++ b/crates/weaver_forge/src/extensions/attributes.rs @@ -6,4 +6,4 @@ use minijinja::{Error, State, Value}; pub fn attributes(_state: &State, v: Value) -> Result { Ok(v) -} \ No newline at end of file +} diff --git a/crates/weaver_forge/src/extensions/case_converter.rs b/crates/weaver_forge/src/extensions/case_converter.rs index ee1e896e..1010c6fe 100644 --- a/crates/weaver_forge/src/extensions/case_converter.rs +++ b/crates/weaver_forge/src/extensions/case_converter.rs @@ -4,7 +4,7 @@ use crate::config::CaseConvention; -pub fn case_converter(case_convention: CaseConvention) -> fn(&str) -> String { +pub fn case_converter(case_convention: CaseConvention) -> fn(&str) -> String { match case_convention { CaseConvention::LowerCase => lower_case, CaseConvention::UpperCase => upper_case, @@ -55,4 +55,4 @@ fn kebab_case(input: &str) -> String { /// Converts input string to screaming kebab case fn screaming_kebab_case(input: &str) -> String { CaseConvention::ScreamingKebabCase.convert(input) -} \ No newline at end of file +} diff --git a/crates/weaver_forge/src/extensions/mod.rs b/crates/weaver_forge/src/extensions/mod.rs index 7907bc94..1c28856e 100644 --- a/crates/weaver_forge/src/extensions/mod.rs +++ b/crates/weaver_forge/src/extensions/mod.rs @@ -1,5 +1,5 @@ // SPDX-License-Identifier: Apache-2.0 //! Custom filters used by the template engine. +pub mod attributes; pub mod case_converter; -pub mod attributes; \ No newline at end of file diff --git a/crates/weaver_forge/src/lib.rs b/crates/weaver_forge/src/lib.rs index fb514415..37413990 100644 --- a/crates/weaver_forge/src/lib.rs +++ b/crates/weaver_forge/src/lib.rs @@ -5,13 +5,13 @@ //! schemas. #![deny( -missing_docs, -clippy::print_stdout, -unstable_features, -unused_import_braces, -unused_qualifications, -unused_results, -unused_extern_crates + missing_docs, + clippy::print_stdout, + unstable_features, + unused_import_braces, + unused_qualifications, + unused_results, + unused_extern_crates )] use std::fmt::{Debug, Display, Formatter}; @@ -20,8 +20,8 @@ use std::path::{Path, PathBuf}; use std::sync::{Arc, Mutex}; use glob::{glob, Paths}; -use minijinja::{Environment, path_loader, State, Value}; use minijinja::value::{from_args, Object}; +use minijinja::{path_loader, Environment, State, Value}; use rayon::iter::IntoParallelIterator; use rayon::iter::ParallelIterator; use serde::Serialize; @@ -32,10 +32,13 @@ use weaver_resolved_schema::catalog::Catalog; use weaver_resolved_schema::registry::{Registry, TypedGroup}; use crate::config::TargetConfig; -use crate::Error::{InternalError, InvalidTemplateDir, InvalidTemplateDirectory, InvalidTemplateFile, TargetNotSupported, WriteGeneratedCodeFailed}; use crate::extensions::attributes::attributes; use crate::extensions::case_converter::case_converter; use crate::registry::{TemplateGroup, TemplateRegistry}; +use crate::Error::{ + InternalError, InvalidTemplateDir, InvalidTemplateDirectory, InvalidTemplateFile, + TargetNotSupported, WriteGeneratedCodeFailed, +}; mod config; mod extensions; @@ -67,7 +70,9 @@ pub enum Error { /// Invalid template directory. #[error("Invalid template directory {template_dir}: {error}")] InvalidTemplateDir { + /// Template directory. template_dir: PathBuf, + /// Error message. error: String, }, @@ -83,7 +88,9 @@ pub enum Error { /// Invalid template file. #[error("Invalid template file '{template}': {error}")] InvalidTemplateFile { + /// Template path. template: PathBuf, + /// Error message. error: String, }, @@ -172,14 +179,22 @@ impl TemplateObject { impl Display for TemplateObject { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - f.write_str(&format!("template file name: {}", self.file_name.lock().unwrap())) + f.write_str(&format!( + "template file name: {}", + self.file_name.lock().unwrap() + )) } } impl Object for TemplateObject { - fn call_method(&self, _state: &State, name: &str, args: &[Value]) -> Result { + fn call_method( + &self, + _state: &State, + name: &str, + args: &[Value], + ) -> Result { if name == "set_file_name" { - let (file_name, ): (&str, ) = from_args(args)?; + let (file_name,): (&str,) = from_args(args)?; *self.file_name.lock().unwrap() = file_name.to_string(); Ok(Value::from("")) } else { @@ -201,10 +216,14 @@ pub struct TemplateEngine { target_config: TargetConfig, } +/// Global context for the template engine. #[derive(Serialize, Debug)] pub struct Context<'a> { + /// The semantic convention registry. pub registry: &'a TemplateRegistry, + /// The group to generate doc or code for. pub group: Option<&'a TemplateGroup>, + /// The groups to generate doc or code for. pub groups: Option>, } @@ -256,58 +275,59 @@ impl TemplateEngine { // engine as all pairs are independent. self.list_registry_templates(&template_registry, paths)? .into_par_iter() - .try_for_each(|pair| { - match pair { - TemplateObjectPair::Group { - template_path: relative_template_path, - group - } => { - let ctx: serde_json::Value = serde_json::to_value(Context { - registry: &template_registry, - group: Some(group), - groups: None, - }) - .map_err(|e| InternalError(e.to_string()))?; - self.evaluate_template(log.clone(), ctx, relative_template_path, &output_dir) - } - TemplateObjectPair::Groups { - template_path: relative_template_path, - groups - } => { - let ctx: serde_json::Value = serde_json::to_value(Context { - registry: &template_registry, - group: None, - groups: Some(groups), - }) - .map_err(|e| InternalError(e.to_string()))?; - self.evaluate_template(log.clone(), ctx, relative_template_path, &output_dir) - } - TemplateObjectPair::Registry { - template_path: relative_template_path, + .try_for_each(|pair| match pair { + TemplateObjectPair::Group { + template_path: relative_template_path, + group, + } => { + let ctx: serde_json::Value = serde_json::to_value(Context { + registry: &template_registry, + group: Some(group), + groups: None, + }) + .map_err(|e| InternalError(e.to_string()))?; + self.evaluate_template(log.clone(), ctx, relative_template_path, &output_dir) + } + TemplateObjectPair::Groups { + template_path: relative_template_path, + groups, + } => { + let ctx: serde_json::Value = serde_json::to_value(Context { + registry: &template_registry, + group: None, + groups: Some(groups), + }) + .map_err(|e| InternalError(e.to_string()))?; + self.evaluate_template(log.clone(), ctx, relative_template_path, &output_dir) + } + TemplateObjectPair::Registry { + template_path: relative_template_path, + registry, + } => { + let ctx: serde_json::Value = serde_json::to_value(Context { registry, - } => { - let ctx: serde_json::Value = serde_json::to_value(Context { - registry: ®istry, - group: None, - groups: None, - }) - .map_err(|e| InternalError(e.to_string()))?; - self.evaluate_template(log.clone(), ctx, relative_template_path, &output_dir) - } + group: None, + groups: None, + }) + .map_err(|e| InternalError(e.to_string()))?; + self.evaluate_template(log.clone(), ctx, relative_template_path, &output_dir) } })?; Ok(()) } - fn evaluate_template(&self, - log: impl Logger + Clone + Sync, - ctx: serde_json::Value, - template_path: PathBuf, - output_dir: &PathBuf, + fn evaluate_template( + &self, + log: impl Logger + Clone + Sync, + ctx: serde_json::Value, + template_path: PathBuf, + output_dir: &Path, ) -> Result<(), Error> { let template_object = TemplateObject { - file_name: Arc::new(Mutex::new(template_path.to_str().unwrap_or_default().to_string())), + file_name: Arc::new(Mutex::new( + template_path.to_str().unwrap_or_default().to_string(), + )), }; let mut engine = self.template_engine()?; let template_file = template_path.to_str().ok_or(InvalidTemplateFile { @@ -318,8 +338,11 @@ impl TemplateEngine { engine.add_global("template", Value::from_object(template_object.clone())); _ = log.loading(&format!("Generating file {}", template_file)); - let output = engine.get_template(template_file).map_err(|e| InternalError(e.to_string()))? - .render(ctx).map_err(|e| InternalError(e.to_string()))?; + let output = engine + .get_template(template_file) + .map_err(|e| InternalError(e.to_string()))? + .render(ctx) + .map_err(|e| InternalError(e.to_string()))?; let generated_file = Self::save_generated_code(output_dir, template_object.file_name(), output)?; _ = log.success(&format!("Generated file {:?}", generated_file)); @@ -330,14 +353,30 @@ impl TemplateEngine { fn template_engine(&self) -> Result { let mut env = Environment::new(); env.set_loader(path_loader(&self.path)); - env.set_syntax(self.target_config.template_syntax.clone().into()).map_err(|e| InternalError(e.to_string()))?; + env.set_syntax(self.target_config.template_syntax.clone().into()) + .map_err(|e| InternalError(e.to_string()))?; // Register case conversion filters based on the target configuration - env.add_filter("file_name", case_converter(self.target_config.file_name.clone())); - env.add_filter("function_name", case_converter(self.target_config.function_name.clone())); - env.add_filter("arg_name", case_converter(self.target_config.arg_name.clone())); - env.add_filter("struct_name", case_converter(self.target_config.struct_name.clone())); - env.add_filter("field_name", case_converter(self.target_config.field_name.clone())); + env.add_filter( + "file_name", + case_converter(self.target_config.file_name.clone()), + ); + env.add_filter( + "function_name", + case_converter(self.target_config.function_name.clone()), + ); + env.add_filter( + "arg_name", + case_converter(self.target_config.arg_name.clone()), + ); + env.add_filter( + "struct_name", + case_converter(self.target_config.struct_name.clone()), + ); + env.add_filter( + "field_name", + case_converter(self.target_config.field_name.clone()), + ); env.add_filter("attributes", attributes); @@ -378,12 +417,17 @@ impl TemplateEngine { if tmpl_file_path.is_dir() { continue; } - let relative_path = tmpl_file_path - .strip_prefix(&self.path) - .map_err(|e| InvalidTemplateDir { template_dir: self.path.clone(), error: e.to_string() })?; - let tmpl_file = tmpl_file_path - .to_str() - .ok_or(InvalidTemplateFile { template: tmpl_file_path.clone(), error: "".to_string() })?; + let relative_path = + tmpl_file_path + .strip_prefix(&self.path) + .map_err(|e| InvalidTemplateDir { + template_dir: self.path.clone(), + error: e.to_string(), + })?; + let tmpl_file = tmpl_file_path.to_str().ok_or(InvalidTemplateFile { + template: tmpl_file_path.clone(), + error: "".to_string(), + })?; if tmpl_file.ends_with(".macro.j2") { // Macro files are not templates. @@ -399,8 +443,12 @@ impl TemplateEngine { match tmpl_file_path.file_stem().and_then(|s| s.to_str()) { Some("attribute_group") => { - registry.groups.iter() - .filter(|group| if let TypedGroup::AttributeGroup { .. } = group.typed_group { true } else { false }) + registry + .groups + .iter() + .filter(|group| { + matches!(group.typed_group, TypedGroup::AttributeGroup { .. }) + }) .for_each(|group| { templates.push(TemplateObjectPair::Group { template_path: relative_path.to_path_buf(), @@ -409,8 +457,10 @@ impl TemplateEngine { }); } Some("event") => { - registry.groups.iter() - .filter(|group| if let TypedGroup::Event { .. } = group.typed_group { true } else { false }) + registry + .groups + .iter() + .filter(|group| matches!(group.typed_group, TypedGroup::Event { .. })) .for_each(|group| { templates.push(TemplateObjectPair::Group { template_path: relative_path.to_path_buf(), @@ -419,17 +469,18 @@ impl TemplateEngine { }); } Some("group") => { - registry.groups.iter() - .for_each(|group| { - templates.push(TemplateObjectPair::Group { - template_path: relative_path.to_path_buf(), - group, - }) - }); + registry.groups.iter().for_each(|group| { + templates.push(TemplateObjectPair::Group { + template_path: relative_path.to_path_buf(), + group, + }) + }); } Some("metric") => { - registry.groups.iter() - .filter(|group| if let TypedGroup::Metric { .. } = group.typed_group { true } else { false }) + registry + .groups + .iter() + .filter(|group| matches!(group.typed_group, TypedGroup::Metric { .. })) .for_each(|group| { templates.push(TemplateObjectPair::Group { template_path: relative_path.to_path_buf(), @@ -438,8 +489,12 @@ impl TemplateEngine { }); } Some("metric_group") => { - registry.groups.iter() - .filter(|group| if let TypedGroup::MetricGroup { .. } = group.typed_group { true } else { false }) + registry + .groups + .iter() + .filter(|group| { + matches!(group.typed_group, TypedGroup::MetricGroup { .. }) + }) .for_each(|group| { templates.push(TemplateObjectPair::Group { template_path: relative_path.to_path_buf(), @@ -454,8 +509,12 @@ impl TemplateEngine { }); } Some("resource") => { - registry.groups.iter() - .filter(|group| if let TypedGroup::Resource { .. } = group.typed_group { true } else { false }) + registry + .groups + .iter() + .filter(|group| { + matches!(group.typed_group, TypedGroup::Resource { .. }) + }) .for_each(|group| { templates.push(TemplateObjectPair::Group { template_path: relative_path.to_path_buf(), @@ -464,8 +523,10 @@ impl TemplateEngine { }); } Some("scope") => { - registry.groups.iter() - .filter(|group| if let TypedGroup::Scope { .. } = group.typed_group { true } else { false }) + registry + .groups + .iter() + .filter(|group| matches!(group.typed_group, TypedGroup::Scope { .. })) .for_each(|group| { templates.push(TemplateObjectPair::Group { template_path: relative_path.to_path_buf(), @@ -474,8 +535,10 @@ impl TemplateEngine { }); } Some("span") => { - registry.groups.iter() - .filter(|group| if let TypedGroup::Span { .. } = group.typed_group { true } else { false }) + registry + .groups + .iter() + .filter(|group| matches!(group.typed_group, TypedGroup::Span { .. })) .for_each(|group| { templates.push(TemplateObjectPair::Group { template_path: relative_path.to_path_buf(), @@ -484,8 +547,12 @@ impl TemplateEngine { }); } Some("attribute_groups") => { - let groups = registry.groups.iter() - .filter(|group| if let TypedGroup::AttributeGroup { .. } = group.typed_group { true } else { false }) + let groups = registry + .groups + .iter() + .filter(|group| { + matches!(group.typed_group, TypedGroup::AttributeGroup { .. }) + }) .collect::>(); templates.push(TemplateObjectPair::Groups { template_path: relative_path.to_path_buf(), @@ -493,8 +560,10 @@ impl TemplateEngine { }) } Some("events") => { - let groups = registry.groups.iter() - .filter(|group| if let TypedGroup::Event { .. } = group.typed_group { true } else { false }) + let groups = registry + .groups + .iter() + .filter(|group| matches!(group.typed_group, TypedGroup::Event { .. })) .collect::>(); templates.push(TemplateObjectPair::Groups { template_path: relative_path.to_path_buf(), @@ -502,16 +571,17 @@ impl TemplateEngine { }) } Some("groups") => { - let groups = registry.groups.iter() - .collect::>(); + let groups = registry.groups.iter().collect::>(); templates.push(TemplateObjectPair::Groups { template_path: relative_path.to_path_buf(), groups, }) } Some("metrics") => { - let groups = registry.groups.iter() - .filter(|group| if let TypedGroup::Metric { .. } = group.typed_group { true } else { false }) + let groups = registry + .groups + .iter() + .filter(|group| matches!(group.typed_group, TypedGroup::Metric { .. })) .collect::>(); templates.push(TemplateObjectPair::Groups { template_path: relative_path.to_path_buf(), @@ -519,8 +589,12 @@ impl TemplateEngine { }) } Some("metric_groups") => { - let groups = registry.groups.iter() - .filter(|group| if let TypedGroup::MetricGroup { .. } = group.typed_group { true } else { false }) + let groups = registry + .groups + .iter() + .filter(|group| { + matches!(group.typed_group, TypedGroup::MetricGroup { .. }) + }) .collect::>(); templates.push(TemplateObjectPair::Groups { template_path: relative_path.to_path_buf(), @@ -528,8 +602,12 @@ impl TemplateEngine { }) } Some("resources") => { - let groups = registry.groups.iter() - .filter(|group| if let TypedGroup::Resource { .. } = group.typed_group { true } else { false }) + let groups = registry + .groups + .iter() + .filter(|group| { + matches!(group.typed_group, TypedGroup::Resource { .. }) + }) .collect::>(); templates.push(TemplateObjectPair::Groups { template_path: relative_path.to_path_buf(), @@ -537,8 +615,10 @@ impl TemplateEngine { }) } Some("scopes") => { - let groups = registry.groups.iter() - .filter(|group| if let TypedGroup::Scope { .. } = group.typed_group { true } else { false }) + let groups = registry + .groups + .iter() + .filter(|group| matches!(group.typed_group, TypedGroup::Scope { .. })) .collect::>(); templates.push(TemplateObjectPair::Groups { template_path: relative_path.to_path_buf(), @@ -546,20 +626,20 @@ impl TemplateEngine { }) } Some("spans") => { - let groups = registry.groups.iter() - .filter(|group| if let TypedGroup::Span { .. } = group.typed_group { true } else { false }) + let groups = registry + .groups + .iter() + .filter(|group| matches!(group.typed_group, TypedGroup::Span { .. })) .collect::>(); templates.push(TemplateObjectPair::Groups { template_path: relative_path.to_path_buf(), groups, }) } - _ => { - templates.push(TemplateObjectPair::Registry { - template_path: relative_path.to_path_buf(), - registry, - }) - } + _ => templates.push(TemplateObjectPair::Registry { + template_path: relative_path.to_path_buf(), + registry, + }), } } else { return Err(InvalidTemplateDirectory(self.path.clone())); @@ -607,25 +687,27 @@ mod tests { #[test] fn test() { let logger = TestLogger::default(); - let engine = super::TemplateEngine::try_new( - "test", - super::GeneratorConfig::default(), - ).expect("Failed to create template engine"); + let engine = super::TemplateEngine::try_new("test", super::GeneratorConfig::default()) + .expect("Failed to create template engine"); - let mut registry = SemConvRegistry::try_from_path("data/*.yaml").expect("Failed to load registry"); - let schema = SchemaResolver::resolve_semantic_convention_registry(&mut registry, logger.clone()) + let mut registry = + SemConvRegistry::try_from_path("data/*.yaml").expect("Failed to load registry"); + let schema = + SchemaResolver::resolve_semantic_convention_registry(&mut registry, logger.clone()) .expect("Failed to resolve registry"); - engine.generate_registry( - logger, - &schema.registries[0], - &schema.catalog, - "output".into(), - ).expect("Failed to generate registry assets"); + engine + .generate_registry( + logger, + &schema.registries[0], + &schema.catalog, + "output".into(), + ) + .expect("Failed to generate registry assets"); // let mut env = Environment::new(); // env.add_template("hello.txt", "Hello {{ name }}!").unwrap(); // let template = env.get_template("hello.txt").unwrap(); // println!("{}", template.render(context! { name => "World" }).unwrap()); } -} \ No newline at end of file +} diff --git a/crates/weaver_forge/src/registry.rs b/crates/weaver_forge/src/registry.rs index f6eaa55d..bb99ad49 100644 --- a/crates/weaver_forge/src/registry.rs +++ b/crates/weaver_forge/src/registry.rs @@ -4,12 +4,12 @@ //! catalog are resolved to the actual catalog entries to ease the template //! evaluation. +use crate::Error; use serde::{Deserialize, Serialize}; use weaver_resolved_schema::attribute::Attribute; use weaver_resolved_schema::catalog::{Catalog, Stability}; use weaver_resolved_schema::lineage::GroupLineage; use weaver_resolved_schema::registry::{Constraint, Registry, TypedGroup}; -use crate::Error; /// A semantic convention registry used in the context of the template engine. #[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] @@ -94,16 +94,20 @@ impl TemplateRegistry { let stability = group.stability.clone(); let deprecated = group.deprecated.clone(); let constraints = group.constraints.clone(); - let attributes = group.attributes.iter().flat_map(|attr_ref| { - let attr = catalog.attribute(attr_ref).map(|a| a.clone()); - if attr.is_none() { - errors.push(Error::AttributeNotFound { - group_id: id.clone(), - attr_ref: *attr_ref, - }); - } - attr - }).collect(); + let attributes = group + .attributes + .iter() + .flat_map(|attr_ref| { + let attr = catalog.attribute(attr_ref).cloned(); + if attr.is_none() { + errors.push(Error::AttributeNotFound { + group_id: id.clone(), + attr_ref: *attr_ref, + }); + } + attr + }) + .collect(); let lineage = group.lineage.clone(); TemplateGroup { id, @@ -122,7 +126,7 @@ impl TemplateRegistry { .collect(); if !errors.is_empty() { - return Err(Error::CompoundError(errors)) + return Err(Error::CompoundError(errors)); } Ok(Self { @@ -130,4 +134,4 @@ impl TemplateRegistry { groups, }) } -} \ No newline at end of file +} diff --git a/crates/weaver_resolved_schema/src/attribute.rs b/crates/weaver_resolved_schema/src/attribute.rs index 89794eb7..13e73a01 100644 --- a/crates/weaver_resolved_schema/src/attribute.rs +++ b/crates/weaver_resolved_schema/src/attribute.rs @@ -4,12 +4,12 @@ //! Specification of a resolved attribute. -use std::fmt::Display; use crate::catalog::Stability; use crate::tags::Tags; use crate::value::Value; use ordered_float::OrderedFloat; use serde::{Deserialize, Serialize}; +use std::fmt::Display; use weaver_semconv::attribute::AttributeSpec; /// An attribute definition. diff --git a/crates/weaver_resolver/src/attribute.rs b/crates/weaver_resolver/src/attribute.rs index 288461dd..741ed921 100644 --- a/crates/weaver_resolver/src/attribute.rs +++ b/crates/weaver_resolver/src/attribute.rs @@ -209,7 +209,7 @@ impl AttributeCatalog { let attr = attribute::Attribute { name: root_attr_id.clone(), r#type: semconv_to_resolved_attr_type(r#type), - brief: brief.clone(), + brief: brief.clone().unwrap_or_default(), examples: semconv_to_resolved_examples(examples), tag: tag.clone(), requirement_level: semconv_to_resolved_req_level(requirement_level), @@ -428,7 +428,7 @@ pub fn resolve_attribute( } => Ok(attribute::Attribute { name: id.clone(), r#type: semconv_to_resolved_attr_type(r#type), - brief: brief.clone(), + brief: brief.clone().unwrap_or_default(), examples: semconv_to_resolved_examples(examples), tag: tag.clone(), requirement_level: semconv_to_resolved_req_level(requirement_level), diff --git a/crates/weaver_schema/src/attribute.rs b/crates/weaver_schema/src/attribute.rs index 65f58e14..36e0b396 100644 --- a/crates/weaver_schema/src/attribute.rs +++ b/crates/weaver_schema/src/attribute.rs @@ -226,7 +226,7 @@ impl From<&weaver_semconv::attribute::AttributeSpec> for Attribute { } => Attribute::Id { id, r#type, - brief, + brief: brief.unwrap_or_default(), examples, tag, requirement_level, @@ -327,7 +327,7 @@ impl Attribute { { let id = id.clone(); let r#type = r#type.clone(); - let mut brief = brief.clone(); + let mut brief = brief.clone().unwrap_or_default(); let mut examples = examples.clone(); let mut requirement_level = requirement_level.clone(); let mut tag = tag.clone(); diff --git a/crates/weaver_semconv/data/exporter.yaml b/crates/weaver_semconv/data/exporter.yaml new file mode 100644 index 00000000..36a66ff4 --- /dev/null +++ b/crates/weaver_semconv/data/exporter.yaml @@ -0,0 +1,32 @@ +groups: + - id: otel.scope + prefix: otel.scope + type: resource + brief: Attributes used by non-OTLP exporters to represent OpenTelemetry Scope's concepts. + attributes: + - id: name + type: string + brief: The name of the instrumentation scope - (`InstrumentationScope.Name` in OTLP). + examples: ['io.opentelemetry.contrib.mongodb'] + stability: stable + - id: version + type: string + brief: The version of the instrumentation scope - (`InstrumentationScope.Version` in OTLP). + examples: ['1.0.0'] + stability: stable + - id: otel.library + prefix: otel.library + type: resource + brief: > + Span attributes used by non-OTLP exporters to represent OpenTelemetry Scope's concepts. + attributes: + - id: name + type: string + deprecated: use the `otel.scope.name` attribute. + brief: + examples: ['io.opentelemetry.contrib.mongodb'] + - id: version + type: string + deprecated: use the `otel.scope.version` attribute. + brief: + examples: ['1.0.0'] \ No newline at end of file diff --git a/crates/weaver_semconv/src/attribute.rs b/crates/weaver_semconv/src/attribute.rs index 553a9e1b..d138df4d 100644 --- a/crates/weaver_semconv/src/attribute.rs +++ b/crates/weaver_semconv/src/attribute.rs @@ -75,7 +75,7 @@ pub enum AttributeSpec { /// array type, a template type or an enum definition. r#type: AttributeTypeSpec, /// A brief description of the attribute. - brief: String, + brief: Option, /// Sequence of example values for the attribute or single example /// value. They are required only for string and string array /// attributes. Example values must be of the same type of the @@ -148,7 +148,7 @@ impl AttributeSpec { pub fn brief(&self) -> String { match self { AttributeSpec::Ref { brief, .. } => brief.clone().unwrap_or_default(), - AttributeSpec::Id { brief, .. } => brief.clone(), + AttributeSpec::Id { brief, .. } => brief.clone().unwrap_or_default(), } } diff --git a/crates/weaver_semconv/src/group.rs b/crates/weaver_semconv/src/group.rs index 737eaf3a..cb7a1603 100644 --- a/crates/weaver_semconv/src/group.rs +++ b/crates/weaver_semconv/src/group.rs @@ -143,11 +143,24 @@ fn validate_group(group: &GroupSpec) -> Result<(), ValidationError> { // will result in an error. match attribute { AttributeSpec::Id { + brief, stability, deprecated, .. + } => { + if brief.is_none() && deprecated.is_none() { + return Err(ValidationError::new( + "This attribute is not deprecated and does not contain a brief field.", + )); + } + if deprecated.is_some() + && stability.is_some() + && *stability != Some(StabilitySpec::Deprecated) + { + return Err(ValidationError::new("This attribute contains a deprecated field but the stability is not set to deprecated.")); + } } - | AttributeSpec::Ref { + AttributeSpec::Ref { stability, deprecated, .. diff --git a/crates/weaver_semconv/src/lib.rs b/crates/weaver_semconv/src/lib.rs index b9c32316..64daa7b0 100644 --- a/crates/weaver_semconv/src/lib.rs +++ b/crates/weaver_semconv/src/lib.rs @@ -16,11 +16,11 @@ unused_extern_crates )] +use glob::glob; use std::collections::{HashMap, HashSet}; use std::fs::File; use std::io::BufReader; use std::path::Path; -use glob::glob; use serde::{Deserialize, Serialize}; use validator::Validate; @@ -897,6 +897,7 @@ mod tests { "data/network.yaml", "data/server.yaml", "data/url.yaml", + "data/exporter.yaml", ]; let mut catalog = SemConvRegistry::default(); diff --git a/docs/images/dependencies.svg b/docs/images/dependencies.svg index 672a5008..40228d2a 100644 --- a/docs/images/dependencies.svg +++ b/docs/images/dependencies.svg @@ -4,10 +4,10 @@ - + - + 0 @@ -17,170 +17,200 @@ 1 - -weaver_logger + +weaver_forge 2 - -weaver_resolved_schema + +weaver_logger + + + +1->2 + + 3 - -weaver_semconv + +weaver_resolved_schema - - -2->3 - - + + +1->3 + + 4 - -weaver_version + +weaver_semconv - - -2->4 - - + + +1->4 + + - - -5 - -weaver_resolver + + +6 + +weaver_resolver - + -5->0 - - - - - -5->1 - - +1->6 + + - + -5->2 - - +3->4 + + - - -5->3 - - + + +5 + +weaver_version - - -5->4 - - + + +3->5 + + - - -6 - -weaver_schema + + +6->0 + + - - -5->6 - - + + +6->2 + + 6->3 - - + + - + 6->4 - - + + + + + +6->5 + + 7 - -weaver_template + +weaver_schema - - -7->0 - - - - - -7->1 - - + + +6->7 + + - + -7->5 - - +7->4 + + - + -7->6 - - +7->5 + + 8 - -weaver + +weaver_template 8->0 - - + + - + -8->1 - - - - - -8->3 - - - - - -8->5 - - +8->2 + + - + 8->6 - - + + - + 8->7 - - + + + + + +9 + +weaver + + + +9->0 + + + + + +9->2 + + + + + +9->4 + + + + + +9->6 + + + + + +9->7 + + + + + +9->8 + + diff --git a/src/search/semconv/attribute.rs b/src/search/semconv/attribute.rs index 92564904..1ed48687 100644 --- a/src/search/semconv/attribute.rs +++ b/src/search/semconv/attribute.rs @@ -52,13 +52,15 @@ pub fn widget<'a>( } // Brief - if !brief.trim().is_empty() { - text.push(Line::from("")); - text.push(Line::from(Span::styled( - "Brief: ", - Style::default().fg(theme.label), - ))); - text.push(Line::from(brief.as_str())); + if let Some(brief) = brief { + if !brief.trim().is_empty() { + text.push(Line::from("")); + text.push(Line::from(Span::styled( + "Brief: ", + Style::default().fg(theme.label), + ))); + text.push(Line::from(brief.as_str())); + } } // Note From 37a7579367151937cf3e3cf4a7253e6c46f6371d Mon Sep 17 00:00:00 2001 From: Laurent Querel Date: Wed, 6 Mar 2024 14:02:56 -0800 Subject: [PATCH 10/20] chore(compatibility): make resolved registry compatible with official registry syntax --- crates/weaver_forge/src/lib.rs | 43 +++---- crates/weaver_forge/src/registry.rs | 9 +- crates/weaver_forge/templates/test/group.md | 2 +- crates/weaver_resolved_schema/src/registry.rs | 81 +++++-------- .../expected-registry.json | 8 +- .../expected-registry.json | 8 +- .../expected-registry.json | 104 ++++++---------- .../expected-registry.json | 22 +--- .../expected-registry.json | 94 ++++++--------- .../expected-registry.json | 8 +- .../expected-registry.json | 112 ++++++------------ crates/weaver_resolver/src/attribute.rs | 10 +- crates/weaver_resolver/src/registry.rs | 30 ++--- crates/weaver_resolver/src/spans.rs | 12 -- crates/weaver_semconv/src/group.rs | 16 +-- crates/weaver_semconv/src/lib.rs | 46 ++++--- 16 files changed, 217 insertions(+), 388 deletions(-) diff --git a/crates/weaver_forge/src/lib.rs b/crates/weaver_forge/src/lib.rs index 37413990..e1a66e66 100644 --- a/crates/weaver_forge/src/lib.rs +++ b/crates/weaver_forge/src/lib.rs @@ -29,7 +29,8 @@ use serde::Serialize; use weaver_logger::Logger; use weaver_resolved_schema::attribute::AttributeRef; use weaver_resolved_schema::catalog::Catalog; -use weaver_resolved_schema::registry::{Registry, TypedGroup}; +use weaver_resolved_schema::registry::Registry; +use weaver_semconv::group::GroupType; use crate::config::TargetConfig; use crate::extensions::attributes::attributes; @@ -446,9 +447,7 @@ impl TemplateEngine { registry .groups .iter() - .filter(|group| { - matches!(group.typed_group, TypedGroup::AttributeGroup { .. }) - }) + .filter(|group| matches!(group.r#type, GroupType::AttributeGroup)) .for_each(|group| { templates.push(TemplateObjectPair::Group { template_path: relative_path.to_path_buf(), @@ -460,7 +459,7 @@ impl TemplateEngine { registry .groups .iter() - .filter(|group| matches!(group.typed_group, TypedGroup::Event { .. })) + .filter(|group| matches!(group.r#type, GroupType::Event)) .for_each(|group| { templates.push(TemplateObjectPair::Group { template_path: relative_path.to_path_buf(), @@ -480,7 +479,7 @@ impl TemplateEngine { registry .groups .iter() - .filter(|group| matches!(group.typed_group, TypedGroup::Metric { .. })) + .filter(|group| matches!(group.r#type, GroupType::Metric)) .for_each(|group| { templates.push(TemplateObjectPair::Group { template_path: relative_path.to_path_buf(), @@ -492,9 +491,7 @@ impl TemplateEngine { registry .groups .iter() - .filter(|group| { - matches!(group.typed_group, TypedGroup::MetricGroup { .. }) - }) + .filter(|group| matches!(group.r#type, GroupType::MetricGroup)) .for_each(|group| { templates.push(TemplateObjectPair::Group { template_path: relative_path.to_path_buf(), @@ -512,9 +509,7 @@ impl TemplateEngine { registry .groups .iter() - .filter(|group| { - matches!(group.typed_group, TypedGroup::Resource { .. }) - }) + .filter(|group| matches!(group.r#type, GroupType::Resource)) .for_each(|group| { templates.push(TemplateObjectPair::Group { template_path: relative_path.to_path_buf(), @@ -526,7 +521,7 @@ impl TemplateEngine { registry .groups .iter() - .filter(|group| matches!(group.typed_group, TypedGroup::Scope { .. })) + .filter(|group| matches!(group.r#type, GroupType::Scope)) .for_each(|group| { templates.push(TemplateObjectPair::Group { template_path: relative_path.to_path_buf(), @@ -538,7 +533,7 @@ impl TemplateEngine { registry .groups .iter() - .filter(|group| matches!(group.typed_group, TypedGroup::Span { .. })) + .filter(|group| matches!(group.r#type, GroupType::Span)) .for_each(|group| { templates.push(TemplateObjectPair::Group { template_path: relative_path.to_path_buf(), @@ -550,9 +545,7 @@ impl TemplateEngine { let groups = registry .groups .iter() - .filter(|group| { - matches!(group.typed_group, TypedGroup::AttributeGroup { .. }) - }) + .filter(|group| matches!(group.r#type, GroupType::AttributeGroup)) .collect::>(); templates.push(TemplateObjectPair::Groups { template_path: relative_path.to_path_buf(), @@ -563,7 +556,7 @@ impl TemplateEngine { let groups = registry .groups .iter() - .filter(|group| matches!(group.typed_group, TypedGroup::Event { .. })) + .filter(|group| matches!(group.r#type, GroupType::Event)) .collect::>(); templates.push(TemplateObjectPair::Groups { template_path: relative_path.to_path_buf(), @@ -581,7 +574,7 @@ impl TemplateEngine { let groups = registry .groups .iter() - .filter(|group| matches!(group.typed_group, TypedGroup::Metric { .. })) + .filter(|group| matches!(group.r#type, GroupType::Metric)) .collect::>(); templates.push(TemplateObjectPair::Groups { template_path: relative_path.to_path_buf(), @@ -592,9 +585,7 @@ impl TemplateEngine { let groups = registry .groups .iter() - .filter(|group| { - matches!(group.typed_group, TypedGroup::MetricGroup { .. }) - }) + .filter(|group| matches!(group.r#type, GroupType::MetricGroup)) .collect::>(); templates.push(TemplateObjectPair::Groups { template_path: relative_path.to_path_buf(), @@ -605,9 +596,7 @@ impl TemplateEngine { let groups = registry .groups .iter() - .filter(|group| { - matches!(group.typed_group, TypedGroup::Resource { .. }) - }) + .filter(|group| matches!(group.r#type, GroupType::Resource)) .collect::>(); templates.push(TemplateObjectPair::Groups { template_path: relative_path.to_path_buf(), @@ -618,7 +607,7 @@ impl TemplateEngine { let groups = registry .groups .iter() - .filter(|group| matches!(group.typed_group, TypedGroup::Scope { .. })) + .filter(|group| matches!(group.r#type, GroupType::Scope)) .collect::>(); templates.push(TemplateObjectPair::Groups { template_path: relative_path.to_path_buf(), @@ -629,7 +618,7 @@ impl TemplateEngine { let groups = registry .groups .iter() - .filter(|group| matches!(group.typed_group, TypedGroup::Span { .. })) + .filter(|group| matches!(group.r#type, GroupType::Span)) .collect::>(); templates.push(TemplateObjectPair::Groups { template_path: relative_path.to_path_buf(), diff --git a/crates/weaver_forge/src/registry.rs b/crates/weaver_forge/src/registry.rs index bb99ad49..48cc793f 100644 --- a/crates/weaver_forge/src/registry.rs +++ b/crates/weaver_forge/src/registry.rs @@ -9,7 +9,8 @@ use serde::{Deserialize, Serialize}; use weaver_resolved_schema::attribute::Attribute; use weaver_resolved_schema::catalog::{Catalog, Stability}; use weaver_resolved_schema::lineage::GroupLineage; -use weaver_resolved_schema::registry::{Constraint, Registry, TypedGroup}; +use weaver_resolved_schema::registry::{Constraint, Registry}; +use weaver_semconv::group::GroupType; /// A semantic convention registry used in the context of the template engine. #[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] @@ -28,7 +29,7 @@ pub struct TemplateGroup { /// The id that uniquely identifies the semantic convention. pub id: String, /// The type of the group including the specific fields for each type. - pub typed_group: TypedGroup, + pub r#type: GroupType, /// A brief description of the semantic convention. #[serde(skip_serializing_if = "String::is_empty")] pub brief: String, @@ -86,7 +87,7 @@ impl TemplateRegistry { .iter() .map(|group| { let id = group.id.clone(); - let typed_group = group.typed_group.clone(); + let group_type = group.r#type.clone(); let brief = group.brief.clone(); let note = group.note.clone(); let prefix = group.prefix.clone(); @@ -111,7 +112,7 @@ impl TemplateRegistry { let lineage = group.lineage.clone(); TemplateGroup { id, - typed_group, + r#type: group_type, brief, note, prefix, diff --git a/crates/weaver_forge/templates/test/group.md b/crates/weaver_forge/templates/test/group.md index 8fc37222..144701fd 100644 --- a/crates/weaver_forge/templates/test/group.md +++ b/crates/weaver_forge/templates/test/group.md @@ -1,7 +1,7 @@ {%- set file_name = group.id | file_name -%} {{- template.set_file_name("group/" ~ file_name ~ ".md") -}} -# {{ group.typed_group.type }} `{{ group.id }}` +# {{ group.type }} `{{ group.id }}` ## Brief diff --git a/crates/weaver_resolved_schema/src/registry.rs b/crates/weaver_resolved_schema/src/registry.rs index b1b9562a..92a9b8ed 100644 --- a/crates/weaver_resolved_schema/src/registry.rs +++ b/crates/weaver_resolved_schema/src/registry.rs @@ -7,11 +7,10 @@ use crate::attribute::AttributeRef; use serde::{Deserialize, Serialize}; use std::collections::HashSet; +use weaver_semconv::group::{GroupType, InstrumentSpec, SpanKindSpec}; use crate::catalog::Stability; use crate::lineage::GroupLineage; -use crate::metric::Instrument; -use crate::signal::SpanKind; /// A semantic convention registry. #[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] @@ -30,7 +29,7 @@ pub struct Group { /// The id that uniquely identifies the semantic convention. pub id: String, /// The type of the group including the specific fields for each type. - pub typed_group: TypedGroup, + pub r#type: GroupType, /// A brief description of the semantic convention. #[serde(skip_serializing_if = "String::is_empty")] pub brief: String, @@ -70,60 +69,38 @@ pub struct Group { /// List of attributes that belong to the semantic convention. #[serde(default)] pub attributes: Vec, + + /// Specifies the kind of the span. + /// Note: only valid if type is span (the default) + pub span_kind: Option, + /// List of strings that specify the ids of event semantic conventions + /// associated with this span semantic convention. + /// Note: only valid if type is span (the default) + #[serde(default)] + pub events: Vec, + /// The metric name as described by the [OpenTelemetry Specification](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/data-model.md#timeseries-model). + /// Note: This field is required if type is metric. + pub metric_name: Option, + /// The instrument type that should be used to record the metric. Note that + /// the semantic conventions must be written using the names of the + /// synchronous instrument types (counter, gauge, updowncounter and + /// histogram). + /// For more details: [Metrics semantic conventions - Instrument types](https://github.com/open-telemetry/opentelemetry-specification/tree/main/specification/metrics/semantic_conventions#instrument-types). + /// Note: This field is required if type is metric. + pub instrument: Option, + /// The unit in which the metric is measured, which should adhere to the + /// [guidelines](https://github.com/open-telemetry/opentelemetry-specification/tree/main/specification/metrics/semantic_conventions#instrument-units). + /// Note: This field is required if type is metric. + pub unit: Option, + /// The name of the event. If not specified, the prefix is used. + /// If prefix is empty (or unspecified), name is required. + pub name: Option, + /// The lineage of the group. #[serde(skip_serializing_if = "Option::is_none")] pub lineage: Option, } -/// An enum representing the type of the group including the specific fields -/// for each type. -#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] -#[serde(tag = "type")] -pub enum TypedGroup { - /// A semantic convention group representing an attribute group. - AttributeGroup {}, - /// A semantic convention group representing a span. - Span { - /// Specifies the kind of the span. - /// Note: only valid if type is span (the default) - span_kind: Option, - /// List of strings that specify the ids of event semantic conventions - /// associated with this span semantic convention. - /// Note: only valid if type is span (the default) - #[serde(default)] - events: Vec, - }, - /// A semantic convention group representing an event. - Event { - /// The name of the event. If not specified, the prefix is used. - /// If prefix is empty (or unspecified), name is required. - name: Option, - }, - /// A semantic convention group representing a metric. - Metric { - /// The metric name as described by the [OpenTelemetry Specification](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/data-model.md#timeseries-model). - /// Note: This field is required if type is metric. - metric_name: Option, - /// The instrument type that should be used to record the metric. Note that - /// the semantic conventions must be written using the names of the - /// synchronous instrument types (counter, gauge, updowncounter and - /// histogram). - /// For more details: [Metrics semantic conventions - Instrument types](https://github.com/open-telemetry/opentelemetry-specification/tree/main/specification/metrics/semantic_conventions#instrument-types). - /// Note: This field is required if type is metric. - instrument: Option, - /// The unit in which the metric is measured, which should adhere to the - /// [guidelines](https://github.com/open-telemetry/opentelemetry-specification/tree/main/specification/metrics/semantic_conventions#instrument-units). - /// Note: This field is required if type is metric. - unit: Option, - }, - /// A semantic convention group representing a metric group. - MetricGroup {}, - /// A semantic convention group representing a resource. - Resource {}, - /// A semantic convention group representing a scope. - Scope {}, -} - /// Allow to define additional requirements on the semantic convention. #[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Hash, Eq)] #[serde(deny_unknown_fields)] diff --git a/crates/weaver_resolver/data/registry-test-1-single-attr-ref/expected-registry.json b/crates/weaver_resolver/data/registry-test-1-single-attr-ref/expected-registry.json index 49c7f92f..b823da1a 100644 --- a/crates/weaver_resolver/data/registry-test-1-single-attr-ref/expected-registry.json +++ b/crates/weaver_resolver/data/registry-test-1-single-attr-ref/expected-registry.json @@ -3,9 +3,7 @@ "groups": [ { "id": "metric.messaging.attributes", - "typed_group": { - "type": "AttributeGroup" - }, + "type": "attribute_group", "brief": "Common messaging metrics attributes.", "attributes": [ 1 @@ -48,9 +46,7 @@ }, { "id": "registry.messaging", - "typed_group": { - "type": "AttributeGroup" - }, + "type": "attribute_group", "brief": "Attributes describing telemetry around messaging systems and messaging activities.", "prefix": "messaging", "attributes": [ diff --git a/crates/weaver_resolver/data/registry-test-2-multi-attr-refs/expected-registry.json b/crates/weaver_resolver/data/registry-test-2-multi-attr-refs/expected-registry.json index 2df81272..c6aff442 100644 --- a/crates/weaver_resolver/data/registry-test-2-multi-attr-refs/expected-registry.json +++ b/crates/weaver_resolver/data/registry-test-2-multi-attr-refs/expected-registry.json @@ -3,9 +3,7 @@ "groups": [ { "id": "metric.messaging.attributes", - "typed_group": { - "type": "AttributeGroup" - }, + "type": "attribute_group", "brief": "Common messaging metrics attributes.", "attributes": [ 30, @@ -79,9 +77,7 @@ }, { "id": "registry.messaging", - "typed_group": { - "type": "AttributeGroup" - }, + "type": "attribute_group", "brief": "Attributes describing telemetry around messaging systems and messaging activities.", "prefix": "messaging", "attributes": [ diff --git a/crates/weaver_resolver/data/registry-test-3-extends/expected-registry.json b/crates/weaver_resolver/data/registry-test-3-extends/expected-registry.json index 9c89edf4..674310ad 100644 --- a/crates/weaver_resolver/data/registry-test-3-extends/expected-registry.json +++ b/crates/weaver_resolver/data/registry-test-3-extends/expected-registry.json @@ -3,9 +3,7 @@ "groups": [ { "id": "attributes.http.common", - "typed_group": { - "type": "AttributeGroup" - }, + "type": "attribute_group", "brief": "Describes HTTP attributes.", "attributes": [ 62, @@ -160,9 +158,7 @@ }, { "id": "attributes.http.client", - "typed_group": { - "type": "AttributeGroup" - }, + "type": "attribute_group", "brief": "HTTP Client attributes", "attributes": [ 62, @@ -286,9 +282,7 @@ }, { "id": "attributes.http.server", - "typed_group": { - "type": "AttributeGroup" - }, + "type": "attribute_group", "brief": "HTTP Server attributes", "attributes": [ 62, @@ -439,9 +433,7 @@ }, { "id": "messaging.attributes.common", - "typed_group": { - "type": "AttributeGroup" - }, + "type": "attribute_group", "brief": "Common messaging attributes.", "prefix": "messaging", "attributes": [ @@ -632,9 +624,7 @@ }, { "id": "metric.messaging.attributes", - "typed_group": { - "type": "AttributeGroup" - }, + "type": "attribute_group", "brief": "Common messaging metrics attributes.", "attributes": [ 56, @@ -750,12 +740,7 @@ }, { "id": "metric.messaging.publish.duration", - "typed_group": { - "type": "Metric", - "metric_name": "messaging.publish.duration", - "instrument": "Histogram", - "unit": "s" - }, + "type": "metric", "brief": "Measures the duration of publish operation.", "attributes": [ 56, @@ -767,6 +752,9 @@ 79, 80 ], + "metric_name": "messaging.publish.duration", + "instrument": "histogram", + "unit": "s", "lineage": { "provenance": "data/registry-test-3-extends/registry/metrics-messaging.yaml", "attributes": { @@ -823,12 +811,7 @@ }, { "id": "metric.messaging.receive.duration", - "typed_group": { - "type": "Metric", - "metric_name": "messaging.receive.duration", - "instrument": "Histogram", - "unit": "s" - }, + "type": "metric", "brief": "Measures the duration of receive operation.", "attributes": [ 56, @@ -840,6 +823,9 @@ 79, 80 ], + "metric_name": "messaging.receive.duration", + "instrument": "histogram", + "unit": "s", "lineage": { "provenance": "data/registry-test-3-extends/registry/metrics-messaging.yaml", "attributes": { @@ -896,12 +882,7 @@ }, { "id": "metric.messaging.deliver.duration", - "typed_group": { - "type": "Metric", - "metric_name": "messaging.deliver.duration", - "instrument": "Histogram", - "unit": "s" - }, + "type": "metric", "brief": "Measures the duration of deliver operation.", "attributes": [ 56, @@ -913,6 +894,9 @@ 79, 80 ], + "metric_name": "messaging.deliver.duration", + "instrument": "histogram", + "unit": "s", "lineage": { "provenance": "data/registry-test-3-extends/registry/metrics-messaging.yaml", "attributes": { @@ -969,12 +953,7 @@ }, { "id": "metric.messaging.publish.messages", - "typed_group": { - "type": "Metric", - "metric_name": "messaging.publish.messages", - "instrument": "Counter", - "unit": "{message}" - }, + "type": "metric", "brief": "Measures the number of published messages.", "attributes": [ 56, @@ -986,6 +965,9 @@ 79, 80 ], + "metric_name": "messaging.publish.messages", + "instrument": "counter", + "unit": "{message}", "lineage": { "provenance": "data/registry-test-3-extends/registry/metrics-messaging.yaml", "attributes": { @@ -1042,12 +1024,7 @@ }, { "id": "metric.messaging.receive.messages", - "typed_group": { - "type": "Metric", - "metric_name": "messaging.receive.messages", - "instrument": "Counter", - "unit": "{message}" - }, + "type": "metric", "brief": "Measures the number of received messages.", "attributes": [ 56, @@ -1059,6 +1036,9 @@ 79, 80 ], + "metric_name": "messaging.receive.messages", + "instrument": "counter", + "unit": "{message}", "lineage": { "provenance": "data/registry-test-3-extends/registry/metrics-messaging.yaml", "attributes": { @@ -1115,12 +1095,7 @@ }, { "id": "metric.messaging.deliver.messages", - "typed_group": { - "type": "Metric", - "metric_name": "messaging.deliver.messages", - "instrument": "Counter", - "unit": "{message}" - }, + "type": "metric", "brief": "Measures the number of delivered messages.", "attributes": [ 56, @@ -1132,6 +1107,9 @@ 79, 80 ], + "metric_name": "messaging.deliver.messages", + "instrument": "counter", + "unit": "{message}", "lineage": { "provenance": "data/registry-test-3-extends/registry/metrics-messaging.yaml", "attributes": { @@ -1188,9 +1166,7 @@ }, { "id": "registry.error", - "typed_group": { - "type": "AttributeGroup" - }, + "type": "attribute_group", "brief": "This document defines the shared attributes used to report an error.\n", "prefix": "error", "attributes": [ @@ -1202,9 +1178,7 @@ }, { "id": "registry.http", - "typed_group": { - "type": "AttributeGroup" - }, + "type": "attribute_group", "brief": "This document defines semantic convention attributes in the HTTP namespace.", "prefix": "http", "attributes": [ @@ -1224,9 +1198,7 @@ }, { "id": "registry.messaging", - "typed_group": { - "type": "AttributeGroup" - }, + "type": "attribute_group", "brief": "Attributes describing telemetry around messaging systems and messaging activities.", "prefix": "messaging", "attributes": [ @@ -1267,9 +1239,7 @@ }, { "id": "registry.network", - "typed_group": { - "type": "AttributeGroup" - }, + "type": "attribute_group", "brief": "These attributes may be used for any network related operation.\n", "prefix": "network", "attributes": [ @@ -1295,9 +1265,7 @@ }, { "id": "server", - "typed_group": { - "type": "AttributeGroup" - }, + "type": "attribute_group", "brief": "These attributes may be used to describe the server in a connection-based network interaction where there is one side that initiates the connection (the client is the side that initiates the connection). This covers all TCP network interactions since TCP is connection-based and one side initiates the connection (an exception is made for peer-to-peer communication over TCP where the \"user-facing\" surface of the protocol / API doesn't expose a clear notion of client and server). This also covers UDP network interactions where one side initiates the interaction, e.g. QUIC (HTTP/3) and DNS.\n", "prefix": "server", "attributes": [ @@ -1310,9 +1278,7 @@ }, { "id": "registry.url", - "typed_group": { - "type": "AttributeGroup" - }, + "type": "attribute_group", "brief": "Attributes describing URL.", "prefix": "url", "attributes": [ diff --git a/crates/weaver_resolver/data/registry-test-4-events/expected-registry.json b/crates/weaver_resolver/data/registry-test-4-events/expected-registry.json index 05105035..b5423075 100644 --- a/crates/weaver_resolver/data/registry-test-4-events/expected-registry.json +++ b/crates/weaver_resolver/data/registry-test-4-events/expected-registry.json @@ -3,10 +3,7 @@ "groups": [ { "id": "log-feature_flag", - "typed_group": { - "type": "Event", - "name": null - }, + "type": "event", "brief": "This document defines attributes for feature flag evaluations represented using Log Records.\n", "prefix": "feature_flag", "attributes": [ @@ -124,40 +121,33 @@ }, { "id": "ios.lifecycle.events", - "typed_group": { - "type": "Event", - "name": "device.app.lifecycle" - }, + "type": "event", "brief": "This event represents an occurrence of a lifecycle transition on the iOS platform.\n", "prefix": "ios", "attributes": [ 0 ], + "name": "device.app.lifecycle", "lineage": { "provenance": "data/registry-test-4-events/registry/mobile-events.yaml" } }, { "id": "android.lifecycle.events", - "typed_group": { - "type": "Event", - "name": "device.app.lifecycle" - }, + "type": "event", "brief": "This event represents an occurrence of a lifecycle transition on the Android platform.\n", "prefix": "android", "attributes": [ 1 ], + "name": "device.app.lifecycle", "lineage": { "provenance": "data/registry-test-4-events/registry/mobile-events.yaml" } }, { "id": "feature_flag", - "typed_group": { - "type": "Event", - "name": null - }, + "type": "event", "brief": "This semantic convention defines the attributes used to represent a feature flag evaluation as an event.\n", "prefix": "feature_flag", "attributes": [ diff --git a/crates/weaver_resolver/data/registry-test-5-metrics/expected-registry.json b/crates/weaver_resolver/data/registry-test-5-metrics/expected-registry.json index 8d280565..00fc3b71 100644 --- a/crates/weaver_resolver/data/registry-test-5-metrics/expected-registry.json +++ b/crates/weaver_resolver/data/registry-test-5-metrics/expected-registry.json @@ -3,9 +3,7 @@ "groups": [ { "id": "attributes.faas.common", - "typed_group": { - "type": "AttributeGroup" - }, + "type": "attribute_group", "brief": "Describes FaaS attributes.", "prefix": "faas", "attributes": [ @@ -20,16 +18,14 @@ }, { "id": "metric.faas.invoke_duration", - "typed_group": { - "type": "Metric", - "metric_name": "faas.invoke_duration", - "instrument": "Histogram", - "unit": "s" - }, + "type": "metric", "brief": "Measures the duration of the function's logic execution", "attributes": [ 0 ], + "metric_name": "faas.invoke_duration", + "instrument": "histogram", + "unit": "s", "lineage": { "provenance": "data/registry-test-5-metrics/registry/faas-metrics.yaml", "attributes": { @@ -72,16 +68,14 @@ }, { "id": "metric.faas.init_duration", - "typed_group": { - "type": "Metric", - "metric_name": "faas.init_duration", - "instrument": "Histogram", - "unit": "s" - }, + "type": "metric", "brief": "Measures the duration of the function's initialization, such as a cold start", "attributes": [ 0 ], + "metric_name": "faas.init_duration", + "instrument": "histogram", + "unit": "s", "lineage": { "provenance": "data/registry-test-5-metrics/registry/faas-metrics.yaml", "attributes": { @@ -124,16 +118,14 @@ }, { "id": "metric.faas.coldstarts", - "typed_group": { - "type": "Metric", - "metric_name": "faas.coldstarts", - "instrument": "Counter", - "unit": "{coldstart}" - }, + "type": "metric", "brief": "Number of invocation cold starts", "attributes": [ 0 ], + "metric_name": "faas.coldstarts", + "instrument": "counter", + "unit": "{coldstart}", "lineage": { "provenance": "data/registry-test-5-metrics/registry/faas-metrics.yaml", "attributes": { @@ -176,16 +168,14 @@ }, { "id": "metric.faas.errors", - "typed_group": { - "type": "Metric", - "metric_name": "faas.errors", - "instrument": "Counter", - "unit": "{error}" - }, + "type": "metric", "brief": "Number of invocation errors", "attributes": [ 0 ], + "metric_name": "faas.errors", + "instrument": "counter", + "unit": "{error}", "lineage": { "provenance": "data/registry-test-5-metrics/registry/faas-metrics.yaml", "attributes": { @@ -228,16 +218,14 @@ }, { "id": "metric.faas.invocations", - "typed_group": { - "type": "Metric", - "metric_name": "faas.invocations", - "instrument": "Counter", - "unit": "{invocation}" - }, + "type": "metric", "brief": "Number of successful invocations", "attributes": [ 0 ], + "metric_name": "faas.invocations", + "instrument": "counter", + "unit": "{invocation}", "lineage": { "provenance": "data/registry-test-5-metrics/registry/faas-metrics.yaml", "attributes": { @@ -280,16 +268,14 @@ }, { "id": "metric.faas.timeouts", - "typed_group": { - "type": "Metric", - "metric_name": "faas.timeouts", - "instrument": "Counter", - "unit": "{timeout}" - }, + "type": "metric", "brief": "Number of invocation timeouts", "attributes": [ 0 ], + "metric_name": "faas.timeouts", + "instrument": "counter", + "unit": "{timeout}", "lineage": { "provenance": "data/registry-test-5-metrics/registry/faas-metrics.yaml", "attributes": { @@ -332,16 +318,14 @@ }, { "id": "metric.faas.mem_usage", - "typed_group": { - "type": "Metric", - "metric_name": "faas.mem_usage", - "instrument": "Histogram", - "unit": "By" - }, + "type": "metric", "brief": "Distribution of max memory usage per invocation", "attributes": [ 0 ], + "metric_name": "faas.mem_usage", + "instrument": "histogram", + "unit": "By", "lineage": { "provenance": "data/registry-test-5-metrics/registry/faas-metrics.yaml", "attributes": { @@ -384,16 +368,14 @@ }, { "id": "metric.faas.cpu_usage", - "typed_group": { - "type": "Metric", - "metric_name": "faas.cpu_usage", - "instrument": "Histogram", - "unit": "s" - }, + "type": "metric", "brief": "Distribution of CPU usage per invocation", "attributes": [ 0 ], + "metric_name": "faas.cpu_usage", + "instrument": "histogram", + "unit": "s", "lineage": { "provenance": "data/registry-test-5-metrics/registry/faas-metrics.yaml", "attributes": { @@ -436,16 +418,14 @@ }, { "id": "metric.faas.net_io", - "typed_group": { - "type": "Metric", - "metric_name": "faas.net_io", - "instrument": "Histogram", - "unit": "By" - }, + "type": "metric", "brief": "Distribution of net I/O usage per invocation", "attributes": [ 0 ], + "metric_name": "faas.net_io", + "instrument": "histogram", + "unit": "By", "lineage": { "provenance": "data/registry-test-5-metrics/registry/faas-metrics.yaml", "attributes": { diff --git a/crates/weaver_resolver/data/registry-test-6-resources/expected-registry.json b/crates/weaver_resolver/data/registry-test-6-resources/expected-registry.json index dc1d9fe9..f1939e85 100644 --- a/crates/weaver_resolver/data/registry-test-6-resources/expected-registry.json +++ b/crates/weaver_resolver/data/registry-test-6-resources/expected-registry.json @@ -3,9 +3,7 @@ "groups": [ { "id": "registry.user_agent", - "typed_group": { - "type": "AttributeGroup" - }, + "type": "attribute_group", "brief": "Describes user-agent attributes.", "prefix": "user_agent", "attributes": [ @@ -17,9 +15,7 @@ }, { "id": "browser", - "typed_group": { - "type": "Resource" - }, + "type": "resource", "brief": "The web browser in which the application represented by the resource is running. The `browser.*` attributes MUST be used only for resources that represent applications running in a web browser (regardless of whether running on a mobile or desktop device).\n", "prefix": "browser", "attributes": [ diff --git a/crates/weaver_resolver/data/registry-test-7-spans/expected-registry.json b/crates/weaver_resolver/data/registry-test-7-spans/expected-registry.json index ea4d44f2..a557ba81 100644 --- a/crates/weaver_resolver/data/registry-test-7-spans/expected-registry.json +++ b/crates/weaver_resolver/data/registry-test-7-spans/expected-registry.json @@ -3,9 +3,7 @@ "groups": [ { "id": "registry.db", - "typed_group": { - "type": "AttributeGroup" - }, + "type": "attribute_group", "brief": "This document defines the attributes used to describe telemetry in the context of databases.\n", "prefix": "db", "attributes": [ @@ -46,9 +44,7 @@ }, { "id": "registry.http", - "typed_group": { - "type": "AttributeGroup" - }, + "type": "attribute_group", "brief": "This document defines semantic convention attributes in the HTTP namespace.", "prefix": "http", "attributes": [ @@ -68,9 +64,7 @@ }, { "id": "registry.network", - "typed_group": { - "type": "AttributeGroup" - }, + "type": "attribute_group", "brief": "These attributes may be used for any network related operation.\n", "prefix": "network", "attributes": [ @@ -96,9 +90,7 @@ }, { "id": "server", - "typed_group": { - "type": "AttributeGroup" - }, + "type": "attribute_group", "brief": "These attributes may be used to describe the server in a connection-based network interaction where there is one side that initiates the connection (the client is the side that initiates the connection). This covers all TCP network interactions since TCP is connection-based and one side initiates the connection (an exception is made for peer-to-peer communication over TCP where the \"user-facing\" surface of the protocol / API doesn't expose a clear notion of client and server). This also covers UDP network interactions where one side initiates the interaction, e.g. QUIC (HTTP/3) and DNS.\n", "prefix": "server", "attributes": [ @@ -111,9 +103,7 @@ }, { "id": "registry.url", - "typed_group": { - "type": "AttributeGroup" - }, + "type": "attribute_group", "brief": "Attributes describing URL.", "prefix": "url", "attributes": [ @@ -129,9 +119,7 @@ }, { "id": "registry.user_agent", - "typed_group": { - "type": "AttributeGroup" - }, + "type": "attribute_group", "brief": "Describes user-agent attributes.", "prefix": "user_agent", "attributes": [ @@ -143,11 +131,7 @@ }, { "id": "db", - "typed_group": { - "type": "Span", - "span_kind": "Client", - "events": [] - }, + "type": "span", "brief": "This document defines the attributes used to perform database client calls.\n", "attributes": [ 62, @@ -165,6 +149,8 @@ 74, 75 ], + "span_kind": "client", + "events": [], "lineage": { "provenance": "data/registry-test-7-spans/registry/trace-database.yaml", "attributes": { @@ -561,11 +547,7 @@ }, { "id": "db.mssql", - "typed_group": { - "type": "Span", - "span_kind": null, - "events": [] - }, + "type": "span", "brief": "Connection-level attributes for Microsoft SQL Server\n", "attributes": [ 62, @@ -584,6 +566,8 @@ 75, 76 ], + "span_kind": null, + "events": [], "lineage": { "provenance": "data/registry-test-7-spans/registry/trace-database.yaml", "attributes": { @@ -706,11 +690,7 @@ }, { "id": "db.cassandra", - "typed_group": { - "type": "Span", - "span_kind": null, - "events": [] - }, + "type": "span", "brief": "Call-level attributes for Cassandra\n", "attributes": [ 62, @@ -736,6 +716,8 @@ 83, 84 ], + "span_kind": null, + "events": [], "lineage": { "provenance": "data/registry-test-7-spans/registry/trace-database.yaml", "attributes": { @@ -1056,11 +1038,7 @@ }, { "id": "db.hbase", - "typed_group": { - "type": "Span", - "span_kind": null, - "events": [] - }, + "type": "span", "brief": "Call-level attributes for HBase\n", "attributes": [ 62, @@ -1079,6 +1057,8 @@ 75, 85 ], + "span_kind": null, + "events": [], "lineage": { "provenance": "data/registry-test-7-spans/registry/trace-database.yaml", "attributes": { @@ -1189,11 +1169,7 @@ }, { "id": "db.couchdb", - "typed_group": { - "type": "Span", - "span_kind": null, - "events": [] - }, + "type": "span", "brief": "Call-level attributes for CouchDB\n", "attributes": [ 62, @@ -1212,6 +1188,8 @@ 75, 86 ], + "span_kind": null, + "events": [], "lineage": { "provenance": "data/registry-test-7-spans/registry/trace-database.yaml", "attributes": { @@ -1322,11 +1300,7 @@ }, { "id": "db.redis", - "typed_group": { - "type": "Span", - "span_kind": null, - "events": [] - }, + "type": "span", "brief": "Call-level attributes for Redis\n", "attributes": [ 62, @@ -1346,6 +1320,8 @@ 87, 88 ], + "span_kind": null, + "events": [], "lineage": { "provenance": "data/registry-test-7-spans/registry/trace-database.yaml", "attributes": { @@ -1482,11 +1458,7 @@ }, { "id": "db.mongodb", - "typed_group": { - "type": "Span", - "span_kind": null, - "events": [] - }, + "type": "span", "brief": "Call-level attributes for MongoDB\n", "attributes": [ 62, @@ -1505,6 +1477,8 @@ 75, 89 ], + "span_kind": null, + "events": [], "lineage": { "provenance": "data/registry-test-7-spans/registry/trace-database.yaml", "attributes": { @@ -1623,11 +1597,7 @@ }, { "id": "db.elasticsearch", - "typed_group": { - "type": "Span", - "span_kind": null, - "events": [] - }, + "type": "span", "brief": "Call-level attributes for Elasticsearch\n", "attributes": [ 62, @@ -1654,6 +1624,8 @@ 97, 98 ], + "span_kind": null, + "events": [], "lineage": { "provenance": "data/registry-test-7-spans/registry/trace-database.yaml", "attributes": { @@ -1968,11 +1940,7 @@ }, { "id": "db.sql", - "typed_group": { - "type": "Span", - "span_kind": null, - "events": [] - }, + "type": "span", "brief": "Call-level attributes for SQL databases\n", "attributes": [ 62, @@ -1991,6 +1959,8 @@ 75, 99 ], + "span_kind": null, + "events": [], "lineage": { "provenance": "data/registry-test-7-spans/registry/trace-database.yaml", "attributes": { @@ -2113,11 +2083,7 @@ }, { "id": "db.cosmosdb", - "typed_group": { - "type": "Span", - "span_kind": null, - "events": [] - }, + "type": "span", "brief": "Call-level attributes for Cosmos DB.\n", "prefix": "db.cosmosdb", "attributes": [ @@ -2145,6 +2111,8 @@ 107, 108 ], + "span_kind": null, + "events": [], "lineage": { "provenance": "data/registry-test-7-spans/registry/trace-database.yaml", "attributes": { @@ -2471,11 +2439,7 @@ }, { "id": "db.tech", - "typed_group": { - "type": "Span", - "span_kind": null, - "events": [] - }, + "type": "span", "brief": "Semantic convention group for specific technologies", "constraints": [], "attributes": [ @@ -2515,6 +2479,8 @@ 107, 108 ], + "span_kind": null, + "events": [], "lineage": { "provenance": "data/registry-test-7-spans/registry/trace-database.yaml" } diff --git a/crates/weaver_resolver/src/attribute.rs b/crates/weaver_resolver/src/attribute.rs index 741ed921..dcac29cf 100644 --- a/crates/weaver_resolver/src/attribute.rs +++ b/crates/weaver_resolver/src/attribute.rs @@ -14,7 +14,7 @@ use weaver_semconv::attribute::{ AttributeSpec, AttributeTypeSpec, BasicRequirementLevelSpec, ExamplesSpec, PrimitiveOrArrayTypeSpec, RequirementLevelSpec, TemplateTypeSpec, ValueSpec, }; -use weaver_semconv::group::ConvTypeSpec; +use weaver_semconv::group::GroupType; use weaver_semconv::SemConvRegistry; use weaver_version::VersionAttributeChanges; @@ -270,7 +270,7 @@ pub fn resolve_attributes( } = attribute { let attrs = semconv_registry - .attributes(attribute_group_ref, ConvTypeSpec::AttributeGroup) + .attributes(attribute_group_ref, GroupType::AttributeGroup) .map_err(|e| Error::FailToResolveAttributes { ids: vec![attribute_group_ref.clone()], error: e.to_string(), @@ -283,7 +283,7 @@ pub fn resolve_attributes( for attribute in attributes.iter() { if let Attribute::ResourceRef { resource_ref, tags } = attribute { let attrs = semconv_registry - .attributes(resource_ref, ConvTypeSpec::Resource) + .attributes(resource_ref, GroupType::Resource) .map_err(|e| Error::FailToResolveAttributes { ids: vec![resource_ref.clone()], error: e.to_string(), @@ -296,7 +296,7 @@ pub fn resolve_attributes( for attribute in attributes.iter() { if let Attribute::SpanRef { span_ref, tags } = attribute { let attrs = semconv_registry - .attributes(span_ref, ConvTypeSpec::Span) + .attributes(span_ref, GroupType::Span) .map_err(|e| Error::FailToResolveAttributes { ids: vec![span_ref.clone()], error: e.to_string(), @@ -309,7 +309,7 @@ pub fn resolve_attributes( for attribute in attributes.iter() { if let Attribute::EventRef { event_ref, tags } = attribute { let attrs = semconv_registry - .attributes(event_ref, ConvTypeSpec::Event) + .attributes(event_ref, GroupType::Event) .map_err(|e| Error::FailToResolveAttributes { ids: vec![event_ref.clone()], error: e.to_string(), diff --git a/crates/weaver_resolver/src/registry.rs b/crates/weaver_resolver/src/registry.rs index 3c699e65..9e1ee31d 100644 --- a/crates/weaver_resolver/src/registry.rs +++ b/crates/weaver_resolver/src/registry.rs @@ -8,15 +8,12 @@ use serde::Deserialize; use weaver_resolved_schema::attribute::UnresolvedAttribute; use weaver_resolved_schema::lineage::{FieldId, FieldLineage, GroupLineage, ResolutionMode}; -use weaver_resolved_schema::registry::{Constraint, Group, Registry, TypedGroup}; +use weaver_resolved_schema::registry::{Constraint, Group, Registry}; use weaver_semconv::attribute::AttributeSpec; -use weaver_semconv::group::ConvTypeSpec; use weaver_semconv::{GroupSpecWithProvenance, SemConvRegistry}; use crate::attribute::AttributeCatalog; use crate::constraint::resolve_constraints; -use crate::metrics::resolve_instrument; -use crate::spans::resolve_span_kind; use crate::stability::resolve_stability; use crate::{handle_errors, Error, UnsatisfiedAnyOfConstraint}; @@ -285,24 +282,7 @@ fn group_from_spec(group: GroupSpecWithProvenance) -> UnresolvedGroup { UnresolvedGroup { group: Group { id: group.spec.id, - typed_group: match group.spec.r#type { - ConvTypeSpec::AttributeGroup => TypedGroup::AttributeGroup {}, - ConvTypeSpec::Span => TypedGroup::Span { - span_kind: group.spec.span_kind.as_ref().map(resolve_span_kind), - events: group.spec.events, - }, - ConvTypeSpec::Event => TypedGroup::Event { - name: group.spec.name, - }, - ConvTypeSpec::Metric => TypedGroup::Metric { - metric_name: group.spec.metric_name, - instrument: group.spec.instrument.as_ref().map(resolve_instrument), - unit: group.spec.unit, - }, - ConvTypeSpec::MetricGroup => TypedGroup::MetricGroup {}, - ConvTypeSpec::Resource => TypedGroup::Resource {}, - ConvTypeSpec::Scope => TypedGroup::Scope {}, - }, + r#type: group.spec.r#type, brief: group.spec.brief, note: group.spec.note, prefix: group.spec.prefix, @@ -311,6 +291,12 @@ fn group_from_spec(group: GroupSpecWithProvenance) -> UnresolvedGroup { deprecated: group.spec.deprecated, constraints: resolve_constraints(&group.spec.constraints), attributes: vec![], + span_kind: group.spec.span_kind, + events: group.spec.events, + metric_name: group.spec.metric_name, + instrument: group.spec.instrument, + unit: group.spec.unit, + name: group.spec.name, lineage: Some(GroupLineage::new(group.provenance.clone())), }, attributes: attrs, diff --git a/crates/weaver_resolver/src/spans.rs b/crates/weaver_resolver/src/spans.rs index b46d1745..ab5884a9 100644 --- a/crates/weaver_resolver/src/spans.rs +++ b/crates/weaver_resolver/src/spans.rs @@ -5,7 +5,6 @@ use crate::attribute::resolve_attributes; use crate::Error; use weaver_schema::schema_spec::SchemaSpec; -use weaver_semconv::group::SpanKindSpec; use weaver_semconv::SemConvRegistry; use weaver_version::VersionChanges; @@ -45,14 +44,3 @@ pub fn resolve_spans( } Ok(()) } - -/// Resolve a span kind. -pub fn resolve_span_kind(span_kind: &SpanKindSpec) -> weaver_resolved_schema::signal::SpanKind { - match span_kind { - SpanKindSpec::Client => weaver_resolved_schema::signal::SpanKind::Client, - SpanKindSpec::Consumer => weaver_resolved_schema::signal::SpanKind::Consumer, - SpanKindSpec::Internal => weaver_resolved_schema::signal::SpanKind::Internal, - SpanKindSpec::Producer => weaver_resolved_schema::signal::SpanKind::Producer, - SpanKindSpec::Server => weaver_resolved_schema::signal::SpanKind::Server, - } -} diff --git a/crates/weaver_semconv/src/group.rs b/crates/weaver_semconv/src/group.rs index cb7a1603..ac0c1e92 100644 --- a/crates/weaver_semconv/src/group.rs +++ b/crates/weaver_semconv/src/group.rs @@ -22,7 +22,7 @@ pub struct GroupSpec { pub id: String, /// The type of the semantic convention (default to span). #[serde(default)] - pub r#type: ConvTypeSpec, + pub r#type: GroupType, /// A brief description of the semantic convention. pub brief: String, /// A more elaborate description of the semantic convention. @@ -98,7 +98,7 @@ fn validate_group(group: &GroupSpec) -> Result<(), ValidationError> { } // Fields span_kind and events are only valid if type is span (the default). - if group.r#type != ConvTypeSpec::Span { + if group.r#type != GroupType::Span { if group.span_kind.is_some() { return Err(ValidationError::new( "This group contains a span_kind field but the type is not set to span.", @@ -112,14 +112,14 @@ fn validate_group(group: &GroupSpec) -> Result<(), ValidationError> { } // Field name is required if prefix is empty and if type is event. - if group.r#type == ConvTypeSpec::Event && group.prefix.is_empty() && group.name.is_none() { + if group.r#type == GroupType::Event && group.prefix.is_empty() && group.name.is_none() { return Err(ValidationError::new( "This group contains an event type but the prefix is empty and the name is not set.", )); } // Fields metric_name, instrument and unit are required if type is metric. - if group.r#type == ConvTypeSpec::Metric { + if group.r#type == GroupType::Metric { if group.metric_name.is_none() { return Err(ValidationError::new( "This group contains a metric type but the metric_name is not set.", @@ -202,7 +202,7 @@ fn validate_group(group: &GroupSpec) -> Result<(), ValidationError> { /// The different types of groups (specification). #[derive(Serialize, Deserialize, Debug, PartialEq, Clone)] #[serde(rename_all = "snake_case")] -pub enum ConvTypeSpec { +pub enum GroupType { /// Attribute group (attribute_group type) defines a set of attributes that /// can be declared once and referenced by semantic conventions for /// different signals, for example spans and logs. Attribute groups don't @@ -223,7 +223,7 @@ pub enum ConvTypeSpec { Scope, } -impl Default for ConvTypeSpec { +impl Default for GroupType { /// Returns the default convention type that is span based on /// the OpenTelemetry specification. fn default() -> Self { @@ -232,7 +232,7 @@ impl Default for ConvTypeSpec { } /// The span kind. -#[derive(Serialize, Deserialize, Debug, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] #[serde(rename_all = "snake_case")] pub enum SpanKindSpec { /// An internal span. @@ -263,7 +263,7 @@ pub struct ConstraintSpec { } /// The type of the metric. -#[derive(Serialize, Deserialize, Debug, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] #[serde(rename_all = "snake_case")] pub enum InstrumentSpec { /// An up-down counter metric. diff --git a/crates/weaver_semconv/src/lib.rs b/crates/weaver_semconv/src/lib.rs index 64daa7b0..9cdb2f09 100644 --- a/crates/weaver_semconv/src/lib.rs +++ b/crates/weaver_semconv/src/lib.rs @@ -406,12 +406,12 @@ impl SemConvRegistry { for group in spec.groups.iter() { // Process attributes match group.r#type { - group::ConvTypeSpec::AttributeGroup - | group::ConvTypeSpec::Span - | group::ConvTypeSpec::Resource - | group::ConvTypeSpec::Metric - | group::ConvTypeSpec::Event - | group::ConvTypeSpec::MetricGroup => { + group::GroupType::AttributeGroup + | group::GroupType::Span + | group::GroupType::Resource + | group::GroupType::Metric + | group::GroupType::Event + | group::GroupType::MetricGroup => { let attributes_in_group = self.process_attributes( provenance.clone(), group.id.clone(), @@ -421,16 +421,14 @@ impl SemConvRegistry { )?; let group_attributes = match group.r#type { - group::ConvTypeSpec::AttributeGroup => { + group::GroupType::AttributeGroup => { Some(&mut self.attr_grp_group_attributes) } - group::ConvTypeSpec::Span => Some(&mut self.span_group_attributes), - group::ConvTypeSpec::Resource => { - Some(&mut self.resource_group_attributes) - } - group::ConvTypeSpec::Metric => Some(&mut self.metric_group_attributes), - group::ConvTypeSpec::Event => Some(&mut self.event_group_attributes), - group::ConvTypeSpec::MetricGroup => { + group::GroupType::Span => Some(&mut self.span_group_attributes), + group::GroupType::Resource => Some(&mut self.resource_group_attributes), + group::GroupType::Metric => Some(&mut self.metric_group_attributes), + group::GroupType::Event => Some(&mut self.event_group_attributes), + group::GroupType::MetricGroup => { Some(&mut self.metric_group_group_attributes) } _ => None, @@ -461,7 +459,7 @@ impl SemConvRegistry { // Process metrics match group.r#type { - group::ConvTypeSpec::Metric => { + group::GroupType::Metric => { let metric_name = if let Some(metric_name) = group.metric_name.as_ref() { metric_name.clone() } else { @@ -519,7 +517,7 @@ impl SemConvRegistry { } } } - group::ConvTypeSpec::MetricGroup => { + group::GroupType::MetricGroup => { eprintln!("Warning: group type `metric_group` not implemented yet"); } _ => { @@ -621,17 +619,17 @@ impl SemConvRegistry { pub fn attributes( &self, r#ref: &str, - r#type: group::ConvTypeSpec, + r#type: group::GroupType, ) -> Result, Error> { let mut attributes = HashMap::new(); let group_ids = match r#type { - group::ConvTypeSpec::AttributeGroup => self.attr_grp_group_attributes.get(r#ref), - group::ConvTypeSpec::Span => self.span_group_attributes.get(r#ref), - group::ConvTypeSpec::Event => self.event_group_attributes.get(r#ref), - group::ConvTypeSpec::Metric => self.metric_group_attributes.get(r#ref), - group::ConvTypeSpec::MetricGroup => self.metric_group_group_attributes.get(r#ref), - group::ConvTypeSpec::Resource => self.resource_group_attributes.get(r#ref), - group::ConvTypeSpec::Scope => panic!("Scope not implemented yet"), + group::GroupType::AttributeGroup => self.attr_grp_group_attributes.get(r#ref), + group::GroupType::Span => self.span_group_attributes.get(r#ref), + group::GroupType::Event => self.event_group_attributes.get(r#ref), + group::GroupType::Metric => self.metric_group_attributes.get(r#ref), + group::GroupType::MetricGroup => self.metric_group_group_attributes.get(r#ref), + group::GroupType::Resource => self.resource_group_attributes.get(r#ref), + group::GroupType::Scope => panic!("Scope not implemented yet"), }; if let Some(group_ids) = group_ids { for attr_id in group_ids.ids.iter() { From 810948640cdc66661df0cf4458958e27a52e3d40 Mon Sep 17 00:00:00 2001 From: Laurent Querel Date: Wed, 6 Mar 2024 14:17:30 -0800 Subject: [PATCH 11/20] chore(compatibility): align requirement level definition --- crates/weaver_forge/templates/test/group.md | 10 +++---- .../weaver_resolved_schema/src/attribute.rs | 24 +--------------- crates/weaver_resolver/src/attribute.rs | 28 ++++--------------- crates/weaver_schema/src/attribute.rs | 6 ++-- crates/weaver_semconv/src/attribute.rs | 24 ++++++++-------- src/search/schema/attributes.rs | 4 +-- src/search/semconv/attributes.rs | 4 +-- 7 files changed, 30 insertions(+), 70 deletions(-) diff --git a/crates/weaver_forge/templates/test/group.md b/crates/weaver_forge/templates/test/group.md index 144701fd..799a842c 100644 --- a/crates/weaver_forge/templates/test/group.md +++ b/crates/weaver_forge/templates/test/group.md @@ -5,20 +5,20 @@ ## Brief -{{ group.brief }} - +{{ group.brief }} ## Attributes -{%- for attribute in group.attributes %} +{% for attribute in group.attributes -%} ### Attribute `{{ attribute.name }}` +Requirement level: {{ attribute.requirement_level }} {% if attribute.tag -%} -tag: {{ attribute.tag }} +Tag: {{ attribute.tag }} {%- endif %} {{ attribute.brief }} -{%- endfor %} +{% endfor %} ## Provenance diff --git a/crates/weaver_resolved_schema/src/attribute.rs b/crates/weaver_resolved_schema/src/attribute.rs index 13e73a01..6242235a 100644 --- a/crates/weaver_resolved_schema/src/attribute.rs +++ b/crates/weaver_resolved_schema/src/attribute.rs @@ -10,7 +10,7 @@ use crate::value::Value; use ordered_float::OrderedFloat; use serde::{Deserialize, Serialize}; use std::fmt::Display; -use weaver_semconv::attribute::AttributeSpec; +use weaver_semconv::attribute::{AttributeSpec, RequirementLevel}; /// An attribute definition. #[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq, Hash)] @@ -216,28 +216,6 @@ impl Example { } } -/// The different requirement levels. -#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq, Hash)] -#[serde(tag = "type")] -pub enum RequirementLevel { - /// A required requirement level. - Required, - /// An optional requirement level. - Recommended { - /// The description of the recommendation. - #[serde(skip_serializing_if = "Option::is_none")] - text: Option, - }, - /// An opt-in requirement level. - OptIn, - /// A conditional requirement level. - ConditionallyRequired { - /// The description of the condition. - #[serde(skip_serializing_if = "String::is_empty")] - text: String, - }, -} - /// An internal reference to an attribute in the catalog. #[derive(Serialize, Deserialize, Debug, Copy, Clone, Eq, PartialEq, PartialOrd, Ord)] pub struct AttributeRef(pub u32); diff --git a/crates/weaver_resolver/src/attribute.rs b/crates/weaver_resolver/src/attribute.rs index dcac29cf..7f8c5c58 100644 --- a/crates/weaver_resolver/src/attribute.rs +++ b/crates/weaver_resolver/src/attribute.rs @@ -11,8 +11,8 @@ use weaver_resolved_schema::lineage::{FieldId, FieldLineage, GroupLineage, Resol use weaver_schema::attribute::Attribute; use weaver_schema::tags::Tags; use weaver_semconv::attribute::{ - AttributeSpec, AttributeTypeSpec, BasicRequirementLevelSpec, ExamplesSpec, - PrimitiveOrArrayTypeSpec, RequirementLevelSpec, TemplateTypeSpec, ValueSpec, + AttributeSpec, AttributeTypeSpec, ExamplesSpec, + PrimitiveOrArrayTypeSpec, TemplateTypeSpec, ValueSpec, }; use weaver_semconv::group::GroupType; use weaver_semconv::SemConvRegistry; @@ -122,7 +122,7 @@ impl AttributeCatalog { }, requirement_level: match requirement_level { Some(requirement_level) => { - semconv_to_resolved_req_level(requirement_level) + requirement_level.clone() } None => { inherited_fields.push(FieldId::AttributeRequirementLevel); @@ -212,7 +212,7 @@ impl AttributeCatalog { brief: brief.clone().unwrap_or_default(), examples: semconv_to_resolved_examples(examples), tag: tag.clone(), - requirement_level: semconv_to_resolved_req_level(requirement_level), + requirement_level: requirement_level.clone(), sampling_relevant: *sampling_relevant, note: note.clone(), stability: stability::resolve_stability(stability), @@ -431,7 +431,7 @@ pub fn resolve_attribute( brief: brief.clone().unwrap_or_default(), examples: semconv_to_resolved_examples(examples), tag: tag.clone(), - requirement_level: semconv_to_resolved_req_level(requirement_level), + requirement_level: requirement_level.clone(), sampling_relevant: *sampling_relevant, note: note.clone(), stability: stability::resolve_stability(stability), @@ -505,24 +505,6 @@ fn semconv_to_resolved_examples(examples: &Option) -> Option attribute::RequirementLevel { - match req_level { - RequirementLevelSpec::Basic(level) => match level { - BasicRequirementLevelSpec::Required => attribute::RequirementLevel::Required, - BasicRequirementLevelSpec::Recommended => { - attribute::RequirementLevel::Recommended { text: None } - } - BasicRequirementLevelSpec::OptIn => attribute::RequirementLevel::OptIn, - }, - RequirementLevelSpec::Recommended { text } => attribute::RequirementLevel::Recommended { - text: Some(text.clone()), - }, - RequirementLevelSpec::ConditionallyRequired { text } => { - attribute::RequirementLevel::ConditionallyRequired { text: text.clone() } - } - } -} - #[allow(dead_code)] // ToDo Remove this once we have values in the resolved schema fn semconv_to_resolved_value( value: &Option, diff --git a/crates/weaver_schema/src/attribute.rs b/crates/weaver_schema/src/attribute.rs index 36e0b396..198f15ba 100644 --- a/crates/weaver_schema/src/attribute.rs +++ b/crates/weaver_schema/src/attribute.rs @@ -6,7 +6,7 @@ use serde::{Deserialize, Serialize}; -use weaver_semconv::attribute::{AttributeTypeSpec, ExamplesSpec, RequirementLevelSpec, ValueSpec}; +use weaver_semconv::attribute::{AttributeTypeSpec, ExamplesSpec, RequirementLevel, ValueSpec}; use weaver_semconv::stability::StabilitySpec; use crate::tags::Tags; @@ -50,7 +50,7 @@ pub enum Attribute { /// "conditionally_required", the string provided as MUST /// specify the conditions under which the attribute is required. #[serde(skip_serializing_if = "Option::is_none")] - requirement_level: Option, + requirement_level: Option, /// Specifies if the attribute is (especially) relevant for sampling /// and thus should be set at span start. It defaults to false. /// Note: this field is experimental. @@ -152,7 +152,7 @@ pub enum Attribute { /// "conditionally_required", the string provided as MUST /// specify the conditions under which the attribute is required. #[serde(default)] - requirement_level: RequirementLevelSpec, + requirement_level: RequirementLevel, /// Specifies if the attribute is (especially) relevant for sampling /// and thus should be set at span start. It defaults to false. /// Note: this field is experimental. diff --git a/crates/weaver_semconv/src/attribute.rs b/crates/weaver_semconv/src/attribute.rs index d138df4d..b6f5a0fa 100644 --- a/crates/weaver_semconv/src/attribute.rs +++ b/crates/weaver_semconv/src/attribute.rs @@ -43,7 +43,7 @@ pub enum AttributeSpec { /// "conditionally_required", the string provided as MUST /// specify the conditions under which the attribute is required. #[serde(skip_serializing_if = "Option::is_none")] - requirement_level: Option, + requirement_level: Option, /// Specifies if the attribute is (especially) relevant for sampling /// and thus should be set at span start. It defaults to false. /// Note: this field is experimental. @@ -94,7 +94,7 @@ pub enum AttributeSpec { /// "conditionally_required", the string provided as MUST /// specify the conditions under which the attribute is required. #[serde(default)] - requirement_level: RequirementLevelSpec, + requirement_level: RequirementLevel, /// Specifies if the attribute is (especially) relevant for sampling /// and thus should be set at span start. It defaults to false. /// Note: this field is experimental. @@ -125,12 +125,12 @@ impl AttributeSpec { matches!( self, AttributeSpec::Ref { - requirement_level: Some(RequirementLevelSpec::Basic( + requirement_level: Some(RequirementLevel::Basic( BasicRequirementLevelSpec::Required )), .. } | AttributeSpec::Id { - requirement_level: RequirementLevelSpec::Basic(BasicRequirementLevelSpec::Required), + requirement_level: RequirementLevel::Basic(BasicRequirementLevelSpec::Required), .. } ) @@ -372,10 +372,10 @@ pub enum ExamplesSpec { } /// The different requirement level specifications. -#[derive(Serialize, Deserialize, Debug, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq, Hash)] #[serde(rename_all = "snake_case")] #[serde(untagged)] -pub enum RequirementLevelSpec { +pub enum RequirementLevel { /// A basic requirement level. Basic(BasicRequirementLevelSpec), /// A conditional requirement level. @@ -393,23 +393,23 @@ pub enum RequirementLevelSpec { } /// Implements a human readable display for RequirementLevel. -impl Display for RequirementLevelSpec { +impl Display for RequirementLevel { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { match self { - RequirementLevelSpec::Basic(brl) => write!(f, "{}", brl), - RequirementLevelSpec::ConditionallyRequired { text } => { + RequirementLevel::Basic(brl) => write!(f, "{}", brl), + RequirementLevel::ConditionallyRequired { text } => { write!(f, "conditionally required (condition: {})", text) } - RequirementLevelSpec::Recommended { text } => write!(f, "recommended ({})", text), + RequirementLevel::Recommended { text } => write!(f, "recommended ({})", text), } } } // Specifies the default requirement level as defined in the OTel // specification. -impl Default for RequirementLevelSpec { +impl Default for RequirementLevel { fn default() -> Self { - RequirementLevelSpec::Basic(BasicRequirementLevelSpec::Recommended) + RequirementLevel::Basic(BasicRequirementLevelSpec::Recommended) } } diff --git a/src/search/schema/attributes.rs b/src/search/schema/attributes.rs index 6499338e..f91838bf 100644 --- a/src/search/schema/attributes.rs +++ b/src/search/schema/attributes.rs @@ -6,7 +6,7 @@ use crate::search::theme::ThemeConfig; use ratatui::style::Style; use ratatui::text::{Line, Span}; use weaver_schema::attribute::Attribute; -use weaver_semconv::attribute::{BasicRequirementLevelSpec, RequirementLevelSpec}; +use weaver_semconv::attribute::{BasicRequirementLevelSpec, RequirementLevel}; /// Append attributes to the text. pub fn append_lines(attributes: &[Attribute], text: &mut Vec, theme: &ThemeConfig) { @@ -26,7 +26,7 @@ pub fn append_lines(attributes: &[Attribute], text: &mut Vec, theme: &Them } = attr { let mut properties = vec![format!("type={}", r#type)]; - if let RequirementLevelSpec::Basic(BasicRequirementLevelSpec::Required) = + if let RequirementLevel::Basic(BasicRequirementLevelSpec::Required) = requirement_level { properties.push("required".to_string()); diff --git a/src/search/semconv/attributes.rs b/src/search/semconv/attributes.rs index a181f5f3..f550b1d5 100644 --- a/src/search/semconv/attributes.rs +++ b/src/search/semconv/attributes.rs @@ -5,7 +5,7 @@ use crate::search::theme::ThemeConfig; use ratatui::style::Style; use ratatui::text::{Line, Span}; -use weaver_semconv::attribute::{AttributeSpec, BasicRequirementLevelSpec, RequirementLevelSpec}; +use weaver_semconv::attribute::{AttributeSpec, BasicRequirementLevelSpec, RequirementLevel}; /// Append attributes to the text. pub fn append_lines(attributes: &[AttributeSpec], text: &mut Vec, theme: &ThemeConfig) { @@ -23,7 +23,7 @@ pub fn append_lines(attributes: &[AttributeSpec], text: &mut Vec, theme: & } = attr { let mut properties = vec![format!("type={}", r#type)]; - if let RequirementLevelSpec::Basic(BasicRequirementLevelSpec::Required) = + if let RequirementLevel::Basic(BasicRequirementLevelSpec::Required) = requirement_level { properties.push("required".to_string()); From d8c78f1e57102737ca755b912932d2fc5b65e992 Mon Sep 17 00:00:00 2001 From: Laurent Querel Date: Wed, 6 Mar 2024 14:23:58 -0800 Subject: [PATCH 12/20] chore(compatibility): align stability definition --- crates/weaver_forge/src/registry.rs | 3 ++- crates/weaver_resolved_schema/src/attribute.rs | 2 +- crates/weaver_resolved_schema/src/catalog.rs | 11 ----------- crates/weaver_resolved_schema/src/registry.rs | 2 +- crates/weaver_resolver/src/attribute.rs | 8 ++++---- crates/weaver_resolver/src/lib.rs | 1 - crates/weaver_resolver/src/registry.rs | 3 +-- crates/weaver_resolver/src/stability.rs | 15 --------------- crates/weaver_schema/src/attribute.rs | 6 +++--- crates/weaver_semconv/src/attribute.rs | 6 +++--- crates/weaver_semconv/src/group.rs | 10 +++++----- crates/weaver_semconv/src/stability.rs | 10 +++++----- 12 files changed, 25 insertions(+), 52 deletions(-) delete mode 100644 crates/weaver_resolver/src/stability.rs diff --git a/crates/weaver_forge/src/registry.rs b/crates/weaver_forge/src/registry.rs index 48cc793f..046f6b99 100644 --- a/crates/weaver_forge/src/registry.rs +++ b/crates/weaver_forge/src/registry.rs @@ -7,10 +7,11 @@ use crate::Error; use serde::{Deserialize, Serialize}; use weaver_resolved_schema::attribute::Attribute; -use weaver_resolved_schema::catalog::{Catalog, Stability}; +use weaver_resolved_schema::catalog::Catalog; use weaver_resolved_schema::lineage::GroupLineage; use weaver_resolved_schema::registry::{Constraint, Registry}; use weaver_semconv::group::GroupType; +use weaver_semconv::stability::Stability; /// A semantic convention registry used in the context of the template engine. #[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] diff --git a/crates/weaver_resolved_schema/src/attribute.rs b/crates/weaver_resolved_schema/src/attribute.rs index 6242235a..385a49aa 100644 --- a/crates/weaver_resolved_schema/src/attribute.rs +++ b/crates/weaver_resolved_schema/src/attribute.rs @@ -4,13 +4,13 @@ //! Specification of a resolved attribute. -use crate::catalog::Stability; use crate::tags::Tags; use crate::value::Value; use ordered_float::OrderedFloat; use serde::{Deserialize, Serialize}; use std::fmt::Display; use weaver_semconv::attribute::{AttributeSpec, RequirementLevel}; +use weaver_semconv::stability::Stability; /// An attribute definition. #[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq, Hash)] diff --git a/crates/weaver_resolved_schema/src/catalog.rs b/crates/weaver_resolved_schema/src/catalog.rs index 93739266..84db42c9 100644 --- a/crates/weaver_resolved_schema/src/catalog.rs +++ b/crates/weaver_resolved_schema/src/catalog.rs @@ -21,17 +21,6 @@ pub struct Catalog { pub metrics: Vec, } -/// The level of stability for a definition. -#[derive(Serialize, Deserialize, Clone, Debug, Eq, PartialEq, Hash)] -pub enum Stability { - /// A deprecated definition. - Deprecated, - /// An experimental definition. - Experimental, - /// A stable definition. - Stable, -} - impl Catalog { /// Returns the attribute name from an attribute ref if it exists /// in the catalog or None if it does not exist. diff --git a/crates/weaver_resolved_schema/src/registry.rs b/crates/weaver_resolved_schema/src/registry.rs index 92a9b8ed..e3110e5e 100644 --- a/crates/weaver_resolved_schema/src/registry.rs +++ b/crates/weaver_resolved_schema/src/registry.rs @@ -8,8 +8,8 @@ use crate::attribute::AttributeRef; use serde::{Deserialize, Serialize}; use std::collections::HashSet; use weaver_semconv::group::{GroupType, InstrumentSpec, SpanKindSpec}; +use weaver_semconv::stability::Stability; -use crate::catalog::Stability; use crate::lineage::GroupLineage; /// A semantic convention registry. diff --git a/crates/weaver_resolver/src/attribute.rs b/crates/weaver_resolver/src/attribute.rs index 7f8c5c58..fe4240da 100644 --- a/crates/weaver_resolver/src/attribute.rs +++ b/crates/weaver_resolver/src/attribute.rs @@ -18,7 +18,7 @@ use weaver_semconv::group::GroupType; use weaver_semconv::SemConvRegistry; use weaver_version::VersionAttributeChanges; -use crate::{stability, Error}; +use crate::Error; /// A catalog of deduplicated resolved attributes with their corresponding reference. #[derive(Deserialize, Debug, Default, PartialEq)] @@ -144,7 +144,7 @@ impl AttributeCatalog { } }, stability: match stability { - Some(_) => stability::resolve_stability(stability), + Some(_) => stability.clone(), None => { inherited_fields.push(FieldId::AttributeStability); root_attr.attribute.stability.clone() @@ -215,7 +215,7 @@ impl AttributeCatalog { requirement_level: requirement_level.clone(), sampling_relevant: *sampling_relevant, note: note.clone(), - stability: stability::resolve_stability(stability), + stability: stability.clone(), deprecated: deprecated.clone(), tags: None, value: None, @@ -434,7 +434,7 @@ pub fn resolve_attribute( requirement_level: requirement_level.clone(), sampling_relevant: *sampling_relevant, note: note.clone(), - stability: stability::resolve_stability(stability), + stability: stability.clone(), deprecated: deprecated.clone(), tags: None, value: None, diff --git a/crates/weaver_resolver/src/lib.rs b/crates/weaver_resolver/src/lib.rs index 022f958b..7437b5fa 100644 --- a/crates/weaver_resolver/src/lib.rs +++ b/crates/weaver_resolver/src/lib.rs @@ -40,7 +40,6 @@ mod metrics; pub mod registry; mod resource; mod spans; -mod stability; mod tags; /// A resolver that can be used to resolve telemetry schemas. diff --git a/crates/weaver_resolver/src/registry.rs b/crates/weaver_resolver/src/registry.rs index 9e1ee31d..8b2f6ed7 100644 --- a/crates/weaver_resolver/src/registry.rs +++ b/crates/weaver_resolver/src/registry.rs @@ -14,7 +14,6 @@ use weaver_semconv::{GroupSpecWithProvenance, SemConvRegistry}; use crate::attribute::AttributeCatalog; use crate::constraint::resolve_constraints; -use crate::stability::resolve_stability; use crate::{handle_errors, Error, UnsatisfiedAnyOfConstraint}; /// A registry containing unresolved groups. @@ -287,7 +286,7 @@ fn group_from_spec(group: GroupSpecWithProvenance) -> UnresolvedGroup { note: group.spec.note, prefix: group.spec.prefix, extends: group.spec.extends, - stability: resolve_stability(&group.spec.stability), + stability: group.spec.stability, deprecated: group.spec.deprecated, constraints: resolve_constraints(&group.spec.constraints), attributes: vec![], diff --git a/crates/weaver_resolver/src/stability.rs b/crates/weaver_resolver/src/stability.rs deleted file mode 100644 index d992698e..00000000 --- a/crates/weaver_resolver/src/stability.rs +++ /dev/null @@ -1,15 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 - -//! Functions to resolve a semantic convention stability field. - -use weaver_semconv::stability::StabilitySpec; - -pub fn resolve_stability( - stability: &Option, -) -> Option { - stability.as_ref().map(|stability| match stability { - StabilitySpec::Deprecated => weaver_resolved_schema::catalog::Stability::Deprecated, - StabilitySpec::Experimental => weaver_resolved_schema::catalog::Stability::Experimental, - StabilitySpec::Stable => weaver_resolved_schema::catalog::Stability::Stable, - }) -} diff --git a/crates/weaver_schema/src/attribute.rs b/crates/weaver_schema/src/attribute.rs index 198f15ba..1dd4225c 100644 --- a/crates/weaver_schema/src/attribute.rs +++ b/crates/weaver_schema/src/attribute.rs @@ -7,7 +7,7 @@ use serde::{Deserialize, Serialize}; use weaver_semconv::attribute::{AttributeTypeSpec, ExamplesSpec, RequirementLevel, ValueSpec}; -use weaver_semconv::stability::StabilitySpec; +use weaver_semconv::stability::Stability; use crate::tags::Tags; use crate::Error; @@ -67,7 +67,7 @@ pub enum Attribute { /// present and stability differs from deprecated, this will result in an /// error. #[serde(skip_serializing_if = "Option::is_none")] - stability: Option, + stability: Option, /// Specifies if the attribute is deprecated. The string /// provided as MUST specify why it's deprecated and/or what /// to use instead. See also stability. @@ -168,7 +168,7 @@ pub enum Attribute { /// present and stability differs from deprecated, this will result in an /// error. #[serde(skip_serializing_if = "Option::is_none")] - stability: Option, + stability: Option, /// Specifies if the attribute is deprecated. The string /// provided as MUST specify why it's deprecated and/or what /// to use instead. See also stability. diff --git a/crates/weaver_semconv/src/attribute.rs b/crates/weaver_semconv/src/attribute.rs index b6f5a0fa..35c203a3 100644 --- a/crates/weaver_semconv/src/attribute.rs +++ b/crates/weaver_semconv/src/attribute.rs @@ -8,7 +8,7 @@ use ordered_float::OrderedFloat; use serde::{Deserialize, Serialize}; use std::fmt::{Display, Formatter}; -use crate::stability::StabilitySpec; +use crate::stability::Stability; /// An attribute specification. #[derive(Serialize, Deserialize, Debug, Clone)] @@ -60,7 +60,7 @@ pub enum AttributeSpec { /// present and stability differs from deprecated, this will result in an /// error. #[serde(skip_serializing_if = "Option::is_none")] - stability: Option, + stability: Option, /// Specifies if the attribute is deprecated. The string /// provided as MUST specify why it's deprecated and/or what /// to use instead. See also stability. @@ -110,7 +110,7 @@ pub enum AttributeSpec { /// present and stability differs from deprecated, this will result in an /// error. #[serde(skip_serializing_if = "Option::is_none")] - stability: Option, + stability: Option, /// Specifies if the attribute is deprecated. The string /// provided as MUST specify why it's deprecated and/or what /// to use instead. See also stability. diff --git a/crates/weaver_semconv/src/group.rs b/crates/weaver_semconv/src/group.rs index ac0c1e92..a0b78055 100644 --- a/crates/weaver_semconv/src/group.rs +++ b/crates/weaver_semconv/src/group.rs @@ -10,7 +10,7 @@ use validator::{Validate, ValidationError}; use crate::attribute::{AttributeSpec, AttributeTypeSpec, PrimitiveOrArrayTypeSpec}; use crate::group::InstrumentSpec::{Counter, Gauge, Histogram, UpDownCounter}; -use crate::stability::StabilitySpec; +use crate::stability::Stability; /// Group Spec contain the list of semantic conventions and it is the root node /// of each yaml file. @@ -43,7 +43,7 @@ pub struct GroupSpec { /// present and stability differs from deprecated, this will result in an /// error. #[serde(skip_serializing_if = "Option::is_none")] - pub stability: Option, + pub stability: Option, /// Specifies if the semantic convention is deprecated. The string /// provided as MUST specify why it's deprecated and/or what /// to use instead. See also stability. @@ -90,7 +90,7 @@ fn validate_group(group: &GroupSpec) -> Result<(), ValidationError> { // will result in an error. if group.deprecated.is_some() && group.stability.is_some() - && group.stability != Some(StabilitySpec::Deprecated) + && group.stability != Some(Stability::Deprecated) { return Err(ValidationError::new( "This group contains a deprecated field but the stability is not set to deprecated.", @@ -155,7 +155,7 @@ fn validate_group(group: &GroupSpec) -> Result<(), ValidationError> { } if deprecated.is_some() && stability.is_some() - && *stability != Some(StabilitySpec::Deprecated) + && *stability != Some(Stability::Deprecated) { return Err(ValidationError::new("This attribute contains a deprecated field but the stability is not set to deprecated.")); } @@ -167,7 +167,7 @@ fn validate_group(group: &GroupSpec) -> Result<(), ValidationError> { } => { if deprecated.is_some() && stability.is_some() - && *stability != Some(StabilitySpec::Deprecated) + && *stability != Some(Stability::Deprecated) { return Err(ValidationError::new("This attribute contains a deprecated field but the stability is not set to deprecated.")); } diff --git a/crates/weaver_semconv/src/stability.rs b/crates/weaver_semconv/src/stability.rs index 00917690..bd54012c 100644 --- a/crates/weaver_semconv/src/stability.rs +++ b/crates/weaver_semconv/src/stability.rs @@ -8,7 +8,7 @@ use std::fmt::{Display, Formatter}; /// The level of stability for a definition. #[derive(Serialize, Deserialize, Clone, Debug, Eq, PartialEq, Hash)] #[serde(rename_all = "snake_case")] -pub enum StabilitySpec { +pub enum Stability { /// A deprecated definition. Deprecated, /// An experimental definition. @@ -18,12 +18,12 @@ pub enum StabilitySpec { } /// Implements a human readable display for the stability. -impl Display for StabilitySpec { +impl Display for Stability { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { match self { - StabilitySpec::Deprecated => write!(f, "deprecated"), - StabilitySpec::Experimental => write!(f, "experimental"), - StabilitySpec::Stable => write!(f, "stable"), + Stability::Deprecated => write!(f, "deprecated"), + Stability::Experimental => write!(f, "experimental"), + Stability::Stable => write!(f, "stable"), } } } From 9d589898511cef94bdffa85621bd4f42a7de5d7f Mon Sep 17 00:00:00 2001 From: Laurent Querel Date: Wed, 6 Mar 2024 15:09:06 -0800 Subject: [PATCH 13/20] chore(compatibility): align requirement level definition --- crates/weaver_forge/templates/test/group.md | 4 + .../expected-attribute-catalog.json | 7 +- .../expected-attribute-catalog.json | 126 ++--- .../expected-attribute-catalog.json | 397 +++++--------- .../expected-attribute-catalog.json | 20 +- .../expected-attribute-catalog.json | 15 +- .../expected-attribute-catalog.json | 28 +- .../expected-attribute-catalog.json | 491 ++++++------------ crates/weaver_resolver/src/attribute.rs | 8 +- crates/weaver_resolver/src/registry.rs | 5 +- 10 files changed, 328 insertions(+), 773 deletions(-) diff --git a/crates/weaver_forge/templates/test/group.md b/crates/weaver_forge/templates/test/group.md index 799a842c..8fac1bbc 100644 --- a/crates/weaver_forge/templates/test/group.md +++ b/crates/weaver_forge/templates/test/group.md @@ -12,12 +12,16 @@ ### Attribute `{{ attribute.name }}` Requirement level: {{ attribute.requirement_level }} + {% if attribute.tag -%} Tag: {{ attribute.tag }} {%- endif %} {{ attribute.brief }} +{% if attribute.stability -%} +Stability: {{ attribute.stability }} +{%- endif %} {% endfor %} ## Provenance 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 2e220385..dd0aeba8 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 @@ -12,9 +12,7 @@ "MyTopic" ] }, - "requirement_level": { - "type": "Recommended" - }, + "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" }, { @@ -31,8 +29,7 @@ ] }, "requirement_level": { - "type": "ConditionallyRequired", - "text": "if and only if `messaging.destination.name` is known to have low cardinality. Otherwise, `messaging.destination.template` MAY be populated." + "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" } 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 5baa47a7..a891f788 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 @@ -13,9 +13,7 @@ 2 ] }, - "requirement_level": { - "type": "Recommended" - }, + "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" }, { @@ -31,9 +29,7 @@ "myhost@8742@s8083jm" ] }, - "requirement_level": { - "type": "Recommended" - } + "requirement_level": "recommended" }, { "name": "messaging.destination.name", @@ -48,9 +44,7 @@ "MyTopic" ] }, - "requirement_level": { - "type": "Recommended" - }, + "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" }, { @@ -65,9 +59,7 @@ "/customers/{customerId}" ] }, - "requirement_level": { - "type": "Recommended" - }, + "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" }, { @@ -76,9 +68,7 @@ "type": "Boolean" }, "brief": "A boolean that is true if the message destination is anonymous (could be unnamed or have auto-generated name).", - "requirement_level": { - "type": "Recommended" - } + "requirement_level": "recommended" }, { "name": "messaging.destination.temporary", @@ -86,9 +76,7 @@ "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": { - "type": "Recommended" - } + "requirement_level": "recommended" }, { "name": "messaging.destination_publish.anonymous", @@ -96,9 +84,7 @@ "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": { - "type": "Recommended" - } + "requirement_level": "recommended" }, { "name": "messaging.destination_publish.name", @@ -113,9 +99,7 @@ "MyTopic" ] }, - "requirement_level": { - "type": "Recommended" - }, + "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" }, { @@ -128,9 +112,7 @@ "type": "String", "value": "my-group" }, - "requirement_level": { - "type": "Recommended" - } + "requirement_level": "recommended" }, { "name": "messaging.kafka.destination.partition", @@ -142,9 +124,7 @@ "type": "Int", "value": 2 }, - "requirement_level": { - "type": "Recommended" - } + "requirement_level": "recommended" }, { "name": "messaging.kafka.message.key", @@ -156,9 +136,7 @@ "type": "String", "value": "myKey" }, - "requirement_level": { - "type": "Recommended" - }, + "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" }, { @@ -171,9 +149,7 @@ "type": "Int", "value": 42 }, - "requirement_level": { - "type": "Recommended" - } + "requirement_level": "recommended" }, { "name": "messaging.kafka.message.tombstone", @@ -181,9 +157,7 @@ "type": "Boolean" }, "brief": "A boolean that is true if the message is a tombstone.", - "requirement_level": { - "type": "Recommended" - } + "requirement_level": "recommended" }, { "name": "messaging.message.conversation_id", @@ -195,9 +169,7 @@ "type": "String", "value": "MyConversationId" }, - "requirement_level": { - "type": "Recommended" - } + "requirement_level": "recommended" }, { "name": "messaging.message.envelope.size", @@ -209,9 +181,7 @@ "type": "Int", "value": 2738 }, - "requirement_level": { - "type": "Recommended" - }, + "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" }, { @@ -224,9 +194,7 @@ "type": "String", "value": "452a7c7c7c7048c2f887f61572b18fc2" }, - "requirement_level": { - "type": "Recommended" - } + "requirement_level": "recommended" }, { "name": "messaging.message.body.size", @@ -238,9 +206,7 @@ "type": "Int", "value": 1439 }, - "requirement_level": { - "type": "Recommended" - }, + "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" }, { @@ -284,9 +250,7 @@ ] }, "brief": "A string identifying the kind of messaging operation.\n", - "requirement_level": { - "type": "Recommended" - }, + "requirement_level": "recommended", "note": "If a custom value is used, it MUST be of low cardinality." }, { @@ -299,9 +263,7 @@ "type": "String", "value": "myKey" }, - "requirement_level": { - "type": "Recommended" - } + "requirement_level": "recommended" }, { "name": "messaging.rocketmq.client_group", @@ -313,9 +275,7 @@ "type": "String", "value": "myConsumerGroup" }, - "requirement_level": { - "type": "Recommended" - } + "requirement_level": "recommended" }, { "name": "messaging.rocketmq.consumption_model", @@ -342,9 +302,7 @@ ] }, "brief": "Model of message consumption. This only applies to consumer spans.\n", - "requirement_level": { - "type": "Recommended" - } + "requirement_level": "recommended" }, { "name": "messaging.rocketmq.message.delay_time_level", @@ -356,9 +314,7 @@ "type": "Int", "value": 3 }, - "requirement_level": { - "type": "Recommended" - } + "requirement_level": "recommended" }, { "name": "messaging.rocketmq.message.delivery_timestamp", @@ -370,9 +326,7 @@ "type": "Int", "value": 1665987217045 }, - "requirement_level": { - "type": "Recommended" - } + "requirement_level": "recommended" }, { "name": "messaging.rocketmq.message.group", @@ -384,9 +338,7 @@ "type": "String", "value": "myMessageGroup" }, - "requirement_level": { - "type": "Recommended" - } + "requirement_level": "recommended" }, { "name": "messaging.rocketmq.message.keys", @@ -401,9 +353,7 @@ "keyB" ] }, - "requirement_level": { - "type": "Recommended" - } + "requirement_level": "recommended" }, { "name": "messaging.rocketmq.message.tag", @@ -415,9 +365,7 @@ "type": "String", "value": "tagA" }, - "requirement_level": { - "type": "Recommended" - } + "requirement_level": "recommended" }, { "name": "messaging.rocketmq.message.type", @@ -460,9 +408,7 @@ ] }, "brief": "Type of message.\n", - "requirement_level": { - "type": "Recommended" - } + "requirement_level": "recommended" }, { "name": "messaging.rocketmq.namespace", @@ -474,9 +420,7 @@ "type": "String", "value": "myNamespace" }, - "requirement_level": { - "type": "Recommended" - } + "requirement_level": "recommended" }, { "name": "messaging.gcp_pubsub.message.ordering_key", @@ -488,9 +432,7 @@ "type": "String", "value": "ordering_key" }, - "requirement_level": { - "type": "Recommended" - } + "requirement_level": "recommended" }, { "name": "messaging.system", @@ -581,9 +523,7 @@ ] }, "brief": "An identifier for the messaging system being used. See below for a list of well-known identifiers.\n", - "requirement_level": { - "type": "Recommended" - } + "requirement_level": "recommended" }, { "name": "messaging.destination.name", @@ -599,8 +539,7 @@ ] }, "requirement_level": { - "type": "ConditionallyRequired", - "text": "if and only if `messaging.destination.name` is known to have low cardinality. Otherwise, `messaging.destination.template` MAY be populated." + "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" }, @@ -617,8 +556,7 @@ ] }, "requirement_level": { - "type": "ConditionallyRequired", - "text": "if available." + "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" } 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 fc216371..4203108a 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 @@ -25,11 +25,9 @@ "500" ] }, - "requirement_level": { - "type": "Recommended" - }, + "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.", - "stability": "Stable" + "stability": "stable" }, { "name": "http.request.body.size", @@ -41,10 +39,8 @@ "type": "Int", "value": 3495 }, - "requirement_level": { - "type": "Recommended" - }, - "stability": "Experimental" + "requirement_level": "recommended", + "stability": "experimental" }, { "name": "http.request.header", @@ -59,11 +55,9 @@ "http.request.header.x-forwarded-for=[\"1.2.3.4\", \"1.2.3.5\"]" ] }, - "requirement_level": { - "type": "Recommended" - }, + "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" + "stability": "stable" }, { "name": "http.request.method", @@ -162,11 +156,9 @@ "HEAD" ] }, - "requirement_level": { - "type": "Recommended" - }, + "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" + "stability": "stable" }, { "name": "http.request.method_original", @@ -182,10 +174,8 @@ "foo" ] }, - "requirement_level": { - "type": "Recommended" - }, - "stability": "Stable" + "requirement_level": "recommended", + "stability": "stable" }, { "name": "http.request.resend_count", @@ -197,11 +187,9 @@ "type": "Int", "value": 3 }, - "requirement_level": { - "type": "Recommended" - }, + "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" + "stability": "stable" }, { "name": "http.response.body.size", @@ -213,10 +201,8 @@ "type": "Int", "value": 3495 }, - "requirement_level": { - "type": "Recommended" - }, - "stability": "Experimental" + "requirement_level": "recommended", + "stability": "experimental" }, { "name": "http.response.header", @@ -231,11 +217,9 @@ "http.response.header.my-custom-header=[\"abc\", \"def\"]" ] }, - "requirement_level": { - "type": "Recommended" - }, + "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" + "stability": "stable" }, { "name": "http.response.status_code", @@ -249,10 +233,8 @@ 200 ] }, - "requirement_level": { - "type": "Recommended" - }, - "stability": "Stable" + "requirement_level": "recommended", + "stability": "stable" }, { "name": "http.route", @@ -267,11 +249,9 @@ "{controller}/{action}/{id?}" ] }, - "requirement_level": { - "type": "Recommended" - }, + "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" + "stability": "stable" }, { "name": "messaging.batch.message_count", @@ -287,9 +267,7 @@ 2 ] }, - "requirement_level": { - "type": "Recommended" - }, + "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" }, { @@ -305,9 +283,7 @@ "myhost@8742@s8083jm" ] }, - "requirement_level": { - "type": "Recommended" - } + "requirement_level": "recommended" }, { "name": "messaging.destination.name", @@ -322,9 +298,7 @@ "MyTopic" ] }, - "requirement_level": { - "type": "Recommended" - }, + "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" }, { @@ -339,9 +313,7 @@ "/customers/{customerId}" ] }, - "requirement_level": { - "type": "Recommended" - }, + "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" }, { @@ -350,9 +322,7 @@ "type": "Boolean" }, "brief": "A boolean that is true if the message destination is anonymous (could be unnamed or have auto-generated name).", - "requirement_level": { - "type": "Recommended" - } + "requirement_level": "recommended" }, { "name": "messaging.destination.temporary", @@ -360,9 +330,7 @@ "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": { - "type": "Recommended" - } + "requirement_level": "recommended" }, { "name": "messaging.destination_publish.anonymous", @@ -370,9 +338,7 @@ "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": { - "type": "Recommended" - } + "requirement_level": "recommended" }, { "name": "messaging.destination_publish.name", @@ -387,9 +353,7 @@ "MyTopic" ] }, - "requirement_level": { - "type": "Recommended" - }, + "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" }, { @@ -402,9 +366,7 @@ "type": "String", "value": "my-group" }, - "requirement_level": { - "type": "Recommended" - } + "requirement_level": "recommended" }, { "name": "messaging.kafka.destination.partition", @@ -416,9 +378,7 @@ "type": "Int", "value": 2 }, - "requirement_level": { - "type": "Recommended" - } + "requirement_level": "recommended" }, { "name": "messaging.kafka.message.key", @@ -430,9 +390,7 @@ "type": "String", "value": "myKey" }, - "requirement_level": { - "type": "Recommended" - }, + "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" }, { @@ -445,9 +403,7 @@ "type": "Int", "value": 42 }, - "requirement_level": { - "type": "Recommended" - } + "requirement_level": "recommended" }, { "name": "messaging.kafka.message.tombstone", @@ -455,9 +411,7 @@ "type": "Boolean" }, "brief": "A boolean that is true if the message is a tombstone.", - "requirement_level": { - "type": "Recommended" - } + "requirement_level": "recommended" }, { "name": "messaging.message.conversation_id", @@ -469,9 +423,7 @@ "type": "String", "value": "MyConversationId" }, - "requirement_level": { - "type": "Recommended" - } + "requirement_level": "recommended" }, { "name": "messaging.message.envelope.size", @@ -483,9 +435,7 @@ "type": "Int", "value": 2738 }, - "requirement_level": { - "type": "Recommended" - }, + "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" }, { @@ -498,9 +448,7 @@ "type": "String", "value": "452a7c7c7c7048c2f887f61572b18fc2" }, - "requirement_level": { - "type": "Recommended" - } + "requirement_level": "recommended" }, { "name": "messaging.message.body.size", @@ -512,9 +460,7 @@ "type": "Int", "value": 1439 }, - "requirement_level": { - "type": "Recommended" - }, + "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" }, { @@ -558,9 +504,7 @@ ] }, "brief": "A string identifying the kind of messaging operation.\n", - "requirement_level": { - "type": "Recommended" - }, + "requirement_level": "recommended", "note": "If a custom value is used, it MUST be of low cardinality." }, { @@ -573,9 +517,7 @@ "type": "String", "value": "myKey" }, - "requirement_level": { - "type": "Recommended" - } + "requirement_level": "recommended" }, { "name": "messaging.rocketmq.client_group", @@ -587,9 +529,7 @@ "type": "String", "value": "myConsumerGroup" }, - "requirement_level": { - "type": "Recommended" - } + "requirement_level": "recommended" }, { "name": "messaging.rocketmq.consumption_model", @@ -616,9 +556,7 @@ ] }, "brief": "Model of message consumption. This only applies to consumer spans.\n", - "requirement_level": { - "type": "Recommended" - } + "requirement_level": "recommended" }, { "name": "messaging.rocketmq.message.delay_time_level", @@ -630,9 +568,7 @@ "type": "Int", "value": 3 }, - "requirement_level": { - "type": "Recommended" - } + "requirement_level": "recommended" }, { "name": "messaging.rocketmq.message.delivery_timestamp", @@ -644,9 +580,7 @@ "type": "Int", "value": 1665987217045 }, - "requirement_level": { - "type": "Recommended" - } + "requirement_level": "recommended" }, { "name": "messaging.rocketmq.message.group", @@ -658,9 +592,7 @@ "type": "String", "value": "myMessageGroup" }, - "requirement_level": { - "type": "Recommended" - } + "requirement_level": "recommended" }, { "name": "messaging.rocketmq.message.keys", @@ -675,9 +607,7 @@ "keyB" ] }, - "requirement_level": { - "type": "Recommended" - } + "requirement_level": "recommended" }, { "name": "messaging.rocketmq.message.tag", @@ -689,9 +619,7 @@ "type": "String", "value": "tagA" }, - "requirement_level": { - "type": "Recommended" - } + "requirement_level": "recommended" }, { "name": "messaging.rocketmq.message.type", @@ -734,9 +662,7 @@ ] }, "brief": "Type of message.\n", - "requirement_level": { - "type": "Recommended" - } + "requirement_level": "recommended" }, { "name": "messaging.rocketmq.namespace", @@ -748,9 +674,7 @@ "type": "String", "value": "myNamespace" }, - "requirement_level": { - "type": "Recommended" - } + "requirement_level": "recommended" }, { "name": "messaging.gcp_pubsub.message.ordering_key", @@ -762,9 +686,7 @@ "type": "String", "value": "ordering_key" }, - "requirement_level": { - "type": "Recommended" - } + "requirement_level": "recommended" }, { "name": "messaging.system", @@ -855,9 +777,7 @@ ] }, "brief": "An identifier for the messaging system being used. See below for a list of well-known identifiers.\n", - "requirement_level": { - "type": "Recommended" - } + "requirement_level": "recommended" }, { "name": "network.carrier.icc", @@ -869,9 +789,7 @@ "type": "String", "value": "DE" }, - "requirement_level": { - "type": "Recommended" - } + "requirement_level": "recommended" }, { "name": "network.carrier.mcc", @@ -883,9 +801,7 @@ "type": "String", "value": "310" }, - "requirement_level": { - "type": "Recommended" - } + "requirement_level": "recommended" }, { "name": "network.carrier.mnc", @@ -897,9 +813,7 @@ "type": "String", "value": "001" }, - "requirement_level": { - "type": "Recommended" - } + "requirement_level": "recommended" }, { "name": "network.carrier.name", @@ -911,9 +825,7 @@ "type": "String", "value": "sprint" }, - "requirement_level": { - "type": "Recommended" - } + "requirement_level": "recommended" }, { "name": "network.connection.subtype", @@ -1096,9 +1008,7 @@ "type": "String", "value": "LTE" }, - "requirement_level": { - "type": "Recommended" - } + "requirement_level": "recommended" }, { "name": "network.connection.type", @@ -1148,9 +1058,7 @@ "type": "String", "value": "wifi" }, - "requirement_level": { - "type": "Recommended" - } + "requirement_level": "recommended" }, { "name": "network.local.address", @@ -1165,10 +1073,8 @@ "/tmp/my.sock" ] }, - "requirement_level": { - "type": "Recommended" - }, - "stability": "Stable" + "requirement_level": "recommended", + "stability": "stable" }, { "name": "network.local.port", @@ -1182,10 +1088,8 @@ 65123 ] }, - "requirement_level": { - "type": "Recommended" - }, - "stability": "Stable" + "requirement_level": "recommended", + "stability": "stable" }, { "name": "network.peer.address", @@ -1200,10 +1104,8 @@ "/tmp/my.sock" ] }, - "requirement_level": { - "type": "Recommended" - }, - "stability": "Stable" + "requirement_level": "recommended", + "stability": "stable" }, { "name": "network.peer.port", @@ -1217,10 +1119,8 @@ 65123 ] }, - "requirement_level": { - "type": "Recommended" - }, - "stability": "Stable" + "requirement_level": "recommended", + "stability": "stable" }, { "name": "network.protocol.name", @@ -1236,11 +1136,9 @@ "mqtt" ] }, - "requirement_level": { - "type": "Recommended" - }, + "requirement_level": "recommended", "note": "The value SHOULD be normalized to lowercase.", - "stability": "Stable" + "stability": "stable" }, { "name": "network.protocol.version", @@ -1252,11 +1150,9 @@ "type": "String", "value": "3.1.1" }, - "requirement_level": { - "type": "Recommended" - }, + "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" + "stability": "stable" }, { "name": "network.transport", @@ -1306,11 +1202,9 @@ "udp" ] }, - "requirement_level": { - "type": "Recommended" - }, + "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" + "stability": "stable" }, { "name": "network.type", @@ -1344,11 +1238,9 @@ "ipv6" ] }, - "requirement_level": { - "type": "Recommended" - }, + "requirement_level": "recommended", "note": "The value SHOULD be normalized to lowercase.", - "stability": "Stable" + "stability": "stable" }, { "name": "network.io.direction", @@ -1379,9 +1271,7 @@ "transmit" ] }, - "requirement_level": { - "type": "Recommended" - } + "requirement_level": "recommended" }, { "name": "server.address", @@ -1397,11 +1287,9 @@ "/tmp/my.sock" ] }, - "requirement_level": { - "type": "Recommended" - }, + "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" + "stability": "stable" }, { "name": "server.port", @@ -1417,11 +1305,9 @@ 443 ] }, - "requirement_level": { - "type": "Recommended" - }, + "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" + "stability": "stable" }, { "name": "url.scheme", @@ -1437,10 +1323,8 @@ "telnet" ] }, - "requirement_level": { - "type": "Recommended" - }, - "stability": "Stable" + "requirement_level": "recommended", + "stability": "stable" }, { "name": "url.full", @@ -1455,11 +1339,9 @@ "//localhost" ] }, - "requirement_level": { - "type": "Recommended" - }, + "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" + "stability": "stable" }, { "name": "url.path", @@ -1473,10 +1355,8 @@ "/search" ] }, - "requirement_level": { - "type": "Recommended" - }, - "stability": "Stable" + "requirement_level": "recommended", + "stability": "stable" }, { "name": "url.query", @@ -1490,11 +1370,9 @@ "q=OpenTelemetry" ] }, - "requirement_level": { - "type": "Recommended" - }, + "requirement_level": "recommended", "note": "Sensitive content provided in query string SHOULD be scrubbed when instrumentations can identify it.", - "stability": "Stable" + "stability": "stable" }, { "name": "url.fragment", @@ -1508,10 +1386,8 @@ "SemConv" ] }, - "requirement_level": { - "type": "Recommended" - }, - "stability": "Stable" + "requirement_level": "recommended", + "stability": "stable" }, { "name": "http.request.method", @@ -1610,11 +1486,9 @@ "HEAD" ] }, - "requirement_level": { - "type": "Required" - }, + "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" + "stability": "stable" }, { "name": "http.response.status_code", @@ -1629,10 +1503,9 @@ ] }, "requirement_level": { - "type": "ConditionallyRequired", - "text": "If and only if one was received/sent." + "conditionally_required": "If and only if one was received/sent." }, - "stability": "Stable" + "stability": "stable" }, { "name": "error.type", @@ -1661,11 +1534,10 @@ ] }, "requirement_level": { - "type": "ConditionallyRequired", - "text": "If request has ended with an error." + "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" + "stability": "stable" }, { "name": "network.protocol.name", @@ -1681,11 +1553,10 @@ ] }, "requirement_level": { - "type": "ConditionallyRequired", - "text": "If not `http` and `network.protocol.version` is set." + "conditionally_required": "If not `http` and `network.protocol.version` is set." }, "note": "The value SHOULD be normalized to lowercase.", - "stability": "Stable" + "stability": "stable" }, { "name": "network.protocol.version", @@ -1702,11 +1573,9 @@ "3" ] }, - "requirement_level": { - "type": "Recommended" - }, + "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" + "stability": "stable" }, { "name": "server.address", @@ -1722,11 +1591,9 @@ "/tmp/my.sock" ] }, - "requirement_level": { - "type": "Required" - }, + "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" + "stability": "stable" }, { "name": "server.port", @@ -1742,11 +1609,9 @@ 443 ] }, - "requirement_level": { - "type": "Required" - }, + "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" + "stability": "stable" }, { "name": "url.scheme", @@ -1761,10 +1626,8 @@ "https" ] }, - "requirement_level": { - "type": "OptIn" - }, - "stability": "Stable" + "requirement_level": "opt_in", + "stability": "stable" }, { "name": "http.route", @@ -1780,11 +1643,10 @@ ] }, "requirement_level": { - "type": "ConditionallyRequired", - "text": "If and only if it's available" + "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" + "stability": "stable" }, { "name": "server.address", @@ -1800,11 +1662,9 @@ "/tmp/my.sock" ] }, - "requirement_level": { - "type": "Recommended" - }, + "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" + "stability": "stable" }, { "name": "server.port", @@ -1821,11 +1681,10 @@ ] }, "requirement_level": { - "type": "ConditionallyRequired", - "text": "If `server.address` is set." + "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" + "stability": "stable" }, { "name": "url.scheme", @@ -1840,11 +1699,9 @@ "https" ] }, - "requirement_level": { - "type": "Required" - }, + "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" + "stability": "stable" }, { "name": "messaging.system", @@ -1935,9 +1792,7 @@ ] }, "brief": "An identifier for the messaging system being used. See below for a list of well-known identifiers.\n", - "requirement_level": { - "type": "Required" - } + "requirement_level": "required" }, { "name": "error.type", @@ -1965,11 +1820,10 @@ ] }, "requirement_level": { - "type": "ConditionallyRequired", - "text": "If and only if the messaging operation has failed." + "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.", - "stability": "Stable" + "stability": "stable" }, { "name": "server.address", @@ -1986,11 +1840,10 @@ ] }, "requirement_level": { - "type": "ConditionallyRequired", - "text": "If available." + "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" + "stability": "stable" }, { "name": "network.protocol.name", @@ -2006,11 +1859,9 @@ ] }, "tag": "connection-level", - "requirement_level": { - "type": "Recommended" - }, + "requirement_level": "recommended", "note": "The value SHOULD be normalized to lowercase.", - "stability": "Stable" + "stability": "stable" }, { "name": "network.protocol.version", @@ -2023,11 +1874,9 @@ "value": "3.1.1" }, "tag": "connection-level", - "requirement_level": { - "type": "Recommended" - }, + "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" + "stability": "stable" }, { "name": "messaging.destination.name", @@ -2043,8 +1892,7 @@ ] }, "requirement_level": { - "type": "ConditionallyRequired", - "text": "if and only if `messaging.destination.name` is known to have low cardinality. Otherwise, `messaging.destination.template` MAY be populated." + "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" }, @@ -2061,8 +1909,7 @@ ] }, "requirement_level": { - "type": "ConditionallyRequired", - "text": "if available." + "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" } 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 27efb1f9..3eb37df4 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 @@ -48,9 +48,7 @@ ] }, "brief": "This attribute represents the state the application has transitioned into at the occurrence of the event.\n", - "requirement_level": { - "type": "Required" - }, + "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" }, { @@ -86,9 +84,7 @@ ] }, "brief": "This attribute represents the state the application has transitioned into at the occurrence of the event.\n", - "requirement_level": { - "type": "Required" - }, + "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" }, { @@ -103,9 +99,7 @@ "logo-color" ] }, - "requirement_level": { - "type": "Required" - } + "requirement_level": "required" }, { "name": "feature_flag.provider_name", @@ -119,9 +113,7 @@ "Flag Manager" ] }, - "requirement_level": { - "type": "Recommended" - } + "requirement_level": "recommended" }, { "name": "feature_flag.variant", @@ -137,9 +129,7 @@ "on" ] }, - "requirement_level": { - "type": "Recommended" - }, + "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." } ] \ No newline at end of file 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 63e3a890..760aa55a 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 @@ -48,9 +48,7 @@ ] }, "brief": "Type of the trigger which caused this function invocation.", - "requirement_level": { - "type": "Recommended" - } + "requirement_level": "recommended" }, { "name": "faas.invoked_name", @@ -62,9 +60,7 @@ "type": "String", "value": "my-function" }, - "requirement_level": { - "type": "Required" - }, + "requirement_level": "required", "note": "SHOULD be equal to the `faas.name` resource attribute of the invoked function.\n" }, { @@ -116,9 +112,7 @@ ] }, "brief": "The cloud provider of the invoked function.\n", - "requirement_level": { - "type": "Required" - }, + "requirement_level": "required", "note": "SHOULD be equal to the `cloud.provider` resource attribute of the invoked function.\n" }, { @@ -132,8 +126,7 @@ "value": "eu-central-1" }, "requirement_level": { - "type": "ConditionallyRequired", - "text": "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" + "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" } 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 ee1a889d..b1a974b5 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 @@ -12,10 +12,8 @@ "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": { - "type": "Recommended" - }, - "stability": "Stable" + "requirement_level": "recommended", + "stability": "stable" }, { "name": "browser.brands", @@ -31,9 +29,7 @@ "Chrome 99" ] }, - "requirement_level": { - "type": "Recommended" - }, + "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" }, { @@ -50,9 +46,7 @@ "Android" ] }, - "requirement_level": { - "type": "Recommended" - }, + "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" }, { @@ -61,9 +55,7 @@ "type": "Boolean" }, "brief": "A boolean that is true if the browser is running on a mobile device", - "requirement_level": { - "type": "Recommended" - }, + "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" }, { @@ -81,9 +73,7 @@ "fr-FR" ] }, - "requirement_level": { - "type": "Recommended" - }, + "requirement_level": "recommended", "note": "This value is intended to be taken from the Navigator API `navigator.language`.\n" }, { @@ -98,10 +88,8 @@ "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": { - "type": "Recommended" - }, + "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" + "stability": "stable" } ] \ No newline at end of file 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 126a5697..aa6c944f 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 @@ -10,9 +10,7 @@ "value": "us-west-2" }, "tag": "tech-specific-cassandra", - "requirement_level": { - "type": "Recommended" - } + "requirement_level": "recommended" }, { "name": "db.cassandra.coordinator.id", @@ -25,9 +23,7 @@ "value": "be13faa2-8574-4d71-926d-27f16cf8a7af" }, "tag": "tech-specific-cassandra", - "requirement_level": { - "type": "Recommended" - } + "requirement_level": "recommended" }, { "name": "db.cassandra.consistency_level", @@ -116,9 +112,7 @@ }, "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": { - "type": "Recommended" - } + "requirement_level": "recommended" }, { "name": "db.cassandra.idempotence", @@ -127,9 +121,7 @@ }, "brief": "Whether or not the query is idempotent.\n", "tag": "tech-specific-cassandra", - "requirement_level": { - "type": "Recommended" - } + "requirement_level": "recommended" }, { "name": "db.cassandra.page_size", @@ -144,9 +136,7 @@ ] }, "tag": "tech-specific-cassandra", - "requirement_level": { - "type": "Recommended" - } + "requirement_level": "recommended" }, { "name": "db.cassandra.speculative_execution_count", @@ -162,9 +152,7 @@ ] }, "tag": "tech-specific-cassandra", - "requirement_level": { - "type": "Recommended" - } + "requirement_level": "recommended" }, { "name": "db.cassandra.table", @@ -177,9 +165,7 @@ "value": "mytable" }, "tag": "tech-specific-cassandra", - "requirement_level": { - "type": "Recommended" - }, + "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" }, { @@ -193,9 +179,7 @@ "value": "Server=(localdb)\\v11.0;Integrated Security=true;" }, "tag": "db-generic", - "requirement_level": { - "type": "Recommended" - } + "requirement_level": "recommended" }, { "name": "db.cosmosdb.client_id", @@ -208,9 +192,7 @@ "value": "3ba4827d-4422-483f-b59f-85b74211c11d" }, "tag": "tech-specific-cosmosdb", - "requirement_level": { - "type": "Recommended" - } + "requirement_level": "recommended" }, { "name": "db.cosmosdb.connection_mode", @@ -238,9 +220,7 @@ }, "brief": "Cosmos client connection mode.", "tag": "tech-specific-cosmosdb", - "requirement_level": { - "type": "Recommended" - } + "requirement_level": "recommended" }, { "name": "db.cosmosdb.container", @@ -253,9 +233,7 @@ "value": "anystring" }, "tag": "tech-specific-cosmosdb", - "requirement_level": { - "type": "Recommended" - } + "requirement_level": "recommended" }, { "name": "db.cosmosdb.operation_type", @@ -372,9 +350,7 @@ }, "brief": "CosmosDB Operation Type.", "tag": "tech-specific-cosmosdb", - "requirement_level": { - "type": "Recommended" - } + "requirement_level": "recommended" }, { "name": "db.cosmosdb.request_charge", @@ -390,9 +366,7 @@ ] }, "tag": "tech-specific-cosmosdb", - "requirement_level": { - "type": "Recommended" - } + "requirement_level": "recommended" }, { "name": "db.cosmosdb.request_content_length", @@ -401,9 +375,7 @@ }, "brief": "Request payload size in bytes", "tag": "tech-specific-cosmosdb", - "requirement_level": { - "type": "Recommended" - } + "requirement_level": "recommended" }, { "name": "db.cosmosdb.status_code", @@ -419,9 +391,7 @@ ] }, "tag": "tech-specific-cosmosdb", - "requirement_level": { - "type": "Recommended" - } + "requirement_level": "recommended" }, { "name": "db.cosmosdb.sub_status_code", @@ -437,9 +407,7 @@ ] }, "tag": "tech-specific-cosmosdb", - "requirement_level": { - "type": "Recommended" - } + "requirement_level": "recommended" }, { "name": "db.elasticsearch.cluster.name", @@ -454,9 +422,7 @@ ] }, "tag": "tech-specific-elasticsearch", - "requirement_level": { - "type": "Recommended" - } + "requirement_level": "recommended" }, { "name": "db.elasticsearch.node.name", @@ -471,9 +437,7 @@ ] }, "tag": "tech-specific-elasticsearch", - "requirement_level": { - "type": "Recommended" - } + "requirement_level": "recommended" }, { "name": "db.elasticsearch.path_parts", @@ -489,9 +453,7 @@ ] }, "tag": "tech-specific-elasticsearch", - "requirement_level": { - "type": "Recommended" - }, + "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" }, { @@ -508,9 +470,7 @@ ] }, "tag": "tech-specific-jdbc", - "requirement_level": { - "type": "Recommended" - } + "requirement_level": "recommended" }, { "name": "db.mongodb.collection", @@ -526,9 +486,7 @@ ] }, "tag": "tech-specific-mongodb", - "requirement_level": { - "type": "Recommended" - } + "requirement_level": "recommended" }, { "name": "db.mssql.instance_name", @@ -541,9 +499,7 @@ "value": "MSSQLSERVER" }, "tag": "tech-specific-mssql", - "requirement_level": { - "type": "Recommended" - }, + "requirement_level": "recommended", "note": "If setting a `db.mssql.instance_name`, `server.port` is no longer required (but still recommended if non-standard).\n" }, { @@ -560,9 +516,7 @@ ] }, "tag": "db-generic", - "requirement_level": { - "type": "Recommended" - }, + "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" }, { @@ -580,9 +534,7 @@ ] }, "tag": "db-generic", - "requirement_level": { - "type": "Recommended" - }, + "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" }, { @@ -600,9 +552,7 @@ ] }, "tag": "tech-specific-redis", - "requirement_level": { - "type": "Recommended" - } + "requirement_level": "recommended" }, { "name": "db.sql.table", @@ -618,9 +568,7 @@ ] }, "tag": "tech-specific-sql", - "requirement_level": { - "type": "Recommended" - }, + "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" }, { @@ -637,9 +585,7 @@ ] }, "tag": "db-generic", - "requirement_level": { - "type": "Recommended" - } + "requirement_level": "recommended" }, { "name": "db.system", @@ -1067,9 +1013,7 @@ }, "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": { - "type": "Recommended" - } + "requirement_level": "recommended" }, { "name": "db.user", @@ -1085,9 +1029,7 @@ ] }, "tag": "db-generic", - "requirement_level": { - "type": "Recommended" - } + "requirement_level": "recommended" }, { "name": "db.instance.id", @@ -1100,9 +1042,7 @@ "value": "mysql-e26b99z.example.com" }, "tag": "db-generic", - "requirement_level": { - "type": "Recommended" - } + "requirement_level": "recommended" }, { "name": "http.request.body.size", @@ -1114,10 +1054,8 @@ "type": "Int", "value": 3495 }, - "requirement_level": { - "type": "Recommended" - }, - "stability": "Experimental" + "requirement_level": "recommended", + "stability": "experimental" }, { "name": "http.request.header", @@ -1132,11 +1070,9 @@ "http.request.header.x-forwarded-for=[\"1.2.3.4\", \"1.2.3.5\"]" ] }, - "requirement_level": { - "type": "Recommended" - }, + "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" + "stability": "stable" }, { "name": "http.request.method", @@ -1235,11 +1171,9 @@ "HEAD" ] }, - "requirement_level": { - "type": "Recommended" - }, + "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" + "stability": "stable" }, { "name": "http.request.method_original", @@ -1255,10 +1189,8 @@ "foo" ] }, - "requirement_level": { - "type": "Recommended" - }, - "stability": "Stable" + "requirement_level": "recommended", + "stability": "stable" }, { "name": "http.request.resend_count", @@ -1270,11 +1202,9 @@ "type": "Int", "value": 3 }, - "requirement_level": { - "type": "Recommended" - }, + "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" + "stability": "stable" }, { "name": "http.response.body.size", @@ -1286,10 +1216,8 @@ "type": "Int", "value": 3495 }, - "requirement_level": { - "type": "Recommended" - }, - "stability": "Experimental" + "requirement_level": "recommended", + "stability": "experimental" }, { "name": "http.response.header", @@ -1304,11 +1232,9 @@ "http.response.header.my-custom-header=[\"abc\", \"def\"]" ] }, - "requirement_level": { - "type": "Recommended" - }, + "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" + "stability": "stable" }, { "name": "http.response.status_code", @@ -1322,10 +1248,8 @@ 200 ] }, - "requirement_level": { - "type": "Recommended" - }, - "stability": "Stable" + "requirement_level": "recommended", + "stability": "stable" }, { "name": "http.route", @@ -1340,11 +1264,9 @@ "{controller}/{action}/{id?}" ] }, - "requirement_level": { - "type": "Recommended" - }, + "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" + "stability": "stable" }, { "name": "network.carrier.icc", @@ -1356,9 +1278,7 @@ "type": "String", "value": "DE" }, - "requirement_level": { - "type": "Recommended" - } + "requirement_level": "recommended" }, { "name": "network.carrier.mcc", @@ -1370,9 +1290,7 @@ "type": "String", "value": "310" }, - "requirement_level": { - "type": "Recommended" - } + "requirement_level": "recommended" }, { "name": "network.carrier.mnc", @@ -1384,9 +1302,7 @@ "type": "String", "value": "001" }, - "requirement_level": { - "type": "Recommended" - } + "requirement_level": "recommended" }, { "name": "network.carrier.name", @@ -1398,9 +1314,7 @@ "type": "String", "value": "sprint" }, - "requirement_level": { - "type": "Recommended" - } + "requirement_level": "recommended" }, { "name": "network.connection.subtype", @@ -1583,9 +1497,7 @@ "type": "String", "value": "LTE" }, - "requirement_level": { - "type": "Recommended" - } + "requirement_level": "recommended" }, { "name": "network.connection.type", @@ -1635,9 +1547,7 @@ "type": "String", "value": "wifi" }, - "requirement_level": { - "type": "Recommended" - } + "requirement_level": "recommended" }, { "name": "network.local.address", @@ -1652,10 +1562,8 @@ "/tmp/my.sock" ] }, - "requirement_level": { - "type": "Recommended" - }, - "stability": "Stable" + "requirement_level": "recommended", + "stability": "stable" }, { "name": "network.local.port", @@ -1669,10 +1577,8 @@ 65123 ] }, - "requirement_level": { - "type": "Recommended" - }, - "stability": "Stable" + "requirement_level": "recommended", + "stability": "stable" }, { "name": "network.peer.address", @@ -1687,10 +1593,8 @@ "/tmp/my.sock" ] }, - "requirement_level": { - "type": "Recommended" - }, - "stability": "Stable" + "requirement_level": "recommended", + "stability": "stable" }, { "name": "network.peer.port", @@ -1704,10 +1608,8 @@ 65123 ] }, - "requirement_level": { - "type": "Recommended" - }, - "stability": "Stable" + "requirement_level": "recommended", + "stability": "stable" }, { "name": "network.protocol.name", @@ -1723,11 +1625,9 @@ "mqtt" ] }, - "requirement_level": { - "type": "Recommended" - }, + "requirement_level": "recommended", "note": "The value SHOULD be normalized to lowercase.", - "stability": "Stable" + "stability": "stable" }, { "name": "network.protocol.version", @@ -1739,11 +1639,9 @@ "type": "String", "value": "3.1.1" }, - "requirement_level": { - "type": "Recommended" - }, + "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" + "stability": "stable" }, { "name": "network.transport", @@ -1793,11 +1691,9 @@ "udp" ] }, - "requirement_level": { - "type": "Recommended" - }, + "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" + "stability": "stable" }, { "name": "network.type", @@ -1831,11 +1727,9 @@ "ipv6" ] }, - "requirement_level": { - "type": "Recommended" - }, + "requirement_level": "recommended", "note": "The value SHOULD be normalized to lowercase.", - "stability": "Stable" + "stability": "stable" }, { "name": "network.io.direction", @@ -1866,9 +1760,7 @@ "transmit" ] }, - "requirement_level": { - "type": "Recommended" - } + "requirement_level": "recommended" }, { "name": "server.address", @@ -1884,11 +1776,9 @@ "/tmp/my.sock" ] }, - "requirement_level": { - "type": "Recommended" - }, + "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" + "stability": "stable" }, { "name": "server.port", @@ -1904,11 +1794,9 @@ 443 ] }, - "requirement_level": { - "type": "Recommended" - }, + "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" + "stability": "stable" }, { "name": "url.scheme", @@ -1924,10 +1812,8 @@ "telnet" ] }, - "requirement_level": { - "type": "Recommended" - }, - "stability": "Stable" + "requirement_level": "recommended", + "stability": "stable" }, { "name": "url.full", @@ -1942,11 +1828,9 @@ "//localhost" ] }, - "requirement_level": { - "type": "Recommended" - }, + "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" + "stability": "stable" }, { "name": "url.path", @@ -1960,10 +1844,8 @@ "/search" ] }, - "requirement_level": { - "type": "Recommended" - }, - "stability": "Stable" + "requirement_level": "recommended", + "stability": "stable" }, { "name": "url.query", @@ -1977,11 +1859,9 @@ "q=OpenTelemetry" ] }, - "requirement_level": { - "type": "Recommended" - }, + "requirement_level": "recommended", "note": "Sensitive content provided in query string SHOULD be scrubbed when instrumentations can identify it.", - "stability": "Stable" + "stability": "stable" }, { "name": "url.fragment", @@ -1995,10 +1875,8 @@ "SemConv" ] }, - "requirement_level": { - "type": "Recommended" - }, - "stability": "Stable" + "requirement_level": "recommended", + "stability": "stable" }, { "name": "user_agent.original", @@ -2013,10 +1891,8 @@ "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": { - "type": "Recommended" - }, - "stability": "Stable" + "requirement_level": "recommended", + "stability": "stable" }, { "name": "db.system", @@ -2444,9 +2320,7 @@ }, "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": { - "type": "Required" - } + "requirement_level": "required" }, { "name": "db.connection_string", @@ -2459,9 +2333,7 @@ "value": "Server=(localdb)\\v11.0;Integrated Security=true;" }, "tag": "connection-level", - "requirement_level": { - "type": "Recommended" - } + "requirement_level": "recommended" }, { "name": "db.user", @@ -2477,9 +2349,7 @@ ] }, "tag": "connection-level", - "requirement_level": { - "type": "Recommended" - } + "requirement_level": "recommended" }, { "name": "db.jdbc.driver_classname", @@ -2495,9 +2365,7 @@ ] }, "tag": "connection-level-tech-specific", - "requirement_level": { - "type": "Recommended" - } + "requirement_level": "recommended" }, { "name": "db.name", @@ -2514,8 +2382,7 @@ }, "tag": "call-level", "requirement_level": { - "type": "ConditionallyRequired", - "text": "If applicable." + "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" }, @@ -2534,8 +2401,7 @@ }, "tag": "call-level", "requirement_level": { - "type": "Recommended", - "text": "Should be collected by default only if there is sanitization that excludes sensitive information.\n" + "recommended": "Should be collected by default only if there is sanitization that excludes sensitive information.\n" } }, { @@ -2554,8 +2420,7 @@ }, "tag": "call-level", "requirement_level": { - "type": "ConditionallyRequired", - "text": "If `db.statement` is not applicable." + "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" }, @@ -2574,11 +2439,9 @@ ] }, "tag": "connection-level", - "requirement_level": { - "type": "Recommended" - }, + "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" + "stability": "stable" }, { "name": "server.port", @@ -2596,11 +2459,10 @@ }, "tag": "connection-level", "requirement_level": { - "type": "ConditionallyRequired", - "text": "If using a port other than the default port for this DBMS and if `server.address` is set." + "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" + "stability": "stable" }, { "name": "network.peer.address", @@ -2616,10 +2478,8 @@ ] }, "tag": "connection-level", - "requirement_level": { - "type": "Recommended" - }, - "stability": "Stable" + "requirement_level": "recommended", + "stability": "stable" }, { "name": "network.peer.port", @@ -2635,10 +2495,9 @@ }, "tag": "connection-level", "requirement_level": { - "type": "Recommended", - "text": "If `network.peer.address` is set." + "recommended": "If `network.peer.address` is set." }, - "stability": "Stable" + "stability": "stable" }, { "name": "network.transport", @@ -2689,11 +2548,9 @@ ] }, "tag": "connection-level", - "requirement_level": { - "type": "Recommended" - }, + "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" + "stability": "stable" }, { "name": "network.type", @@ -2728,11 +2585,9 @@ ] }, "tag": "connection-level", - "requirement_level": { - "type": "Recommended" - }, + "requirement_level": "recommended", "note": "The value SHOULD be normalized to lowercase.", - "stability": "Stable" + "stability": "stable" }, { "name": "db.instance.id", @@ -2746,8 +2601,7 @@ }, "tag": "connection-level", "requirement_level": { - "type": "Recommended", - "text": "If different from the `server.address`" + "recommended": "If different from the `server.address`" } }, { @@ -2761,9 +2615,7 @@ "value": "MSSQLSERVER" }, "tag": "connection-level-tech-specific", - "requirement_level": { - "type": "Recommended" - }, + "requirement_level": "recommended", "note": "If setting a `db.mssql.instance_name`, `server.port` is no longer required (but still recommended if non-standard).\n" }, { @@ -2779,9 +2631,7 @@ ] }, "tag": "call-level-tech-specific-cassandra", - "requirement_level": { - "type": "Recommended" - }, + "requirement_level": "recommended", "note": "For Cassandra the `db.name` should be set to the Cassandra keyspace name." }, { @@ -2797,9 +2647,7 @@ ] }, "tag": "call-level-tech-specific-cassandra", - "requirement_level": { - "type": "Recommended" - } + "requirement_level": "recommended" }, { "name": "db.cassandra.consistency_level", @@ -2888,9 +2736,7 @@ }, "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": { - "type": "Recommended" - } + "requirement_level": "recommended" }, { "name": "db.cassandra.table", @@ -2903,9 +2749,7 @@ "value": "mytable" }, "tag": "call-level-tech-specific-cassandra", - "requirement_level": { - "type": "Recommended" - }, + "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" }, { @@ -2915,9 +2759,7 @@ }, "brief": "Whether or not the query is idempotent.\n", "tag": "call-level-tech-specific-cassandra", - "requirement_level": { - "type": "Recommended" - } + "requirement_level": "recommended" }, { "name": "db.cassandra.speculative_execution_count", @@ -2933,9 +2775,7 @@ ] }, "tag": "call-level-tech-specific-cassandra", - "requirement_level": { - "type": "Recommended" - } + "requirement_level": "recommended" }, { "name": "db.cassandra.coordinator.id", @@ -2948,9 +2788,7 @@ "value": "be13faa2-8574-4d71-926d-27f16cf8a7af" }, "tag": "call-level-tech-specific-cassandra", - "requirement_level": { - "type": "Recommended" - } + "requirement_level": "recommended" }, { "name": "db.cassandra.coordinator.dc", @@ -2963,9 +2801,7 @@ "value": "us-west-2" }, "tag": "call-level-tech-specific-cassandra", - "requirement_level": { - "type": "Recommended" - } + "requirement_level": "recommended" }, { "name": "db.name", @@ -2980,9 +2816,7 @@ ] }, "tag": "call-level-tech-specific", - "requirement_level": { - "type": "Recommended" - }, + "requirement_level": "recommended", "note": "For HBase the `db.name` should be set to the HBase namespace." }, { @@ -2998,9 +2832,7 @@ ] }, "tag": "call-level-tech-specific", - "requirement_level": { - "type": "Recommended" - }, + "requirement_level": "recommended", "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" }, { @@ -3019,8 +2851,7 @@ }, "tag": "call-level-tech-specific", "requirement_level": { - "type": "ConditionallyRequired", - "text": "If other than the default database (`0`)." + "conditionally_required": "If other than the default database (`0`)." } }, { @@ -3036,9 +2867,7 @@ ] }, "tag": "call-level-tech-specific", - "requirement_level": { - "type": "Recommended" - }, + "requirement_level": "recommended", "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" }, { @@ -3055,9 +2884,7 @@ ] }, "tag": "call-level-tech-specific", - "requirement_level": { - "type": "Required" - } + "requirement_level": "required" }, { "name": "http.request.method", @@ -3157,11 +2984,9 @@ ] }, "tag": "call-level-tech-specific", - "requirement_level": { - "type": "Required" - }, + "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" + "stability": "stable" }, { "name": "db.operation", @@ -3178,9 +3003,7 @@ ] }, "tag": "call-level-tech-specific", - "requirement_level": { - "type": "Required" - }, + "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" }, { @@ -3196,11 +3019,9 @@ ] }, "tag": "call-level-tech-specific", - "requirement_level": { - "type": "Required" - }, + "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" + "stability": "stable" }, { "name": "db.statement", @@ -3216,8 +3037,7 @@ }, "tag": "call-level-tech-specific", "requirement_level": { - "type": "Recommended", - "text": "Should be collected by default for search-type queries and only if there is sanitization that excludes sensitive information.\n" + "recommended": "Should be collected by default for search-type queries and only if there is sanitization that excludes sensitive information.\n" } }, { @@ -3235,11 +3055,9 @@ ] }, "tag": "call-level-tech-specific", - "requirement_level": { - "type": "Recommended" - }, + "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" + "stability": "stable" }, { "name": "server.port", @@ -3256,11 +3074,9 @@ ] }, "tag": "call-level-tech-specific", - "requirement_level": { - "type": "Recommended" - }, + "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" + "stability": "stable" }, { "name": "db.elasticsearch.cluster.name", @@ -3276,8 +3092,7 @@ }, "tag": "call-level-tech-specific", "requirement_level": { - "type": "Recommended", - "text": "When communicating with an Elastic Cloud deployment, this should be collected from the \"X-Found-Handling-Cluster\" HTTP response header.\n" + "recommended": "When communicating with an Elastic Cloud deployment, this should be collected from the \"X-Found-Handling-Cluster\" HTTP response header.\n" } }, { @@ -3294,8 +3109,7 @@ }, "tag": "call-level-tech-specific", "requirement_level": { - "type": "Recommended", - "text": "When communicating with an Elastic Cloud deployment, this should be collected from the \"X-Found-Handling-Instance\" HTTP response header.\n" + "recommended": "When communicating with an Elastic Cloud deployment, this should be collected from the \"X-Found-Handling-Instance\" HTTP response header.\n" } }, { @@ -3313,8 +3127,7 @@ }, "tag": "call-level-tech-specific", "requirement_level": { - "type": "ConditionallyRequired", - "text": "when the url has dynamic values" + "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" }, @@ -3332,9 +3145,7 @@ ] }, "tag": "call-level-tech-specific", - "requirement_level": { - "type": "Recommended" - }, + "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" }, { @@ -3348,9 +3159,7 @@ "value": "3ba4827d-4422-483f-b59f-85b74211c11d" }, "tag": "call-level-tech-specific", - "requirement_level": { - "type": "Recommended" - } + "requirement_level": "recommended" }, { "name": "db.cosmosdb.operation_type", @@ -3468,8 +3277,7 @@ "brief": "CosmosDB Operation Type.", "tag": "call-level-tech-specific", "requirement_level": { - "type": "ConditionallyRequired", - "text": "when performing one of the operations in this list" + "conditionally_required": "when performing one of the operations in this list" } }, { @@ -3485,11 +3293,9 @@ ] }, "tag": "call-level-tech-specific", - "requirement_level": { - "type": "Recommended" - }, + "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" + "stability": "stable" }, { "name": "db.cosmosdb.connection_mode", @@ -3518,8 +3324,7 @@ "brief": "Cosmos client connection mode.", "tag": "call-level-tech-specific", "requirement_level": { - "type": "ConditionallyRequired", - "text": "if not `direct` (or pick gw as default)" + "conditionally_required": "if not `direct` (or pick gw as default)" } }, { @@ -3534,8 +3339,7 @@ }, "tag": "call-level-tech-specific", "requirement_level": { - "type": "ConditionallyRequired", - "text": "if available" + "conditionally_required": "if available" } }, { @@ -3545,9 +3349,7 @@ }, "brief": "Request payload size in bytes", "tag": "call-level-tech-specific", - "requirement_level": { - "type": "Recommended" - } + "requirement_level": "recommended" }, { "name": "db.cosmosdb.status_code", @@ -3564,8 +3366,7 @@ }, "tag": "call-level-tech-specific", "requirement_level": { - "type": "ConditionallyRequired", - "text": "if response was received" + "conditionally_required": "if response was received" } }, { @@ -3583,8 +3384,7 @@ }, "tag": "call-level-tech-specific", "requirement_level": { - "type": "ConditionallyRequired", - "text": "when response was received and contained sub-code." + "conditionally_required": "when response was received and contained sub-code." } }, { @@ -3602,8 +3402,7 @@ }, "tag": "call-level-tech-specific", "requirement_level": { - "type": "ConditionallyRequired", - "text": "when available" + "conditionally_required": "when available" } } ] \ No newline at end of file diff --git a/crates/weaver_resolver/src/attribute.rs b/crates/weaver_resolver/src/attribute.rs index fe4240da..6a7b5a89 100644 --- a/crates/weaver_resolver/src/attribute.rs +++ b/crates/weaver_resolver/src/attribute.rs @@ -11,8 +11,8 @@ use weaver_resolved_schema::lineage::{FieldId, FieldLineage, GroupLineage, Resol use weaver_schema::attribute::Attribute; use weaver_schema::tags::Tags; use weaver_semconv::attribute::{ - AttributeSpec, AttributeTypeSpec, ExamplesSpec, - PrimitiveOrArrayTypeSpec, TemplateTypeSpec, ValueSpec, + AttributeSpec, AttributeTypeSpec, ExamplesSpec, PrimitiveOrArrayTypeSpec, TemplateTypeSpec, + ValueSpec, }; use weaver_semconv::group::GroupType; use weaver_semconv::SemConvRegistry; @@ -121,9 +121,7 @@ impl AttributeCatalog { } }, requirement_level: match requirement_level { - Some(requirement_level) => { - requirement_level.clone() - } + Some(requirement_level) => requirement_level.clone(), None => { inherited_fields.push(FieldId::AttributeRequirementLevel); root_attr.attribute.requirement_level.clone() diff --git a/crates/weaver_resolver/src/registry.rs b/crates/weaver_resolver/src/registry.rs index 8b2f6ed7..9107a020 100644 --- a/crates/weaver_resolver/src/registry.rs +++ b/crates/weaver_resolver/src/registry.rs @@ -593,6 +593,7 @@ mod tests { let observed_attr_catalog_json = serde_json::to_string_pretty(&observed_attr_catalog) .expect("Failed to serialize observed attribute catalog"); + // println!("Observed catalog: {}", observed_attr_catalog_json); assert_eq!( observed_attr_catalog, expected_attr_catalog, "Attribute catalog does not match for `{}`.\nObserved catalog:\n{}", @@ -612,8 +613,8 @@ mod tests { test_dir, observed_registry_json ); - let yaml = serde_yaml::to_string(&observed_registry).unwrap(); - println!("{}", yaml); + // let yaml = serde_yaml::to_string(&observed_registry).unwrap(); + // println!("{}", yaml); } } From 9ebc894f81db232960d5263cafbe8035af2b9147 Mon Sep 17 00:00:00 2001 From: Laurent Querel Date: Wed, 6 Mar 2024 15:39:11 -0800 Subject: [PATCH 14/20] chore(compatibility): align attribute type and examples definitions --- Cargo.lock | 1 - crates/weaver_forge/templates/test/group.md | 8 +- .../weaver_resolved_schema/src/attribute.rs | 140 +- crates/weaver_resolver/Cargo.toml | 1 - .../expected-attribute-catalog.json | 30 +- .../expected-attribute-catalog.json | 442 +-- .../expected-attribute-catalog.json | 1618 +++------ .../expected-attribute-catalog.json | 109 +- .../expected-attribute-catalog.json | 100 +- .../expected-attribute-catalog.json | 85 +- .../expected-attribute-catalog.json | 2987 ++++++----------- crates/weaver_resolver/src/attribute.rs | 78 +- crates/weaver_resolver/src/registry.rs | 4 +- crates/weaver_schema/src/attribute.rs | 8 +- crates/weaver_semconv/src/attribute.rs | 32 +- crates/weaver_semconv/src/group.rs | 6 +- src/search/semconv/examples.rs | 20 +- 17 files changed, 1903 insertions(+), 3766 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2377f9cb..eeb75f73 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3865,7 +3865,6 @@ dependencies = [ "regex", "serde", "serde_json", - "serde_yaml", "thiserror", "url", "walkdir", diff --git a/crates/weaver_forge/templates/test/group.md b/crates/weaver_forge/templates/test/group.md index 8fac1bbc..0013daab 100644 --- a/crates/weaver_forge/templates/test/group.md +++ b/crates/weaver_forge/templates/test/group.md @@ -17,7 +17,13 @@ Requirement level: {{ attribute.requirement_level }} Tag: {{ attribute.tag }} {%- endif %} -{{ attribute.brief }} +Brief: {{ attribute.brief }} + +Type: {{ attribute.type }} + +{% if attribute.note -%} +Note: {{ attribute.note }} +{%- endif %} {% if attribute.stability -%} Stability: {{ attribute.stability }} diff --git a/crates/weaver_resolved_schema/src/attribute.rs b/crates/weaver_resolved_schema/src/attribute.rs index 385a49aa..8a72acef 100644 --- a/crates/weaver_resolved_schema/src/attribute.rs +++ b/crates/weaver_resolved_schema/src/attribute.rs @@ -6,10 +6,9 @@ use crate::tags::Tags; use crate::value::Value; -use ordered_float::OrderedFloat; use serde::{Deserialize, Serialize}; use std::fmt::Display; -use weaver_semconv::attribute::{AttributeSpec, RequirementLevel}; +use weaver_semconv::attribute::{AttributeSpec, AttributeType, Examples, RequirementLevel}; use weaver_semconv::stability::Stability; /// An attribute definition. @@ -30,7 +29,7 @@ pub struct Attribute { /// attribute. If only a single example is provided, it can directly /// be reported without encapsulating it into a sequence/dictionary. #[serde(skip_serializing_if = "Option::is_none")] - pub examples: Option, + pub examples: Option, /// Associates a tag ("sub-group") to the attribute. It carries no /// particular semantic meaning but can be used e.g. for filtering /// in the markdown generator. @@ -81,141 +80,6 @@ pub struct UnresolvedAttribute { pub spec: AttributeSpec, } -/// The different types of attributes. -#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq, Hash)] -#[serde(tag = "type")] -pub enum AttributeType { - /// A boolean attribute. - Boolean, - /// A integer attribute (signed 64 bit integer). - Int, - /// A double attribute (double precision floating point (IEEE 754-1985)). - Double, - /// A string attribute. - String, - /// An array of strings attribute. - Strings, - /// An array of integer attribute. - Ints, - /// An array of double attribute. - Doubles, - /// An array of boolean attribute. - Booleans, - - /// A template boolean attribute. - TemplateBoolean, - /// A template integer attribute. - #[serde(rename = "template[int]")] - TemplateInt, - /// A template double attribute. - #[serde(rename = "template[double]")] - TemplateDouble, - /// A template string attribute. - #[serde(rename = "template[string]")] - TemplateString, - /// A template array of strings attribute. - #[serde(rename = "template[string[]]")] - TemplateStrings, - /// A template array of integer attribute. - #[serde(rename = "template[int[]]")] - TemplateInts, - /// A template array of double attribute. - #[serde(rename = "template[double[]]")] - TemplateDoubles, - /// A template array of boolean attribute. - #[serde(rename = "template[boolean[]]")] - TemplateBooleans, - - /// An enum definition type. - Enum { - /// Set to false to not accept values other than the specified members. - /// It defaults to true. - allow_custom_values: bool, - /// List of enum entries. - members: Vec, - }, -} - -/// Possible enum entries. -#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq, Hash)] -#[serde(deny_unknown_fields)] -pub struct EnumEntries { - /// String that uniquely identifies the enum entry. - pub id: String, - /// String, int, or boolean; value of the enum entry. - pub value: Value, - /// Brief description of the enum entry value. - /// It defaults to the value of id. - #[serde(skip_serializing_if = "Option::is_none")] - pub brief: Option, - /// Longer description. - /// It defaults to an empty string. - #[serde(skip_serializing_if = "Option::is_none")] - pub note: Option, -} - -/// The different types of examples. -#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq, Hash)] -#[serde(tag = "type")] -pub enum Example { - /// A boolean example. - Bool { - /// The value of the example. - value: bool, - }, - /// A integer example. - Int { - /// The value of the example. - value: i64, - }, - /// A double example. - Double { - /// The value of the example. - value: OrderedFloat, - }, - /// A string example. - String { - /// The value of the example. - value: String, - }, - /// A array of integers example. - Ints { - /// The value of the example. - values: Vec, - }, - /// A array of doubles example. - Doubles { - /// The value of the example. - values: Vec>, - }, - /// A array of bools example. - Bools { - /// The value of the example. - values: Vec, - }, - /// A array of strings example. - Strings { - /// The value of the example. - values: Vec, - }, -} - -impl Example { - /// Creates an example from a f64. - pub fn from_f64(value: f64) -> Self { - Example::Double { - value: OrderedFloat(value), - } - } - - /// Creates an example from several f64. - pub fn from_f64s(values: Vec) -> Self { - Example::Doubles { - values: values.into_iter().map(OrderedFloat).collect(), - } - } -} - /// An internal reference to an attribute in the catalog. #[derive(Serialize, Deserialize, Debug, Copy, Clone, Eq, PartialEq, PartialOrd, Ord)] pub struct AttributeRef(pub u32); diff --git a/crates/weaver_resolver/Cargo.toml b/crates/weaver_resolver/Cargo.toml index e6b179cd..632f5c4f 100644 --- a/crates/weaver_resolver/Cargo.toml +++ b/crates/weaver_resolver/Cargo.toml @@ -19,7 +19,6 @@ regex.workspace = true thiserror.workspace = true rayon.workspace = true serde_json.workspace = true -serde_yaml.workspace = true url = "2.5.0" walkdir = "2.4.0" 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 dd0aeba8..d763c2a1 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,33 +1,23 @@ [ { "name": "messaging.destination.name", - "type": { - "type": "String" - }, + "type": "string", "brief": "The message destination name", - "examples": { - "type": "Strings", - "values": [ - "MyQueue", - "MyTopic" - ] - }, + "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" }, { "name": "messaging.destination.name", - "type": { - "type": "String" - }, + "type": "string", "brief": "The message destination name", - "examples": { - "type": "Strings", - "values": [ - "MyQueue", - "MyTopic" - ] - }, + "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." }, 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 a891f788..c4e7e9fd 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,251 +1,169 @@ [ { "name": "messaging.batch.message_count", - "type": { - "type": "Int" - }, + "type": "int", "brief": "The number of messages sent, received, or processed in the scope of the batching operation.", - "examples": { - "type": "Ints", - "values": [ - 0, - 1, - 2 - ] - }, + "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" }, { "name": "messaging.client_id", - "type": { - "type": "String" - }, + "type": "string", "brief": "A unique identifier for the client that consumes or produces a message.\n", - "examples": { - "type": "Strings", - "values": [ - "client-5", - "myhost@8742@s8083jm" - ] - }, + "examples": [ + "client-5", + "myhost@8742@s8083jm" + ], "requirement_level": "recommended" }, { "name": "messaging.destination.name", - "type": { - "type": "String" - }, + "type": "string", "brief": "The message destination name", - "examples": { - "type": "Strings", - "values": [ - "MyQueue", - "MyTopic" - ] - }, + "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" }, { "name": "messaging.destination.template", - "type": { - "type": "String" - }, + "type": "string", "brief": "Low cardinality representation of the messaging destination name", - "examples": { - "type": "Strings", - "values": [ - "/customers/{customerId}" - ] - }, + "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" }, { "name": "messaging.destination.anonymous", - "type": { - "type": "Boolean" - }, + "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" }, { "name": "messaging.destination.temporary", - "type": { - "type": "Boolean" - }, + "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" }, { "name": "messaging.destination_publish.anonymous", - "type": { - "type": "Boolean" - }, + "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" }, { "name": "messaging.destination_publish.name", - "type": { - "type": "String" - }, + "type": "string", "brief": "The name of the original destination the message was published to", - "examples": { - "type": "Strings", - "values": [ - "MyQueue", - "MyTopic" - ] - }, + "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" }, { "name": "messaging.kafka.consumer.group", - "type": { - "type": "String" - }, + "type": "string", "brief": "Name of the Kafka Consumer Group that is handling the message. Only applies to consumers, not producers.\n", - "examples": { - "type": "String", - "value": "my-group" - }, + "examples": "my-group", "requirement_level": "recommended" }, { "name": "messaging.kafka.destination.partition", - "type": { - "type": "Int" - }, + "type": "int", "brief": "Partition the message is sent to.\n", - "examples": { - "type": "Int", - "value": 2 - }, + "examples": 2, "requirement_level": "recommended" }, { "name": "messaging.kafka.message.key", - "type": { - "type": "String" - }, + "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": { - "type": "String", - "value": "myKey" - }, + "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" }, { "name": "messaging.kafka.message.offset", - "type": { - "type": "Int" - }, + "type": "int", "brief": "The offset of a record in the corresponding Kafka partition.\n", - "examples": { - "type": "Int", - "value": 42 - }, + "examples": 42, "requirement_level": "recommended" }, { "name": "messaging.kafka.message.tombstone", - "type": { - "type": "Boolean" - }, + "type": "boolean", "brief": "A boolean that is true if the message is a tombstone.", "requirement_level": "recommended" }, { "name": "messaging.message.conversation_id", - "type": { - "type": "String" - }, + "type": "string", "brief": "The conversation ID identifying the conversation to which the message belongs, represented as a string. Sometimes called \"Correlation ID\".\n", - "examples": { - "type": "String", - "value": "MyConversationId" - }, + "examples": "MyConversationId", "requirement_level": "recommended" }, { "name": "messaging.message.envelope.size", - "type": { - "type": "Int" - }, + "type": "int", "brief": "The size of the message body and metadata in bytes.\n", - "examples": { - "type": "Int", - "value": 2738 - }, + "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" }, { "name": "messaging.message.id", - "type": { - "type": "String" - }, + "type": "string", "brief": "A value used by the messaging system as an identifier for the message, represented as a string.", - "examples": { - "type": "String", - "value": "452a7c7c7c7048c2f887f61572b18fc2" - }, + "examples": "452a7c7c7c7048c2f887f61572b18fc2", "requirement_level": "recommended" }, { "name": "messaging.message.body.size", - "type": { - "type": "Int" - }, + "type": "int", "brief": "The size of the message body in bytes.\n", - "examples": { - "type": "Int", - "value": 1439 - }, + "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" }, { "name": "messaging.operation", "type": { - "type": "Enum", "allow_custom_values": true, "members": [ { "id": "publish", - "value": { - "type": "String", - "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" + "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", + "note": null }, { "id": "create", - "value": { - "type": "String", - "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" + "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", + "note": null }, { "id": "receive", - "value": { - "type": "String", - "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" + "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", + "note": null }, { "id": "deliver", - "value": { - "type": "String", - "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" + "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", + "note": null } ] }, @@ -255,49 +173,34 @@ }, { "name": "messaging.rabbitmq.destination.routing_key", - "type": { - "type": "String" - }, + "type": "string", "brief": "RabbitMQ message routing key.\n", - "examples": { - "type": "String", - "value": "myKey" - }, + "examples": "myKey", "requirement_level": "recommended" }, { "name": "messaging.rocketmq.client_group", - "type": { - "type": "String" - }, + "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": { - "type": "String", - "value": "myConsumerGroup" - }, + "examples": "myConsumerGroup", "requirement_level": "recommended" }, { "name": "messaging.rocketmq.consumption_model", "type": { - "type": "Enum", "allow_custom_values": false, "members": [ { "id": "clustering", - "value": { - "type": "String", - "value": "clustering" - }, - "brief": "Clustering consumption model" + "value": "clustering", + "brief": "Clustering consumption model", + "note": null }, { "id": "broadcasting", - "value": { - "type": "String", - "value": "broadcasting" - }, - "brief": "Broadcasting consumption model" + "value": "broadcasting", + "brief": "Broadcasting consumption model", + "note": null } ] }, @@ -306,104 +209,70 @@ }, { "name": "messaging.rocketmq.message.delay_time_level", - "type": { - "type": "Int" - }, + "type": "int", "brief": "The delay time level for delay message, which determines the message delay time.\n", - "examples": { - "type": "Int", - "value": 3 - }, + "examples": 3, "requirement_level": "recommended" }, { "name": "messaging.rocketmq.message.delivery_timestamp", - "type": { - "type": "Int" - }, + "type": "int", "brief": "The timestamp in milliseconds that the delay message is expected to be delivered to consumer.\n", - "examples": { - "type": "Int", - "value": 1665987217045 - }, + "examples": 1665987217045, "requirement_level": "recommended" }, { "name": "messaging.rocketmq.message.group", - "type": { - "type": "String" - }, + "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": { - "type": "String", - "value": "myMessageGroup" - }, + "examples": "myMessageGroup", "requirement_level": "recommended" }, { "name": "messaging.rocketmq.message.keys", - "type": { - "type": "Strings" - }, + "type": "string[]", "brief": "Key(s) of message, another way to mark message besides message id.\n", - "examples": { - "type": "Strings", - "values": [ - "keyA", - "keyB" - ] - }, + "examples": [ + "keyA", + "keyB" + ], "requirement_level": "recommended" }, { "name": "messaging.rocketmq.message.tag", - "type": { - "type": "String" - }, + "type": "string", "brief": "The secondary classifier of message besides topic.\n", - "examples": { - "type": "String", - "value": "tagA" - }, + "examples": "tagA", "requirement_level": "recommended" }, { "name": "messaging.rocketmq.message.type", "type": { - "type": "Enum", "allow_custom_values": false, "members": [ { "id": "normal", - "value": { - "type": "String", - "value": "normal" - }, - "brief": "Normal message" + "value": "normal", + "brief": "Normal message", + "note": null }, { "id": "fifo", - "value": { - "type": "String", - "value": "fifo" - }, - "brief": "FIFO message" + "value": "fifo", + "brief": "FIFO message", + "note": null }, { "id": "delay", - "value": { - "type": "String", - "value": "delay" - }, - "brief": "Delay message" + "value": "delay", + "brief": "Delay message", + "note": null }, { "id": "transaction", - "value": { - "type": "String", - "value": "transaction" - }, - "brief": "Transaction message" + "value": "transaction", + "brief": "Transaction message", + "note": null } ] }, @@ -412,113 +281,82 @@ }, { "name": "messaging.rocketmq.namespace", - "type": { - "type": "String" - }, + "type": "string", "brief": "Namespace of RocketMQ resources, resources in different namespaces are individual.\n", - "examples": { - "type": "String", - "value": "myNamespace" - }, + "examples": "myNamespace", "requirement_level": "recommended" }, { "name": "messaging.gcp_pubsub.message.ordering_key", - "type": { - "type": "String" - }, + "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": { - "type": "String", - "value": "ordering_key" - }, + "examples": "ordering_key", "requirement_level": "recommended" }, { "name": "messaging.system", "type": { - "type": "Enum", "allow_custom_values": true, "members": [ { "id": "activemq", - "value": { - "type": "String", - "value": "activemq" - }, - "brief": "Apache ActiveMQ" + "value": "activemq", + "brief": "Apache ActiveMQ", + "note": null }, { "id": "aws_sqs", - "value": { - "type": "String", - "value": "aws_sqs" - }, - "brief": "Amazon Simple Queue Service (SQS)" + "value": "aws_sqs", + "brief": "Amazon Simple Queue Service (SQS)", + "note": null }, { "id": "azure_eventgrid", - "value": { - "type": "String", - "value": "azure_eventgrid" - }, - "brief": "Azure Event Grid" + "value": "azure_eventgrid", + "brief": "Azure Event Grid", + "note": null }, { "id": "azure_eventhubs", - "value": { - "type": "String", - "value": "azure_eventhubs" - }, - "brief": "Azure Event Hubs" + "value": "azure_eventhubs", + "brief": "Azure Event Hubs", + "note": null }, { "id": "azure_servicebus", - "value": { - "type": "String", - "value": "azure_servicebus" - }, - "brief": "Azure Service Bus" + "value": "azure_servicebus", + "brief": "Azure Service Bus", + "note": null }, { "id": "gcp_pubsub", - "value": { - "type": "String", - "value": "gcp_pubsub" - }, - "brief": "Google Cloud Pub/Sub" + "value": "gcp_pubsub", + "brief": "Google Cloud Pub/Sub", + "note": null }, { "id": "jms", - "value": { - "type": "String", - "value": "jms" - }, - "brief": "Java Message Service" + "value": "jms", + "brief": "Java Message Service", + "note": null }, { "id": "kafka", - "value": { - "type": "String", - "value": "kafka" - }, - "brief": "Apache Kafka" + "value": "kafka", + "brief": "Apache Kafka", + "note": null }, { "id": "rabbitmq", - "value": { - "type": "String", - "value": "rabbitmq" - }, - "brief": "RabbitMQ" + "value": "rabbitmq", + "brief": "RabbitMQ", + "note": null }, { "id": "rocketmq", - "value": { - "type": "String", - "value": "rocketmq" - }, - "brief": "Apache RocketMQ" + "value": "rocketmq", + "brief": "Apache RocketMQ", + "note": null } ] }, @@ -527,17 +365,12 @@ }, { "name": "messaging.destination.name", - "type": { - "type": "String" - }, + "type": "string", "brief": "The message destination name", - "examples": { - "type": "Strings", - "values": [ - "MyQueue", - "MyTopic" - ] - }, + "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." }, @@ -545,16 +378,11 @@ }, { "name": "messaging.destination.template", - "type": { - "type": "String" - }, + "type": "string", "brief": "Low cardinality representation of the messaging destination name", - "examples": { - "type": "Strings", - "values": [ - "/customers/{customerId}" - ] - }, + "examples": [ + "/customers/{customerId}" + ], "requirement_level": { "conditionally_required": "if available." }, 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 4203108a..a6351752 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 @@ -2,59 +2,43 @@ { "name": "error.type", "type": { - "type": "Enum", "allow_custom_values": true, "members": [ { "id": "other", - "value": { - "type": "String", - "value": "_OTHER" - }, - "brief": "A fallback error value to be used when the instrumentation doesn't define a custom value.\n" + "value": "_OTHER", + "brief": "A fallback error value to be used when the instrumentation doesn't define a custom value.\n", + "note": null } ] }, "brief": "Describes a class of error the operation ended with.\n", - "examples": { - "type": "Strings", - "values": [ - "timeout", - "java.net.UnknownHostException", - "server_certificate_invalid", - "500" - ] - }, + "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.", "stability": "stable" }, { "name": "http.request.body.size", - "type": { - "type": "Int" - }, + "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": { - "type": "Int", - "value": 3495 - }, + "examples": 3495, "requirement_level": "recommended", "stability": "experimental" }, { "name": "http.request.header", - "type": { - "type": "template[string[]]" - }, + "type": "template[string[]]", "brief": "HTTP request headers, `` being the normalized HTTP Header name (lowercase), the value being the header values.\n", - "examples": { - "type": "Strings", - "values": [ - "http.request.header.content-type=[\"application/json\"]", - "http.request.header.x-forwarded-for=[\"1.2.3.4\", \"1.2.3.5\"]" - ] - }, + "examples": [ + "http.request.header.content-type=[\"application/json\"]", + "http.request.header.x-forwarded-for=[\"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" @@ -62,444 +46,308 @@ { "name": "http.request.method", "type": { - "type": "Enum", "allow_custom_values": true, "members": [ { "id": "connect", - "value": { - "type": "String", - "value": "CONNECT" - }, - "brief": "CONNECT method." + "value": "CONNECT", + "brief": "CONNECT method.", + "note": null }, { "id": "delete", - "value": { - "type": "String", - "value": "DELETE" - }, - "brief": "DELETE method." + "value": "DELETE", + "brief": "DELETE method.", + "note": null }, { "id": "get", - "value": { - "type": "String", - "value": "GET" - }, - "brief": "GET method." + "value": "GET", + "brief": "GET method.", + "note": null }, { "id": "head", - "value": { - "type": "String", - "value": "HEAD" - }, - "brief": "HEAD method." + "value": "HEAD", + "brief": "HEAD method.", + "note": null }, { "id": "options", - "value": { - "type": "String", - "value": "OPTIONS" - }, - "brief": "OPTIONS method." + "value": "OPTIONS", + "brief": "OPTIONS method.", + "note": null }, { "id": "patch", - "value": { - "type": "String", - "value": "PATCH" - }, - "brief": "PATCH method." + "value": "PATCH", + "brief": "PATCH method.", + "note": null }, { "id": "post", - "value": { - "type": "String", - "value": "POST" - }, - "brief": "POST method." + "value": "POST", + "brief": "POST method.", + "note": null }, { "id": "put", - "value": { - "type": "String", - "value": "PUT" - }, - "brief": "PUT method." + "value": "PUT", + "brief": "PUT method.", + "note": null }, { "id": "trace", - "value": { - "type": "String", - "value": "TRACE" - }, - "brief": "TRACE method." + "value": "TRACE", + "brief": "TRACE method.", + "note": null }, { "id": "other", - "value": { - "type": "String", - "value": "_OTHER" - }, - "brief": "Any HTTP method that the instrumentation has no prior knowledge of." + "value": "_OTHER", + "brief": "Any HTTP method that the instrumentation has no prior knowledge of.", + "note": null } ] }, "brief": "HTTP request method.", - "examples": { - "type": "Strings", - "values": [ - "GET", - "POST", - "HEAD" - ] - }, + "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": { - "type": "String" - }, + "type": "string", "brief": "Original HTTP method sent by the client in the request line.", - "examples": { - "type": "Strings", - "values": [ - "GeT", - "ACL", - "foo" - ] - }, + "examples": [ + "GeT", + "ACL", + "foo" + ], "requirement_level": "recommended", "stability": "stable" }, { "name": "http.request.resend_count", - "type": { - "type": "Int" - }, + "type": "int", "brief": "The ordinal number of request resending attempt (for any reason, including redirects).\n", - "examples": { - "type": "Int", - "value": 3 - }, + "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": { - "type": "Int" - }, + "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": { - "type": "Int", - "value": 3495 - }, + "examples": 3495, "requirement_level": "recommended", "stability": "experimental" }, { "name": "http.response.header", - "type": { - "type": "template[string[]]" - }, + "type": "template[string[]]", "brief": "HTTP response headers, `` being the normalized HTTP Header name (lowercase), the value being the header values.\n", - "examples": { - "type": "Strings", - "values": [ - "http.response.header.content-type=[\"application/json\"]", - "http.response.header.my-custom-header=[\"abc\", \"def\"]" - ] - }, + "examples": [ + "http.response.header.content-type=[\"application/json\"]", + "http.response.header.my-custom-header=[\"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": { - "type": "Int" - }, + "type": "int", "brief": "[HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6).", - "examples": { - "type": "Ints", - "values": [ - 200 - ] - }, + "examples": [ + 200 + ], "requirement_level": "recommended", "stability": "stable" }, { "name": "http.route", - "type": { - "type": "String" - }, + "type": "string", "brief": "The matched route, that is, the path template in the format used by the respective server framework.\n", - "examples": { - "type": "Strings", - "values": [ - "/users/:userID?", - "{controller}/{action}/{id?}" - ] - }, + "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": "messaging.batch.message_count", - "type": { - "type": "Int" - }, + "type": "int", "brief": "The number of messages sent, received, or processed in the scope of the batching operation.", - "examples": { - "type": "Ints", - "values": [ - 0, - 1, - 2 - ] - }, + "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" }, { "name": "messaging.client_id", - "type": { - "type": "String" - }, + "type": "string", "brief": "A unique identifier for the client that consumes or produces a message.\n", - "examples": { - "type": "Strings", - "values": [ - "client-5", - "myhost@8742@s8083jm" - ] - }, + "examples": [ + "client-5", + "myhost@8742@s8083jm" + ], "requirement_level": "recommended" }, { "name": "messaging.destination.name", - "type": { - "type": "String" - }, + "type": "string", "brief": "The message destination name", - "examples": { - "type": "Strings", - "values": [ - "MyQueue", - "MyTopic" - ] - }, + "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" }, { "name": "messaging.destination.template", - "type": { - "type": "String" - }, + "type": "string", "brief": "Low cardinality representation of the messaging destination name", - "examples": { - "type": "Strings", - "values": [ - "/customers/{customerId}" - ] - }, + "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" }, { "name": "messaging.destination.anonymous", - "type": { - "type": "Boolean" - }, + "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" }, { "name": "messaging.destination.temporary", - "type": { - "type": "Boolean" - }, + "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" }, { "name": "messaging.destination_publish.anonymous", - "type": { - "type": "Boolean" - }, + "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" }, { "name": "messaging.destination_publish.name", - "type": { - "type": "String" - }, + "type": "string", "brief": "The name of the original destination the message was published to", - "examples": { - "type": "Strings", - "values": [ - "MyQueue", - "MyTopic" - ] - }, + "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" }, { "name": "messaging.kafka.consumer.group", - "type": { - "type": "String" - }, + "type": "string", "brief": "Name of the Kafka Consumer Group that is handling the message. Only applies to consumers, not producers.\n", - "examples": { - "type": "String", - "value": "my-group" - }, + "examples": "my-group", "requirement_level": "recommended" }, { "name": "messaging.kafka.destination.partition", - "type": { - "type": "Int" - }, + "type": "int", "brief": "Partition the message is sent to.\n", - "examples": { - "type": "Int", - "value": 2 - }, + "examples": 2, "requirement_level": "recommended" }, { "name": "messaging.kafka.message.key", - "type": { - "type": "String" - }, + "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": { - "type": "String", - "value": "myKey" - }, + "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" }, { "name": "messaging.kafka.message.offset", - "type": { - "type": "Int" - }, + "type": "int", "brief": "The offset of a record in the corresponding Kafka partition.\n", - "examples": { - "type": "Int", - "value": 42 - }, + "examples": 42, "requirement_level": "recommended" }, { "name": "messaging.kafka.message.tombstone", - "type": { - "type": "Boolean" - }, + "type": "boolean", "brief": "A boolean that is true if the message is a tombstone.", "requirement_level": "recommended" }, { "name": "messaging.message.conversation_id", - "type": { - "type": "String" - }, + "type": "string", "brief": "The conversation ID identifying the conversation to which the message belongs, represented as a string. Sometimes called \"Correlation ID\".\n", - "examples": { - "type": "String", - "value": "MyConversationId" - }, + "examples": "MyConversationId", "requirement_level": "recommended" }, { "name": "messaging.message.envelope.size", - "type": { - "type": "Int" - }, + "type": "int", "brief": "The size of the message body and metadata in bytes.\n", - "examples": { - "type": "Int", - "value": 2738 - }, + "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" }, { "name": "messaging.message.id", - "type": { - "type": "String" - }, + "type": "string", "brief": "A value used by the messaging system as an identifier for the message, represented as a string.", - "examples": { - "type": "String", - "value": "452a7c7c7c7048c2f887f61572b18fc2" - }, + "examples": "452a7c7c7c7048c2f887f61572b18fc2", "requirement_level": "recommended" }, { "name": "messaging.message.body.size", - "type": { - "type": "Int" - }, + "type": "int", "brief": "The size of the message body in bytes.\n", - "examples": { - "type": "Int", - "value": 1439 - }, + "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" }, { "name": "messaging.operation", "type": { - "type": "Enum", "allow_custom_values": true, "members": [ { "id": "publish", - "value": { - "type": "String", - "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" + "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", + "note": null }, { "id": "create", - "value": { - "type": "String", - "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" + "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", + "note": null }, { "id": "receive", - "value": { - "type": "String", - "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" + "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", + "note": null }, { "id": "deliver", - "value": { - "type": "String", - "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" + "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", + "note": null } ] }, @@ -509,49 +357,34 @@ }, { "name": "messaging.rabbitmq.destination.routing_key", - "type": { - "type": "String" - }, + "type": "string", "brief": "RabbitMQ message routing key.\n", - "examples": { - "type": "String", - "value": "myKey" - }, + "examples": "myKey", "requirement_level": "recommended" }, { "name": "messaging.rocketmq.client_group", - "type": { - "type": "String" - }, + "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": { - "type": "String", - "value": "myConsumerGroup" - }, + "examples": "myConsumerGroup", "requirement_level": "recommended" }, { "name": "messaging.rocketmq.consumption_model", "type": { - "type": "Enum", "allow_custom_values": false, "members": [ { "id": "clustering", - "value": { - "type": "String", - "value": "clustering" - }, - "brief": "Clustering consumption model" + "value": "clustering", + "brief": "Clustering consumption model", + "note": null }, { "id": "broadcasting", - "value": { - "type": "String", - "value": "broadcasting" - }, - "brief": "Broadcasting consumption model" + "value": "broadcasting", + "brief": "Broadcasting consumption model", + "note": null } ] }, @@ -560,104 +393,70 @@ }, { "name": "messaging.rocketmq.message.delay_time_level", - "type": { - "type": "Int" - }, + "type": "int", "brief": "The delay time level for delay message, which determines the message delay time.\n", - "examples": { - "type": "Int", - "value": 3 - }, + "examples": 3, "requirement_level": "recommended" }, { "name": "messaging.rocketmq.message.delivery_timestamp", - "type": { - "type": "Int" - }, + "type": "int", "brief": "The timestamp in milliseconds that the delay message is expected to be delivered to consumer.\n", - "examples": { - "type": "Int", - "value": 1665987217045 - }, + "examples": 1665987217045, "requirement_level": "recommended" }, { "name": "messaging.rocketmq.message.group", - "type": { - "type": "String" - }, + "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": { - "type": "String", - "value": "myMessageGroup" - }, + "examples": "myMessageGroup", "requirement_level": "recommended" }, { "name": "messaging.rocketmq.message.keys", - "type": { - "type": "Strings" - }, + "type": "string[]", "brief": "Key(s) of message, another way to mark message besides message id.\n", - "examples": { - "type": "Strings", - "values": [ - "keyA", - "keyB" - ] - }, + "examples": [ + "keyA", + "keyB" + ], "requirement_level": "recommended" }, { "name": "messaging.rocketmq.message.tag", - "type": { - "type": "String" - }, + "type": "string", "brief": "The secondary classifier of message besides topic.\n", - "examples": { - "type": "String", - "value": "tagA" - }, + "examples": "tagA", "requirement_level": "recommended" }, { "name": "messaging.rocketmq.message.type", "type": { - "type": "Enum", "allow_custom_values": false, "members": [ { "id": "normal", - "value": { - "type": "String", - "value": "normal" - }, - "brief": "Normal message" + "value": "normal", + "brief": "Normal message", + "note": null }, { "id": "fifo", - "value": { - "type": "String", - "value": "fifo" - }, - "brief": "FIFO message" + "value": "fifo", + "brief": "FIFO message", + "note": null }, { "id": "delay", - "value": { - "type": "String", - "value": "delay" - }, - "brief": "Delay message" + "value": "delay", + "brief": "Delay message", + "note": null }, { "id": "transaction", - "value": { - "type": "String", - "value": "transaction" - }, - "brief": "Transaction message" + "value": "transaction", + "brief": "Transaction message", + "note": null } ] }, @@ -666,113 +465,82 @@ }, { "name": "messaging.rocketmq.namespace", - "type": { - "type": "String" - }, + "type": "string", "brief": "Namespace of RocketMQ resources, resources in different namespaces are individual.\n", - "examples": { - "type": "String", - "value": "myNamespace" - }, + "examples": "myNamespace", "requirement_level": "recommended" }, { "name": "messaging.gcp_pubsub.message.ordering_key", - "type": { - "type": "String" - }, + "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": { - "type": "String", - "value": "ordering_key" - }, + "examples": "ordering_key", "requirement_level": "recommended" }, { "name": "messaging.system", "type": { - "type": "Enum", "allow_custom_values": true, "members": [ { "id": "activemq", - "value": { - "type": "String", - "value": "activemq" - }, - "brief": "Apache ActiveMQ" + "value": "activemq", + "brief": "Apache ActiveMQ", + "note": null }, { "id": "aws_sqs", - "value": { - "type": "String", - "value": "aws_sqs" - }, - "brief": "Amazon Simple Queue Service (SQS)" + "value": "aws_sqs", + "brief": "Amazon Simple Queue Service (SQS)", + "note": null }, { "id": "azure_eventgrid", - "value": { - "type": "String", - "value": "azure_eventgrid" - }, - "brief": "Azure Event Grid" + "value": "azure_eventgrid", + "brief": "Azure Event Grid", + "note": null }, { "id": "azure_eventhubs", - "value": { - "type": "String", - "value": "azure_eventhubs" - }, - "brief": "Azure Event Hubs" + "value": "azure_eventhubs", + "brief": "Azure Event Hubs", + "note": null }, { "id": "azure_servicebus", - "value": { - "type": "String", - "value": "azure_servicebus" - }, - "brief": "Azure Service Bus" + "value": "azure_servicebus", + "brief": "Azure Service Bus", + "note": null }, { "id": "gcp_pubsub", - "value": { - "type": "String", - "value": "gcp_pubsub" - }, - "brief": "Google Cloud Pub/Sub" + "value": "gcp_pubsub", + "brief": "Google Cloud Pub/Sub", + "note": null }, { "id": "jms", - "value": { - "type": "String", - "value": "jms" - }, - "brief": "Java Message Service" + "value": "jms", + "brief": "Java Message Service", + "note": null }, { "id": "kafka", - "value": { - "type": "String", - "value": "kafka" - }, - "brief": "Apache Kafka" + "value": "kafka", + "brief": "Apache Kafka", + "note": null }, { "id": "rabbitmq", - "value": { - "type": "String", - "value": "rabbitmq" - }, - "brief": "RabbitMQ" + "value": "rabbitmq", + "brief": "RabbitMQ", + "note": null }, { "id": "rocketmq", - "value": { - "type": "String", - "value": "rocketmq" - }, - "brief": "Apache RocketMQ" + "value": "rocketmq", + "brief": "Apache RocketMQ", + "note": null } ] }, @@ -781,375 +549,270 @@ }, { "name": "network.carrier.icc", - "type": { - "type": "String" - }, + "type": "string", "brief": "The ISO 3166-1 alpha-2 2-character country code associated with the mobile carrier network.", - "examples": { - "type": "String", - "value": "DE" - }, + "examples": "DE", "requirement_level": "recommended" }, { "name": "network.carrier.mcc", - "type": { - "type": "String" - }, + "type": "string", "brief": "The mobile carrier country code.", - "examples": { - "type": "String", - "value": "310" - }, + "examples": "310", "requirement_level": "recommended" }, { "name": "network.carrier.mnc", - "type": { - "type": "String" - }, + "type": "string", "brief": "The mobile carrier network code.", - "examples": { - "type": "String", - "value": "001" - }, + "examples": "001", "requirement_level": "recommended" }, { "name": "network.carrier.name", - "type": { - "type": "String" - }, + "type": "string", "brief": "The name of the mobile carrier.", - "examples": { - "type": "String", - "value": "sprint" - }, + "examples": "sprint", "requirement_level": "recommended" }, { "name": "network.connection.subtype", "type": { - "type": "Enum", "allow_custom_values": true, "members": [ { "id": "gprs", - "value": { - "type": "String", - "value": "gprs" - }, - "brief": "GPRS" + "value": "gprs", + "brief": "GPRS", + "note": null }, { "id": "edge", - "value": { - "type": "String", - "value": "edge" - }, - "brief": "EDGE" + "value": "edge", + "brief": "EDGE", + "note": null }, { "id": "umts", - "value": { - "type": "String", - "value": "umts" - }, - "brief": "UMTS" + "value": "umts", + "brief": "UMTS", + "note": null }, { "id": "cdma", - "value": { - "type": "String", - "value": "cdma" - }, - "brief": "CDMA" + "value": "cdma", + "brief": "CDMA", + "note": null }, { "id": "evdo_0", - "value": { - "type": "String", - "value": "evdo_0" - }, - "brief": "EVDO Rel. 0" + "value": "evdo_0", + "brief": "EVDO Rel. 0", + "note": null }, { "id": "evdo_a", - "value": { - "type": "String", - "value": "evdo_a" - }, - "brief": "EVDO Rev. A" + "value": "evdo_a", + "brief": "EVDO Rev. A", + "note": null }, { "id": "cdma2000_1xrtt", - "value": { - "type": "String", - "value": "cdma2000_1xrtt" - }, - "brief": "CDMA2000 1XRTT" + "value": "cdma2000_1xrtt", + "brief": "CDMA2000 1XRTT", + "note": null }, { "id": "hsdpa", - "value": { - "type": "String", - "value": "hsdpa" - }, - "brief": "HSDPA" + "value": "hsdpa", + "brief": "HSDPA", + "note": null }, { "id": "hsupa", - "value": { - "type": "String", - "value": "hsupa" - }, - "brief": "HSUPA" + "value": "hsupa", + "brief": "HSUPA", + "note": null }, { "id": "hspa", - "value": { - "type": "String", - "value": "hspa" - }, - "brief": "HSPA" + "value": "hspa", + "brief": "HSPA", + "note": null }, { "id": "iden", - "value": { - "type": "String", - "value": "iden" - }, - "brief": "IDEN" + "value": "iden", + "brief": "IDEN", + "note": null }, { "id": "evdo_b", - "value": { - "type": "String", - "value": "evdo_b" - }, - "brief": "EVDO Rev. B" + "value": "evdo_b", + "brief": "EVDO Rev. B", + "note": null }, { "id": "lte", - "value": { - "type": "String", - "value": "lte" - }, - "brief": "LTE" + "value": "lte", + "brief": "LTE", + "note": null }, { "id": "ehrpd", - "value": { - "type": "String", - "value": "ehrpd" - }, - "brief": "EHRPD" + "value": "ehrpd", + "brief": "EHRPD", + "note": null }, { "id": "hspap", - "value": { - "type": "String", - "value": "hspap" - }, - "brief": "HSPAP" + "value": "hspap", + "brief": "HSPAP", + "note": null }, { "id": "gsm", - "value": { - "type": "String", - "value": "gsm" - }, - "brief": "GSM" + "value": "gsm", + "brief": "GSM", + "note": null }, { "id": "td_scdma", - "value": { - "type": "String", - "value": "td_scdma" - }, - "brief": "TD-SCDMA" + "value": "td_scdma", + "brief": "TD-SCDMA", + "note": null }, { "id": "iwlan", - "value": { - "type": "String", - "value": "iwlan" - }, - "brief": "IWLAN" + "value": "iwlan", + "brief": "IWLAN", + "note": null }, { "id": "nr", - "value": { - "type": "String", - "value": "nr" - }, - "brief": "5G NR (New Radio)" + "value": "nr", + "brief": "5G NR (New Radio)", + "note": null }, { "id": "nrnsa", - "value": { - "type": "String", - "value": "nrnsa" - }, - "brief": "5G NRNSA (New Radio Non-Standalone)" + "value": "nrnsa", + "brief": "5G NRNSA (New Radio Non-Standalone)", + "note": null }, { "id": "lte_ca", - "value": { - "type": "String", - "value": "lte_ca" - }, - "brief": "LTE CA" + "value": "lte_ca", + "brief": "LTE CA", + "note": null } ] }, "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": { - "type": "String", - "value": "LTE" - }, + "examples": "LTE", "requirement_level": "recommended" }, { "name": "network.connection.type", "type": { - "type": "Enum", "allow_custom_values": true, "members": [ { "id": "wifi", - "value": { - "type": "String", - "value": "wifi" - } + "value": "wifi", + "brief": null, + "note": null }, { "id": "wired", - "value": { - "type": "String", - "value": "wired" - } + "value": "wired", + "brief": null, + "note": null }, { "id": "cell", - "value": { - "type": "String", - "value": "cell" - } + "value": "cell", + "brief": null, + "note": null }, { "id": "unavailable", - "value": { - "type": "String", - "value": "unavailable" - } + "value": "unavailable", + "brief": null, + "note": null }, { "id": "unknown", - "value": { - "type": "String", - "value": "unknown" - } + "value": "unknown", + "brief": null, + "note": null } ] }, "brief": "The internet connection type.", - "examples": { - "type": "String", - "value": "wifi" - }, + "examples": "wifi", "requirement_level": "recommended" }, { "name": "network.local.address", - "type": { - "type": "String" - }, + "type": "string", "brief": "Local address of the network connection - IP address or Unix domain socket name.", - "examples": { - "type": "Strings", - "values": [ - "10.1.2.80", - "/tmp/my.sock" - ] - }, + "examples": [ + "10.1.2.80", + "/tmp/my.sock" + ], "requirement_level": "recommended", "stability": "stable" }, { "name": "network.local.port", - "type": { - "type": "Int" - }, + "type": "int", "brief": "Local port number of the network connection.", - "examples": { - "type": "Ints", - "values": [ - 65123 - ] - }, + "examples": [ + 65123 + ], "requirement_level": "recommended", "stability": "stable" }, { "name": "network.peer.address", - "type": { - "type": "String" - }, + "type": "string", "brief": "Peer address of the network connection - IP address or Unix domain socket name.", - "examples": { - "type": "Strings", - "values": [ - "10.1.2.80", - "/tmp/my.sock" - ] - }, + "examples": [ + "10.1.2.80", + "/tmp/my.sock" + ], "requirement_level": "recommended", "stability": "stable" }, { "name": "network.peer.port", - "type": { - "type": "Int" - }, + "type": "int", "brief": "Peer port number of the network connection.", - "examples": { - "type": "Ints", - "values": [ - 65123 - ] - }, + "examples": [ + 65123 + ], "requirement_level": "recommended", "stability": "stable" }, { "name": "network.protocol.name", - "type": { - "type": "String" - }, + "type": "string", "brief": "[OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent.", - "examples": { - "type": "Strings", - "values": [ - "amqp", - "http", - "mqtt" - ] - }, + "examples": [ + "amqp", + "http", + "mqtt" + ], "requirement_level": "recommended", "note": "The value SHOULD be normalized to lowercase.", "stability": "stable" }, { "name": "network.protocol.version", - "type": { - "type": "String" - }, + "type": "string", "brief": "Version of the protocol specified in `network.protocol.name`.", - "examples": { - "type": "String", - "value": "3.1.1" - }, + "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" @@ -1157,51 +820,39 @@ { "name": "network.transport", "type": { - "type": "Enum", "allow_custom_values": true, "members": [ { "id": "tcp", - "value": { - "type": "String", - "value": "tcp" - }, - "brief": "TCP" + "value": "tcp", + "brief": "TCP", + "note": null }, { "id": "udp", - "value": { - "type": "String", - "value": "udp" - }, - "brief": "UDP" + "value": "udp", + "brief": "UDP", + "note": null }, { "id": "pipe", - "value": { - "type": "String", - "value": "pipe" - }, - "brief": "Named or anonymous pipe." + "value": "pipe", + "brief": "Named or anonymous pipe.", + "note": null }, { "id": "unix", - "value": { - "type": "String", - "value": "unix" - }, - "brief": "Unix domain socket" + "value": "unix", + "brief": "Unix domain socket", + "note": null } ] }, "brief": "[OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication).\n", - "examples": { - "type": "Strings", - "values": [ - "tcp", - "udp" - ] - }, + "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" @@ -1209,35 +860,27 @@ { "name": "network.type", "type": { - "type": "Enum", "allow_custom_values": true, "members": [ { "id": "ipv4", - "value": { - "type": "String", - "value": "ipv4" - }, - "brief": "IPv4" + "value": "ipv4", + "brief": "IPv4", + "note": null }, { "id": "ipv6", - "value": { - "type": "String", - "value": "ipv6" - }, - "brief": "IPv6" + "value": "ipv6", + "brief": "IPv6", + "note": null } ] }, "brief": "[OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent.", - "examples": { - "type": "Strings", - "values": [ - "ipv4", - "ipv6" - ] - }, + "examples": [ + "ipv4", + "ipv6" + ], "requirement_level": "recommended", "note": "The value SHOULD be normalized to lowercase.", "stability": "stable" @@ -1245,263 +888,193 @@ { "name": "network.io.direction", "type": { - "type": "Enum", "allow_custom_values": false, "members": [ { "id": "transmit", - "value": { - "type": "String", - "value": "transmit" - } + "value": "transmit", + "brief": null, + "note": null }, { "id": "receive", - "value": { - "type": "String", - "value": "receive" - } + "value": "receive", + "brief": null, + "note": null } ] }, "brief": "The network IO operation direction.", - "examples": { - "type": "Strings", - "values": [ - "transmit" - ] - }, + "examples": [ + "transmit" + ], "requirement_level": "recommended" }, { "name": "server.address", - "type": { - "type": "String" - }, + "type": "string", "brief": "Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name.", - "examples": { - "type": "Strings", - "values": [ - "example.com", - "10.1.2.80", - "/tmp/my.sock" - ] - }, + "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": { - "type": "Int" - }, + "type": "int", "brief": "Server port number.", - "examples": { - "type": "Ints", - "values": [ - 80, - 8080, - 443 - ] - }, + "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.scheme", - "type": { - "type": "String" - }, + "type": "string", "brief": "The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol.", - "examples": { - "type": "Strings", - "values": [ - "https", - "ftp", - "telnet" - ] - }, + "examples": [ + "https", + "ftp", + "telnet" + ], "requirement_level": "recommended", "stability": "stable" }, { "name": "url.full", - "type": { - "type": "String" - }, + "type": "string", "brief": "Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986)", - "examples": { - "type": "Strings", - "values": [ - "https://www.foo.bar/search?q=OpenTelemetry#SemConv", - "//localhost" - ] - }, + "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": { - "type": "String" - }, + "type": "string", "brief": "The [URI path](https://www.rfc-editor.org/rfc/rfc3986#section-3.3) component", - "examples": { - "type": "Strings", - "values": [ - "/search" - ] - }, + "examples": [ + "/search" + ], "requirement_level": "recommended", "stability": "stable" }, { "name": "url.query", - "type": { - "type": "String" - }, + "type": "string", "brief": "The [URI query](https://www.rfc-editor.org/rfc/rfc3986#section-3.4) component", - "examples": { - "type": "Strings", - "values": [ - "q=OpenTelemetry" - ] - }, + "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.fragment", - "type": { - "type": "String" - }, + "type": "string", "brief": "The [URI fragment](https://www.rfc-editor.org/rfc/rfc3986#section-3.5) component", - "examples": { - "type": "Strings", - "values": [ - "SemConv" - ] - }, + "examples": [ + "SemConv" + ], "requirement_level": "recommended", "stability": "stable" }, { "name": "http.request.method", "type": { - "type": "Enum", "allow_custom_values": true, "members": [ { "id": "connect", - "value": { - "type": "String", - "value": "CONNECT" - }, - "brief": "CONNECT method." + "value": "CONNECT", + "brief": "CONNECT method.", + "note": null }, { "id": "delete", - "value": { - "type": "String", - "value": "DELETE" - }, - "brief": "DELETE method." + "value": "DELETE", + "brief": "DELETE method.", + "note": null }, { "id": "get", - "value": { - "type": "String", - "value": "GET" - }, - "brief": "GET method." + "value": "GET", + "brief": "GET method.", + "note": null }, { "id": "head", - "value": { - "type": "String", - "value": "HEAD" - }, - "brief": "HEAD method." + "value": "HEAD", + "brief": "HEAD method.", + "note": null }, { "id": "options", - "value": { - "type": "String", - "value": "OPTIONS" - }, - "brief": "OPTIONS method." + "value": "OPTIONS", + "brief": "OPTIONS method.", + "note": null }, { "id": "patch", - "value": { - "type": "String", - "value": "PATCH" - }, - "brief": "PATCH method." + "value": "PATCH", + "brief": "PATCH method.", + "note": null }, { "id": "post", - "value": { - "type": "String", - "value": "POST" - }, - "brief": "POST method." + "value": "POST", + "brief": "POST method.", + "note": null }, { "id": "put", - "value": { - "type": "String", - "value": "PUT" - }, - "brief": "PUT method." + "value": "PUT", + "brief": "PUT method.", + "note": null }, { "id": "trace", - "value": { - "type": "String", - "value": "TRACE" - }, - "brief": "TRACE method." + "value": "TRACE", + "brief": "TRACE method.", + "note": null }, { "id": "other", - "value": { - "type": "String", - "value": "_OTHER" - }, - "brief": "Any HTTP method that the instrumentation has no prior knowledge of." + "value": "_OTHER", + "brief": "Any HTTP method that the instrumentation has no prior knowledge of.", + "note": null } ] }, "brief": "HTTP request method.", - "examples": { - "type": "Strings", - "values": [ - "GET", - "POST", - "HEAD" - ] - }, + "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.response.status_code", - "type": { - "type": "Int" - }, + "type": "int", "brief": "[HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6).", - "examples": { - "type": "Ints", - "values": [ - 200 - ] - }, + "examples": [ + 200 + ], "requirement_level": { "conditionally_required": "If and only if one was received/sent." }, @@ -1510,29 +1083,23 @@ { "name": "error.type", "type": { - "type": "Enum", "allow_custom_values": true, "members": [ { "id": "other", - "value": { - "type": "String", - "value": "_OTHER" - }, - "brief": "A fallback error value to be used when the instrumentation doesn't define a custom value.\n" + "value": "_OTHER", + "brief": "A fallback error value to be used when the instrumentation doesn't define a custom value.\n", + "note": null } ] }, "brief": "Describes a class of error the operation ended with.\n", - "examples": { - "type": "Strings", - "values": [ - "timeout", - "java.net.UnknownHostException", - "server_certificate_invalid", - "500" - ] - }, + "examples": [ + "timeout", + "java.net.UnknownHostException", + "server_certificate_invalid", + "500" + ], "requirement_level": { "conditionally_required": "If request has ended with an error." }, @@ -1541,17 +1108,12 @@ }, { "name": "network.protocol.name", - "type": { - "type": "String" - }, + "type": "string", "brief": "[OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent.", - "examples": { - "type": "Strings", - "values": [ - "http", - "spdy" - ] - }, + "examples": [ + "http", + "spdy" + ], "requirement_level": { "conditionally_required": "If not `http` and `network.protocol.version` is set." }, @@ -1560,88 +1122,63 @@ }, { "name": "network.protocol.version", - "type": { - "type": "String" - }, + "type": "string", "brief": "Version of the protocol specified in `network.protocol.name`.", - "examples": { - "type": "Strings", - "values": [ - "1.0", - "1.1", - "2", - "3" - ] - }, + "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": "server.address", - "type": { - "type": "String" - }, + "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": { - "type": "Strings", - "values": [ - "example.com", - "10.1.2.80", - "/tmp/my.sock" - ] - }, + "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.port", - "type": { - "type": "Int" - }, + "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": { - "type": "Ints", - "values": [ - 80, - 8080, - 443 - ] - }, + "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": "url.scheme", - "type": { - "type": "String" - }, + "type": "string", "brief": "The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol.", - "examples": { - "type": "Strings", - "values": [ - "http", - "https" - ] - }, + "examples": [ + "http", + "https" + ], "requirement_level": "opt_in", "stability": "stable" }, { "name": "http.route", - "type": { - "type": "String" - }, + "type": "string", "brief": "The matched route, that is, the path template in the format used by the respective server framework.\n", - "examples": { - "type": "Strings", - "values": [ - "/users/:userID?", - "{controller}/{action}/{id?}" - ] - }, + "examples": [ + "/users/:userID?", + "{controller}/{action}/{id?}" + ], "requirement_level": { "conditionally_required": "If and only if it's available" }, @@ -1650,36 +1187,26 @@ }, { "name": "server.address", - "type": { - "type": "String" - }, + "type": "string", "brief": "Name of the local HTTP server that received the request.\n", - "examples": { - "type": "Strings", - "values": [ - "example.com", - "10.1.2.80", - "/tmp/my.sock" - ] - }, + "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.port", - "type": { - "type": "Int" - }, + "type": "int", "brief": "Port of the local HTTP server that received the request.\n", - "examples": { - "type": "Ints", - "values": [ - 80, - 8080, - 443 - ] - }, + "examples": [ + 80, + 8080, + 443 + ], "requirement_level": { "conditionally_required": "If `server.address` is set." }, @@ -1688,17 +1215,12 @@ }, { "name": "url.scheme", - "type": { - "type": "String" - }, + "type": "string", "brief": "The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol.", - "examples": { - "type": "Strings", - "values": [ - "http", - "https" - ] - }, + "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" @@ -1706,88 +1228,67 @@ { "name": "messaging.system", "type": { - "type": "Enum", "allow_custom_values": true, "members": [ { "id": "activemq", - "value": { - "type": "String", - "value": "activemq" - }, - "brief": "Apache ActiveMQ" + "value": "activemq", + "brief": "Apache ActiveMQ", + "note": null }, { "id": "aws_sqs", - "value": { - "type": "String", - "value": "aws_sqs" - }, - "brief": "Amazon Simple Queue Service (SQS)" + "value": "aws_sqs", + "brief": "Amazon Simple Queue Service (SQS)", + "note": null }, { "id": "azure_eventgrid", - "value": { - "type": "String", - "value": "azure_eventgrid" - }, - "brief": "Azure Event Grid" + "value": "azure_eventgrid", + "brief": "Azure Event Grid", + "note": null }, { "id": "azure_eventhubs", - "value": { - "type": "String", - "value": "azure_eventhubs" - }, - "brief": "Azure Event Hubs" + "value": "azure_eventhubs", + "brief": "Azure Event Hubs", + "note": null }, { "id": "azure_servicebus", - "value": { - "type": "String", - "value": "azure_servicebus" - }, - "brief": "Azure Service Bus" + "value": "azure_servicebus", + "brief": "Azure Service Bus", + "note": null }, { "id": "gcp_pubsub", - "value": { - "type": "String", - "value": "gcp_pubsub" - }, - "brief": "Google Cloud Pub/Sub" + "value": "gcp_pubsub", + "brief": "Google Cloud Pub/Sub", + "note": null }, { "id": "jms", - "value": { - "type": "String", - "value": "jms" - }, - "brief": "Java Message Service" + "value": "jms", + "brief": "Java Message Service", + "note": null }, { "id": "kafka", - "value": { - "type": "String", - "value": "kafka" - }, - "brief": "Apache Kafka" + "value": "kafka", + "brief": "Apache Kafka", + "note": null }, { "id": "rabbitmq", - "value": { - "type": "String", - "value": "rabbitmq" - }, - "brief": "RabbitMQ" + "value": "rabbitmq", + "brief": "RabbitMQ", + "note": null }, { "id": "rocketmq", - "value": { - "type": "String", - "value": "rocketmq" - }, - "brief": "Apache RocketMQ" + "value": "rocketmq", + "brief": "Apache RocketMQ", + "note": null } ] }, @@ -1797,28 +1298,22 @@ { "name": "error.type", "type": { - "type": "Enum", "allow_custom_values": true, "members": [ { "id": "other", - "value": { - "type": "String", - "value": "_OTHER" - }, - "brief": "A fallback error value to be used when the instrumentation doesn't define a custom value.\n" + "value": "_OTHER", + "brief": "A fallback error value to be used when the instrumentation doesn't define a custom value.\n", + "note": null } ] }, "brief": "Describes a class of error the operation ended with.\n", - "examples": { - "type": "Strings", - "values": [ - "amqp:decode-error", - "KAFKA_STORAGE_ERROR", - "channel-error" - ] - }, + "examples": [ + "amqp:decode-error", + "KAFKA_STORAGE_ERROR", + "channel-error" + ], "requirement_level": { "conditionally_required": "If and only if the messaging operation has failed." }, @@ -1827,18 +1322,13 @@ }, { "name": "server.address", - "type": { - "type": "String" - }, + "type": "string", "brief": "Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name.", - "examples": { - "type": "Strings", - "values": [ - "example.com", - "10.1.2.80", - "/tmp/my.sock" - ] - }, + "examples": [ + "example.com", + "10.1.2.80", + "/tmp/my.sock" + ], "requirement_level": { "conditionally_required": "If available." }, @@ -1847,17 +1337,12 @@ }, { "name": "network.protocol.name", - "type": { - "type": "String" - }, + "type": "string", "brief": "[OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent.", - "examples": { - "type": "Strings", - "values": [ - "amqp", - "mqtt" - ] - }, + "examples": [ + "amqp", + "mqtt" + ], "tag": "connection-level", "requirement_level": "recommended", "note": "The value SHOULD be normalized to lowercase.", @@ -1865,14 +1350,9 @@ }, { "name": "network.protocol.version", - "type": { - "type": "String" - }, + "type": "string", "brief": "Version of the protocol specified in `network.protocol.name`.", - "examples": { - "type": "String", - "value": "3.1.1" - }, + "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", @@ -1880,17 +1360,12 @@ }, { "name": "messaging.destination.name", - "type": { - "type": "String" - }, + "type": "string", "brief": "The message destination name", - "examples": { - "type": "Strings", - "values": [ - "MyQueue", - "MyTopic" - ] - }, + "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." }, @@ -1898,16 +1373,11 @@ }, { "name": "messaging.destination.template", - "type": { - "type": "String" - }, + "type": "string", "brief": "Low cardinality representation of the messaging destination name", - "examples": { - "type": "Strings", - "values": [ - "/customers/{customerId}" - ] - }, + "examples": [ + "/customers/{customerId}" + ], "requirement_level": { "conditionally_required": "if available." }, 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 3eb37df4..dcd9d812 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 @@ -2,48 +2,37 @@ { "name": "ios.state", "type": { - "type": "Enum", "allow_custom_values": false, "members": [ { "id": "active", - "value": { - "type": "String", - "value": "active" - }, - "brief": "The app has become `active`. Associated with UIKit notification `applicationDidBecomeActive`.\n" + "value": "active", + "brief": "The app has become `active`. Associated with UIKit notification `applicationDidBecomeActive`.\n", + "note": null }, { "id": "inactive", - "value": { - "type": "String", - "value": "inactive" - }, - "brief": "The app is now `inactive`. Associated with UIKit notification `applicationWillResignActive`.\n" + "value": "inactive", + "brief": "The app is now `inactive`. Associated with UIKit notification `applicationWillResignActive`.\n", + "note": null }, { "id": "background", - "value": { - "type": "String", - "value": "background" - }, - "brief": "The app is now in the background. This value is associated with UIKit notification `applicationDidEnterBackground`.\n" + "value": "background", + "brief": "The app is now in the background. This value is associated with UIKit notification `applicationDidEnterBackground`.\n", + "note": null }, { "id": "foreground", - "value": { - "type": "String", - "value": "foreground" - }, - "brief": "The app is now in the foreground. This value is associated with UIKit notification `applicationWillEnterForeground`.\n" + "value": "foreground", + "brief": "The app is now in the foreground. This value is associated with UIKit notification `applicationWillEnterForeground`.\n", + "note": null }, { "id": "terminate", - "value": { - "type": "String", - "value": "terminate" - }, - "brief": "The app is about to terminate. Associated with UIKit notification `applicationWillTerminate`.\n" + "value": "terminate", + "brief": "The app is about to terminate. Associated with UIKit notification `applicationWillTerminate`.\n", + "note": null } ] }, @@ -54,32 +43,25 @@ { "name": "android.state", "type": { - "type": "Enum", "allow_custom_values": false, "members": [ { "id": "created", - "value": { - "type": "String", - "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" + "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", + "note": null }, { "id": "background", - "value": { - "type": "String", - "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" + "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", + "note": null }, { "id": "foreground", - "value": { - "type": "String", - "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." + "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.", + "note": null } ] }, @@ -89,46 +71,31 @@ }, { "name": "feature_flag.key", - "type": { - "type": "String" - }, + "type": "string", "brief": "The unique identifier of the feature flag.", - "examples": { - "type": "Strings", - "values": [ - "logo-color" - ] - }, + "examples": [ + "logo-color" + ], "requirement_level": "required" }, { "name": "feature_flag.provider_name", - "type": { - "type": "String" - }, + "type": "string", "brief": "The name of the service provider that performs the flag evaluation.", - "examples": { - "type": "Strings", - "values": [ - "Flag Manager" - ] - }, + "examples": [ + "Flag Manager" + ], "requirement_level": "recommended" }, { "name": "feature_flag.variant", - "type": { - "type": "String" - }, + "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": { - "type": "Strings", - "values": [ - "red", - "true", - "on" - ] - }, + "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." } 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 760aa55a..b1a84ba5 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 @@ -2,48 +2,37 @@ { "name": "faas.trigger", "type": { - "type": "Enum", "allow_custom_values": false, "members": [ { "id": "datasource", - "value": { - "type": "String", - "value": "datasource" - }, - "brief": "A response to some data source operation such as a database or filesystem read/write" + "value": "datasource", + "brief": "A response to some data source operation such as a database or filesystem read/write", + "note": null }, { "id": "http", - "value": { - "type": "String", - "value": "http" - }, - "brief": "To provide an answer to an inbound HTTP request" + "value": "http", + "brief": "To provide an answer to an inbound HTTP request", + "note": null }, { "id": "pubsub", - "value": { - "type": "String", - "value": "pubsub" - }, - "brief": "A function is set to be executed when messages are sent to a messaging system" + "value": "pubsub", + "brief": "A function is set to be executed when messages are sent to a messaging system", + "note": null }, { "id": "timer", - "value": { - "type": "String", - "value": "timer" - }, - "brief": "A function is scheduled to be executed regularly" + "value": "timer", + "brief": "A function is scheduled to be executed regularly", + "note": null }, { "id": "other", - "value": { - "type": "String", - "value": "other" - }, - "brief": "If none of the others apply" + "value": "other", + "brief": "If none of the others apply", + "note": null } ] }, @@ -52,62 +41,46 @@ }, { "name": "faas.invoked_name", - "type": { - "type": "String" - }, + "type": "string", "brief": "The name of the invoked function.\n", - "examples": { - "type": "String", - "value": "my-function" - }, + "examples": "my-function", "requirement_level": "required", "note": "SHOULD be equal to the `faas.name` resource attribute of the invoked function.\n" }, { "name": "faas.invoked_provider", "type": { - "type": "Enum", "allow_custom_values": true, "members": [ { "id": "alibaba_cloud", - "value": { - "type": "String", - "value": "alibaba_cloud" - }, - "brief": "Alibaba Cloud" + "value": "alibaba_cloud", + "brief": "Alibaba Cloud", + "note": null }, { "id": "aws", - "value": { - "type": "String", - "value": "aws" - }, - "brief": "Amazon Web Services" + "value": "aws", + "brief": "Amazon Web Services", + "note": null }, { "id": "azure", - "value": { - "type": "String", - "value": "azure" - }, - "brief": "Microsoft Azure" + "value": "azure", + "brief": "Microsoft Azure", + "note": null }, { "id": "gcp", - "value": { - "type": "String", - "value": "gcp" - }, - "brief": "Google Cloud Platform" + "value": "gcp", + "brief": "Google Cloud Platform", + "note": null }, { "id": "tencent_cloud", - "value": { - "type": "String", - "value": "tencent_cloud" - }, - "brief": "Tencent Cloud" + "value": "tencent_cloud", + "brief": "Tencent Cloud", + "note": null } ] }, @@ -117,14 +90,9 @@ }, { "name": "faas.invoked_region", - "type": { - "type": "String" - }, + "type": "string", "brief": "The cloud region of the invoked function.\n", - "examples": { - "type": "String", - "value": "eu-central-1" - }, + "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" }, 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 b1a974b5..0a264e13 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,93 +1,66 @@ [ { "name": "user_agent.original", - "type": { - "type": "String" - }, + "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": { - "type": "Strings", - "values": [ - "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" - ] - }, + "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" }, { "name": "browser.brands", - "type": { - "type": "Strings" - }, + "type": "string[]", "brief": "Array of brand name and version separated by a space", - "examples": { - "type": "Strings", - "values": [ - " Not A;Brand 99", - "Chromium 99", - "Chrome 99" - ] - }, + "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" }, { "name": "browser.platform", - "type": { - "type": "String" - }, + "type": "string", "brief": "The platform on which the browser is running", - "examples": { - "type": "Strings", - "values": [ - "Windows", - "macOS", - "Android" - ] - }, + "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" }, { "name": "browser.mobile", - "type": { - "type": "Boolean" - }, + "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" }, { "name": "browser.language", - "type": { - "type": "String" - }, + "type": "string", "brief": "Preferred language of the user using the browser", - "examples": { - "type": "Strings", - "values": [ - "en", - "en-US", - "fr", - "fr-FR" - ] - }, + "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" }, { "name": "user_agent.original", - "type": { - "type": "String" - }, + "type": "string", "brief": "Full user-agent string provided by the browser", - "examples": { - "type": "Strings", - "values": [ - "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" - ] - }, + "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" 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 aa6c944f..543b1257 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,112 +1,90 @@ [ { "name": "db.cassandra.coordinator.dc", - "type": { - "type": "String" - }, + "type": "string", "brief": "The data center of the coordinating node for a query.\n", - "examples": { - "type": "String", - "value": "us-west-2" - }, + "examples": "us-west-2", "tag": "tech-specific-cassandra", "requirement_level": "recommended" }, { "name": "db.cassandra.coordinator.id", - "type": { - "type": "String" - }, + "type": "string", "brief": "The ID of the coordinating node for a query.\n", - "examples": { - "type": "String", - "value": "be13faa2-8574-4d71-926d-27f16cf8a7af" - }, + "examples": "be13faa2-8574-4d71-926d-27f16cf8a7af", "tag": "tech-specific-cassandra", "requirement_level": "recommended" }, { "name": "db.cassandra.consistency_level", "type": { - "type": "Enum", "allow_custom_values": true, "members": [ { "id": "all", - "value": { - "type": "String", - "value": "all" - } + "value": "all", + "brief": null, + "note": null }, { "id": "each_quorum", - "value": { - "type": "String", - "value": "each_quorum" - } + "value": "each_quorum", + "brief": null, + "note": null }, { "id": "quorum", - "value": { - "type": "String", - "value": "quorum" - } + "value": "quorum", + "brief": null, + "note": null }, { "id": "local_quorum", - "value": { - "type": "String", - "value": "local_quorum" - } + "value": "local_quorum", + "brief": null, + "note": null }, { "id": "one", - "value": { - "type": "String", - "value": "one" - } + "value": "one", + "brief": null, + "note": null }, { "id": "two", - "value": { - "type": "String", - "value": "two" - } + "value": "two", + "brief": null, + "note": null }, { "id": "three", - "value": { - "type": "String", - "value": "three" - } + "value": "three", + "brief": null, + "note": null }, { "id": "local_one", - "value": { - "type": "String", - "value": "local_one" - } + "value": "local_one", + "brief": null, + "note": null }, { "id": "any", - "value": { - "type": "String", - "value": "any" - } + "value": "any", + "brief": null, + "note": null }, { "id": "serial", - "value": { - "type": "String", - "value": "serial" - } + "value": "serial", + "brief": null, + "note": null }, { "id": "local_serial", - "value": { - "type": "String", - "value": "local_serial" - } + "value": "local_serial", + "brief": null, + "note": null } ] }, @@ -116,105 +94,73 @@ }, { "name": "db.cassandra.idempotence", - "type": { - "type": "Boolean" - }, + "type": "boolean", "brief": "Whether or not the query is idempotent.\n", "tag": "tech-specific-cassandra", "requirement_level": "recommended" }, { "name": "db.cassandra.page_size", - "type": { - "type": "Int" - }, + "type": "int", "brief": "The fetch size used for paging, i.e. how many rows will be returned at once.\n", - "examples": { - "type": "Ints", - "values": [ - 5000 - ] - }, + "examples": [ + 5000 + ], "tag": "tech-specific-cassandra", "requirement_level": "recommended" }, { "name": "db.cassandra.speculative_execution_count", - "type": { - "type": "Int" - }, + "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": { - "type": "Ints", - "values": [ - 0, - 2 - ] - }, + "examples": [ + 0, + 2 + ], "tag": "tech-specific-cassandra", "requirement_level": "recommended" }, { "name": "db.cassandra.table", - "type": { - "type": "String" - }, + "type": "string", "brief": "The name of the primary Cassandra table that the operation is acting upon, including the keyspace name (if applicable).", - "examples": { - "type": "String", - "value": "mytable" - }, + "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" }, { "name": "db.connection_string", - "type": { - "type": "String" - }, + "type": "string", "brief": "The connection string used to connect to the database. It is recommended to remove embedded credentials.\n", - "examples": { - "type": "String", - "value": "Server=(localdb)\\v11.0;Integrated Security=true;" - }, + "examples": "Server=(localdb)\\v11.0;Integrated Security=true;", "tag": "db-generic", "requirement_level": "recommended" }, { "name": "db.cosmosdb.client_id", - "type": { - "type": "String" - }, + "type": "string", "brief": "Unique Cosmos client instance id.", - "examples": { - "type": "String", - "value": "3ba4827d-4422-483f-b59f-85b74211c11d" - }, + "examples": "3ba4827d-4422-483f-b59f-85b74211c11d", "tag": "tech-specific-cosmosdb", "requirement_level": "recommended" }, { "name": "db.cosmosdb.connection_mode", "type": { - "type": "Enum", "allow_custom_values": false, "members": [ { "id": "gateway", - "value": { - "type": "String", - "value": "gateway" - }, - "brief": "Gateway (HTTP) connections mode" + "value": "gateway", + "brief": "Gateway (HTTP) connections mode", + "note": null }, { "id": "direct", - "value": { - "type": "String", - "value": "direct" - }, - "brief": "Direct connection." + "value": "direct", + "brief": "Direct connection.", + "note": null } ] }, @@ -224,127 +170,106 @@ }, { "name": "db.cosmosdb.container", - "type": { - "type": "String" - }, + "type": "string", "brief": "Cosmos DB container name.", - "examples": { - "type": "String", - "value": "anystring" - }, + "examples": "anystring", "tag": "tech-specific-cosmosdb", "requirement_level": "recommended" }, { "name": "db.cosmosdb.operation_type", "type": { - "type": "Enum", "allow_custom_values": true, "members": [ { "id": "invalid", - "value": { - "type": "String", - "value": "Invalid" - } + "value": "Invalid", + "brief": null, + "note": null }, { "id": "create", - "value": { - "type": "String", - "value": "Create" - } + "value": "Create", + "brief": null, + "note": null }, { "id": "patch", - "value": { - "type": "String", - "value": "Patch" - } + "value": "Patch", + "brief": null, + "note": null }, { "id": "read", - "value": { - "type": "String", - "value": "Read" - } + "value": "Read", + "brief": null, + "note": null }, { "id": "read_feed", - "value": { - "type": "String", - "value": "ReadFeed" - } + "value": "ReadFeed", + "brief": null, + "note": null }, { "id": "delete", - "value": { - "type": "String", - "value": "Delete" - } + "value": "Delete", + "brief": null, + "note": null }, { "id": "replace", - "value": { - "type": "String", - "value": "Replace" - } + "value": "Replace", + "brief": null, + "note": null }, { "id": "execute", - "value": { - "type": "String", - "value": "Execute" - } + "value": "Execute", + "brief": null, + "note": null }, { "id": "query", - "value": { - "type": "String", - "value": "Query" - } + "value": "Query", + "brief": null, + "note": null }, { "id": "head", - "value": { - "type": "String", - "value": "Head" - } + "value": "Head", + "brief": null, + "note": null }, { "id": "head_feed", - "value": { - "type": "String", - "value": "HeadFeed" - } + "value": "HeadFeed", + "brief": null, + "note": null }, { "id": "upsert", - "value": { - "type": "String", - "value": "Upsert" - } + "value": "Upsert", + "brief": null, + "note": null }, { "id": "batch", - "value": { - "type": "String", - "value": "Batch" - } + "value": "Batch", + "brief": null, + "note": null }, { "id": "query_plan", - "value": { - "type": "String", - "value": "QueryPlan" - } + "value": "QueryPlan", + "brief": null, + "note": null }, { "id": "execute_javascript", - "value": { - "type": "String", - "value": "ExecuteJavaScript" - } + "value": "ExecuteJavaScript", + "brief": null, + "note": null } ] }, @@ -354,660 +279,483 @@ }, { "name": "db.cosmosdb.request_charge", - "type": { - "type": "Double" - }, + "type": "double", "brief": "RU consumed for that operation", - "examples": { - "type": "Doubles", - "values": [ - 46.18, - 1.0 - ] - }, + "examples": [ + 46.18, + 1.0 + ], "tag": "tech-specific-cosmosdb", "requirement_level": "recommended" }, { "name": "db.cosmosdb.request_content_length", - "type": { - "type": "Int" - }, + "type": "int", "brief": "Request payload size in bytes", "tag": "tech-specific-cosmosdb", "requirement_level": "recommended" }, { "name": "db.cosmosdb.status_code", - "type": { - "type": "Int" - }, + "type": "int", "brief": "Cosmos DB status code.", - "examples": { - "type": "Ints", - "values": [ - 200, - 201 - ] - }, + "examples": [ + 200, + 201 + ], "tag": "tech-specific-cosmosdb", "requirement_level": "recommended" }, { "name": "db.cosmosdb.sub_status_code", - "type": { - "type": "Int" - }, + "type": "int", "brief": "Cosmos DB sub status code.", - "examples": { - "type": "Ints", - "values": [ - 1000, - 1002 - ] - }, + "examples": [ + 1000, + 1002 + ], "tag": "tech-specific-cosmosdb", "requirement_level": "recommended" }, { "name": "db.elasticsearch.cluster.name", - "type": { - "type": "String" - }, + "type": "string", "brief": "Represents the identifier of an Elasticsearch cluster.\n", - "examples": { - "type": "Strings", - "values": [ - "e9106fc68e3044f0b1475b04bf4ffd5f" - ] - }, + "examples": [ + "e9106fc68e3044f0b1475b04bf4ffd5f" + ], "tag": "tech-specific-elasticsearch", "requirement_level": "recommended" }, { "name": "db.elasticsearch.node.name", - "type": { - "type": "String" - }, + "type": "string", "brief": "Represents the human-readable identifier of the node/instance to which a request was routed.\n", - "examples": { - "type": "Strings", - "values": [ - "instance-0000000001" - ] - }, + "examples": [ + "instance-0000000001" + ], "tag": "tech-specific-elasticsearch", "requirement_level": "recommended" }, { "name": "db.elasticsearch.path_parts", - "type": { - "type": "template[string]" - }, + "type": "template[string]", "brief": "A dynamic value in the url path.\n", - "examples": { - "type": "Strings", - "values": [ - "db.elasticsearch.path_parts.index=test-index", - "db.elasticsearch.path_parts.doc_id=123" - ] - }, + "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" }, { "name": "db.jdbc.driver_classname", - "type": { - "type": "String" - }, + "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": { - "type": "Strings", - "values": [ - "org.postgresql.Driver", - "com.microsoft.sqlserver.jdbc.SQLServerDriver" - ] - }, + "examples": [ + "org.postgresql.Driver", + "com.microsoft.sqlserver.jdbc.SQLServerDriver" + ], "tag": "tech-specific-jdbc", "requirement_level": "recommended" }, { "name": "db.mongodb.collection", - "type": { - "type": "String" - }, + "type": "string", "brief": "The MongoDB collection being accessed within the database stated in `db.name`.\n", - "examples": { - "type": "Strings", - "values": [ - "customers", - "products" - ] - }, + "examples": [ + "customers", + "products" + ], "tag": "tech-specific-mongodb", "requirement_level": "recommended" }, { "name": "db.mssql.instance_name", - "type": { - "type": "String" - }, + "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": { - "type": "String", - "value": "MSSQLSERVER" - }, + "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" }, { "name": "db.name", - "type": { - "type": "String" - }, + "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": { - "type": "Strings", - "values": [ - "customers", - "main" - ] - }, + "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" }, { "name": "db.operation", - "type": { - "type": "String" - }, + "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": { - "type": "Strings", - "values": [ - "findAndModify", - "HMSET", - "SELECT" - ] - }, + "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" }, { "name": "db.redis.database_index", - "type": { - "type": "Int" - }, + "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": { - "type": "Ints", - "values": [ - 0, - 1, - 15 - ] - }, + "examples": [ + 0, + 1, + 15 + ], "tag": "tech-specific-redis", "requirement_level": "recommended" }, { "name": "db.sql.table", - "type": { - "type": "String" - }, + "type": "string", "brief": "The name of the primary table that the operation is acting upon, including the database name (if applicable).", - "examples": { - "type": "Strings", - "values": [ - "public.users", - "customers" - ] - }, + "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" }, { "name": "db.statement", - "type": { - "type": "String" - }, + "type": "string", "brief": "The database statement being executed.\n", - "examples": { - "type": "Strings", - "values": [ - "SELECT * FROM wuser_table", - "SET mykey \"WuValue\"" - ] - }, + "examples": [ + "SELECT * FROM wuser_table", + "SET mykey \"WuValue\"" + ], "tag": "db-generic", "requirement_level": "recommended" }, { "name": "db.system", "type": { - "type": "Enum", "allow_custom_values": true, "members": [ { "id": "other_sql", - "value": { - "type": "String", - "value": "other_sql" - }, - "brief": "Some other SQL database. Fallback only. See notes." + "value": "other_sql", + "brief": "Some other SQL database. Fallback only. See notes.", + "note": null }, { "id": "mssql", - "value": { - "type": "String", - "value": "mssql" - }, - "brief": "Microsoft SQL Server" + "value": "mssql", + "brief": "Microsoft SQL Server", + "note": null }, { "id": "mssqlcompact", - "value": { - "type": "String", - "value": "mssqlcompact" - }, - "brief": "Microsoft SQL Server Compact" + "value": "mssqlcompact", + "brief": "Microsoft SQL Server Compact", + "note": null }, { "id": "mysql", - "value": { - "type": "String", - "value": "mysql" - }, - "brief": "MySQL" + "value": "mysql", + "brief": "MySQL", + "note": null }, { "id": "oracle", - "value": { - "type": "String", - "value": "oracle" - }, - "brief": "Oracle Database" + "value": "oracle", + "brief": "Oracle Database", + "note": null }, { "id": "db2", - "value": { - "type": "String", - "value": "db2" - }, - "brief": "IBM Db2" + "value": "db2", + "brief": "IBM Db2", + "note": null }, { "id": "postgresql", - "value": { - "type": "String", - "value": "postgresql" - }, - "brief": "PostgreSQL" + "value": "postgresql", + "brief": "PostgreSQL", + "note": null }, { "id": "redshift", - "value": { - "type": "String", - "value": "redshift" - }, - "brief": "Amazon Redshift" + "value": "redshift", + "brief": "Amazon Redshift", + "note": null }, { "id": "hive", - "value": { - "type": "String", - "value": "hive" - }, - "brief": "Apache Hive" + "value": "hive", + "brief": "Apache Hive", + "note": null }, { "id": "cloudscape", - "value": { - "type": "String", - "value": "cloudscape" - }, - "brief": "Cloudscape" + "value": "cloudscape", + "brief": "Cloudscape", + "note": null }, { "id": "hsqldb", - "value": { - "type": "String", - "value": "hsqldb" - }, - "brief": "HyperSQL DataBase" + "value": "hsqldb", + "brief": "HyperSQL DataBase", + "note": null }, { "id": "progress", - "value": { - "type": "String", - "value": "progress" - }, - "brief": "Progress Database" + "value": "progress", + "brief": "Progress Database", + "note": null }, { "id": "maxdb", - "value": { - "type": "String", - "value": "maxdb" - }, - "brief": "SAP MaxDB" + "value": "maxdb", + "brief": "SAP MaxDB", + "note": null }, { "id": "hanadb", - "value": { - "type": "String", - "value": "hanadb" - }, - "brief": "SAP HANA" + "value": "hanadb", + "brief": "SAP HANA", + "note": null }, { "id": "ingres", - "value": { - "type": "String", - "value": "ingres" - }, - "brief": "Ingres" + "value": "ingres", + "brief": "Ingres", + "note": null }, { "id": "firstsql", - "value": { - "type": "String", - "value": "firstsql" - }, - "brief": "FirstSQL" + "value": "firstsql", + "brief": "FirstSQL", + "note": null }, { "id": "edb", - "value": { - "type": "String", - "value": "edb" - }, - "brief": "EnterpriseDB" + "value": "edb", + "brief": "EnterpriseDB", + "note": null }, { "id": "cache", - "value": { - "type": "String", - "value": "cache" - }, - "brief": "InterSystems Caché" + "value": "cache", + "brief": "InterSystems Caché", + "note": null }, { "id": "adabas", - "value": { - "type": "String", - "value": "adabas" - }, - "brief": "Adabas (Adaptable Database System)" + "value": "adabas", + "brief": "Adabas (Adaptable Database System)", + "note": null }, { "id": "firebird", - "value": { - "type": "String", - "value": "firebird" - }, - "brief": "Firebird" + "value": "firebird", + "brief": "Firebird", + "note": null }, { "id": "derby", - "value": { - "type": "String", - "value": "derby" - }, - "brief": "Apache Derby" + "value": "derby", + "brief": "Apache Derby", + "note": null }, { "id": "filemaker", - "value": { - "type": "String", - "value": "filemaker" - }, - "brief": "FileMaker" + "value": "filemaker", + "brief": "FileMaker", + "note": null }, { "id": "informix", - "value": { - "type": "String", - "value": "informix" - }, - "brief": "Informix" + "value": "informix", + "brief": "Informix", + "note": null }, { "id": "instantdb", - "value": { - "type": "String", - "value": "instantdb" - }, - "brief": "InstantDB" + "value": "instantdb", + "brief": "InstantDB", + "note": null }, { "id": "interbase", - "value": { - "type": "String", - "value": "interbase" - }, - "brief": "InterBase" + "value": "interbase", + "brief": "InterBase", + "note": null }, { "id": "mariadb", - "value": { - "type": "String", - "value": "mariadb" - }, - "brief": "MariaDB" + "value": "mariadb", + "brief": "MariaDB", + "note": null }, { "id": "netezza", - "value": { - "type": "String", - "value": "netezza" - }, - "brief": "Netezza" + "value": "netezza", + "brief": "Netezza", + "note": null }, { "id": "pervasive", - "value": { - "type": "String", - "value": "pervasive" - }, - "brief": "Pervasive PSQL" + "value": "pervasive", + "brief": "Pervasive PSQL", + "note": null }, { "id": "pointbase", - "value": { - "type": "String", - "value": "pointbase" - }, - "brief": "PointBase" + "value": "pointbase", + "brief": "PointBase", + "note": null }, { "id": "sqlite", - "value": { - "type": "String", - "value": "sqlite" - }, - "brief": "SQLite" + "value": "sqlite", + "brief": "SQLite", + "note": null }, { "id": "sybase", - "value": { - "type": "String", - "value": "sybase" - }, - "brief": "Sybase" + "value": "sybase", + "brief": "Sybase", + "note": null }, { "id": "teradata", - "value": { - "type": "String", - "value": "teradata" - }, - "brief": "Teradata" + "value": "teradata", + "brief": "Teradata", + "note": null }, { "id": "vertica", - "value": { - "type": "String", - "value": "vertica" - }, - "brief": "Vertica" + "value": "vertica", + "brief": "Vertica", + "note": null }, { "id": "h2", - "value": { - "type": "String", - "value": "h2" - }, - "brief": "H2" + "value": "h2", + "brief": "H2", + "note": null }, { "id": "coldfusion", - "value": { - "type": "String", - "value": "coldfusion" - }, - "brief": "ColdFusion IMQ" + "value": "coldfusion", + "brief": "ColdFusion IMQ", + "note": null }, { "id": "cassandra", - "value": { - "type": "String", - "value": "cassandra" - }, - "brief": "Apache Cassandra" + "value": "cassandra", + "brief": "Apache Cassandra", + "note": null }, { "id": "hbase", - "value": { - "type": "String", - "value": "hbase" - }, - "brief": "Apache HBase" + "value": "hbase", + "brief": "Apache HBase", + "note": null }, { "id": "mongodb", - "value": { - "type": "String", - "value": "mongodb" - }, - "brief": "MongoDB" + "value": "mongodb", + "brief": "MongoDB", + "note": null }, { "id": "redis", - "value": { - "type": "String", - "value": "redis" - }, - "brief": "Redis" + "value": "redis", + "brief": "Redis", + "note": null }, { "id": "couchbase", - "value": { - "type": "String", - "value": "couchbase" - }, - "brief": "Couchbase" + "value": "couchbase", + "brief": "Couchbase", + "note": null }, { "id": "couchdb", - "value": { - "type": "String", - "value": "couchdb" - }, - "brief": "CouchDB" + "value": "couchdb", + "brief": "CouchDB", + "note": null }, { "id": "cosmosdb", - "value": { - "type": "String", - "value": "cosmosdb" - }, - "brief": "Microsoft Azure Cosmos DB" + "value": "cosmosdb", + "brief": "Microsoft Azure Cosmos DB", + "note": null }, { "id": "dynamodb", - "value": { - "type": "String", - "value": "dynamodb" - }, - "brief": "Amazon DynamoDB" + "value": "dynamodb", + "brief": "Amazon DynamoDB", + "note": null }, { "id": "neo4j", - "value": { - "type": "String", - "value": "neo4j" - }, - "brief": "Neo4j" + "value": "neo4j", + "brief": "Neo4j", + "note": null }, { "id": "geode", - "value": { - "type": "String", - "value": "geode" - }, - "brief": "Apache Geode" + "value": "geode", + "brief": "Apache Geode", + "note": null }, { "id": "elasticsearch", - "value": { - "type": "String", - "value": "elasticsearch" - }, - "brief": "Elasticsearch" + "value": "elasticsearch", + "brief": "Elasticsearch", + "note": null }, { "id": "memcached", - "value": { - "type": "String", - "value": "memcached" - }, - "brief": "Memcached" + "value": "memcached", + "brief": "Memcached", + "note": null }, { "id": "cockroachdb", - "value": { - "type": "String", - "value": "cockroachdb" - }, - "brief": "CockroachDB" + "value": "cockroachdb", + "brief": "CockroachDB", + "note": null }, { "id": "opensearch", - "value": { - "type": "String", - "value": "opensearch" - }, - "brief": "OpenSearch" + "value": "opensearch", + "brief": "OpenSearch", + "note": null }, { "id": "clickhouse", - "value": { - "type": "String", - "value": "clickhouse" - }, - "brief": "ClickHouse" + "value": "clickhouse", + "brief": "ClickHouse", + "note": null }, { "id": "spanner", - "value": { - "type": "String", - "value": "spanner" - }, - "brief": "Cloud Spanner" + "value": "spanner", + "brief": "Cloud Spanner", + "note": null }, { "id": "trino", - "value": { - "type": "String", - "value": "trino" - }, - "brief": "Trino" + "value": "trino", + "brief": "Trino", + "note": null } ] }, @@ -1017,59 +765,39 @@ }, { "name": "db.user", - "type": { - "type": "String" - }, + "type": "string", "brief": "Username for accessing the database.\n", - "examples": { - "type": "Strings", - "values": [ - "readonly_user", - "reporting_user" - ] - }, + "examples": [ + "readonly_user", + "reporting_user" + ], "tag": "db-generic", "requirement_level": "recommended" }, { "name": "db.instance.id", - "type": { - "type": "String" - }, + "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": { - "type": "String", - "value": "mysql-e26b99z.example.com" - }, + "examples": "mysql-e26b99z.example.com", "tag": "db-generic", "requirement_level": "recommended" }, { "name": "http.request.body.size", - "type": { - "type": "Int" - }, + "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": { - "type": "Int", - "value": 3495 - }, + "examples": 3495, "requirement_level": "recommended", "stability": "experimental" }, { "name": "http.request.header", - "type": { - "type": "template[string[]]" - }, + "type": "template[string[]]", "brief": "HTTP request headers, `` being the normalized HTTP Header name (lowercase), the value being the header values.\n", - "examples": { - "type": "Strings", - "values": [ - "http.request.header.content-type=[\"application/json\"]", - "http.request.header.x-forwarded-for=[\"1.2.3.4\", \"1.2.3.5\"]" - ] - }, + "examples": [ + "http.request.header.content-type=[\"application/json\"]", + "http.request.header.x-forwarded-for=[\"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" @@ -1077,568 +805,409 @@ { "name": "http.request.method", "type": { - "type": "Enum", "allow_custom_values": true, "members": [ { "id": "connect", - "value": { - "type": "String", - "value": "CONNECT" - }, - "brief": "CONNECT method." + "value": "CONNECT", + "brief": "CONNECT method.", + "note": null }, { "id": "delete", - "value": { - "type": "String", - "value": "DELETE" - }, - "brief": "DELETE method." + "value": "DELETE", + "brief": "DELETE method.", + "note": null }, { "id": "get", - "value": { - "type": "String", - "value": "GET" - }, - "brief": "GET method." + "value": "GET", + "brief": "GET method.", + "note": null }, { "id": "head", - "value": { - "type": "String", - "value": "HEAD" - }, - "brief": "HEAD method." + "value": "HEAD", + "brief": "HEAD method.", + "note": null }, { "id": "options", - "value": { - "type": "String", - "value": "OPTIONS" - }, - "brief": "OPTIONS method." + "value": "OPTIONS", + "brief": "OPTIONS method.", + "note": null }, { "id": "patch", - "value": { - "type": "String", - "value": "PATCH" - }, - "brief": "PATCH method." + "value": "PATCH", + "brief": "PATCH method.", + "note": null }, { "id": "post", - "value": { - "type": "String", - "value": "POST" - }, - "brief": "POST method." + "value": "POST", + "brief": "POST method.", + "note": null }, { "id": "put", - "value": { - "type": "String", - "value": "PUT" - }, - "brief": "PUT method." + "value": "PUT", + "brief": "PUT method.", + "note": null }, { "id": "trace", - "value": { - "type": "String", - "value": "TRACE" - }, - "brief": "TRACE method." + "value": "TRACE", + "brief": "TRACE method.", + "note": null }, { "id": "other", - "value": { - "type": "String", - "value": "_OTHER" - }, - "brief": "Any HTTP method that the instrumentation has no prior knowledge of." + "value": "_OTHER", + "brief": "Any HTTP method that the instrumentation has no prior knowledge of.", + "note": null } ] }, "brief": "HTTP request method.", - "examples": { - "type": "Strings", - "values": [ - "GET", - "POST", - "HEAD" - ] - }, + "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": { - "type": "String" - }, + "type": "string", "brief": "Original HTTP method sent by the client in the request line.", - "examples": { - "type": "Strings", - "values": [ - "GeT", - "ACL", - "foo" - ] - }, + "examples": [ + "GeT", + "ACL", + "foo" + ], "requirement_level": "recommended", "stability": "stable" }, { "name": "http.request.resend_count", - "type": { - "type": "Int" - }, + "type": "int", "brief": "The ordinal number of request resending attempt (for any reason, including redirects).\n", - "examples": { - "type": "Int", - "value": 3 - }, + "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": { - "type": "Int" - }, + "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": { - "type": "Int", - "value": 3495 - }, + "examples": 3495, "requirement_level": "recommended", "stability": "experimental" }, { "name": "http.response.header", - "type": { - "type": "template[string[]]" - }, + "type": "template[string[]]", "brief": "HTTP response headers, `` being the normalized HTTP Header name (lowercase), the value being the header values.\n", - "examples": { - "type": "Strings", - "values": [ - "http.response.header.content-type=[\"application/json\"]", - "http.response.header.my-custom-header=[\"abc\", \"def\"]" - ] - }, + "examples": [ + "http.response.header.content-type=[\"application/json\"]", + "http.response.header.my-custom-header=[\"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": { - "type": "Int" - }, + "type": "int", "brief": "[HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6).", - "examples": { - "type": "Ints", - "values": [ - 200 - ] - }, + "examples": [ + 200 + ], "requirement_level": "recommended", "stability": "stable" }, { "name": "http.route", - "type": { - "type": "String" - }, + "type": "string", "brief": "The matched route, that is, the path template in the format used by the respective server framework.\n", - "examples": { - "type": "Strings", - "values": [ - "/users/:userID?", - "{controller}/{action}/{id?}" - ] - }, + "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": { - "type": "String" - }, + "type": "string", "brief": "The ISO 3166-1 alpha-2 2-character country code associated with the mobile carrier network.", - "examples": { - "type": "String", - "value": "DE" - }, + "examples": "DE", "requirement_level": "recommended" }, { "name": "network.carrier.mcc", - "type": { - "type": "String" - }, + "type": "string", "brief": "The mobile carrier country code.", - "examples": { - "type": "String", - "value": "310" - }, + "examples": "310", "requirement_level": "recommended" }, { "name": "network.carrier.mnc", - "type": { - "type": "String" - }, + "type": "string", "brief": "The mobile carrier network code.", - "examples": { - "type": "String", - "value": "001" - }, + "examples": "001", "requirement_level": "recommended" }, { "name": "network.carrier.name", - "type": { - "type": "String" - }, + "type": "string", "brief": "The name of the mobile carrier.", - "examples": { - "type": "String", - "value": "sprint" - }, + "examples": "sprint", "requirement_level": "recommended" }, { "name": "network.connection.subtype", "type": { - "type": "Enum", "allow_custom_values": true, "members": [ { "id": "gprs", - "value": { - "type": "String", - "value": "gprs" - }, - "brief": "GPRS" + "value": "gprs", + "brief": "GPRS", + "note": null }, { "id": "edge", - "value": { - "type": "String", - "value": "edge" - }, - "brief": "EDGE" + "value": "edge", + "brief": "EDGE", + "note": null }, { "id": "umts", - "value": { - "type": "String", - "value": "umts" - }, - "brief": "UMTS" + "value": "umts", + "brief": "UMTS", + "note": null }, { "id": "cdma", - "value": { - "type": "String", - "value": "cdma" - }, - "brief": "CDMA" + "value": "cdma", + "brief": "CDMA", + "note": null }, { "id": "evdo_0", - "value": { - "type": "String", - "value": "evdo_0" - }, - "brief": "EVDO Rel. 0" + "value": "evdo_0", + "brief": "EVDO Rel. 0", + "note": null }, { "id": "evdo_a", - "value": { - "type": "String", - "value": "evdo_a" - }, - "brief": "EVDO Rev. A" + "value": "evdo_a", + "brief": "EVDO Rev. A", + "note": null }, { "id": "cdma2000_1xrtt", - "value": { - "type": "String", - "value": "cdma2000_1xrtt" - }, - "brief": "CDMA2000 1XRTT" + "value": "cdma2000_1xrtt", + "brief": "CDMA2000 1XRTT", + "note": null }, { "id": "hsdpa", - "value": { - "type": "String", - "value": "hsdpa" - }, - "brief": "HSDPA" + "value": "hsdpa", + "brief": "HSDPA", + "note": null }, { "id": "hsupa", - "value": { - "type": "String", - "value": "hsupa" - }, - "brief": "HSUPA" + "value": "hsupa", + "brief": "HSUPA", + "note": null }, { "id": "hspa", - "value": { - "type": "String", - "value": "hspa" - }, - "brief": "HSPA" + "value": "hspa", + "brief": "HSPA", + "note": null }, { "id": "iden", - "value": { - "type": "String", - "value": "iden" - }, - "brief": "IDEN" + "value": "iden", + "brief": "IDEN", + "note": null }, { "id": "evdo_b", - "value": { - "type": "String", - "value": "evdo_b" - }, - "brief": "EVDO Rev. B" + "value": "evdo_b", + "brief": "EVDO Rev. B", + "note": null }, { "id": "lte", - "value": { - "type": "String", - "value": "lte" - }, - "brief": "LTE" + "value": "lte", + "brief": "LTE", + "note": null }, { "id": "ehrpd", - "value": { - "type": "String", - "value": "ehrpd" - }, - "brief": "EHRPD" + "value": "ehrpd", + "brief": "EHRPD", + "note": null }, { "id": "hspap", - "value": { - "type": "String", - "value": "hspap" - }, - "brief": "HSPAP" + "value": "hspap", + "brief": "HSPAP", + "note": null }, { "id": "gsm", - "value": { - "type": "String", - "value": "gsm" - }, - "brief": "GSM" + "value": "gsm", + "brief": "GSM", + "note": null }, { "id": "td_scdma", - "value": { - "type": "String", - "value": "td_scdma" - }, - "brief": "TD-SCDMA" + "value": "td_scdma", + "brief": "TD-SCDMA", + "note": null }, { "id": "iwlan", - "value": { - "type": "String", - "value": "iwlan" - }, - "brief": "IWLAN" + "value": "iwlan", + "brief": "IWLAN", + "note": null }, { "id": "nr", - "value": { - "type": "String", - "value": "nr" - }, - "brief": "5G NR (New Radio)" + "value": "nr", + "brief": "5G NR (New Radio)", + "note": null }, { "id": "nrnsa", - "value": { - "type": "String", - "value": "nrnsa" - }, - "brief": "5G NRNSA (New Radio Non-Standalone)" + "value": "nrnsa", + "brief": "5G NRNSA (New Radio Non-Standalone)", + "note": null }, { "id": "lte_ca", - "value": { - "type": "String", - "value": "lte_ca" - }, - "brief": "LTE CA" + "value": "lte_ca", + "brief": "LTE CA", + "note": null } ] }, "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": { - "type": "String", - "value": "LTE" - }, + "examples": "LTE", "requirement_level": "recommended" }, { "name": "network.connection.type", "type": { - "type": "Enum", "allow_custom_values": true, "members": [ { "id": "wifi", - "value": { - "type": "String", - "value": "wifi" - } + "value": "wifi", + "brief": null, + "note": null }, { "id": "wired", - "value": { - "type": "String", - "value": "wired" - } + "value": "wired", + "brief": null, + "note": null }, { "id": "cell", - "value": { - "type": "String", - "value": "cell" - } + "value": "cell", + "brief": null, + "note": null }, { "id": "unavailable", - "value": { - "type": "String", - "value": "unavailable" - } + "value": "unavailable", + "brief": null, + "note": null }, { "id": "unknown", - "value": { - "type": "String", - "value": "unknown" - } + "value": "unknown", + "brief": null, + "note": null } ] }, "brief": "The internet connection type.", - "examples": { - "type": "String", - "value": "wifi" - }, + "examples": "wifi", "requirement_level": "recommended" }, { "name": "network.local.address", - "type": { - "type": "String" - }, + "type": "string", "brief": "Local address of the network connection - IP address or Unix domain socket name.", - "examples": { - "type": "Strings", - "values": [ - "10.1.2.80", - "/tmp/my.sock" - ] - }, + "examples": [ + "10.1.2.80", + "/tmp/my.sock" + ], "requirement_level": "recommended", "stability": "stable" }, { "name": "network.local.port", - "type": { - "type": "Int" - }, + "type": "int", "brief": "Local port number of the network connection.", - "examples": { - "type": "Ints", - "values": [ - 65123 - ] - }, + "examples": [ + 65123 + ], "requirement_level": "recommended", "stability": "stable" }, { "name": "network.peer.address", - "type": { - "type": "String" - }, + "type": "string", "brief": "Peer address of the network connection - IP address or Unix domain socket name.", - "examples": { - "type": "Strings", - "values": [ - "10.1.2.80", - "/tmp/my.sock" - ] - }, + "examples": [ + "10.1.2.80", + "/tmp/my.sock" + ], "requirement_level": "recommended", "stability": "stable" }, { "name": "network.peer.port", - "type": { - "type": "Int" - }, + "type": "int", "brief": "Peer port number of the network connection.", - "examples": { - "type": "Ints", - "values": [ - 65123 - ] - }, + "examples": [ + 65123 + ], "requirement_level": "recommended", "stability": "stable" }, { "name": "network.protocol.name", - "type": { - "type": "String" - }, + "type": "string", "brief": "[OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent.", - "examples": { - "type": "Strings", - "values": [ - "amqp", - "http", - "mqtt" - ] - }, + "examples": [ + "amqp", + "http", + "mqtt" + ], "requirement_level": "recommended", "note": "The value SHOULD be normalized to lowercase.", "stability": "stable" }, { "name": "network.protocol.version", - "type": { - "type": "String" - }, + "type": "string", "brief": "Version of the protocol specified in `network.protocol.name`.", - "examples": { - "type": "String", - "value": "3.1.1" - }, + "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" @@ -1646,51 +1215,39 @@ { "name": "network.transport", "type": { - "type": "Enum", "allow_custom_values": true, "members": [ { "id": "tcp", - "value": { - "type": "String", - "value": "tcp" - }, - "brief": "TCP" + "value": "tcp", + "brief": "TCP", + "note": null }, { "id": "udp", - "value": { - "type": "String", - "value": "udp" - }, - "brief": "UDP" + "value": "udp", + "brief": "UDP", + "note": null }, { "id": "pipe", - "value": { - "type": "String", - "value": "pipe" - }, - "brief": "Named or anonymous pipe." + "value": "pipe", + "brief": "Named or anonymous pipe.", + "note": null }, { "id": "unix", - "value": { - "type": "String", - "value": "unix" - }, - "brief": "Unix domain socket" + "value": "unix", + "brief": "Unix domain socket", + "note": null } ] }, "brief": "[OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication).\n", - "examples": { - "type": "Strings", - "values": [ - "tcp", - "udp" - ] - }, + "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" @@ -1698,35 +1255,27 @@ { "name": "network.type", "type": { - "type": "Enum", "allow_custom_values": true, "members": [ { "id": "ipv4", - "value": { - "type": "String", - "value": "ipv4" - }, - "brief": "IPv4" + "value": "ipv4", + "brief": "IPv4", + "note": null }, { "id": "ipv6", - "value": { - "type": "String", - "value": "ipv6" - }, - "brief": "IPv6" + "value": "ipv6", + "brief": "IPv6", + "note": null } ] }, "brief": "[OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent.", - "examples": { - "type": "Strings", - "values": [ - "ipv4", - "ipv6" - ] - }, + "examples": [ + "ipv4", + "ipv6" + ], "requirement_level": "recommended", "note": "The value SHOULD be normalized to lowercase.", "stability": "stable" @@ -1734,587 +1283,436 @@ { "name": "network.io.direction", "type": { - "type": "Enum", "allow_custom_values": false, "members": [ { "id": "transmit", - "value": { - "type": "String", - "value": "transmit" - } + "value": "transmit", + "brief": null, + "note": null }, { "id": "receive", - "value": { - "type": "String", - "value": "receive" - } + "value": "receive", + "brief": null, + "note": null } ] }, "brief": "The network IO operation direction.", - "examples": { - "type": "Strings", - "values": [ - "transmit" - ] - }, + "examples": [ + "transmit" + ], "requirement_level": "recommended" }, { "name": "server.address", - "type": { - "type": "String" - }, + "type": "string", "brief": "Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name.", - "examples": { - "type": "Strings", - "values": [ - "example.com", - "10.1.2.80", - "/tmp/my.sock" - ] - }, + "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": { - "type": "Int" - }, + "type": "int", "brief": "Server port number.", - "examples": { - "type": "Ints", - "values": [ - 80, - 8080, - 443 - ] - }, + "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.scheme", - "type": { - "type": "String" - }, + "type": "string", "brief": "The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol.", - "examples": { - "type": "Strings", - "values": [ - "https", - "ftp", - "telnet" - ] - }, + "examples": [ + "https", + "ftp", + "telnet" + ], "requirement_level": "recommended", "stability": "stable" }, { "name": "url.full", - "type": { - "type": "String" - }, + "type": "string", "brief": "Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986)", - "examples": { - "type": "Strings", - "values": [ - "https://www.foo.bar/search?q=OpenTelemetry#SemConv", - "//localhost" - ] - }, + "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": { - "type": "String" - }, + "type": "string", "brief": "The [URI path](https://www.rfc-editor.org/rfc/rfc3986#section-3.3) component", - "examples": { - "type": "Strings", - "values": [ - "/search" - ] - }, + "examples": [ + "/search" + ], "requirement_level": "recommended", "stability": "stable" }, { "name": "url.query", - "type": { - "type": "String" - }, + "type": "string", "brief": "The [URI query](https://www.rfc-editor.org/rfc/rfc3986#section-3.4) component", - "examples": { - "type": "Strings", - "values": [ - "q=OpenTelemetry" - ] - }, + "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.fragment", - "type": { - "type": "String" - }, + "type": "string", "brief": "The [URI fragment](https://www.rfc-editor.org/rfc/rfc3986#section-3.5) component", - "examples": { - "type": "Strings", - "values": [ - "SemConv" - ] - }, + "examples": [ + "SemConv" + ], "requirement_level": "recommended", "stability": "stable" }, { "name": "user_agent.original", - "type": { - "type": "String" - }, + "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": { - "type": "Strings", - "values": [ - "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" - ] - }, + "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" }, { "name": "db.system", "type": { - "type": "Enum", "allow_custom_values": true, "members": [ { "id": "other_sql", - "value": { - "type": "String", - "value": "other_sql" - }, - "brief": "Some other SQL database. Fallback only. See notes." + "value": "other_sql", + "brief": "Some other SQL database. Fallback only. See notes.", + "note": null }, { "id": "mssql", - "value": { - "type": "String", - "value": "mssql" - }, - "brief": "Microsoft SQL Server" + "value": "mssql", + "brief": "Microsoft SQL Server", + "note": null }, { "id": "mssqlcompact", - "value": { - "type": "String", - "value": "mssqlcompact" - }, - "brief": "Microsoft SQL Server Compact" + "value": "mssqlcompact", + "brief": "Microsoft SQL Server Compact", + "note": null }, { "id": "mysql", - "value": { - "type": "String", - "value": "mysql" - }, - "brief": "MySQL" + "value": "mysql", + "brief": "MySQL", + "note": null }, { "id": "oracle", - "value": { - "type": "String", - "value": "oracle" - }, - "brief": "Oracle Database" + "value": "oracle", + "brief": "Oracle Database", + "note": null }, { "id": "db2", - "value": { - "type": "String", - "value": "db2" - }, - "brief": "IBM Db2" + "value": "db2", + "brief": "IBM Db2", + "note": null }, { "id": "postgresql", - "value": { - "type": "String", - "value": "postgresql" - }, - "brief": "PostgreSQL" + "value": "postgresql", + "brief": "PostgreSQL", + "note": null }, { "id": "redshift", - "value": { - "type": "String", - "value": "redshift" - }, - "brief": "Amazon Redshift" + "value": "redshift", + "brief": "Amazon Redshift", + "note": null }, { "id": "hive", - "value": { - "type": "String", - "value": "hive" - }, - "brief": "Apache Hive" + "value": "hive", + "brief": "Apache Hive", + "note": null }, { "id": "cloudscape", - "value": { - "type": "String", - "value": "cloudscape" - }, - "brief": "Cloudscape" + "value": "cloudscape", + "brief": "Cloudscape", + "note": null }, { "id": "hsqldb", - "value": { - "type": "String", - "value": "hsqldb" - }, - "brief": "HyperSQL DataBase" + "value": "hsqldb", + "brief": "HyperSQL DataBase", + "note": null }, { "id": "progress", - "value": { - "type": "String", - "value": "progress" - }, - "brief": "Progress Database" + "value": "progress", + "brief": "Progress Database", + "note": null }, { "id": "maxdb", - "value": { - "type": "String", - "value": "maxdb" - }, - "brief": "SAP MaxDB" + "value": "maxdb", + "brief": "SAP MaxDB", + "note": null }, { "id": "hanadb", - "value": { - "type": "String", - "value": "hanadb" - }, - "brief": "SAP HANA" + "value": "hanadb", + "brief": "SAP HANA", + "note": null }, { "id": "ingres", - "value": { - "type": "String", - "value": "ingres" - }, - "brief": "Ingres" + "value": "ingres", + "brief": "Ingres", + "note": null }, { "id": "firstsql", - "value": { - "type": "String", - "value": "firstsql" - }, - "brief": "FirstSQL" + "value": "firstsql", + "brief": "FirstSQL", + "note": null }, { "id": "edb", - "value": { - "type": "String", - "value": "edb" - }, - "brief": "EnterpriseDB" + "value": "edb", + "brief": "EnterpriseDB", + "note": null }, { "id": "cache", - "value": { - "type": "String", - "value": "cache" - }, - "brief": "InterSystems Caché" + "value": "cache", + "brief": "InterSystems Caché", + "note": null }, { "id": "adabas", - "value": { - "type": "String", - "value": "adabas" - }, - "brief": "Adabas (Adaptable Database System)" + "value": "adabas", + "brief": "Adabas (Adaptable Database System)", + "note": null }, { "id": "firebird", - "value": { - "type": "String", - "value": "firebird" - }, - "brief": "Firebird" + "value": "firebird", + "brief": "Firebird", + "note": null }, { "id": "derby", - "value": { - "type": "String", - "value": "derby" - }, - "brief": "Apache Derby" + "value": "derby", + "brief": "Apache Derby", + "note": null }, { "id": "filemaker", - "value": { - "type": "String", - "value": "filemaker" - }, - "brief": "FileMaker" + "value": "filemaker", + "brief": "FileMaker", + "note": null }, { "id": "informix", - "value": { - "type": "String", - "value": "informix" - }, - "brief": "Informix" + "value": "informix", + "brief": "Informix", + "note": null }, { "id": "instantdb", - "value": { - "type": "String", - "value": "instantdb" - }, - "brief": "InstantDB" + "value": "instantdb", + "brief": "InstantDB", + "note": null }, { "id": "interbase", - "value": { - "type": "String", - "value": "interbase" - }, - "brief": "InterBase" + "value": "interbase", + "brief": "InterBase", + "note": null }, { "id": "mariadb", - "value": { - "type": "String", - "value": "mariadb" - }, - "brief": "MariaDB" + "value": "mariadb", + "brief": "MariaDB", + "note": null }, { "id": "netezza", - "value": { - "type": "String", - "value": "netezza" - }, - "brief": "Netezza" + "value": "netezza", + "brief": "Netezza", + "note": null }, { "id": "pervasive", - "value": { - "type": "String", - "value": "pervasive" - }, - "brief": "Pervasive PSQL" + "value": "pervasive", + "brief": "Pervasive PSQL", + "note": null }, { "id": "pointbase", - "value": { - "type": "String", - "value": "pointbase" - }, - "brief": "PointBase" + "value": "pointbase", + "brief": "PointBase", + "note": null }, { "id": "sqlite", - "value": { - "type": "String", - "value": "sqlite" - }, - "brief": "SQLite" + "value": "sqlite", + "brief": "SQLite", + "note": null }, { "id": "sybase", - "value": { - "type": "String", - "value": "sybase" - }, - "brief": "Sybase" + "value": "sybase", + "brief": "Sybase", + "note": null }, { "id": "teradata", - "value": { - "type": "String", - "value": "teradata" - }, - "brief": "Teradata" + "value": "teradata", + "brief": "Teradata", + "note": null }, { "id": "vertica", - "value": { - "type": "String", - "value": "vertica" - }, - "brief": "Vertica" + "value": "vertica", + "brief": "Vertica", + "note": null }, { "id": "h2", - "value": { - "type": "String", - "value": "h2" - }, - "brief": "H2" + "value": "h2", + "brief": "H2", + "note": null }, { "id": "coldfusion", - "value": { - "type": "String", - "value": "coldfusion" - }, - "brief": "ColdFusion IMQ" + "value": "coldfusion", + "brief": "ColdFusion IMQ", + "note": null }, { "id": "cassandra", - "value": { - "type": "String", - "value": "cassandra" - }, - "brief": "Apache Cassandra" + "value": "cassandra", + "brief": "Apache Cassandra", + "note": null }, { "id": "hbase", - "value": { - "type": "String", - "value": "hbase" - }, - "brief": "Apache HBase" + "value": "hbase", + "brief": "Apache HBase", + "note": null }, { "id": "mongodb", - "value": { - "type": "String", - "value": "mongodb" - }, - "brief": "MongoDB" + "value": "mongodb", + "brief": "MongoDB", + "note": null }, { "id": "redis", - "value": { - "type": "String", - "value": "redis" - }, - "brief": "Redis" + "value": "redis", + "brief": "Redis", + "note": null }, { "id": "couchbase", - "value": { - "type": "String", - "value": "couchbase" - }, - "brief": "Couchbase" + "value": "couchbase", + "brief": "Couchbase", + "note": null }, { "id": "couchdb", - "value": { - "type": "String", - "value": "couchdb" - }, - "brief": "CouchDB" + "value": "couchdb", + "brief": "CouchDB", + "note": null }, { "id": "cosmosdb", - "value": { - "type": "String", - "value": "cosmosdb" - }, - "brief": "Microsoft Azure Cosmos DB" + "value": "cosmosdb", + "brief": "Microsoft Azure Cosmos DB", + "note": null }, { "id": "dynamodb", - "value": { - "type": "String", - "value": "dynamodb" - }, - "brief": "Amazon DynamoDB" + "value": "dynamodb", + "brief": "Amazon DynamoDB", + "note": null }, { "id": "neo4j", - "value": { - "type": "String", - "value": "neo4j" - }, - "brief": "Neo4j" + "value": "neo4j", + "brief": "Neo4j", + "note": null }, { "id": "geode", - "value": { - "type": "String", - "value": "geode" - }, - "brief": "Apache Geode" + "value": "geode", + "brief": "Apache Geode", + "note": null }, { "id": "elasticsearch", - "value": { - "type": "String", - "value": "elasticsearch" - }, - "brief": "Elasticsearch" + "value": "elasticsearch", + "brief": "Elasticsearch", + "note": null }, { "id": "memcached", - "value": { - "type": "String", - "value": "memcached" - }, - "brief": "Memcached" + "value": "memcached", + "brief": "Memcached", + "note": null }, { "id": "cockroachdb", - "value": { - "type": "String", - "value": "cockroachdb" - }, - "brief": "CockroachDB" + "value": "cockroachdb", + "brief": "CockroachDB", + "note": null }, { "id": "opensearch", - "value": { - "type": "String", - "value": "opensearch" - }, - "brief": "OpenSearch" + "value": "opensearch", + "brief": "OpenSearch", + "note": null }, { "id": "clickhouse", - "value": { - "type": "String", - "value": "clickhouse" - }, - "brief": "ClickHouse" + "value": "clickhouse", + "brief": "ClickHouse", + "note": null }, { "id": "spanner", - "value": { - "type": "String", - "value": "spanner" - }, - "brief": "Cloud Spanner" + "value": "spanner", + "brief": "Cloud Spanner", + "note": null }, { "id": "trino", - "value": { - "type": "String", - "value": "trino" - }, - "brief": "Trino" + "value": "trino", + "brief": "Trino", + "note": null } ] }, @@ -2324,62 +1722,42 @@ }, { "name": "db.connection_string", - "type": { - "type": "String" - }, + "type": "string", "brief": "The connection string used to connect to the database. It is recommended to remove embedded credentials.\n", - "examples": { - "type": "String", - "value": "Server=(localdb)\\v11.0;Integrated Security=true;" - }, + "examples": "Server=(localdb)\\v11.0;Integrated Security=true;", "tag": "connection-level", "requirement_level": "recommended" }, { "name": "db.user", - "type": { - "type": "String" - }, + "type": "string", "brief": "Username for accessing the database.\n", - "examples": { - "type": "Strings", - "values": [ - "readonly_user", - "reporting_user" - ] - }, + "examples": [ + "readonly_user", + "reporting_user" + ], "tag": "connection-level", "requirement_level": "recommended" }, { "name": "db.jdbc.driver_classname", - "type": { - "type": "String" - }, + "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": { - "type": "Strings", - "values": [ - "org.postgresql.Driver", - "com.microsoft.sqlserver.jdbc.SQLServerDriver" - ] - }, + "examples": [ + "org.postgresql.Driver", + "com.microsoft.sqlserver.jdbc.SQLServerDriver" + ], "tag": "connection-level-tech-specific", "requirement_level": "recommended" }, { "name": "db.name", - "type": { - "type": "String" - }, + "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": { - "type": "Strings", - "values": [ - "customers", - "main" - ] - }, + "examples": [ + "customers", + "main" + ], "tag": "call-level", "requirement_level": { "conditionally_required": "If applicable." @@ -2388,17 +1766,12 @@ }, { "name": "db.statement", - "type": { - "type": "String" - }, + "type": "string", "brief": "The database statement being executed.\n", - "examples": { - "type": "Strings", - "values": [ - "SELECT * FROM wuser_table", - "SET mykey \"WuValue\"" - ] - }, + "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" @@ -2406,18 +1779,13 @@ }, { "name": "db.operation", - "type": { - "type": "String" - }, + "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": { - "type": "Strings", - "values": [ - "findAndModify", - "HMSET", - "SELECT" - ] - }, + "examples": [ + "findAndModify", + "HMSET", + "SELECT" + ], "tag": "call-level", "requirement_level": { "conditionally_required": "If `db.statement` is not applicable." @@ -2426,18 +1794,13 @@ }, { "name": "server.address", - "type": { - "type": "String" - }, + "type": "string", "brief": "Name of the database host.\n", - "examples": { - "type": "Strings", - "values": [ - "example.com", - "10.1.2.80", - "/tmp/my.sock" - ] - }, + "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", @@ -2445,18 +1808,13 @@ }, { "name": "server.port", - "type": { - "type": "Int" - }, + "type": "int", "brief": "Server port number.", - "examples": { - "type": "Ints", - "values": [ - 80, - 8080, - 443 - ] - }, + "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." @@ -2466,33 +1824,23 @@ }, { "name": "network.peer.address", - "type": { - "type": "String" - }, + "type": "string", "brief": "Peer address of the network connection - IP address or Unix domain socket name.", - "examples": { - "type": "Strings", - "values": [ - "10.1.2.80", - "/tmp/my.sock" - ] - }, + "examples": [ + "10.1.2.80", + "/tmp/my.sock" + ], "tag": "connection-level", "requirement_level": "recommended", "stability": "stable" }, { "name": "network.peer.port", - "type": { - "type": "Int" - }, + "type": "int", "brief": "Peer port number of the network connection.", - "examples": { - "type": "Ints", - "values": [ - 65123 - ] - }, + "examples": [ + 65123 + ], "tag": "connection-level", "requirement_level": { "recommended": "If `network.peer.address` is set." @@ -2502,51 +1850,39 @@ { "name": "network.transport", "type": { - "type": "Enum", "allow_custom_values": true, "members": [ { "id": "tcp", - "value": { - "type": "String", - "value": "tcp" - }, - "brief": "TCP" + "value": "tcp", + "brief": "TCP", + "note": null }, { "id": "udp", - "value": { - "type": "String", - "value": "udp" - }, - "brief": "UDP" + "value": "udp", + "brief": "UDP", + "note": null }, { "id": "pipe", - "value": { - "type": "String", - "value": "pipe" - }, - "brief": "Named or anonymous pipe." + "value": "pipe", + "brief": "Named or anonymous pipe.", + "note": null }, { "id": "unix", - "value": { - "type": "String", - "value": "unix" - }, - "brief": "Unix domain socket" + "value": "unix", + "brief": "Unix domain socket", + "note": null } ] }, "brief": "[OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication).\n", - "examples": { - "type": "Strings", - "values": [ - "tcp", - "udp" - ] - }, + "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", @@ -2555,35 +1891,27 @@ { "name": "network.type", "type": { - "type": "Enum", "allow_custom_values": true, "members": [ { "id": "ipv4", - "value": { - "type": "String", - "value": "ipv4" - }, - "brief": "IPv4" + "value": "ipv4", + "brief": "IPv4", + "note": null }, { "id": "ipv6", - "value": { - "type": "String", - "value": "ipv6" - }, - "brief": "IPv6" + "value": "ipv6", + "brief": "IPv6", + "note": null } ] }, "brief": "[OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent.", - "examples": { - "type": "Strings", - "values": [ - "ipv4", - "ipv6" - ] - }, + "examples": [ + "ipv4", + "ipv6" + ], "tag": "connection-level", "requirement_level": "recommended", "note": "The value SHOULD be normalized to lowercase.", @@ -2591,14 +1919,9 @@ }, { "name": "db.instance.id", - "type": { - "type": "String" - }, + "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": { - "type": "String", - "value": "mysql-e26b99z.example.com" - }, + "examples": "mysql-e26b99z.example.com", "tag": "connection-level", "requirement_level": { "recommended": "If different from the `server.address`" @@ -2606,131 +1929,104 @@ }, { "name": "db.mssql.instance_name", - "type": { - "type": "String" - }, + "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": { - "type": "String", - "value": "MSSQLSERVER" - }, + "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" }, { "name": "db.name", - "type": { - "type": "String" - }, + "type": "string", "brief": "The keyspace name in Cassandra.\n", - "examples": { - "type": "Strings", - "values": [ - "mykeyspace" - ] - }, + "examples": [ + "mykeyspace" + ], "tag": "call-level-tech-specific-cassandra", "requirement_level": "recommended", "note": "For Cassandra the `db.name` should be set to the Cassandra keyspace name." }, { "name": "db.cassandra.page_size", - "type": { - "type": "Int" - }, + "type": "int", "brief": "The fetch size used for paging, i.e. how many rows will be returned at once.\n", - "examples": { - "type": "Ints", - "values": [ - 5000 - ] - }, + "examples": [ + 5000 + ], "tag": "call-level-tech-specific-cassandra", "requirement_level": "recommended" }, { "name": "db.cassandra.consistency_level", "type": { - "type": "Enum", "allow_custom_values": true, "members": [ { "id": "all", - "value": { - "type": "String", - "value": "all" - } + "value": "all", + "brief": null, + "note": null }, { "id": "each_quorum", - "value": { - "type": "String", - "value": "each_quorum" - } + "value": "each_quorum", + "brief": null, + "note": null }, { "id": "quorum", - "value": { - "type": "String", - "value": "quorum" - } + "value": "quorum", + "brief": null, + "note": null }, { "id": "local_quorum", - "value": { - "type": "String", - "value": "local_quorum" - } + "value": "local_quorum", + "brief": null, + "note": null }, { "id": "one", - "value": { - "type": "String", - "value": "one" - } + "value": "one", + "brief": null, + "note": null }, { "id": "two", - "value": { - "type": "String", - "value": "two" - } + "value": "two", + "brief": null, + "note": null }, { "id": "three", - "value": { - "type": "String", - "value": "three" - } + "value": "three", + "brief": null, + "note": null }, { "id": "local_one", - "value": { - "type": "String", - "value": "local_one" - } + "value": "local_one", + "brief": null, + "note": null }, { "id": "any", - "value": { - "type": "String", - "value": "any" - } + "value": "any", + "brief": null, + "note": null }, { "id": "serial", - "value": { - "type": "String", - "value": "serial" - } + "value": "serial", + "brief": null, + "note": null }, { "id": "local_serial", - "value": { - "type": "String", - "value": "local_serial" - } + "value": "local_serial", + "brief": null, + "note": null } ] }, @@ -2740,115 +2036,78 @@ }, { "name": "db.cassandra.table", - "type": { - "type": "String" - }, + "type": "string", "brief": "The name of the primary Cassandra table that the operation is acting upon, including the keyspace name (if applicable).", - "examples": { - "type": "String", - "value": "mytable" - }, + "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" }, { "name": "db.cassandra.idempotence", - "type": { - "type": "Boolean" - }, + "type": "boolean", "brief": "Whether or not the query is idempotent.\n", "tag": "call-level-tech-specific-cassandra", "requirement_level": "recommended" }, { "name": "db.cassandra.speculative_execution_count", - "type": { - "type": "Int" - }, + "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": { - "type": "Ints", - "values": [ - 0, - 2 - ] - }, + "examples": [ + 0, + 2 + ], "tag": "call-level-tech-specific-cassandra", "requirement_level": "recommended" }, { "name": "db.cassandra.coordinator.id", - "type": { - "type": "String" - }, + "type": "string", "brief": "The ID of the coordinating node for a query.\n", - "examples": { - "type": "String", - "value": "be13faa2-8574-4d71-926d-27f16cf8a7af" - }, + "examples": "be13faa2-8574-4d71-926d-27f16cf8a7af", "tag": "call-level-tech-specific-cassandra", "requirement_level": "recommended" }, { "name": "db.cassandra.coordinator.dc", - "type": { - "type": "String" - }, + "type": "string", "brief": "The data center of the coordinating node for a query.\n", - "examples": { - "type": "String", - "value": "us-west-2" - }, + "examples": "us-west-2", "tag": "call-level-tech-specific-cassandra", "requirement_level": "recommended" }, { "name": "db.name", - "type": { - "type": "String" - }, + "type": "string", "brief": "The HBase namespace.\n", - "examples": { - "type": "Strings", - "values": [ - "mynamespace" - ] - }, + "examples": [ + "mynamespace" + ], "tag": "call-level-tech-specific", "requirement_level": "recommended", "note": "For HBase the `db.name` should be set to the HBase namespace." }, { "name": "db.operation", - "type": { - "type": "String" - }, + "type": "string", "brief": "The HTTP method + the target REST route.\n", - "examples": { - "type": "Strings", - "values": [ - "GET /{db}/{docid}" - ] - }, + "examples": [ + "GET /{db}/{docid}" + ], "tag": "call-level-tech-specific", "requirement_level": "recommended", "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" }, { "name": "db.redis.database_index", - "type": { - "type": "Int" - }, + "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": { - "type": "Ints", - "values": [ - 0, - 1, - 15 - ] - }, + "examples": [ + 0, + 1, + 15 + ], "tag": "call-level-tech-specific", "requirement_level": { "conditionally_required": "If other than the default database (`0`)." @@ -2856,133 +2115,99 @@ }, { "name": "db.statement", - "type": { - "type": "String" - }, + "type": "string", "brief": "The full syntax of the Redis CLI command.\n", - "examples": { - "type": "Strings", - "values": [ - "HMSET myhash field1 'Hello' field2 'World'" - ] - }, + "examples": [ + "HMSET myhash field1 'Hello' field2 'World'" + ], "tag": "call-level-tech-specific", "requirement_level": "recommended", "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" }, { "name": "db.mongodb.collection", - "type": { - "type": "String" - }, + "type": "string", "brief": "The MongoDB collection being accessed within the database stated in `db.name`.\n", - "examples": { - "type": "Strings", - "values": [ - "customers", - "products" - ] - }, + "examples": [ + "customers", + "products" + ], "tag": "call-level-tech-specific", "requirement_level": "required" }, { "name": "http.request.method", "type": { - "type": "Enum", "allow_custom_values": true, "members": [ { "id": "connect", - "value": { - "type": "String", - "value": "CONNECT" - }, - "brief": "CONNECT method." + "value": "CONNECT", + "brief": "CONNECT method.", + "note": null }, { "id": "delete", - "value": { - "type": "String", - "value": "DELETE" - }, - "brief": "DELETE method." + "value": "DELETE", + "brief": "DELETE method.", + "note": null }, { "id": "get", - "value": { - "type": "String", - "value": "GET" - }, - "brief": "GET method." + "value": "GET", + "brief": "GET method.", + "note": null }, { "id": "head", - "value": { - "type": "String", - "value": "HEAD" - }, - "brief": "HEAD method." + "value": "HEAD", + "brief": "HEAD method.", + "note": null }, { "id": "options", - "value": { - "type": "String", - "value": "OPTIONS" - }, - "brief": "OPTIONS method." + "value": "OPTIONS", + "brief": "OPTIONS method.", + "note": null }, { "id": "patch", - "value": { - "type": "String", - "value": "PATCH" - }, - "brief": "PATCH method." + "value": "PATCH", + "brief": "PATCH method.", + "note": null }, { "id": "post", - "value": { - "type": "String", - "value": "POST" - }, - "brief": "POST method." + "value": "POST", + "brief": "POST method.", + "note": null }, { "id": "put", - "value": { - "type": "String", - "value": "PUT" - }, - "brief": "PUT method." + "value": "PUT", + "brief": "PUT method.", + "note": null }, { "id": "trace", - "value": { - "type": "String", - "value": "TRACE" - }, - "brief": "TRACE method." + "value": "TRACE", + "brief": "TRACE method.", + "note": null }, { "id": "other", - "value": { - "type": "String", - "value": "_OTHER" - }, - "brief": "Any HTTP method that the instrumentation has no prior knowledge of." + "value": "_OTHER", + "brief": "Any HTTP method that the instrumentation has no prior knowledge of.", + "note": null } ] }, "brief": "HTTP request method.", - "examples": { - "type": "Strings", - "values": [ - "GET", - "POST", - "HEAD" - ] - }, + "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", @@ -2990,34 +2215,24 @@ }, { "name": "db.operation", - "type": { - "type": "String" - }, + "type": "string", "brief": "The endpoint identifier for the request.", - "examples": { - "type": "Strings", - "values": [ - "search", - "ml.close_job", - "cat.aliases" - ] - }, + "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" }, { "name": "url.full", - "type": { - "type": "String" - }, + "type": "string", "brief": "Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986)", - "examples": { - "type": "Strings", - "values": [ - "https://localhost:9200/index/_search?q=user.id:kimchy" - ] - }, + "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", @@ -3025,16 +2240,11 @@ }, { "name": "db.statement", - "type": { - "type": "String" - }, + "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": { - "type": "Strings", - "values": [ - "\"{\\\"query\\\":{\\\"term\\\":{\\\"user.id\\\":\\\"kimchy\\\"}}}\"" - ] - }, + "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" @@ -3042,18 +2252,13 @@ }, { "name": "server.address", - "type": { - "type": "String" - }, + "type": "string", "brief": "Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name.", - "examples": { - "type": "Strings", - "values": [ - "example.com", - "10.1.2.80", - "/tmp/my.sock" - ] - }, + "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", @@ -3061,18 +2266,13 @@ }, { "name": "server.port", - "type": { - "type": "Int" - }, + "type": "int", "brief": "Server port number.", - "examples": { - "type": "Ints", - "values": [ - 80, - 8080, - 443 - ] - }, + "examples": [ + 80, + 8080, + 443 + ], "tag": "call-level-tech-specific", "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", @@ -3080,16 +2280,11 @@ }, { "name": "db.elasticsearch.cluster.name", - "type": { - "type": "String" - }, + "type": "string", "brief": "Represents the identifier of an Elasticsearch cluster.\n", - "examples": { - "type": "Strings", - "values": [ - "e9106fc68e3044f0b1475b04bf4ffd5f" - ] - }, + "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" @@ -3097,16 +2292,11 @@ }, { "name": "db.elasticsearch.node.name", - "type": { - "type": "String" - }, + "type": "string", "brief": "Represents the human-readable identifier of the node/instance to which a request was routed.\n", - "examples": { - "type": "Strings", - "values": [ - "instance-0000000001" - ] - }, + "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" @@ -3114,17 +2304,12 @@ }, { "name": "db.elasticsearch.path_parts", - "type": { - "type": "template[string]" - }, + "type": "template[string]", "brief": "A dynamic value in the url path.\n", - "examples": { - "type": "Strings", - "values": [ - "db.elasticsearch.path_parts.index=test-index", - "db.elasticsearch.path_parts.doc_id=123" - ] - }, + "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" @@ -3133,144 +2318,118 @@ }, { "name": "db.sql.table", - "type": { - "type": "String" - }, + "type": "string", "brief": "The name of the primary table that the operation is acting upon, including the database name (if applicable).", - "examples": { - "type": "Strings", - "values": [ - "public.users", - "customers" - ] - }, + "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" }, { "name": "db.cosmosdb.client_id", - "type": { - "type": "String" - }, + "type": "string", "brief": "Unique Cosmos client instance id.", - "examples": { - "type": "String", - "value": "3ba4827d-4422-483f-b59f-85b74211c11d" - }, + "examples": "3ba4827d-4422-483f-b59f-85b74211c11d", "tag": "call-level-tech-specific", "requirement_level": "recommended" }, { "name": "db.cosmosdb.operation_type", "type": { - "type": "Enum", "allow_custom_values": true, "members": [ { "id": "invalid", - "value": { - "type": "String", - "value": "Invalid" - } + "value": "Invalid", + "brief": null, + "note": null }, { "id": "create", - "value": { - "type": "String", - "value": "Create" - } + "value": "Create", + "brief": null, + "note": null }, { "id": "patch", - "value": { - "type": "String", - "value": "Patch" - } + "value": "Patch", + "brief": null, + "note": null }, { "id": "read", - "value": { - "type": "String", - "value": "Read" - } + "value": "Read", + "brief": null, + "note": null }, { "id": "read_feed", - "value": { - "type": "String", - "value": "ReadFeed" - } + "value": "ReadFeed", + "brief": null, + "note": null }, { "id": "delete", - "value": { - "type": "String", - "value": "Delete" - } + "value": "Delete", + "brief": null, + "note": null }, { "id": "replace", - "value": { - "type": "String", - "value": "Replace" - } + "value": "Replace", + "brief": null, + "note": null }, { "id": "execute", - "value": { - "type": "String", - "value": "Execute" - } + "value": "Execute", + "brief": null, + "note": null }, { "id": "query", - "value": { - "type": "String", - "value": "Query" - } + "value": "Query", + "brief": null, + "note": null }, { "id": "head", - "value": { - "type": "String", - "value": "Head" - } + "value": "Head", + "brief": null, + "note": null }, { "id": "head_feed", - "value": { - "type": "String", - "value": "HeadFeed" - } + "value": "HeadFeed", + "brief": null, + "note": null }, { "id": "upsert", - "value": { - "type": "String", - "value": "Upsert" - } + "value": "Upsert", + "brief": null, + "note": null }, { "id": "batch", - "value": { - "type": "String", - "value": "Batch" - } + "value": "Batch", + "brief": null, + "note": null }, { "id": "query_plan", - "value": { - "type": "String", - "value": "QueryPlan" - } + "value": "QueryPlan", + "brief": null, + "note": null }, { "id": "execute_javascript", - "value": { - "type": "String", - "value": "ExecuteJavaScript" - } + "value": "ExecuteJavaScript", + "brief": null, + "note": null } ] }, @@ -3282,16 +2441,11 @@ }, { "name": "user_agent.original", - "type": { - "type": "String" - }, + "type": "string", "brief": "Full user-agent string is generated by Cosmos DB SDK", - "examples": { - "type": "Strings", - "values": [ - "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\\|" - ] - }, + "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", @@ -3300,24 +2454,19 @@ { "name": "db.cosmosdb.connection_mode", "type": { - "type": "Enum", "allow_custom_values": false, "members": [ { "id": "gateway", - "value": { - "type": "String", - "value": "gateway" - }, - "brief": "Gateway (HTTP) connections mode" + "value": "gateway", + "brief": "Gateway (HTTP) connections mode", + "note": null }, { "id": "direct", - "value": { - "type": "String", - "value": "direct" - }, - "brief": "Direct connection." + "value": "direct", + "brief": "Direct connection.", + "note": null } ] }, @@ -3329,14 +2478,9 @@ }, { "name": "db.cosmosdb.container", - "type": { - "type": "String" - }, + "type": "string", "brief": "Cosmos DB container name.", - "examples": { - "type": "String", - "value": "anystring" - }, + "examples": "anystring", "tag": "call-level-tech-specific", "requirement_level": { "conditionally_required": "if available" @@ -3344,26 +2488,19 @@ }, { "name": "db.cosmosdb.request_content_length", - "type": { - "type": "Int" - }, + "type": "int", "brief": "Request payload size in bytes", "tag": "call-level-tech-specific", "requirement_level": "recommended" }, { "name": "db.cosmosdb.status_code", - "type": { - "type": "Int" - }, + "type": "int", "brief": "Cosmos DB status code.", - "examples": { - "type": "Ints", - "values": [ - 200, - 201 - ] - }, + "examples": [ + 200, + 201 + ], "tag": "call-level-tech-specific", "requirement_level": { "conditionally_required": "if response was received" @@ -3371,17 +2508,12 @@ }, { "name": "db.cosmosdb.sub_status_code", - "type": { - "type": "Int" - }, + "type": "int", "brief": "Cosmos DB sub status code.", - "examples": { - "type": "Ints", - "values": [ - 1000, - 1002 - ] - }, + "examples": [ + 1000, + 1002 + ], "tag": "call-level-tech-specific", "requirement_level": { "conditionally_required": "when response was received and contained sub-code." @@ -3389,17 +2521,12 @@ }, { "name": "db.cosmosdb.request_charge", - "type": { - "type": "Double" - }, + "type": "double", "brief": "RU consumed for that operation", - "examples": { - "type": "Doubles", - "values": [ - 46.18, - 1.0 - ] - }, + "examples": [ + 46.18, + 1.0 + ], "tag": "call-level-tech-specific", "requirement_level": { "conditionally_required": "when available" diff --git a/crates/weaver_resolver/src/attribute.rs b/crates/weaver_resolver/src/attribute.rs index 6a7b5a89..8f2b9175 100644 --- a/crates/weaver_resolver/src/attribute.rs +++ b/crates/weaver_resolver/src/attribute.rs @@ -10,10 +10,7 @@ use weaver_resolved_schema::attribute::AttributeRef; use weaver_resolved_schema::lineage::{FieldId, FieldLineage, GroupLineage, ResolutionMode}; use weaver_schema::attribute::Attribute; use weaver_schema::tags::Tags; -use weaver_semconv::attribute::{ - AttributeSpec, AttributeTypeSpec, ExamplesSpec, PrimitiveOrArrayTypeSpec, TemplateTypeSpec, - ValueSpec, -}; +use weaver_semconv::attribute::{AttributeSpec, ValueSpec}; use weaver_semconv::group::GroupType; use weaver_semconv::SemConvRegistry; use weaver_version::VersionAttributeChanges; @@ -107,7 +104,7 @@ impl AttributeCatalog { } }, examples: match examples { - Some(_) => semconv_to_resolved_examples(examples), + Some(_) => examples.clone(), None => { inherited_fields.push(FieldId::AttributeExamples); root_attr.attribute.examples.clone() @@ -206,9 +203,9 @@ impl AttributeCatalog { // If it does not, add it to the catalog and return a new reference. let attr = attribute::Attribute { name: root_attr_id.clone(), - r#type: semconv_to_resolved_attr_type(r#type), + r#type: r#type.clone(), brief: brief.clone().unwrap_or_default(), - examples: semconv_to_resolved_examples(examples), + examples: examples.clone(), tag: tag.clone(), requirement_level: requirement_level.clone(), sampling_relevant: *sampling_relevant, @@ -425,9 +422,9 @@ pub fn resolve_attribute( deprecated, } => Ok(attribute::Attribute { name: id.clone(), - r#type: semconv_to_resolved_attr_type(r#type), + r#type: r#type.clone(), brief: brief.clone().unwrap_or_default(), - examples: semconv_to_resolved_examples(examples), + examples: examples.clone(), tag: tag.clone(), requirement_level: requirement_level.clone(), sampling_relevant: *sampling_relevant, @@ -440,69 +437,6 @@ pub fn resolve_attribute( } } -fn semconv_to_resolved_attr_type(attr_type: &AttributeTypeSpec) -> attribute::AttributeType { - match attr_type { - AttributeTypeSpec::PrimitiveOrArray(poa) => match poa { - PrimitiveOrArrayTypeSpec::Boolean => attribute::AttributeType::Boolean, - PrimitiveOrArrayTypeSpec::Int => weaver_resolved_schema::attribute::AttributeType::Int, - PrimitiveOrArrayTypeSpec::Double => attribute::AttributeType::Double, - PrimitiveOrArrayTypeSpec::String => attribute::AttributeType::String, - PrimitiveOrArrayTypeSpec::Strings => attribute::AttributeType::Strings, - PrimitiveOrArrayTypeSpec::Ints => attribute::AttributeType::Ints, - PrimitiveOrArrayTypeSpec::Doubles => attribute::AttributeType::Doubles, - PrimitiveOrArrayTypeSpec::Booleans => attribute::AttributeType::Booleans, - }, - AttributeTypeSpec::Template(template) => match template { - TemplateTypeSpec::Boolean => attribute::AttributeType::TemplateBoolean, - TemplateTypeSpec::Int => attribute::AttributeType::TemplateInt, - TemplateTypeSpec::Double => attribute::AttributeType::TemplateDouble, - TemplateTypeSpec::String => attribute::AttributeType::TemplateString, - TemplateTypeSpec::Strings => attribute::AttributeType::TemplateStrings, - TemplateTypeSpec::Ints => attribute::AttributeType::TemplateInts, - TemplateTypeSpec::Doubles => attribute::AttributeType::TemplateDoubles, - TemplateTypeSpec::Booleans => attribute::AttributeType::TemplateBooleans, - }, - AttributeTypeSpec::Enum { - allow_custom_values, - members, - } => attribute::AttributeType::Enum { - allow_custom_values: *allow_custom_values, - members: members - .iter() - .map(|member| attribute::EnumEntries { - id: member.id.clone(), - value: match &member.value { - ValueSpec::String(s) => { - weaver_resolved_schema::value::Value::String { value: s.clone() } - } - ValueSpec::Int(i) => { - weaver_resolved_schema::value::Value::Int { value: *i } - } - ValueSpec::Double(d) => { - weaver_resolved_schema::value::Value::Double { value: *d } - } - }, - brief: member.brief.clone(), - note: member.note.clone(), - }) - .collect(), - }, - } -} - -fn semconv_to_resolved_examples(examples: &Option) -> Option { - examples.as_ref().map(|examples| match examples { - ExamplesSpec::Bool(v) => attribute::Example::Bool { value: *v }, - ExamplesSpec::Int(v) => attribute::Example::Int { value: *v }, - ExamplesSpec::Double(v) => attribute::Example::Double { value: *v }, - ExamplesSpec::String(v) => attribute::Example::String { value: v.clone() }, - ExamplesSpec::Ints(v) => attribute::Example::Ints { values: v.clone() }, - ExamplesSpec::Doubles(v) => attribute::Example::Doubles { values: v.clone() }, - ExamplesSpec::Bools(v) => attribute::Example::Bools { values: v.clone() }, - ExamplesSpec::Strings(v) => attribute::Example::Strings { values: v.clone() }, - }) -} - #[allow(dead_code)] // ToDo Remove this once we have values in the resolved schema fn semconv_to_resolved_value( value: &Option, diff --git a/crates/weaver_resolver/src/registry.rs b/crates/weaver_resolver/src/registry.rs index 9107a020..6563e26f 100644 --- a/crates/weaver_resolver/src/registry.rs +++ b/crates/weaver_resolver/src/registry.rs @@ -600,8 +600,8 @@ mod tests { test_dir, observed_attr_catalog_json ); - let yaml = serde_yaml::to_string(&observed_attr_catalog).unwrap(); - println!("{}", yaml); + // let yaml = serde_yaml::to_string(&observed_attr_catalog).unwrap(); + // println!("{}", yaml); // Check that the resolved registry matches the expected registry. let observed_registry_json = serde_json::to_string_pretty(&observed_registry) diff --git a/crates/weaver_schema/src/attribute.rs b/crates/weaver_schema/src/attribute.rs index 1dd4225c..3d786685 100644 --- a/crates/weaver_schema/src/attribute.rs +++ b/crates/weaver_schema/src/attribute.rs @@ -6,7 +6,7 @@ use serde::{Deserialize, Serialize}; -use weaver_semconv::attribute::{AttributeTypeSpec, ExamplesSpec, RequirementLevel, ValueSpec}; +use weaver_semconv::attribute::{AttributeType, Examples, RequirementLevel, ValueSpec}; use weaver_semconv::stability::Stability; use crate::tags::Tags; @@ -38,7 +38,7 @@ pub enum Attribute { /// attribute. If only a single example is provided, it can directly /// be reported without encapsulating it into a sequence/dictionary. #[serde(skip_serializing_if = "Option::is_none")] - examples: Option, + examples: Option, /// Associates a tag ("sub-group") to the attribute. It carries no /// particular semantic meaning but can be used e.g. for filtering /// in the markdown generator. @@ -131,7 +131,7 @@ pub enum Attribute { id: String, /// Either a string literal denoting the type as a primitive or an /// array type, a template type or an enum definition. - r#type: AttributeTypeSpec, + r#type: AttributeType, /// A brief description of the attribute. brief: String, /// Sequence of example values for the attribute or single example @@ -140,7 +140,7 @@ pub enum Attribute { /// attribute. If only a single example is provided, it can directly /// be reported without encapsulating it into a sequence/dictionary. // #[serde(skip_serializing_if = "Option::is_none")] - examples: Option, + examples: Option, /// Associates a tag ("sub-group") to the attribute. It carries no /// particular semantic meaning but can be used e.g. for filtering /// in the markdown generator. diff --git a/crates/weaver_semconv/src/attribute.rs b/crates/weaver_semconv/src/attribute.rs index 35c203a3..d597a294 100644 --- a/crates/weaver_semconv/src/attribute.rs +++ b/crates/weaver_semconv/src/attribute.rs @@ -31,7 +31,7 @@ pub enum AttributeSpec { /// attribute. If only a single example is provided, it can directly /// be reported without encapsulating it into a sequence/dictionary. #[serde(skip_serializing_if = "Option::is_none")] - examples: Option, + examples: Option, /// Associates a tag ("sub-group") to the attribute. It carries no /// particular semantic meaning but can be used e.g. for filtering /// in the markdown generator. @@ -73,7 +73,7 @@ pub enum AttributeSpec { id: String, /// Either a string literal denoting the type as a primitive or an /// array type, a template type or an enum definition. - r#type: AttributeTypeSpec, + r#type: AttributeType, /// A brief description of the attribute. brief: Option, /// Sequence of example values for the attribute or single example @@ -82,7 +82,7 @@ pub enum AttributeSpec { /// attribute. If only a single example is provided, it can directly /// be reported without encapsulating it into a sequence/dictionary. #[serde(skip_serializing_if = "Option::is_none")] - examples: Option, + examples: Option, /// Associates a tag ("sub-group") to the attribute. It carries no /// particular semantic meaning but can be used e.g. for filtering /// in the markdown generator. @@ -173,7 +173,7 @@ impl AttributeSpec { #[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq, Hash)] #[serde(rename_all = "snake_case")] #[serde(untagged)] -pub enum AttributeTypeSpec { +pub enum AttributeType { /// Primitive or array type. PrimitiveOrArray(PrimitiveOrArrayTypeSpec), /// A template type. @@ -190,12 +190,12 @@ pub enum AttributeTypeSpec { } /// Implements a human readable display for AttributeType. -impl Display for AttributeTypeSpec { +impl Display for AttributeType { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { match self { - AttributeTypeSpec::PrimitiveOrArray(t) => write!(f, "{}", t), - AttributeTypeSpec::Template(t) => write!(f, "{}", t), - AttributeTypeSpec::Enum { members, .. } => { + AttributeType::PrimitiveOrArray(t) => write!(f, "{}", t), + AttributeType::Template(t) => write!(f, "{}", t), + AttributeType::Enum { members, .. } => { let entries = members .iter() .map(|m| m.id.clone()) @@ -349,10 +349,10 @@ impl Display for ValueSpec { } /// The different types of examples. -#[derive(Serialize, Deserialize, Debug, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq, Hash)] #[serde(rename_all = "snake_case")] #[serde(untagged)] -pub enum ExamplesSpec { +pub enum Examples { /// A boolean example. Bool(bool), /// A integer example. @@ -435,3 +435,15 @@ impl Display for BasicRequirementLevelSpec { } } } + +impl Examples { + /// Creates an example from a f64. + pub fn from_f64(value: f64) -> Self { + Examples::Double(OrderedFloat(value)) + } + + /// Creates an example from several f64. + pub fn from_f64s(values: Vec) -> Self { + Examples::Doubles(values.into_iter().map(OrderedFloat).collect()) + } +} diff --git a/crates/weaver_semconv/src/group.rs b/crates/weaver_semconv/src/group.rs index a0b78055..d40abc56 100644 --- a/crates/weaver_semconv/src/group.rs +++ b/crates/weaver_semconv/src/group.rs @@ -8,7 +8,7 @@ use serde::{Deserialize, Serialize}; use std::fmt::{Display, Formatter}; use validator::{Validate, ValidationError}; -use crate::attribute::{AttributeSpec, AttributeTypeSpec, PrimitiveOrArrayTypeSpec}; +use crate::attribute::{AttributeSpec, AttributeType, PrimitiveOrArrayTypeSpec}; use crate::group::InstrumentSpec::{Counter, Gauge, Histogram, UpDownCounter}; use crate::stability::Stability; @@ -183,12 +183,12 @@ fn validate_group(group: &GroupSpec) -> Result<(), ValidationError> { continue; } - if *r#type == AttributeTypeSpec::PrimitiveOrArray(PrimitiveOrArrayTypeSpec::String) { + if *r#type == AttributeType::PrimitiveOrArray(PrimitiveOrArrayTypeSpec::String) { return Err(ValidationError::new( "This attribute is a string but it does not contain any examples.", )); } - if *r#type == AttributeTypeSpec::PrimitiveOrArray(PrimitiveOrArrayTypeSpec::Strings) { + if *r#type == AttributeType::PrimitiveOrArray(PrimitiveOrArrayTypeSpec::Strings) { return Err(ValidationError::new( "This attribute is a string array but it does not contain any examples.", )); diff --git a/src/search/semconv/examples.rs b/src/search/semconv/examples.rs index 0fef6387..864c1570 100644 --- a/src/search/semconv/examples.rs +++ b/src/search/semconv/examples.rs @@ -4,35 +4,35 @@ use crate::search::theme::ThemeConfig; use ratatui::prelude::{Line, Span, Style}; -use weaver_semconv::attribute::ExamplesSpec; +use weaver_semconv::attribute::Examples; /// Append examples to the text. -pub fn append_lines(examples: &ExamplesSpec, text: &mut Vec, theme: &ThemeConfig) { +pub fn append_lines(examples: &Examples, text: &mut Vec, theme: &ThemeConfig) { text.push(Line::from(Span::styled( "Examples: ", Style::default().fg(theme.label), ))); match examples { - ExamplesSpec::Int(v) => text.push(Line::from(Span::raw(format!("- {}", v)))), - ExamplesSpec::Double(v) => text.push(Line::from(Span::raw(format!("- {}", v)))), - ExamplesSpec::Bool(v) => text.push(Line::from(Span::raw(format!("- {}", v)))), - ExamplesSpec::String(v) => text.push(Line::from(Span::raw(format!("- {}", v)))), - ExamplesSpec::Ints(vals) => { + Examples::Int(v) => text.push(Line::from(Span::raw(format!("- {}", v)))), + Examples::Double(v) => text.push(Line::from(Span::raw(format!("- {}", v)))), + Examples::Bool(v) => text.push(Line::from(Span::raw(format!("- {}", v)))), + Examples::String(v) => text.push(Line::from(Span::raw(format!("- {}", v)))), + Examples::Ints(vals) => { for v in vals.iter() { text.push(Line::from(Span::raw(format!("- {}", v)))); } } - ExamplesSpec::Doubles(vals) => { + Examples::Doubles(vals) => { for v in vals.iter() { text.push(Line::from(Span::raw(format!("- {}", v)))); } } - ExamplesSpec::Bools(vals) => { + Examples::Bools(vals) => { for v in vals.iter() { text.push(Line::from(Span::raw(format!("- {}", v)))); } } - ExamplesSpec::Strings(vals) => { + Examples::Strings(vals) => { for v in vals.iter() { text.push(Line::from(Span::raw(format!("- {}", v)))); } From 7b1e00623be99034dd211a7ad40ecb301c83c040 Mon Sep 17 00:00:00 2001 From: Laurent Querel Date: Wed, 6 Mar 2024 22:58:35 -0800 Subject: [PATCH 15/20] feature(registry): generate markdown from jinja2 templates --- crates/weaver_forge/data/exporter.yaml | 32 +++ crates/weaver_forge/data/jvm-metrics.yaml | 186 ++++++++++++++++++ crates/weaver_forge/data/mobile-events.yaml | 74 +++++++ crates/weaver_forge/src/lib.rs | 7 +- crates/weaver_forge/src/registry.rs | 35 +++- .../templates/test/attribute_group.md | 47 ++++- .../templates/test/attribute_groups.md | 48 ++++- .../templates/test/attribute_type.j2 | 5 + crates/weaver_forge/templates/test/event.md | 47 +++++ crates/weaver_forge/templates/test/events.md | 48 +++++ .../weaver_forge/templates/test/examples.j2 | 7 + crates/weaver_forge/templates/test/group.md | 54 +++-- crates/weaver_forge/templates/test/groups.md | 47 +++++ crates/weaver_forge/templates/test/metric.md | 52 +++++ .../templates/test/metric_groups.md | 47 +++++ crates/weaver_forge/templates/test/metrics.md | 53 +++++ .../weaver_forge/templates/test/registry.md | 51 ++++- .../weaver_forge/templates/test/resource.md | 46 +++++ .../weaver_forge/templates/test/resources.md | 47 +++++ crates/weaver_forge/templates/test/span.md | 50 ++++- crates/weaver_forge/templates/test/spans.md | 50 +++++ 21 files changed, 1003 insertions(+), 30 deletions(-) create mode 100644 crates/weaver_forge/data/exporter.yaml create mode 100644 crates/weaver_forge/data/jvm-metrics.yaml create mode 100644 crates/weaver_forge/data/mobile-events.yaml create mode 100644 crates/weaver_forge/templates/test/attribute_type.j2 create mode 100644 crates/weaver_forge/templates/test/events.md create mode 100644 crates/weaver_forge/templates/test/examples.j2 create mode 100644 crates/weaver_forge/templates/test/metric_groups.md create mode 100644 crates/weaver_forge/templates/test/metrics.md create mode 100644 crates/weaver_forge/templates/test/resources.md diff --git a/crates/weaver_forge/data/exporter.yaml b/crates/weaver_forge/data/exporter.yaml new file mode 100644 index 00000000..36a66ff4 --- /dev/null +++ b/crates/weaver_forge/data/exporter.yaml @@ -0,0 +1,32 @@ +groups: + - id: otel.scope + prefix: otel.scope + type: resource + brief: Attributes used by non-OTLP exporters to represent OpenTelemetry Scope's concepts. + attributes: + - id: name + type: string + brief: The name of the instrumentation scope - (`InstrumentationScope.Name` in OTLP). + examples: ['io.opentelemetry.contrib.mongodb'] + stability: stable + - id: version + type: string + brief: The version of the instrumentation scope - (`InstrumentationScope.Version` in OTLP). + examples: ['1.0.0'] + stability: stable + - id: otel.library + prefix: otel.library + type: resource + brief: > + Span attributes used by non-OTLP exporters to represent OpenTelemetry Scope's concepts. + attributes: + - id: name + type: string + deprecated: use the `otel.scope.name` attribute. + brief: + examples: ['io.opentelemetry.contrib.mongodb'] + - id: version + type: string + deprecated: use the `otel.scope.version` attribute. + brief: + examples: ['1.0.0'] \ No newline at end of file diff --git a/crates/weaver_forge/data/jvm-metrics.yaml b/crates/weaver_forge/data/jvm-metrics.yaml new file mode 100644 index 00000000..04c1bab8 --- /dev/null +++ b/crates/weaver_forge/data/jvm-metrics.yaml @@ -0,0 +1,186 @@ +groups: + - id: attributes.jvm.memory + type: attribute_group + brief: "Describes JVM memory metric attributes." + prefix: jvm.memory + attributes: + - id: type + stability: stable + type: + allow_custom_values: false + members: + - id: heap + value: 'heap' + brief: 'Heap memory.' + - id: non_heap + value: 'non_heap' + brief: 'Non-heap memory' + requirement_level: recommended + brief: The type of memory. + examples: ["heap", "non_heap"] + - id: pool.name + stability: stable + type: string + requirement_level: recommended + brief: Name of the memory pool. + examples: ["G1 Old Gen", "G1 Eden space", "G1 Survivor Space"] + 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()). + + - id: metric.jvm.memory.used + type: metric + metric_name: jvm.memory.used + extends: attributes.jvm.memory + brief: "Measure of memory used." + instrument: updowncounter + unit: "By" + stability: stable + + - id: metric.jvm.memory.committed + type: metric + metric_name: jvm.memory.committed + extends: attributes.jvm.memory + brief: "Measure of memory committed." + instrument: updowncounter + unit: "By" + stability: stable + + - id: metric.jvm.memory.limit + type: metric + metric_name: jvm.memory.limit + extends: attributes.jvm.memory + brief: "Measure of max obtainable memory." + instrument: updowncounter + unit: "By" + stability: stable + + - id: metric.jvm.memory.used_after_last_gc + type: metric + metric_name: jvm.memory.used_after_last_gc + extends: attributes.jvm.memory + brief: "Measure of memory used, as measured after the most recent garbage collection event on this pool." + instrument: updowncounter + unit: "By" + stability: stable + + - id: metric.jvm.gc.duration + type: metric + metric_name: jvm.gc.duration + brief: "Duration of JVM garbage collection actions." + instrument: histogram + unit: "s" + prefix: jvm.gc + attributes: + - id: name + stability: stable + type: string + requirement_level: recommended + brief: Name of the garbage collector. + examples: ["G1 Young Generation", "G1 Old Generation"] + note: > + Garbage collector name is generally obtained via + [GarbageCollectionNotificationInfo#getGcName()](https://docs.oracle.com/en/java/javase/11/docs/api/jdk.management/com/sun/management/GarbageCollectionNotificationInfo.html#getGcName()). + - id: action + stability: stable + type: string + requirement_level: recommended + brief: Name of the garbage collector action. + examples: ["end of minor GC", "end of major GC"] + note: > + Garbage collector action is generally obtained via + [GarbageCollectionNotificationInfo#getGcAction()](https://docs.oracle.com/en/java/javase/11/docs/api/jdk.management/com/sun/management/GarbageCollectionNotificationInfo.html#getGcAction()). + stability: stable + + - id: metric.jvm.thread.count + type: metric + metric_name: jvm.thread.count + brief: "Number of executing platform threads." + instrument: updowncounter + unit: "{thread}" + attributes: + - id: jvm.thread.daemon + stability: stable + type: boolean + requirement_level: recommended + brief: "Whether the thread is daemon or not." + - id: jvm.thread.state + stability: stable + requirement_level: recommended + type: + allow_custom_values: false + members: + - id: new + value: 'new' + brief: 'A thread that has not yet started is in this state.' + - id: runnable + value: 'runnable' + brief: 'A thread executing in the Java virtual machine is in this state.' + - id: blocked + value: 'blocked' + brief: 'A thread that is blocked waiting for a monitor lock is in this state.' + - id: waiting + value: 'waiting' + brief: 'A thread that is waiting indefinitely for another thread to perform a particular action is in this state.' + - id: timed_waiting + value: 'timed_waiting' + brief: 'A thread that is waiting for another thread to perform an action for up to a specified waiting time is in this state.' + - id: terminated + value: 'terminated' + brief: 'A thread that has exited is in this state.' + brief: "State of the thread." + examples: ["runnable", "blocked"] + stability: stable + + - id: metric.jvm.class.loaded + type: metric + metric_name: jvm.class.loaded + brief: "Number of classes loaded since JVM start." + instrument: counter + unit: "{class}" + stability: stable + + - id: metric.jvm.class.unloaded + type: metric + metric_name: jvm.class.unloaded + brief: "Number of classes unloaded since JVM start." + instrument: counter + unit: "{class}" + stability: stable + + - id: metric.jvm.class.count + type: metric + metric_name: jvm.class.count + brief: "Number of classes currently loaded." + instrument: updowncounter + unit: "{class}" + stability: stable + + - id: metric.jvm.cpu.count + type: metric + metric_name: jvm.cpu.count + brief: "Number of processors available to the Java virtual machine." + instrument: updowncounter + unit: "{cpu}" + stability: stable + + - id: metric.jvm.cpu.time + type: metric + metric_name: jvm.cpu.time + brief: "CPU time used by the process as reported by the JVM." + instrument: counter + unit: "s" + stability: stable + + - id: metric.jvm.cpu.recent_utilization + type: metric + metric_name: jvm.cpu.recent_utilization + brief: "Recent CPU utilization for the process as reported by the JVM." + note: > + The value range is [0.0,1.0]. + This utilization is not defined as being for the specific interval since last measurement + (unlike `system.cpu.utilization`). + [Reference](https://docs.oracle.com/en/java/javase/17/docs/api/jdk.management/com/sun/management/OperatingSystemMXBean.html#getProcessCpuLoad()). + instrument: gauge + unit: "1" + stability: stable \ No newline at end of file diff --git a/crates/weaver_forge/data/mobile-events.yaml b/crates/weaver_forge/data/mobile-events.yaml new file mode 100644 index 00000000..9f0af378 --- /dev/null +++ b/crates/weaver_forge/data/mobile-events.yaml @@ -0,0 +1,74 @@ +groups: + - id: ios.lifecycle.events + type: event + prefix: ios + name: device.app.lifecycle + brief: > + This event represents an occurrence of a lifecycle transition on the iOS platform. + attributes: + - id: state + stability: experimental + 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. + brief: > + This attribute represents the state the application has transitioned into at the occurrence of the event. + type: + allow_custom_values: false + members: + - id: active + value: 'active' + brief: > + The app has become `active`. Associated with UIKit notification `applicationDidBecomeActive`. + - id: inactive + value: 'inactive' + brief: > + The app is now `inactive`. Associated with UIKit notification `applicationWillResignActive`. + - id: background + value: 'background' + brief: > + The app is now in the background. + This value is associated with UIKit notification `applicationDidEnterBackground`. + - id: foreground + value: 'foreground' + brief: > + The app is now in the foreground. + This value is associated with UIKit notification `applicationWillEnterForeground`. + - id: terminate + value: 'terminate' + brief: > + The app is about to terminate. Associated with UIKit notification `applicationWillTerminate`. + - id: android.lifecycle.events + type: event + prefix: android + name: device.app.lifecycle + brief: > + This event represents an occurrence of a lifecycle transition on the Android platform. + attributes: + - id: state + stability: experimental + requirement_level: required + brief: > + This attribute represents the state the application has transitioned into at the occurrence of the event. + 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. + type: + allow_custom_values: false + 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. + - 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. + - 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. \ No newline at end of file diff --git a/crates/weaver_forge/src/lib.rs b/crates/weaver_forge/src/lib.rs index e1a66e66..1de90086 100644 --- a/crates/weaver_forge/src/lib.rs +++ b/crates/weaver_forge/src/lib.rs @@ -430,10 +430,9 @@ impl TemplateEngine { error: "".to_string(), })?; - if tmpl_file.ends_with(".macro.j2") { - // Macro files are not templates. - // They are included in other templates. - // So we skip them. + if tmpl_file.ends_with(".j2") { + // Files with .j2 are either macros or included files + // imported from the template files, so we skip them. continue; } diff --git a/crates/weaver_forge/src/registry.rs b/crates/weaver_forge/src/registry.rs index 046f6b99..ff4b6d13 100644 --- a/crates/weaver_forge/src/registry.rs +++ b/crates/weaver_forge/src/registry.rs @@ -10,7 +10,7 @@ use weaver_resolved_schema::attribute::Attribute; use weaver_resolved_schema::catalog::Catalog; use weaver_resolved_schema::lineage::GroupLineage; use weaver_resolved_schema::registry::{Constraint, Registry}; -use weaver_semconv::group::GroupType; +use weaver_semconv::group::{GroupType, InstrumentSpec, SpanKindSpec}; use weaver_semconv::stability::Stability; /// A semantic convention registry used in the context of the template engine. @@ -70,6 +70,33 @@ pub struct TemplateGroup { /// List of attributes that belong to the semantic convention. #[serde(default)] pub attributes: Vec, + + /// Specifies the kind of the span. + /// Note: only valid if type is span (the default) + pub span_kind: Option, + /// List of strings that specify the ids of event semantic conventions + /// associated with this span semantic convention. + /// Note: only valid if type is span (the default) + #[serde(default)] + pub events: Vec, + /// The metric name as described by the [OpenTelemetry Specification](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/data-model.md#timeseries-model). + /// Note: This field is required if type is metric. + pub metric_name: Option, + /// The instrument type that should be used to record the metric. Note that + /// the semantic conventions must be written using the names of the + /// synchronous instrument types (counter, gauge, updowncounter and + /// histogram). + /// For more details: [Metrics semantic conventions - Instrument types](https://github.com/open-telemetry/opentelemetry-specification/tree/main/specification/metrics/semantic_conventions#instrument-types). + /// Note: This field is required if type is metric. + pub instrument: Option, + /// The unit in which the metric is measured, which should adhere to the + /// [guidelines](https://github.com/open-telemetry/opentelemetry-specification/tree/main/specification/metrics/semantic_conventions#instrument-units). + /// Note: This field is required if type is metric. + pub unit: Option, + /// The name of the event. If not specified, the prefix is used. + /// If prefix is empty (or unspecified), name is required. + pub name: Option, + /// The lineage of the group. #[serde(skip_serializing_if = "Option::is_none")] pub lineage: Option, @@ -122,6 +149,12 @@ impl TemplateRegistry { deprecated, constraints, attributes, + span_kind: group.span_kind.clone(), + events: group.events.clone(), + metric_name: group.metric_name.clone(), + instrument: group.instrument.clone(), + unit: group.unit.clone(), + name: group.name.clone(), lineage, } }) diff --git a/crates/weaver_forge/templates/test/attribute_group.md b/crates/weaver_forge/templates/test/attribute_group.md index 025b7741..24c5023d 100644 --- a/crates/weaver_forge/templates/test/attribute_group.md +++ b/crates/weaver_forge/templates/test/attribute_group.md @@ -1 +1,46 @@ -# Attribute Group `{{ id }}` +{%- set file_name = group.id | file_name -%} +{{- template.set_file_name("attribute_group/" ~ file_name ~ ".md") -}} + +## Group `{{ group.id }}` ({{ group.type }}) + +### Brief + +{{ group.brief | trim }} + +prefix: {{ group.prefix }} + +### Attributes + +{% for attribute in group.attributes %} +#### Attribute `{{ attribute.name }}` + +{{ attribute.brief }} + +{% if attribute.note %} +{{ attribute.note | trim }} +{% endif %} + +{%- if attribute.requirement_level == "required" %} +- Requirement Level: Required + {%- elif attribute.requirement_level.conditionally_required %} +- Requirement Level: Conditionally Required - {{ attribute.requirement_level.conditionally_required }} + {%- elif attribute.requirement_level == "recommended" %} +- Requirement Level: Recommended + {%- else %} +- Requirement Level: Optional + {%- endif %} + {% if attribute.tag %} +- Tag: {{ attribute.tag }} + {% endif %} + {%- include "attribute_type.j2" %} + {%- include "examples.j2" -%} + {%- if attribute.sampling_relevant %} +- Sampling relevant: {{ attribute.sampling_relevant }} + {%- endif %} + {%- if attribute.deprecated %} +- Deprecated: {{ attribute.deprecated }} + {%- endif %} + {% if attribute.stability %} +- Stability: {{ attribute.stability | capitalize }} + {% endif %} + {% endfor %} diff --git a/crates/weaver_forge/templates/test/attribute_groups.md b/crates/weaver_forge/templates/test/attribute_groups.md index a39a20dd..ae59a378 100644 --- a/crates/weaver_forge/templates/test/attribute_groups.md +++ b/crates/weaver_forge/templates/test/attribute_groups.md @@ -1 +1,47 @@ -# Attribute Groups \ No newline at end of file +# Semantic Convention Attribute Groups + +{% for group in groups %} +## Group `{{ group.id }}` ({{ group.type }}) + +### Brief + +{{ group.brief | trim }} + +prefix: {{ group.prefix }} + +### Attributes + +{% for attribute in group.attributes %} +#### Attribute `{{ attribute.name }}` + +{{ attribute.brief }} + +{% if attribute.note %} +{{ attribute.note | trim }} +{% endif %} + +{%- if attribute.requirement_level == "required" %} +- Requirement Level: Required + {%- elif attribute.requirement_level.conditionally_required %} +- Requirement Level: Conditionally Required - {{ attribute.requirement_level.conditionally_required }} + {%- elif attribute.requirement_level == "recommended" %} +- Requirement Level: Recommended + {%- else %} +- Requirement Level: Optional + {%- endif %} + {% if attribute.tag %} +- Tag: {{ attribute.tag }} + {% endif %} + {%- include "attribute_type.j2" %} + {%- include "examples.j2" -%} + {%- if attribute.sampling_relevant %} +- Sampling relevant: {{ attribute.sampling_relevant }} + {%- endif %} + {%- if attribute.deprecated %} +- Deprecated: {{ attribute.deprecated }} + {%- endif %} + {% if attribute.stability %} +- Stability: {{ attribute.stability | capitalize }} + {% endif %} + {% endfor %} + {% endfor %} diff --git a/crates/weaver_forge/templates/test/attribute_type.j2 b/crates/weaver_forge/templates/test/attribute_type.j2 new file mode 100644 index 00000000..1c9147ba --- /dev/null +++ b/crates/weaver_forge/templates/test/attribute_type.j2 @@ -0,0 +1,5 @@ +{%- if attribute.type is mapping %} +- Type: Enum [{{ attribute.type.members | map(attribute="value") | join(", ") }}] +{%- else %} +- Type: {{ attribute.type }} +{%- endif %} \ No newline at end of file diff --git a/crates/weaver_forge/templates/test/event.md b/crates/weaver_forge/templates/test/event.md index e69de29b..2752b07f 100644 --- a/crates/weaver_forge/templates/test/event.md +++ b/crates/weaver_forge/templates/test/event.md @@ -0,0 +1,47 @@ +{%- set file_name = group.id | file_name -%} +{{- template.set_file_name("event/" ~ file_name ~ ".md") -}} + +# Group `{{ group.id }}` ({{ group.type }}) + +## Brief + +{{ group.brief | trim }} + +Prefix: {{ group.prefix }} +Name: {{ group.name }} + +## Attributes + +{% for attribute in group.attributes %} +### Attribute `{{ attribute.name }}` + +{{ attribute.brief }} + +{% if attribute.note %} +{{ attribute.note | trim }} +{% endif %} + +{%- if attribute.requirement_level == "required" %} +- Requirement Level: Required + {%- elif attribute.requirement_level.conditionally_required %} +- Requirement Level: Conditionally Required - {{ attribute.requirement_level.conditionally_required }} + {%- elif attribute.requirement_level == "recommended" %} +- Requirement Level: Recommended + {%- else %} +- Requirement Level: Optional + {%- endif %} + {% if attribute.tag %} +- Tag: {{ attribute.tag }} + {% endif %} + {%- include "attribute_type.j2" %} + {%- include "examples.j2" -%} + {%- if attribute.sampling_relevant %} +- Sampling relevant: {{ attribute.sampling_relevant }} + {%- endif %} + {%- if attribute.deprecated %} +- Deprecated: {{ attribute.deprecated }} + {%- endif %} + {% if attribute.stability %} +- Stability: {{ attribute.stability | capitalize }} + {% endif %} + {% endfor %} diff --git a/crates/weaver_forge/templates/test/events.md b/crates/weaver_forge/templates/test/events.md new file mode 100644 index 00000000..bcc09d59 --- /dev/null +++ b/crates/weaver_forge/templates/test/events.md @@ -0,0 +1,48 @@ +# Semantic Convention Event Groups + +{% for group in groups %} +## Group `{{ group.id }}` ({{ group.type }}) + +### Brief + +{{ group.brief | trim }} + +Prefix: {{ group.prefix }} +Name: {{ group.name }} + +### Attributes + +{% for attribute in group.attributes %} +#### Attribute `{{ attribute.name }}` + +{{ attribute.brief }} + +{% if attribute.note %} +{{ attribute.note | trim }} +{% endif %} + +{%- if attribute.requirement_level == "required" %} +- Requirement Level: Required + {%- elif attribute.requirement_level.conditionally_required %} +- Requirement Level: Conditionally Required - {{ attribute.requirement_level.conditionally_required }} + {%- elif attribute.requirement_level == "recommended" %} +- Requirement Level: Recommended + {%- else %} +- Requirement Level: Optional + {%- endif %} + {% if attribute.tag %} +- Tag: {{ attribute.tag }} + {% endif %} + {%- include "attribute_type.j2" %} + {%- include "examples.j2" -%} + {%- if attribute.sampling_relevant %} +- Sampling relevant: {{ attribute.sampling_relevant }} + {%- endif %} + {%- if attribute.deprecated %} +- Deprecated: {{ attribute.deprecated }} + {%- endif %} + {% if attribute.stability %} +- Stability: {{ attribute.stability | capitalize }} + {% endif %} + {% endfor %} + {% endfor %} diff --git a/crates/weaver_forge/templates/test/examples.j2 b/crates/weaver_forge/templates/test/examples.j2 new file mode 100644 index 00000000..337fc479 --- /dev/null +++ b/crates/weaver_forge/templates/test/examples.j2 @@ -0,0 +1,7 @@ +{%- if attribute.examples %} +{%- if attribute.examples is sequence %} +- Examples: {{ attribute.examples | pprint }} +{%- else %} +- Examples: {{ attribute.examples }} +{%- endif %} +{%- endif %} diff --git a/crates/weaver_forge/templates/test/group.md b/crates/weaver_forge/templates/test/group.md index 0013daab..c58c8e3c 100644 --- a/crates/weaver_forge/templates/test/group.md +++ b/crates/weaver_forge/templates/test/group.md @@ -1,42 +1,54 @@ {%- set file_name = group.id | file_name -%} {{- template.set_file_name("group/" ~ file_name ~ ".md") -}} -# {{ group.type }} `{{ group.id }}` +# Group `{{ group.id }}` ({{ group.type }}) ## Brief -{{ group.brief }} -## Attributes +{{ group.brief | trim }} -{% for attribute in group.attributes -%} -### Attribute `{{ attribute.name }}` +prefix: {{ group.prefix }} -Requirement level: {{ attribute.requirement_level }} +## Attributes -{% if attribute.tag -%} -Tag: {{ attribute.tag }} -{%- endif %} +{% for attribute in group.attributes %} +### Attribute `{{ attribute.name }}` -Brief: {{ attribute.brief }} +{{ attribute.brief }} -Type: {{ attribute.type }} +{% if attribute.note %} +{{ attribute.note | trim }} +{% endif %} -{% if attribute.note -%} -Note: {{ attribute.note }} +{%- if attribute.requirement_level == "required" %} +- Requirement Level: Required +{%- elif attribute.requirement_level.conditionally_required %} +- Requirement Level: Conditionally Required - {{ attribute.requirement_level.conditionally_required }} +{%- elif attribute.requirement_level == "recommended" %} +- Requirement Level: Recommended +{%- else %} +- Requirement Level: Optional {%- endif %} - -{% if attribute.stability -%} -Stability: {{ attribute.stability }} +{% if attribute.tag %} +- Tag: {{ attribute.tag }} +{% endif %} +{%- include "attribute_type.j2" %} +{%- include "examples.j2" -%} +{%- if attribute.sampling_relevant %} +- Sampling relevant: {{ attribute.sampling_relevant }} +{%- endif %} +{%- if attribute.deprecated %} +- Deprecated: {{ attribute.deprecated }} {%- endif %} +{% if attribute.stability %} +- Stability: {{ attribute.stability | capitalize }} +{% endif %} {% endfor %} ## Provenance Source: {{ group.lineage.provenance }} -{{ debug() }} - -{%- for item in group.lineage.attributes -%} +{% for item in group.lineage.attributes -%} item: {{ group.lineage.attributes[item] }} -{% endfor -%} - +{% endfor -%} \ No newline at end of file diff --git a/crates/weaver_forge/templates/test/groups.md b/crates/weaver_forge/templates/test/groups.md index e69de29b..3e8188f9 100644 --- a/crates/weaver_forge/templates/test/groups.md +++ b/crates/weaver_forge/templates/test/groups.md @@ -0,0 +1,47 @@ +# Semantic Convention Groups + +{% for group in groups %} +## Group `{{ group.id }}` ({{ group.type }}) + +### Brief + +{{ group.brief | trim }} + +prefix: {{ group.prefix }} + +### Attributes + +{% for attribute in group.attributes %} +#### Attribute `{{ attribute.name }}` + +{{ attribute.brief }} + +{% if attribute.note %} +{{ attribute.note | trim }} +{% endif %} + +{%- if attribute.requirement_level == "required" %} +- Requirement Level: Required + {%- elif attribute.requirement_level.conditionally_required %} +- Requirement Level: Conditionally Required - {{ attribute.requirement_level.conditionally_required }} + {%- elif attribute.requirement_level == "recommended" %} +- Requirement Level: Recommended + {%- else %} +- Requirement Level: Optional + {%- endif %} + {% if attribute.tag %} +- Tag: {{ attribute.tag }} + {% endif %} + {%- include "attribute_type.j2" %} + {%- include "examples.j2" -%} + {%- if attribute.sampling_relevant %} +- Sampling relevant: {{ attribute.sampling_relevant }} + {%- endif %} + {%- if attribute.deprecated %} +- Deprecated: {{ attribute.deprecated }} + {%- endif %} + {% if attribute.stability %} +- Stability: {{ attribute.stability | capitalize }} + {% endif %} + {% endfor %} +{% endfor %} diff --git a/crates/weaver_forge/templates/test/metric.md b/crates/weaver_forge/templates/test/metric.md index e69de29b..fc58ca10 100644 --- a/crates/weaver_forge/templates/test/metric.md +++ b/crates/weaver_forge/templates/test/metric.md @@ -0,0 +1,52 @@ +{%- set file_name = group.id | file_name -%} +{{- template.set_file_name("metric/" ~ file_name ~ ".md") -}} + +## Group `{{ group.id }}` ({{ group.type }}) + +### Brief + +{{ group.brief | trim }} + +{{ group.note | trim }} + +Prefix: {{ group.prefix }} +Metric: {{ group.metric_name }} +Instrument: {{ group.instrument }} +Unit: {{ group.unit }} +Stability: {{ group.stability | capitalize }} + +### Attributes + +{% for attribute in group.attributes %} +#### Attribute `{{ attribute.name }}` + +{{ attribute.brief }} + +{% if attribute.note %} +{{ attribute.note | trim }} +{% endif %} + +{%- if attribute.requirement_level == "required" %} +- Requirement Level: Required + {%- elif attribute.requirement_level.conditionally_required %} +- Requirement Level: Conditionally Required - {{ attribute.requirement_level.conditionally_required }} + {%- elif attribute.requirement_level == "recommended" %} +- Requirement Level: Recommended + {%- else %} +- Requirement Level: Optional + {%- endif %} + {% if attribute.tag %} +- Tag: {{ attribute.tag }} + {% endif %} + {%- include "attribute_type.j2" %} + {%- include "examples.j2" -%} + {%- if attribute.sampling_relevant %} +- Sampling relevant: {{ attribute.sampling_relevant }} + {%- endif %} + {%- if attribute.deprecated %} +- Deprecated: {{ attribute.deprecated }} + {%- endif %} + {% if attribute.stability %} +- Stability: {{ attribute.stability | capitalize }} + {% endif %} + {% endfor %} diff --git a/crates/weaver_forge/templates/test/metric_groups.md b/crates/weaver_forge/templates/test/metric_groups.md new file mode 100644 index 00000000..6e721a57 --- /dev/null +++ b/crates/weaver_forge/templates/test/metric_groups.md @@ -0,0 +1,47 @@ +# Semantic Convention Metric Group Groups + +{% for group in groups %} +## Group `{{ group.id }}` ({{ group.type }}) + +### Brief + +{{ group.brief | trim }} + +prefix: {{ group.prefix }} + +### Attributes + +{% for attribute in group.attributes %} +#### Attribute `{{ attribute.name }}` + +{{ attribute.brief }} + +{% if attribute.note %} +{{ attribute.note | trim }} +{% endif %} + +{%- if attribute.requirement_level == "required" %} +- Requirement Level: Required + {%- elif attribute.requirement_level.conditionally_required %} +- Requirement Level: Conditionally Required - {{ attribute.requirement_level.conditionally_required }} + {%- elif attribute.requirement_level == "recommended" %} +- Requirement Level: Recommended + {%- else %} +- Requirement Level: Optional + {%- endif %} + {% if attribute.tag %} +- Tag: {{ attribute.tag }} + {% endif %} + {%- include "attribute_type.j2" %} + {%- include "examples.j2" -%} + {%- if attribute.sampling_relevant %} +- Sampling relevant: {{ attribute.sampling_relevant }} + {%- endif %} + {%- if attribute.deprecated %} +- Deprecated: {{ attribute.deprecated }} + {%- endif %} + {% if attribute.stability %} +- Stability: {{ attribute.stability | capitalize }} + {% endif %} + {% endfor %} + {% endfor %} diff --git a/crates/weaver_forge/templates/test/metrics.md b/crates/weaver_forge/templates/test/metrics.md new file mode 100644 index 00000000..df460b78 --- /dev/null +++ b/crates/weaver_forge/templates/test/metrics.md @@ -0,0 +1,53 @@ +# Semantic Convention Metric Groups + +{% for group in groups %} +## Group `{{ group.id }}` ({{ group.type }}) + +### Brief + +{{ group.brief | trim }} + +{{ group.note | trim }} + +Prefix: {{ group.prefix }} +Metric: {{ group.metric_name }} +Instrument: {{ group.instrument }} +Unit: {{ group.unit }} +Stability: {{ group.stability | capitalize }} + +### Attributes + +{% for attribute in group.attributes %} +#### Attribute `{{ attribute.name }}` + +{{ attribute.brief }} + +{% if attribute.note %} +{{ attribute.note | trim }} +{% endif %} + +{%- if attribute.requirement_level == "required" %} +- Requirement Level: Required + {%- elif attribute.requirement_level.conditionally_required %} +- Requirement Level: Conditionally Required - {{ attribute.requirement_level.conditionally_required }} + {%- elif attribute.requirement_level == "recommended" %} +- Requirement Level: Recommended + {%- else %} +- Requirement Level: Optional + {%- endif %} + {% if attribute.tag %} +- Tag: {{ attribute.tag }} + {% endif %} + {%- include "attribute_type.j2" %} + {%- include "examples.j2" -%} + {%- if attribute.sampling_relevant %} +- Sampling relevant: {{ attribute.sampling_relevant }} + {%- endif %} + {%- if attribute.deprecated %} +- Deprecated: {{ attribute.deprecated }} + {%- endif %} + {% if attribute.stability %} +- Stability: {{ attribute.stability | capitalize }} + {% endif %} + {% endfor %} + {% endfor %} diff --git a/crates/weaver_forge/templates/test/registry.md b/crates/weaver_forge/templates/test/registry.md index be6e4d0c..e1c26c56 100644 --- a/crates/weaver_forge/templates/test/registry.md +++ b/crates/weaver_forge/templates/test/registry.md @@ -1,3 +1,52 @@ # Semantic Convention Registry -url: {{ registry_url }} \ No newline at end of file +Url: {{ registry_url }} + +# Attribute Groups +{% for group in registry.groups -%} +{%- if group.type == "attribute_group" %} +- [{{ group.id }}](attribute_group/{{ group.id | file_name }}.md) +{%- endif %} +{%- endfor %} + +# Events +{% for group in registry.groups -%} +{%- if group.type == "event" %} +- [{{ group.id }}](event/{{ group.id | file_name }}.md) + {%- endif %} + {%- endfor %} + +# Metrics +{% for group in registry.groups -%} +{%- if group.type == "metric" %} +- [{{ group.id }}](metric/{{ group.id | file_name }}.md) +{%- endif %} +{%- endfor %} + +# Metric Groups +{% for group in registry.groups -%} +{%- if group.type == "metric_group" %} +- [{{ group.id }}](metric_group/{{ group.id | file_name }}.md) + {%- endif %} + {%- endfor %} + +# Resource +{% for group in registry.groups -%} +{%- if group.type == "resource" %} +- [{{ group.id }}](resource/{{ group.id | file_name }}.md) + {%- endif %} + {%- endfor %} + +# Scope +{% for group in registry.groups -%} +{%- if group.type == "scope" %} +- [{{ group.id }}](scope/{{ group.id | file_name }}.md) + {%- endif %} + {%- endfor %} + +# Span +{% for group in registry.groups -%} +{%- if group.type == "span" %} +- [{{ group.id }}](span/{{ group.id | file_name }}.md) + {%- endif %} + {%- endfor %} \ No newline at end of file diff --git a/crates/weaver_forge/templates/test/resource.md b/crates/weaver_forge/templates/test/resource.md index e69de29b..391d364b 100644 --- a/crates/weaver_forge/templates/test/resource.md +++ b/crates/weaver_forge/templates/test/resource.md @@ -0,0 +1,46 @@ +{%- set file_name = group.id | file_name -%} +{{- template.set_file_name("resource/" ~ file_name ~ ".md") -}} + +## Group `{{ group.id }}` ({{ group.type }}) + +### Brief + +{{ group.brief | trim }} + +prefix: {{ group.prefix }} + +### Attributes + +{% for attribute in group.attributes %} +#### Attribute `{{ attribute.name }}` + +{{ attribute.brief }} + +{% if attribute.note %} +{{ attribute.note | trim }} +{% endif %} + +{%- if attribute.requirement_level == "required" %} +- Requirement Level: Required + {%- elif attribute.requirement_level.conditionally_required %} +- Requirement Level: Conditionally Required - {{ attribute.requirement_level.conditionally_required }} + {%- elif attribute.requirement_level == "recommended" %} +- Requirement Level: Recommended + {%- else %} +- Requirement Level: Optional + {%- endif %} + {% if attribute.tag %} +- Tag: {{ attribute.tag }} + {% endif %} + {%- include "attribute_type.j2" %} + {%- include "examples.j2" -%} + {%- if attribute.sampling_relevant %} +- Sampling relevant: {{ attribute.sampling_relevant }} + {%- endif %} + {%- if attribute.deprecated %} +- Deprecated: {{ attribute.deprecated }} + {%- endif %} + {% if attribute.stability %} +- Stability: {{ attribute.stability | capitalize }} + {% endif %} + {% endfor %} diff --git a/crates/weaver_forge/templates/test/resources.md b/crates/weaver_forge/templates/test/resources.md new file mode 100644 index 00000000..8a33dfbc --- /dev/null +++ b/crates/weaver_forge/templates/test/resources.md @@ -0,0 +1,47 @@ +# Semantic Convention Resource Groups + +{% for group in groups %} +## Group `{{ group.id }}` ({{ group.type }}) + +### Brief + +{{ group.brief | trim }} + +prefix: {{ group.prefix }} + +### Attributes + +{% for attribute in group.attributes %} +#### Attribute `{{ attribute.name }}` + +{{ attribute.brief }} + +{% if attribute.note %} +{{ attribute.note | trim }} +{% endif %} + +{%- if attribute.requirement_level == "required" %} +- Requirement Level: Required + {%- elif attribute.requirement_level.conditionally_required %} +- Requirement Level: Conditionally Required - {{ attribute.requirement_level.conditionally_required }} + {%- elif attribute.requirement_level == "recommended" %} +- Requirement Level: Recommended + {%- else %} +- Requirement Level: Optional + {%- endif %} + {% if attribute.tag %} +- Tag: {{ attribute.tag }} + {% endif %} + {%- include "attribute_type.j2" %} + {%- include "examples.j2" -%} + {%- if attribute.sampling_relevant %} +- Sampling relevant: {{ attribute.sampling_relevant }} + {%- endif %} + {%- if attribute.deprecated %} +- Deprecated: {{ attribute.deprecated }} + {%- endif %} + {% if attribute.stability %} +- Stability: {{ attribute.stability | capitalize }} + {% endif %} + {% endfor %} + {% endfor %} \ No newline at end of file diff --git a/crates/weaver_forge/templates/test/span.md b/crates/weaver_forge/templates/test/span.md index e093a54d..432bc8e9 100644 --- a/crates/weaver_forge/templates/test/span.md +++ b/crates/weaver_forge/templates/test/span.md @@ -1 +1,49 @@ -# Span `{{ id }}` \ No newline at end of file +{%- set file_name = group.id | file_name -%} +{{- template.set_file_name("span/" ~ file_name ~ ".md") -}} + +## Group `{{ group.id }}` ({{ group.type }}) + +### Brief + +{{ group.brief | trim }} + +{{ group.note | trim }} + +Prefix: {{ group.prefix }} +Kind: {{ group.span_kind }} + +### Attributes + +{% for attribute in group.attributes %} +#### Attribute `{{ attribute.name }}` + +{{ attribute.brief }} + +{% if attribute.note %} +{{ attribute.note | trim }} +{% endif %} + +{%- if attribute.requirement_level == "required" %} +- Requirement Level: Required + {%- elif attribute.requirement_level.conditionally_required %} +- Requirement Level: Conditionally Required - {{ attribute.requirement_level.conditionally_required }} + {%- elif attribute.requirement_level == "recommended" %} +- Requirement Level: Recommended + {%- else %} +- Requirement Level: Optional + {%- endif %} + {% if attribute.tag %} +- Tag: {{ attribute.tag }} + {% endif %} + {%- include "attribute_type.j2" %} + {%- include "examples.j2" -%} + {%- if attribute.sampling_relevant %} +- Sampling relevant: {{ attribute.sampling_relevant }} + {%- endif %} + {%- if attribute.deprecated %} +- Deprecated: {{ attribute.deprecated }} + {%- endif %} + {% if attribute.stability %} +- Stability: {{ attribute.stability | capitalize }} + {% endif %} + {% endfor %} \ No newline at end of file diff --git a/crates/weaver_forge/templates/test/spans.md b/crates/weaver_forge/templates/test/spans.md index e69de29b..ebe2f969 100644 --- a/crates/weaver_forge/templates/test/spans.md +++ b/crates/weaver_forge/templates/test/spans.md @@ -0,0 +1,50 @@ +# Semantic Convention Span Groups + +{% for group in groups %} +## Group `{{ group.id }}` ({{ group.type }}) + +### Brief + +{{ group.brief | trim }} + +{{ group.note | trim }} + +Prefix: {{ group.prefix }} +Kind: {{ group.span_kind }} + +### Attributes + +{% for attribute in group.attributes %} +#### Attribute `{{ attribute.name }}` + +{{ attribute.brief }} + +{% if attribute.note %} +{{ attribute.note | trim }} +{% endif %} + +{%- if attribute.requirement_level == "required" %} +- Requirement Level: Required + {%- elif attribute.requirement_level.conditionally_required %} +- Requirement Level: Conditionally Required - {{ attribute.requirement_level.conditionally_required }} + {%- elif attribute.requirement_level == "recommended" %} +- Requirement Level: Recommended + {%- else %} +- Requirement Level: Optional + {%- endif %} + {% if attribute.tag %} +- Tag: {{ attribute.tag }} + {% endif %} + {%- include "attribute_type.j2" %} + {%- include "examples.j2" -%} + {%- if attribute.sampling_relevant %} +- Sampling relevant: {{ attribute.sampling_relevant }} + {%- endif %} + {%- if attribute.deprecated %} +- Deprecated: {{ attribute.deprecated }} + {%- endif %} + {% if attribute.stability %} +- Stability: {{ attribute.stability | capitalize }} + {% endif %} + {% endfor %} + {% endfor %} \ No newline at end of file From 43e8e18910579f3c2736ea185fc0ca32cfde594c Mon Sep 17 00:00:00 2001 From: Laurent Querel Date: Wed, 6 Mar 2024 23:20:54 -0800 Subject: [PATCH 16/20] feature(registry): add unit test to check the generated markdown --- Cargo.lock | 5 +- Cargo.toml | 1 + crates/weaver_forge/Cargo.toml | 1 + .../attribute_group/attributes_jvm_memory.md | 46 + .../attribute_group/registry_db.md | 473 ++ .../attribute_group/registry_http.md | 181 + .../attribute_group/registry_network.md | 227 + .../attribute_group/registry_url.md | 95 + .../attribute_group/registry_user_agent.md | 28 + .../expected_output/attribute_group/server.md | 49 + .../expected_output/attribute_groups.md | 1109 ++++ .../event/android_lifecycle_events.md | 27 + .../event/ios_lifecycle_events.md | 27 + crates/weaver_forge/expected_output/events.md | 59 + .../group/android_lifecycle_events.md | 31 + .../group/attributes_jvm_memory.md | 51 + .../weaver_forge/expected_output/group/db.md | 283 + .../expected_output/group/db_cassandra.md | 411 ++ .../expected_output/group/db_cosmosdb.md | 423 ++ .../expected_output/group/db_couchdb.md | 302 + .../expected_output/group/db_elasticsearch.md | 474 ++ .../expected_output/group/db_hbase.md | 302 + .../expected_output/group/db_mongodb.md | 301 + .../expected_output/group/db_mssql.md | 300 + .../expected_output/group/db_redis.md | 321 + .../expected_output/group/db_sql.md | 302 + .../expected_output/group/db_tech.md | 591 ++ .../group/ios_lifecycle_events.md | 31 + .../group/metric_jvm_class_count.md | 16 + .../group/metric_jvm_class_loaded.md | 16 + .../group/metric_jvm_class_unloaded.md | 16 + .../group/metric_jvm_cpu_count.md | 16 + .../metric_jvm_cpu_recent_utilization.md | 16 + .../group/metric_jvm_cpu_time.md | 16 + .../group/metric_jvm_gc_duration.md | 52 + .../group/metric_jvm_memory_committed.md | 53 + .../group/metric_jvm_memory_limit.md | 53 + .../group/metric_jvm_memory_used.md | 53 + .../metric_jvm_memory_used_after_last_gc.md | 53 + .../group/metric_jvm_thread_count.md | 44 + .../expected_output/group/otel_library.md | 44 + .../expected_output/group/otel_scope.md | 46 + .../expected_output/group/registry_db.md | 478 ++ .../expected_output/group/registry_http.md | 186 + .../expected_output/group/registry_network.md | 232 + .../expected_output/group/registry_url.md | 100 + .../group/registry_user_agent.md | 33 + .../expected_output/group/server.md | 54 + crates/weaver_forge/expected_output/groups.md | 5385 +++++++++++++++++ .../metric/metric_jvm_class_count.md | 16 + .../metric/metric_jvm_class_loaded.md | 16 + .../metric/metric_jvm_class_unloaded.md | 16 + .../metric/metric_jvm_cpu_count.md | 16 + .../metric_jvm_cpu_recent_utilization.md | 16 + .../metric/metric_jvm_cpu_time.md | 16 + .../metric/metric_jvm_gc_duration.md | 53 + .../metric/metric_jvm_memory_committed.md | 52 + .../metric/metric_jvm_memory_limit.md | 52 + .../metric/metric_jvm_memory_used.md | 52 + .../metric_jvm_memory_used_after_last_gc.md | 52 + .../metric/metric_jvm_thread_count.md | 45 + .../expected_output/metric_groups.md | 2 + .../weaver_forge/expected_output/metrics.md | 423 ++ .../weaver_forge/expected_output/registry.md | 58 + .../expected_output/resource/otel_library.md | 39 + .../expected_output/resource/otel_scope.md | 41 + .../weaver_forge/expected_output/resources.md | 85 + .../weaver_forge/expected_output/span/db.md | 267 + .../expected_output/span/db_cassandra.md | 387 ++ .../expected_output/span/db_cosmosdb.md | 398 ++ .../expected_output/span/db_couchdb.md | 285 + .../expected_output/span/db_elasticsearch.md | 449 ++ .../expected_output/span/db_hbase.md | 285 + .../expected_output/span/db_mongodb.md | 284 + .../expected_output/span/db_mssql.md | 283 + .../expected_output/span/db_redis.md | 303 + .../expected_output/span/db_sql.md | 285 + .../expected_output/span/db_tech.md | 589 ++ crates/weaver_forge/expected_output/spans.md | 3829 ++++++++++++ .../weaver_forge/src/extensions/attributes.rs | 9 - crates/weaver_forge/src/extensions/mod.rs | 1 - crates/weaver_forge/src/lib.rs | 58 +- crates/weaver_resolver/Cargo.toml | 2 +- 83 files changed, 22156 insertions(+), 21 deletions(-) create mode 100644 crates/weaver_forge/expected_output/attribute_group/attributes_jvm_memory.md create mode 100644 crates/weaver_forge/expected_output/attribute_group/registry_db.md create mode 100644 crates/weaver_forge/expected_output/attribute_group/registry_http.md create mode 100644 crates/weaver_forge/expected_output/attribute_group/registry_network.md create mode 100644 crates/weaver_forge/expected_output/attribute_group/registry_url.md create mode 100644 crates/weaver_forge/expected_output/attribute_group/registry_user_agent.md create mode 100644 crates/weaver_forge/expected_output/attribute_group/server.md create mode 100644 crates/weaver_forge/expected_output/attribute_groups.md create mode 100644 crates/weaver_forge/expected_output/event/android_lifecycle_events.md create mode 100644 crates/weaver_forge/expected_output/event/ios_lifecycle_events.md create mode 100644 crates/weaver_forge/expected_output/events.md create mode 100644 crates/weaver_forge/expected_output/group/android_lifecycle_events.md create mode 100644 crates/weaver_forge/expected_output/group/attributes_jvm_memory.md create mode 100644 crates/weaver_forge/expected_output/group/db.md create mode 100644 crates/weaver_forge/expected_output/group/db_cassandra.md create mode 100644 crates/weaver_forge/expected_output/group/db_cosmosdb.md create mode 100644 crates/weaver_forge/expected_output/group/db_couchdb.md create mode 100644 crates/weaver_forge/expected_output/group/db_elasticsearch.md create mode 100644 crates/weaver_forge/expected_output/group/db_hbase.md create mode 100644 crates/weaver_forge/expected_output/group/db_mongodb.md create mode 100644 crates/weaver_forge/expected_output/group/db_mssql.md create mode 100644 crates/weaver_forge/expected_output/group/db_redis.md create mode 100644 crates/weaver_forge/expected_output/group/db_sql.md create mode 100644 crates/weaver_forge/expected_output/group/db_tech.md create mode 100644 crates/weaver_forge/expected_output/group/ios_lifecycle_events.md create mode 100644 crates/weaver_forge/expected_output/group/metric_jvm_class_count.md create mode 100644 crates/weaver_forge/expected_output/group/metric_jvm_class_loaded.md create mode 100644 crates/weaver_forge/expected_output/group/metric_jvm_class_unloaded.md create mode 100644 crates/weaver_forge/expected_output/group/metric_jvm_cpu_count.md create mode 100644 crates/weaver_forge/expected_output/group/metric_jvm_cpu_recent_utilization.md create mode 100644 crates/weaver_forge/expected_output/group/metric_jvm_cpu_time.md create mode 100644 crates/weaver_forge/expected_output/group/metric_jvm_gc_duration.md create mode 100644 crates/weaver_forge/expected_output/group/metric_jvm_memory_committed.md create mode 100644 crates/weaver_forge/expected_output/group/metric_jvm_memory_limit.md create mode 100644 crates/weaver_forge/expected_output/group/metric_jvm_memory_used.md create mode 100644 crates/weaver_forge/expected_output/group/metric_jvm_memory_used_after_last_gc.md create mode 100644 crates/weaver_forge/expected_output/group/metric_jvm_thread_count.md create mode 100644 crates/weaver_forge/expected_output/group/otel_library.md create mode 100644 crates/weaver_forge/expected_output/group/otel_scope.md create mode 100644 crates/weaver_forge/expected_output/group/registry_db.md create mode 100644 crates/weaver_forge/expected_output/group/registry_http.md create mode 100644 crates/weaver_forge/expected_output/group/registry_network.md create mode 100644 crates/weaver_forge/expected_output/group/registry_url.md create mode 100644 crates/weaver_forge/expected_output/group/registry_user_agent.md create mode 100644 crates/weaver_forge/expected_output/group/server.md create mode 100644 crates/weaver_forge/expected_output/groups.md create mode 100644 crates/weaver_forge/expected_output/metric/metric_jvm_class_count.md create mode 100644 crates/weaver_forge/expected_output/metric/metric_jvm_class_loaded.md create mode 100644 crates/weaver_forge/expected_output/metric/metric_jvm_class_unloaded.md create mode 100644 crates/weaver_forge/expected_output/metric/metric_jvm_cpu_count.md create mode 100644 crates/weaver_forge/expected_output/metric/metric_jvm_cpu_recent_utilization.md create mode 100644 crates/weaver_forge/expected_output/metric/metric_jvm_cpu_time.md create mode 100644 crates/weaver_forge/expected_output/metric/metric_jvm_gc_duration.md create mode 100644 crates/weaver_forge/expected_output/metric/metric_jvm_memory_committed.md create mode 100644 crates/weaver_forge/expected_output/metric/metric_jvm_memory_limit.md create mode 100644 crates/weaver_forge/expected_output/metric/metric_jvm_memory_used.md create mode 100644 crates/weaver_forge/expected_output/metric/metric_jvm_memory_used_after_last_gc.md create mode 100644 crates/weaver_forge/expected_output/metric/metric_jvm_thread_count.md create mode 100644 crates/weaver_forge/expected_output/metric_groups.md create mode 100644 crates/weaver_forge/expected_output/metrics.md create mode 100644 crates/weaver_forge/expected_output/registry.md create mode 100644 crates/weaver_forge/expected_output/resource/otel_library.md create mode 100644 crates/weaver_forge/expected_output/resource/otel_scope.md create mode 100644 crates/weaver_forge/expected_output/resources.md create mode 100644 crates/weaver_forge/expected_output/span/db.md create mode 100644 crates/weaver_forge/expected_output/span/db_cassandra.md create mode 100644 crates/weaver_forge/expected_output/span/db_cosmosdb.md create mode 100644 crates/weaver_forge/expected_output/span/db_couchdb.md create mode 100644 crates/weaver_forge/expected_output/span/db_elasticsearch.md create mode 100644 crates/weaver_forge/expected_output/span/db_hbase.md create mode 100644 crates/weaver_forge/expected_output/span/db_mongodb.md create mode 100644 crates/weaver_forge/expected_output/span/db_mssql.md create mode 100644 crates/weaver_forge/expected_output/span/db_redis.md create mode 100644 crates/weaver_forge/expected_output/span/db_sql.md create mode 100644 crates/weaver_forge/expected_output/span/db_tech.md create mode 100644 crates/weaver_forge/expected_output/spans.md delete mode 100644 crates/weaver_forge/src/extensions/attributes.rs diff --git a/Cargo.lock b/Cargo.lock index eeb75f73..175ac67b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -248,9 +248,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.89" +version = "1.0.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0ba8f7aaa012f30d5b2861462f6708eccd49c3c39863fe083a308035f63d723" +checksum = "8cd6604a82acf3039f1144f54b8eb34e91ffba622051189e71b781822d5ee1f5" dependencies = [ "jobserver", "libc", @@ -3832,6 +3832,7 @@ dependencies = [ "serde_json", "serde_yaml", "thiserror", + "walkdir", "weaver_logger", "weaver_resolved_schema", "weaver_resolver", diff --git a/Cargo.toml b/Cargo.toml index 7117baa7..709dd388 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,6 +33,7 @@ ureq = "2.9.6" regex = "1.10.3" rayon = "1.8.1" ordered-float = { version = "4.2.0", features = ["serde"] } +walkdir = "2.5.0" # Features definition ========================================================= [features] diff --git a/crates/weaver_forge/Cargo.toml b/crates/weaver_forge/Cargo.toml index 2374c17d..733a8bd6 100644 --- a/crates/weaver_forge/Cargo.toml +++ b/crates/weaver_forge/Cargo.toml @@ -22,4 +22,5 @@ serde.workspace = true serde_yaml.workspace = true serde_json.workspace = true rayon.workspace = true +walkdir.workspace = true diff --git a/crates/weaver_forge/expected_output/attribute_group/attributes_jvm_memory.md b/crates/weaver_forge/expected_output/attribute_group/attributes_jvm_memory.md new file mode 100644 index 00000000..9efa5f68 --- /dev/null +++ b/crates/weaver_forge/expected_output/attribute_group/attributes_jvm_memory.md @@ -0,0 +1,46 @@ +## Group `attributes.jvm.memory` (attribute_group) + +### Brief + +Describes JVM memory metric attributes. + +prefix: jvm.memory + +### Attributes + + +#### Attribute `jvm.memory.type` + +The type of memory. + + +- Requirement Level: Recommended + +- Type: Enum [heap, non_heap] +- Examples: [ + "heap", + "non_heap", +] + +- Stability: Stable + + +#### Attribute `jvm.memory.pool.name` + +Name of the memory pool. + + +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()). + +- Requirement Level: Recommended + +- Type: string +- Examples: [ + "G1 Old Gen", + "G1 Eden space", + "G1 Survivor Space", +] + +- Stability: Stable + + \ No newline at end of file diff --git a/crates/weaver_forge/expected_output/attribute_group/registry_db.md b/crates/weaver_forge/expected_output/attribute_group/registry_db.md new file mode 100644 index 00000000..c01af75e --- /dev/null +++ b/crates/weaver_forge/expected_output/attribute_group/registry_db.md @@ -0,0 +1,473 @@ +## Group `registry.db` (attribute_group) + +### Brief + +This document defines the attributes used to describe telemetry in the context of databases. + +prefix: db + +### Attributes + + +#### Attribute `db.cassandra.coordinator.dc` + +The data center of the coordinating node for a query. + + + +- Requirement Level: Recommended + +- Tag: tech-specific-cassandra + +- Type: string +- Examples: us-west-2 + + +#### Attribute `db.cassandra.coordinator.id` + +The ID of the coordinating node for a query. + + + +- Requirement Level: Recommended + +- Tag: tech-specific-cassandra + +- Type: string +- Examples: be13faa2-8574-4d71-926d-27f16cf8a7af + + +#### Attribute `db.cassandra.consistency_level` + +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). + + + +- Requirement Level: Recommended + +- Tag: tech-specific-cassandra + +- Type: Enum [all, each_quorum, quorum, local_quorum, one, two, three, local_one, any, serial, local_serial] + + +#### Attribute `db.cassandra.idempotence` + +Whether or not the query is idempotent. + + + +- Requirement Level: Recommended + +- Tag: tech-specific-cassandra + +- Type: boolean + + +#### Attribute `db.cassandra.page_size` + +The fetch size used for paging, i.e. how many rows will be returned at once. + + + +- Requirement Level: Recommended + +- Tag: tech-specific-cassandra + +- Type: int +- Examples: [ + 5000, +] + + +#### Attribute `db.cassandra.speculative_execution_count` + +The number of times a query was speculatively executed. Not set or `0` if the query was not executed speculatively. + + + +- Requirement Level: Recommended + +- Tag: tech-specific-cassandra + +- Type: int +- Examples: [ + 0, + 2, +] + + +#### Attribute `db.cassandra.table` + +The name of the primary Cassandra table that the operation is acting upon, including the keyspace name (if applicable). + + +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. + +- Requirement Level: Recommended + +- Tag: tech-specific-cassandra + +- Type: string +- Examples: mytable + + +#### Attribute `db.connection_string` + +The connection string used to connect to the database. It is recommended to remove embedded credentials. + + + +- Requirement Level: Recommended + +- Tag: db-generic + +- Type: string +- Examples: Server=(localdb)\v11.0;Integrated Security=true; + + +#### Attribute `db.cosmosdb.client_id` + +Unique Cosmos client instance id. + + +- Requirement Level: Recommended + +- Tag: tech-specific-cosmosdb + +- Type: string +- Examples: 3ba4827d-4422-483f-b59f-85b74211c11d + + +#### Attribute `db.cosmosdb.connection_mode` + +Cosmos client connection mode. + + +- Requirement Level: Recommended + +- Tag: tech-specific-cosmosdb + +- Type: Enum [gateway, direct] + + +#### Attribute `db.cosmosdb.container` + +Cosmos DB container name. + + +- Requirement Level: Recommended + +- Tag: tech-specific-cosmosdb + +- Type: string +- Examples: anystring + + +#### Attribute `db.cosmosdb.operation_type` + +CosmosDB Operation Type. + + +- Requirement Level: Recommended + +- Tag: tech-specific-cosmosdb + +- Type: Enum [Invalid, Create, Patch, Read, ReadFeed, Delete, Replace, Execute, Query, Head, HeadFeed, Upsert, Batch, QueryPlan, ExecuteJavaScript] + + +#### Attribute `db.cosmosdb.request_charge` + +RU consumed for that operation + + +- Requirement Level: Recommended + +- Tag: tech-specific-cosmosdb + +- Type: double +- Examples: [ + 46.18, + 1.0, +] + + +#### Attribute `db.cosmosdb.request_content_length` + +Request payload size in bytes + + +- Requirement Level: Recommended + +- Tag: tech-specific-cosmosdb + +- Type: int + + +#### Attribute `db.cosmosdb.status_code` + +Cosmos DB status code. + + +- Requirement Level: Recommended + +- Tag: tech-specific-cosmosdb + +- Type: int +- Examples: [ + 200, + 201, +] + + +#### Attribute `db.cosmosdb.sub_status_code` + +Cosmos DB sub status code. + + +- Requirement Level: Recommended + +- Tag: tech-specific-cosmosdb + +- Type: int +- Examples: [ + 1000, + 1002, +] + + +#### Attribute `db.elasticsearch.cluster.name` + +Represents the identifier of an Elasticsearch cluster. + + + +- Requirement Level: Recommended + +- Tag: tech-specific-elasticsearch + +- Type: string +- Examples: [ + "e9106fc68e3044f0b1475b04bf4ffd5f", +] + + +#### Attribute `db.elasticsearch.node.name` + +Represents the human-readable identifier of the node/instance to which a request was routed. + + + +- Requirement Level: Recommended + +- Tag: tech-specific-elasticsearch + +- Type: string +- Examples: [ + "instance-0000000001", +] + + +#### Attribute `db.elasticsearch.path_parts` + +A dynamic value in the url path. + + + +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. + +- Requirement Level: Recommended + +- Tag: tech-specific-elasticsearch + +- Type: template[string] +- Examples: [ + "db.elasticsearch.path_parts.index=test-index", + "db.elasticsearch.path_parts.doc_id=123", +] + + +#### Attribute `db.jdbc.driver_classname` + +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. + + + +- Requirement Level: Recommended + +- Tag: tech-specific-jdbc + +- Type: string +- Examples: [ + "org.postgresql.Driver", + "com.microsoft.sqlserver.jdbc.SQLServerDriver", +] + + +#### Attribute `db.mongodb.collection` + +The MongoDB collection being accessed within the database stated in `db.name`. + + + +- Requirement Level: Recommended + +- Tag: tech-specific-mongodb + +- Type: string +- Examples: [ + "customers", + "products", +] + + +#### Attribute `db.mssql.instance_name` + +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. + + + +If setting a `db.mssql.instance_name`, `server.port` is no longer required (but still recommended if non-standard). + +- Requirement Level: Recommended + +- Tag: tech-specific-mssql + +- Type: string +- Examples: MSSQLSERVER + + +#### Attribute `db.name` + +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). + + + +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). + +- Requirement Level: Recommended + +- Tag: db-generic + +- Type: string +- Examples: [ + "customers", + "main", +] + + +#### Attribute `db.operation` + +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. + + + +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. + +- Requirement Level: Recommended + +- Tag: db-generic + +- Type: string +- Examples: [ + "findAndModify", + "HMSET", + "SELECT", +] + + +#### Attribute `db.redis.database_index` + +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. + + + +- Requirement Level: Recommended + +- Tag: tech-specific-redis + +- Type: int +- Examples: [ + 0, + 1, + 15, +] + + +#### Attribute `db.sql.table` + +The name of the primary table that the operation is acting upon, including the database name (if applicable). + + +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. + +- Requirement Level: Recommended + +- Tag: tech-specific-sql + +- Type: string +- Examples: [ + "public.users", + "customers", +] + + +#### Attribute `db.statement` + +The database statement being executed. + + + +- Requirement Level: Recommended + +- Tag: db-generic + +- Type: string +- Examples: [ + "SELECT * FROM wuser_table", + "SET mykey \"WuValue\"", +] + + +#### Attribute `db.system` + +An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. + + +- Requirement Level: Recommended + +- Tag: db-generic + +- Type: Enum [other_sql, mssql, mssqlcompact, mysql, oracle, db2, postgresql, redshift, hive, cloudscape, hsqldb, progress, maxdb, hanadb, ingres, firstsql, edb, cache, adabas, firebird, derby, filemaker, informix, instantdb, interbase, mariadb, netezza, pervasive, pointbase, sqlite, sybase, teradata, vertica, h2, coldfusion, cassandra, hbase, mongodb, redis, couchbase, couchdb, cosmosdb, dynamodb, neo4j, geode, elasticsearch, memcached, cockroachdb, opensearch, clickhouse, spanner, trino] + + +#### Attribute `db.user` + +Username for accessing the database. + + + +- Requirement Level: Recommended + +- Tag: db-generic + +- Type: string +- Examples: [ + "readonly_user", + "reporting_user", +] + + +#### Attribute `db.instance.id` + +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`. + + + +- Requirement Level: Recommended + +- Tag: db-generic + +- Type: string +- Examples: mysql-e26b99z.example.com + + \ No newline at end of file diff --git a/crates/weaver_forge/expected_output/attribute_group/registry_http.md b/crates/weaver_forge/expected_output/attribute_group/registry_http.md new file mode 100644 index 00000000..95315bcb --- /dev/null +++ b/crates/weaver_forge/expected_output/attribute_group/registry_http.md @@ -0,0 +1,181 @@ +## Group `registry.http` (attribute_group) + +### Brief + +This document defines semantic convention attributes in the HTTP namespace. + +prefix: http + +### Attributes + + +#### Attribute `http.request.body.size` + +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. + + + +- Requirement Level: Recommended + +- Type: int +- Examples: 3495 + +- Stability: Experimental + + +#### Attribute `http.request.header` + +HTTP request headers, `` being the normalized HTTP Header name (lowercase), the value being the header values. + + + +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. +The `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. +The 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. + +- Requirement Level: Recommended + +- Type: template[string[]] +- Examples: [ + "http.request.header.content-type=[\"application/json\"]", + "http.request.header.x-forwarded-for=[\"1.2.3.4\", \"1.2.3.5\"]", +] + +- Stability: Stable + + +#### Attribute `http.request.method` + +HTTP request method. + + +HTTP request method value SHOULD be "known" to the instrumentation. +By default, this convention defines "known" methods as the ones listed in [RFC9110](https://www.rfc-editor.org/rfc/rfc9110.html#name-methods) +and the PATCH method defined in [RFC5789](https://www.rfc-editor.org/rfc/rfc5789.html). + +If the HTTP request method is not known to instrumentation, it MUST set the `http.request.method` attribute to `_OTHER`. + +If the HTTP instrumentation could end up converting valid HTTP request methods to `_OTHER`, then it MUST provide a way to override +the list of known HTTP methods. If this override is done via environment variable, then the environment variable MUST be named +OTEL_INSTRUMENTATION_HTTP_KNOWN_METHODS and support a comma-separated list of case-sensitive known HTTP methods +(this list MUST be a full override of the default known method, it is not a list of known methods in addition to the defaults). + +HTTP method names are case-sensitive and `http.request.method` attribute value MUST match a known HTTP method name exactly. +Instrumentations for specific web frameworks that consider HTTP methods to be case insensitive, SHOULD populate a canonical equivalent. +Tracing instrumentations that do so, MUST also set `http.request.method_original` to the original value. + +- Requirement Level: Recommended + +- Type: Enum [CONNECT, DELETE, GET, HEAD, OPTIONS, PATCH, POST, PUT, TRACE, _OTHER] +- Examples: [ + "GET", + "POST", + "HEAD", +] + +- Stability: Stable + + +#### Attribute `http.request.method_original` + +Original HTTP method sent by the client in the request line. + + +- Requirement Level: Recommended + +- Type: string +- Examples: [ + "GeT", + "ACL", + "foo", +] + +- Stability: Stable + + +#### Attribute `http.request.resend_count` + +The ordinal number of request resending attempt (for any reason, including redirects). + + + +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). + +- Requirement Level: Recommended + +- Type: int +- Examples: 3 + +- Stability: Stable + + +#### Attribute `http.response.body.size` + +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. + + + +- Requirement Level: Recommended + +- Type: int +- Examples: 3495 + +- Stability: Experimental + + +#### Attribute `http.response.header` + +HTTP response headers, `` being the normalized HTTP Header name (lowercase), the value being the header values. + + + +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. +Users MAY explicitly configure instrumentations to capture them even though it is not recommended. +The 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. + +- Requirement Level: Recommended + +- Type: template[string[]] +- Examples: [ + "http.response.header.content-type=[\"application/json\"]", + "http.response.header.my-custom-header=[\"abc\", \"def\"]", +] + +- Stability: Stable + + +#### Attribute `http.response.status_code` + +[HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). + + +- Requirement Level: Recommended + +- Type: int +- Examples: [ + 200, +] + +- Stability: Stable + + +#### Attribute `http.route` + +The matched route, that is, the path template in the format used by the respective server framework. + + + +MUST NOT be populated when this is not supported by the HTTP server framework as the route attribute should have low-cardinality and the URI path can NOT substitute it. +SHOULD include the [application root](/docs/http/http-spans.md#http-server-definitions) if there is one. + +- Requirement Level: Recommended + +- Type: string +- Examples: [ + "/users/:userID?", + "{controller}/{action}/{id?}", +] + +- Stability: Stable + + \ No newline at end of file diff --git a/crates/weaver_forge/expected_output/attribute_group/registry_network.md b/crates/weaver_forge/expected_output/attribute_group/registry_network.md new file mode 100644 index 00000000..cf198ab4 --- /dev/null +++ b/crates/weaver_forge/expected_output/attribute_group/registry_network.md @@ -0,0 +1,227 @@ +## Group `registry.network` (attribute_group) + +### Brief + +These attributes may be used for any network related operation. + +prefix: network + +### Attributes + + +#### Attribute `network.carrier.icc` + +The ISO 3166-1 alpha-2 2-character country code associated with the mobile carrier network. + + +- Requirement Level: Recommended + +- Type: string +- Examples: DE + + +#### Attribute `network.carrier.mcc` + +The mobile carrier country code. + + +- Requirement Level: Recommended + +- Type: string +- Examples: 310 + + +#### Attribute `network.carrier.mnc` + +The mobile carrier network code. + + +- Requirement Level: Recommended + +- Type: string +- Examples: 001 + + +#### Attribute `network.carrier.name` + +The name of the mobile carrier. + + +- Requirement Level: Recommended + +- Type: string +- Examples: sprint + + +#### Attribute `network.connection.subtype` + +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. + + +- Requirement Level: Recommended + +- Type: Enum [gprs, edge, umts, cdma, evdo_0, evdo_a, cdma2000_1xrtt, hsdpa, hsupa, hspa, iden, evdo_b, lte, ehrpd, hspap, gsm, td_scdma, iwlan, nr, nrnsa, lte_ca] +- Examples: LTE + + +#### Attribute `network.connection.type` + +The internet connection type. + + +- Requirement Level: Recommended + +- Type: Enum [wifi, wired, cell, unavailable, unknown] +- Examples: wifi + + +#### Attribute `network.local.address` + +Local address of the network connection - IP address or Unix domain socket name. + + +- Requirement Level: Recommended + +- Type: string +- Examples: [ + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +#### Attribute `network.local.port` + +Local port number of the network connection. + + +- Requirement Level: Recommended + +- Type: int +- Examples: [ + 65123, +] + +- Stability: Stable + + +#### Attribute `network.peer.address` + +Peer address of the network connection - IP address or Unix domain socket name. + + +- Requirement Level: Recommended + +- Type: string +- Examples: [ + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +#### Attribute `network.peer.port` + +Peer port number of the network connection. + + +- Requirement Level: Recommended + +- Type: int +- Examples: [ + 65123, +] + +- Stability: Stable + + +#### Attribute `network.protocol.name` + +[OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. + + +The value SHOULD be normalized to lowercase. + +- Requirement Level: Recommended + +- Type: string +- Examples: [ + "amqp", + "http", + "mqtt", +] + +- Stability: Stable + + +#### Attribute `network.protocol.version` + +Version of the protocol specified in `network.protocol.name`. + + +`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`. + +- Requirement Level: Recommended + +- Type: string +- Examples: 3.1.1 + +- Stability: Stable + + +#### Attribute `network.transport` + +[OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). + + + +The value SHOULD be normalized to lowercase. + +Consider always setting the transport when setting a port number, since +a port number is ambiguous without knowing the transport. For example +different processes could be listening on TCP port 12345 and UDP port 12345. + +- Requirement Level: Recommended + +- Type: Enum [tcp, udp, pipe, unix] +- Examples: [ + "tcp", + "udp", +] + +- Stability: Stable + + +#### Attribute `network.type` + +[OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. + + +The value SHOULD be normalized to lowercase. + +- Requirement Level: Recommended + +- Type: Enum [ipv4, ipv6] +- Examples: [ + "ipv4", + "ipv6", +] + +- Stability: Stable + + +#### Attribute `network.io.direction` + +The network IO operation direction. + + +- Requirement Level: Recommended + +- Type: Enum [transmit, receive] +- Examples: [ + "transmit", +] + + \ No newline at end of file diff --git a/crates/weaver_forge/expected_output/attribute_group/registry_url.md b/crates/weaver_forge/expected_output/attribute_group/registry_url.md new file mode 100644 index 00000000..43298ed5 --- /dev/null +++ b/crates/weaver_forge/expected_output/attribute_group/registry_url.md @@ -0,0 +1,95 @@ +## Group `registry.url` (attribute_group) + +### Brief + +Attributes describing URL. + +prefix: url + +### Attributes + + +#### Attribute `url.scheme` + +The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. + + +- Requirement Level: Recommended + +- Type: string +- Examples: [ + "https", + "ftp", + "telnet", +] + +- Stability: Stable + + +#### Attribute `url.full` + +Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986) + + +For network calls, URL usually has `scheme://host[:port][path][?query][#fragment]` format, where the fragment is not transmitted over HTTP, but if it is known, it SHOULD be included nevertheless. +`url.full` MUST NOT contain credentials passed via URL in form of `https://username:password@www.example.com/`. In such case username and password SHOULD be redacted and attribute's value SHOULD be `https://REDACTED:REDACTED@www.example.com/`. +`url.full` SHOULD capture the absolute URL when it is available (or can be reconstructed) and SHOULD NOT be validated or modified except for sanitizing purposes. + +- Requirement Level: Recommended + +- Type: string +- Examples: [ + "https://www.foo.bar/search?q=OpenTelemetry#SemConv", + "//localhost", +] + +- Stability: Stable + + +#### Attribute `url.path` + +The [URI path](https://www.rfc-editor.org/rfc/rfc3986#section-3.3) component + + +- Requirement Level: Recommended + +- Type: string +- Examples: [ + "/search", +] + +- Stability: Stable + + +#### Attribute `url.query` + +The [URI query](https://www.rfc-editor.org/rfc/rfc3986#section-3.4) component + + +Sensitive content provided in query string SHOULD be scrubbed when instrumentations can identify it. + +- Requirement Level: Recommended + +- Type: string +- Examples: [ + "q=OpenTelemetry", +] + +- Stability: Stable + + +#### Attribute `url.fragment` + +The [URI fragment](https://www.rfc-editor.org/rfc/rfc3986#section-3.5) component + + +- Requirement Level: Recommended + +- Type: string +- Examples: [ + "SemConv", +] + +- Stability: Stable + + \ No newline at end of file diff --git a/crates/weaver_forge/expected_output/attribute_group/registry_user_agent.md b/crates/weaver_forge/expected_output/attribute_group/registry_user_agent.md new file mode 100644 index 00000000..e552920c --- /dev/null +++ b/crates/weaver_forge/expected_output/attribute_group/registry_user_agent.md @@ -0,0 +1,28 @@ +## Group `registry.user_agent` (attribute_group) + +### Brief + +Describes user-agent attributes. + +prefix: user_agent + +### Attributes + + +#### Attribute `user_agent.original` + +Value of the [HTTP User-Agent](https://www.rfc-editor.org/rfc/rfc9110.html#field.user-agent) header sent by the client. + + + +- Requirement Level: Recommended + +- Type: string +- 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", +] + +- Stability: Stable + + \ No newline at end of file diff --git a/crates/weaver_forge/expected_output/attribute_group/server.md b/crates/weaver_forge/expected_output/attribute_group/server.md new file mode 100644 index 00000000..06a10dbe --- /dev/null +++ b/crates/weaver_forge/expected_output/attribute_group/server.md @@ -0,0 +1,49 @@ +## Group `server` (attribute_group) + +### Brief + +These attributes may be used to describe the server in a connection-based network interaction where there is one side that initiates the connection (the client is the side that initiates the connection). This covers all TCP network interactions since TCP is connection-based and one side initiates the connection (an exception is made for peer-to-peer communication over TCP where the "user-facing" surface of the protocol / API doesn't expose a clear notion of client and server). This also covers UDP network interactions where one side initiates the interaction, e.g. QUIC (HTTP/3) and DNS. + +prefix: server + +### Attributes + + +#### Attribute `server.address` + +Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. + + +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. + +- Requirement Level: Recommended + +- Type: string +- Examples: [ + "example.com", + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +#### Attribute `server.port` + +Server port number. + + +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. + +- Requirement Level: Recommended + +- Type: int +- Examples: [ + 80, + 8080, + 443, +] + +- Stability: Stable + + \ No newline at end of file diff --git a/crates/weaver_forge/expected_output/attribute_groups.md b/crates/weaver_forge/expected_output/attribute_groups.md new file mode 100644 index 00000000..849c0b2e --- /dev/null +++ b/crates/weaver_forge/expected_output/attribute_groups.md @@ -0,0 +1,1109 @@ +# Semantic Convention Attribute Groups + + +## Group `attributes.jvm.memory` (attribute_group) + +### Brief + +Describes JVM memory metric attributes. + +prefix: jvm.memory + +### Attributes + + +#### Attribute `jvm.memory.type` + +The type of memory. + + +- Requirement Level: Recommended + +- Type: Enum [heap, non_heap] +- Examples: [ + "heap", + "non_heap", +] + +- Stability: Stable + + +#### Attribute `jvm.memory.pool.name` + +Name of the memory pool. + + +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()). + +- Requirement Level: Recommended + +- Type: string +- Examples: [ + "G1 Old Gen", + "G1 Eden space", + "G1 Survivor Space", +] + +- Stability: Stable + + + +## Group `registry.db` (attribute_group) + +### Brief + +This document defines the attributes used to describe telemetry in the context of databases. + +prefix: db + +### Attributes + + +#### Attribute `db.cassandra.coordinator.dc` + +The data center of the coordinating node for a query. + + + +- Requirement Level: Recommended + +- Tag: tech-specific-cassandra + +- Type: string +- Examples: us-west-2 + + +#### Attribute `db.cassandra.coordinator.id` + +The ID of the coordinating node for a query. + + + +- Requirement Level: Recommended + +- Tag: tech-specific-cassandra + +- Type: string +- Examples: be13faa2-8574-4d71-926d-27f16cf8a7af + + +#### Attribute `db.cassandra.consistency_level` + +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). + + + +- Requirement Level: Recommended + +- Tag: tech-specific-cassandra + +- Type: Enum [all, each_quorum, quorum, local_quorum, one, two, three, local_one, any, serial, local_serial] + + +#### Attribute `db.cassandra.idempotence` + +Whether or not the query is idempotent. + + + +- Requirement Level: Recommended + +- Tag: tech-specific-cassandra + +- Type: boolean + + +#### Attribute `db.cassandra.page_size` + +The fetch size used for paging, i.e. how many rows will be returned at once. + + + +- Requirement Level: Recommended + +- Tag: tech-specific-cassandra + +- Type: int +- Examples: [ + 5000, +] + + +#### Attribute `db.cassandra.speculative_execution_count` + +The number of times a query was speculatively executed. Not set or `0` if the query was not executed speculatively. + + + +- Requirement Level: Recommended + +- Tag: tech-specific-cassandra + +- Type: int +- Examples: [ + 0, + 2, +] + + +#### Attribute `db.cassandra.table` + +The name of the primary Cassandra table that the operation is acting upon, including the keyspace name (if applicable). + + +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. + +- Requirement Level: Recommended + +- Tag: tech-specific-cassandra + +- Type: string +- Examples: mytable + + +#### Attribute `db.connection_string` + +The connection string used to connect to the database. It is recommended to remove embedded credentials. + + + +- Requirement Level: Recommended + +- Tag: db-generic + +- Type: string +- Examples: Server=(localdb)\v11.0;Integrated Security=true; + + +#### Attribute `db.cosmosdb.client_id` + +Unique Cosmos client instance id. + + +- Requirement Level: Recommended + +- Tag: tech-specific-cosmosdb + +- Type: string +- Examples: 3ba4827d-4422-483f-b59f-85b74211c11d + + +#### Attribute `db.cosmosdb.connection_mode` + +Cosmos client connection mode. + + +- Requirement Level: Recommended + +- Tag: tech-specific-cosmosdb + +- Type: Enum [gateway, direct] + + +#### Attribute `db.cosmosdb.container` + +Cosmos DB container name. + + +- Requirement Level: Recommended + +- Tag: tech-specific-cosmosdb + +- Type: string +- Examples: anystring + + +#### Attribute `db.cosmosdb.operation_type` + +CosmosDB Operation Type. + + +- Requirement Level: Recommended + +- Tag: tech-specific-cosmosdb + +- Type: Enum [Invalid, Create, Patch, Read, ReadFeed, Delete, Replace, Execute, Query, Head, HeadFeed, Upsert, Batch, QueryPlan, ExecuteJavaScript] + + +#### Attribute `db.cosmosdb.request_charge` + +RU consumed for that operation + + +- Requirement Level: Recommended + +- Tag: tech-specific-cosmosdb + +- Type: double +- Examples: [ + 46.18, + 1.0, +] + + +#### Attribute `db.cosmosdb.request_content_length` + +Request payload size in bytes + + +- Requirement Level: Recommended + +- Tag: tech-specific-cosmosdb + +- Type: int + + +#### Attribute `db.cosmosdb.status_code` + +Cosmos DB status code. + + +- Requirement Level: Recommended + +- Tag: tech-specific-cosmosdb + +- Type: int +- Examples: [ + 200, + 201, +] + + +#### Attribute `db.cosmosdb.sub_status_code` + +Cosmos DB sub status code. + + +- Requirement Level: Recommended + +- Tag: tech-specific-cosmosdb + +- Type: int +- Examples: [ + 1000, + 1002, +] + + +#### Attribute `db.elasticsearch.cluster.name` + +Represents the identifier of an Elasticsearch cluster. + + + +- Requirement Level: Recommended + +- Tag: tech-specific-elasticsearch + +- Type: string +- Examples: [ + "e9106fc68e3044f0b1475b04bf4ffd5f", +] + + +#### Attribute `db.elasticsearch.node.name` + +Represents the human-readable identifier of the node/instance to which a request was routed. + + + +- Requirement Level: Recommended + +- Tag: tech-specific-elasticsearch + +- Type: string +- Examples: [ + "instance-0000000001", +] + + +#### Attribute `db.elasticsearch.path_parts` + +A dynamic value in the url path. + + + +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. + +- Requirement Level: Recommended + +- Tag: tech-specific-elasticsearch + +- Type: template[string] +- Examples: [ + "db.elasticsearch.path_parts.index=test-index", + "db.elasticsearch.path_parts.doc_id=123", +] + + +#### Attribute `db.jdbc.driver_classname` + +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. + + + +- Requirement Level: Recommended + +- Tag: tech-specific-jdbc + +- Type: string +- Examples: [ + "org.postgresql.Driver", + "com.microsoft.sqlserver.jdbc.SQLServerDriver", +] + + +#### Attribute `db.mongodb.collection` + +The MongoDB collection being accessed within the database stated in `db.name`. + + + +- Requirement Level: Recommended + +- Tag: tech-specific-mongodb + +- Type: string +- Examples: [ + "customers", + "products", +] + + +#### Attribute `db.mssql.instance_name` + +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. + + + +If setting a `db.mssql.instance_name`, `server.port` is no longer required (but still recommended if non-standard). + +- Requirement Level: Recommended + +- Tag: tech-specific-mssql + +- Type: string +- Examples: MSSQLSERVER + + +#### Attribute `db.name` + +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). + + + +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). + +- Requirement Level: Recommended + +- Tag: db-generic + +- Type: string +- Examples: [ + "customers", + "main", +] + + +#### Attribute `db.operation` + +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. + + + +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. + +- Requirement Level: Recommended + +- Tag: db-generic + +- Type: string +- Examples: [ + "findAndModify", + "HMSET", + "SELECT", +] + + +#### Attribute `db.redis.database_index` + +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. + + + +- Requirement Level: Recommended + +- Tag: tech-specific-redis + +- Type: int +- Examples: [ + 0, + 1, + 15, +] + + +#### Attribute `db.sql.table` + +The name of the primary table that the operation is acting upon, including the database name (if applicable). + + +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. + +- Requirement Level: Recommended + +- Tag: tech-specific-sql + +- Type: string +- Examples: [ + "public.users", + "customers", +] + + +#### Attribute `db.statement` + +The database statement being executed. + + + +- Requirement Level: Recommended + +- Tag: db-generic + +- Type: string +- Examples: [ + "SELECT * FROM wuser_table", + "SET mykey \"WuValue\"", +] + + +#### Attribute `db.system` + +An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. + + +- Requirement Level: Recommended + +- Tag: db-generic + +- Type: Enum [other_sql, mssql, mssqlcompact, mysql, oracle, db2, postgresql, redshift, hive, cloudscape, hsqldb, progress, maxdb, hanadb, ingres, firstsql, edb, cache, adabas, firebird, derby, filemaker, informix, instantdb, interbase, mariadb, netezza, pervasive, pointbase, sqlite, sybase, teradata, vertica, h2, coldfusion, cassandra, hbase, mongodb, redis, couchbase, couchdb, cosmosdb, dynamodb, neo4j, geode, elasticsearch, memcached, cockroachdb, opensearch, clickhouse, spanner, trino] + + +#### Attribute `db.user` + +Username for accessing the database. + + + +- Requirement Level: Recommended + +- Tag: db-generic + +- Type: string +- Examples: [ + "readonly_user", + "reporting_user", +] + + +#### Attribute `db.instance.id` + +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`. + + + +- Requirement Level: Recommended + +- Tag: db-generic + +- Type: string +- Examples: mysql-e26b99z.example.com + + + +## Group `registry.http` (attribute_group) + +### Brief + +This document defines semantic convention attributes in the HTTP namespace. + +prefix: http + +### Attributes + + +#### Attribute `http.request.body.size` + +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. + + + +- Requirement Level: Recommended + +- Type: int +- Examples: 3495 + +- Stability: Experimental + + +#### Attribute `http.request.header` + +HTTP request headers, `` being the normalized HTTP Header name (lowercase), the value being the header values. + + + +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. +The `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. +The 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. + +- Requirement Level: Recommended + +- Type: template[string[]] +- Examples: [ + "http.request.header.content-type=[\"application/json\"]", + "http.request.header.x-forwarded-for=[\"1.2.3.4\", \"1.2.3.5\"]", +] + +- Stability: Stable + + +#### Attribute `http.request.method` + +HTTP request method. + + +HTTP request method value SHOULD be "known" to the instrumentation. +By default, this convention defines "known" methods as the ones listed in [RFC9110](https://www.rfc-editor.org/rfc/rfc9110.html#name-methods) +and the PATCH method defined in [RFC5789](https://www.rfc-editor.org/rfc/rfc5789.html). + +If the HTTP request method is not known to instrumentation, it MUST set the `http.request.method` attribute to `_OTHER`. + +If the HTTP instrumentation could end up converting valid HTTP request methods to `_OTHER`, then it MUST provide a way to override +the list of known HTTP methods. If this override is done via environment variable, then the environment variable MUST be named +OTEL_INSTRUMENTATION_HTTP_KNOWN_METHODS and support a comma-separated list of case-sensitive known HTTP methods +(this list MUST be a full override of the default known method, it is not a list of known methods in addition to the defaults). + +HTTP method names are case-sensitive and `http.request.method` attribute value MUST match a known HTTP method name exactly. +Instrumentations for specific web frameworks that consider HTTP methods to be case insensitive, SHOULD populate a canonical equivalent. +Tracing instrumentations that do so, MUST also set `http.request.method_original` to the original value. + +- Requirement Level: Recommended + +- Type: Enum [CONNECT, DELETE, GET, HEAD, OPTIONS, PATCH, POST, PUT, TRACE, _OTHER] +- Examples: [ + "GET", + "POST", + "HEAD", +] + +- Stability: Stable + + +#### Attribute `http.request.method_original` + +Original HTTP method sent by the client in the request line. + + +- Requirement Level: Recommended + +- Type: string +- Examples: [ + "GeT", + "ACL", + "foo", +] + +- Stability: Stable + + +#### Attribute `http.request.resend_count` + +The ordinal number of request resending attempt (for any reason, including redirects). + + + +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). + +- Requirement Level: Recommended + +- Type: int +- Examples: 3 + +- Stability: Stable + + +#### Attribute `http.response.body.size` + +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. + + + +- Requirement Level: Recommended + +- Type: int +- Examples: 3495 + +- Stability: Experimental + + +#### Attribute `http.response.header` + +HTTP response headers, `` being the normalized HTTP Header name (lowercase), the value being the header values. + + + +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. +Users MAY explicitly configure instrumentations to capture them even though it is not recommended. +The 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. + +- Requirement Level: Recommended + +- Type: template[string[]] +- Examples: [ + "http.response.header.content-type=[\"application/json\"]", + "http.response.header.my-custom-header=[\"abc\", \"def\"]", +] + +- Stability: Stable + + +#### Attribute `http.response.status_code` + +[HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). + + +- Requirement Level: Recommended + +- Type: int +- Examples: [ + 200, +] + +- Stability: Stable + + +#### Attribute `http.route` + +The matched route, that is, the path template in the format used by the respective server framework. + + + +MUST NOT be populated when this is not supported by the HTTP server framework as the route attribute should have low-cardinality and the URI path can NOT substitute it. +SHOULD include the [application root](/docs/http/http-spans.md#http-server-definitions) if there is one. + +- Requirement Level: Recommended + +- Type: string +- Examples: [ + "/users/:userID?", + "{controller}/{action}/{id?}", +] + +- Stability: Stable + + + +## Group `registry.network` (attribute_group) + +### Brief + +These attributes may be used for any network related operation. + +prefix: network + +### Attributes + + +#### Attribute `network.carrier.icc` + +The ISO 3166-1 alpha-2 2-character country code associated with the mobile carrier network. + + +- Requirement Level: Recommended + +- Type: string +- Examples: DE + + +#### Attribute `network.carrier.mcc` + +The mobile carrier country code. + + +- Requirement Level: Recommended + +- Type: string +- Examples: 310 + + +#### Attribute `network.carrier.mnc` + +The mobile carrier network code. + + +- Requirement Level: Recommended + +- Type: string +- Examples: 001 + + +#### Attribute `network.carrier.name` + +The name of the mobile carrier. + + +- Requirement Level: Recommended + +- Type: string +- Examples: sprint + + +#### Attribute `network.connection.subtype` + +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. + + +- Requirement Level: Recommended + +- Type: Enum [gprs, edge, umts, cdma, evdo_0, evdo_a, cdma2000_1xrtt, hsdpa, hsupa, hspa, iden, evdo_b, lte, ehrpd, hspap, gsm, td_scdma, iwlan, nr, nrnsa, lte_ca] +- Examples: LTE + + +#### Attribute `network.connection.type` + +The internet connection type. + + +- Requirement Level: Recommended + +- Type: Enum [wifi, wired, cell, unavailable, unknown] +- Examples: wifi + + +#### Attribute `network.local.address` + +Local address of the network connection - IP address or Unix domain socket name. + + +- Requirement Level: Recommended + +- Type: string +- Examples: [ + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +#### Attribute `network.local.port` + +Local port number of the network connection. + + +- Requirement Level: Recommended + +- Type: int +- Examples: [ + 65123, +] + +- Stability: Stable + + +#### Attribute `network.peer.address` + +Peer address of the network connection - IP address or Unix domain socket name. + + +- Requirement Level: Recommended + +- Type: string +- Examples: [ + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +#### Attribute `network.peer.port` + +Peer port number of the network connection. + + +- Requirement Level: Recommended + +- Type: int +- Examples: [ + 65123, +] + +- Stability: Stable + + +#### Attribute `network.protocol.name` + +[OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. + + +The value SHOULD be normalized to lowercase. + +- Requirement Level: Recommended + +- Type: string +- Examples: [ + "amqp", + "http", + "mqtt", +] + +- Stability: Stable + + +#### Attribute `network.protocol.version` + +Version of the protocol specified in `network.protocol.name`. + + +`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`. + +- Requirement Level: Recommended + +- Type: string +- Examples: 3.1.1 + +- Stability: Stable + + +#### Attribute `network.transport` + +[OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). + + + +The value SHOULD be normalized to lowercase. + +Consider always setting the transport when setting a port number, since +a port number is ambiguous without knowing the transport. For example +different processes could be listening on TCP port 12345 and UDP port 12345. + +- Requirement Level: Recommended + +- Type: Enum [tcp, udp, pipe, unix] +- Examples: [ + "tcp", + "udp", +] + +- Stability: Stable + + +#### Attribute `network.type` + +[OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. + + +The value SHOULD be normalized to lowercase. + +- Requirement Level: Recommended + +- Type: Enum [ipv4, ipv6] +- Examples: [ + "ipv4", + "ipv6", +] + +- Stability: Stable + + +#### Attribute `network.io.direction` + +The network IO operation direction. + + +- Requirement Level: Recommended + +- Type: Enum [transmit, receive] +- Examples: [ + "transmit", +] + + + +## Group `server` (attribute_group) + +### Brief + +These attributes may be used to describe the server in a connection-based network interaction where there is one side that initiates the connection (the client is the side that initiates the connection). This covers all TCP network interactions since TCP is connection-based and one side initiates the connection (an exception is made for peer-to-peer communication over TCP where the "user-facing" surface of the protocol / API doesn't expose a clear notion of client and server). This also covers UDP network interactions where one side initiates the interaction, e.g. QUIC (HTTP/3) and DNS. + +prefix: server + +### Attributes + + +#### Attribute `server.address` + +Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. + + +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. + +- Requirement Level: Recommended + +- Type: string +- Examples: [ + "example.com", + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +#### Attribute `server.port` + +Server port number. + + +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. + +- Requirement Level: Recommended + +- Type: int +- Examples: [ + 80, + 8080, + 443, +] + +- Stability: Stable + + + +## Group `registry.url` (attribute_group) + +### Brief + +Attributes describing URL. + +prefix: url + +### Attributes + + +#### Attribute `url.scheme` + +The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. + + +- Requirement Level: Recommended + +- Type: string +- Examples: [ + "https", + "ftp", + "telnet", +] + +- Stability: Stable + + +#### Attribute `url.full` + +Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986) + + +For network calls, URL usually has `scheme://host[:port][path][?query][#fragment]` format, where the fragment is not transmitted over HTTP, but if it is known, it SHOULD be included nevertheless. +`url.full` MUST NOT contain credentials passed via URL in form of `https://username:password@www.example.com/`. In such case username and password SHOULD be redacted and attribute's value SHOULD be `https://REDACTED:REDACTED@www.example.com/`. +`url.full` SHOULD capture the absolute URL when it is available (or can be reconstructed) and SHOULD NOT be validated or modified except for sanitizing purposes. + +- Requirement Level: Recommended + +- Type: string +- Examples: [ + "https://www.foo.bar/search?q=OpenTelemetry#SemConv", + "//localhost", +] + +- Stability: Stable + + +#### Attribute `url.path` + +The [URI path](https://www.rfc-editor.org/rfc/rfc3986#section-3.3) component + + +- Requirement Level: Recommended + +- Type: string +- Examples: [ + "/search", +] + +- Stability: Stable + + +#### Attribute `url.query` + +The [URI query](https://www.rfc-editor.org/rfc/rfc3986#section-3.4) component + + +Sensitive content provided in query string SHOULD be scrubbed when instrumentations can identify it. + +- Requirement Level: Recommended + +- Type: string +- Examples: [ + "q=OpenTelemetry", +] + +- Stability: Stable + + +#### Attribute `url.fragment` + +The [URI fragment](https://www.rfc-editor.org/rfc/rfc3986#section-3.5) component + + +- Requirement Level: Recommended + +- Type: string +- Examples: [ + "SemConv", +] + +- Stability: Stable + + + +## Group `registry.user_agent` (attribute_group) + +### Brief + +Describes user-agent attributes. + +prefix: user_agent + +### Attributes + + +#### Attribute `user_agent.original` + +Value of the [HTTP User-Agent](https://www.rfc-editor.org/rfc/rfc9110.html#field.user-agent) header sent by the client. + + + +- Requirement Level: Recommended + +- Type: string +- 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", +] + +- Stability: Stable + + + \ No newline at end of file diff --git a/crates/weaver_forge/expected_output/event/android_lifecycle_events.md b/crates/weaver_forge/expected_output/event/android_lifecycle_events.md new file mode 100644 index 00000000..de690580 --- /dev/null +++ b/crates/weaver_forge/expected_output/event/android_lifecycle_events.md @@ -0,0 +1,27 @@ +# Group `android.lifecycle.events` (event) + +## Brief + +This event represents an occurrence of a lifecycle transition on the Android platform. + +Prefix: android +Name: device.app.lifecycle + +## Attributes + + +### Attribute `android.state` + +This attribute represents the state the application has transitioned into at the occurrence of the event. + + + +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. + +- Requirement Level: Required + +- Type: Enum [created, background, foreground] + +- Stability: Experimental + + \ No newline at end of file diff --git a/crates/weaver_forge/expected_output/event/ios_lifecycle_events.md b/crates/weaver_forge/expected_output/event/ios_lifecycle_events.md new file mode 100644 index 00000000..83ecf5db --- /dev/null +++ b/crates/weaver_forge/expected_output/event/ios_lifecycle_events.md @@ -0,0 +1,27 @@ +# Group `ios.lifecycle.events` (event) + +## Brief + +This event represents an occurrence of a lifecycle transition on the iOS platform. + +Prefix: ios +Name: device.app.lifecycle + +## Attributes + + +### Attribute `ios.state` + +This attribute represents the state the application has transitioned into at the occurrence of the event. + + + +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. + +- Requirement Level: Required + +- Type: Enum [active, inactive, background, foreground, terminate] + +- Stability: Experimental + + \ No newline at end of file diff --git a/crates/weaver_forge/expected_output/events.md b/crates/weaver_forge/expected_output/events.md new file mode 100644 index 00000000..8066e504 --- /dev/null +++ b/crates/weaver_forge/expected_output/events.md @@ -0,0 +1,59 @@ +# Semantic Convention Event Groups + + +## Group `ios.lifecycle.events` (event) + +### Brief + +This event represents an occurrence of a lifecycle transition on the iOS platform. + +Prefix: ios +Name: device.app.lifecycle + +### Attributes + + +#### Attribute `ios.state` + +This attribute represents the state the application has transitioned into at the occurrence of the event. + + + +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. + +- Requirement Level: Required + +- Type: Enum [active, inactive, background, foreground, terminate] + +- Stability: Experimental + + + +## Group `android.lifecycle.events` (event) + +### Brief + +This event represents an occurrence of a lifecycle transition on the Android platform. + +Prefix: android +Name: device.app.lifecycle + +### Attributes + + +#### Attribute `android.state` + +This attribute represents the state the application has transitioned into at the occurrence of the event. + + + +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. + +- Requirement Level: Required + +- Type: Enum [created, background, foreground] + +- Stability: Experimental + + + \ No newline at end of file diff --git a/crates/weaver_forge/expected_output/group/android_lifecycle_events.md b/crates/weaver_forge/expected_output/group/android_lifecycle_events.md new file mode 100644 index 00000000..25ed13d6 --- /dev/null +++ b/crates/weaver_forge/expected_output/group/android_lifecycle_events.md @@ -0,0 +1,31 @@ +# Group `android.lifecycle.events` (event) + +## Brief + +This event represents an occurrence of a lifecycle transition on the Android platform. + +prefix: android + +## Attributes + + +### Attribute `android.state` + +This attribute represents the state the application has transitioned into at the occurrence of the event. + + + +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. + +- Requirement Level: Required + +- Type: Enum [created, background, foreground] + +- Stability: Experimental + + + +## Provenance + +Source: data/mobile-events.yaml + diff --git a/crates/weaver_forge/expected_output/group/attributes_jvm_memory.md b/crates/weaver_forge/expected_output/group/attributes_jvm_memory.md new file mode 100644 index 00000000..018f1fe4 --- /dev/null +++ b/crates/weaver_forge/expected_output/group/attributes_jvm_memory.md @@ -0,0 +1,51 @@ +# Group `attributes.jvm.memory` (attribute_group) + +## Brief + +Describes JVM memory metric attributes. + +prefix: jvm.memory + +## Attributes + + +### Attribute `jvm.memory.type` + +The type of memory. + + +- Requirement Level: Recommended + +- Type: Enum [heap, non_heap] +- Examples: [ + "heap", + "non_heap", +] + +- Stability: Stable + + +### Attribute `jvm.memory.pool.name` + +Name of the memory pool. + + +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()). + +- Requirement Level: Recommended + +- Type: string +- Examples: [ + "G1 Old Gen", + "G1 Eden space", + "G1 Survivor Space", +] + +- Stability: Stable + + + +## Provenance + +Source: data/jvm-metrics.yaml + diff --git a/crates/weaver_forge/expected_output/group/db.md b/crates/weaver_forge/expected_output/group/db.md new file mode 100644 index 00000000..819862f4 --- /dev/null +++ b/crates/weaver_forge/expected_output/group/db.md @@ -0,0 +1,283 @@ +# Group `db` (span) + +## Brief + +This document defines the attributes used to perform database client calls. + +prefix: + +## Attributes + + +### Attribute `db.system` + +An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. + + +- Requirement Level: Required + +- Tag: connection-level + +- Type: Enum [other_sql, mssql, mssqlcompact, mysql, oracle, db2, postgresql, redshift, hive, cloudscape, hsqldb, progress, maxdb, hanadb, ingres, firstsql, edb, cache, adabas, firebird, derby, filemaker, informix, instantdb, interbase, mariadb, netezza, pervasive, pointbase, sqlite, sybase, teradata, vertica, h2, coldfusion, cassandra, hbase, mongodb, redis, couchbase, couchdb, cosmosdb, dynamodb, neo4j, geode, elasticsearch, memcached, cockroachdb, opensearch, clickhouse, spanner, trino] + + +### Attribute `db.connection_string` + +The connection string used to connect to the database. It is recommended to remove embedded credentials. + + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: Server=(localdb)\v11.0;Integrated Security=true; + + +### Attribute `db.user` + +Username for accessing the database. + + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "readonly_user", + "reporting_user", +] + + +### Attribute `db.jdbc.driver_classname` + +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. + + + +- Requirement Level: Recommended + +- Tag: connection-level-tech-specific + +- Type: string +- Examples: [ + "org.postgresql.Driver", + "com.microsoft.sqlserver.jdbc.SQLServerDriver", +] + + +### Attribute `db.name` + +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). + + + +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). + +- Requirement Level: Conditionally Required - If applicable. + +- Tag: call-level + +- Type: string +- Examples: [ + "customers", + "main", +] + + +### Attribute `db.statement` + +The database statement being executed. + + + +- Requirement Level: Optional + +- Tag: call-level + +- Type: string +- Examples: [ + "SELECT * FROM wuser_table", + "SET mykey \"WuValue\"", +] + + +### Attribute `db.operation` + +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. + + + +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. + +- Requirement Level: Conditionally Required - If `db.statement` is not applicable. + +- Tag: call-level + +- Type: string +- Examples: [ + "findAndModify", + "HMSET", + "SELECT", +] + + +### Attribute `server.address` + +Name of the database host. + + + +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. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "example.com", + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +### Attribute `server.port` + +Server port number. + + +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. + +- Requirement Level: Conditionally Required - If using a port other than the default port for this DBMS and if `server.address` is set. + +- Tag: connection-level + +- Type: int +- Examples: [ + 80, + 8080, + 443, +] + +- Stability: Stable + + +### Attribute `network.peer.address` + +Peer address of the network connection - IP address or Unix domain socket name. + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +### Attribute `network.peer.port` + +Peer port number of the network connection. + + +- Requirement Level: Optional + +- Tag: connection-level + +- Type: int +- Examples: [ + 65123, +] + +- Stability: Stable + + +### Attribute `network.transport` + +[OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). + + + +The value SHOULD be normalized to lowercase. + +Consider always setting the transport when setting a port number, since +a port number is ambiguous without knowing the transport. For example +different processes could be listening on TCP port 12345 and UDP port 12345. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: Enum [tcp, udp, pipe, unix] +- Examples: [ + "tcp", + "udp", +] + +- Stability: Stable + + +### Attribute `network.type` + +[OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. + + +The value SHOULD be normalized to lowercase. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: Enum [ipv4, ipv6] +- Examples: [ + "ipv4", + "ipv6", +] + +- Stability: Stable + + +### Attribute `db.instance.id` + +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`. + + + +- Requirement Level: Optional + +- Tag: connection-level + +- Type: string +- Examples: mysql-e26b99z.example.com + + + +## Provenance + +Source: data/trace-database.yaml + +item: {"AttributeBrief": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeDeprecated": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeExamples": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeNote": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeSamplingRelevant": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeStability": {"group_id": "registry.db", "resolution_mode": "Reference"}} +item: {"AttributeBrief": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeDeprecated": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeExamples": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeNote": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeRequirementLevel": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeSamplingRelevant": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeStability": {"group_id": "registry.db", "resolution_mode": "Reference"}} +item: {"AttributeBrief": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeDeprecated": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeExamples": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeNote": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeRequirementLevel": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeSamplingRelevant": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeStability": {"group_id": "registry.db", "resolution_mode": "Reference"}} +item: {"AttributeBrief": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeDeprecated": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeExamples": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeNote": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeRequirementLevel": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeSamplingRelevant": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeStability": {"group_id": "registry.db", "resolution_mode": "Reference"}} +item: {"AttributeBrief": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeDeprecated": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeExamples": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeNote": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeSamplingRelevant": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeStability": {"group_id": "registry.db", "resolution_mode": "Reference"}} +item: {"AttributeBrief": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeDeprecated": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeExamples": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeNote": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeSamplingRelevant": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeStability": {"group_id": "registry.db", "resolution_mode": "Reference"}} +item: {"AttributeBrief": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeDeprecated": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeExamples": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeNote": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeSamplingRelevant": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeStability": {"group_id": "registry.db", "resolution_mode": "Reference"}} +item: {"AttributeDeprecated": {"group_id": "server", "resolution_mode": "Reference"}, "AttributeExamples": {"group_id": "server", "resolution_mode": "Reference"}, "AttributeNote": {"group_id": "server", "resolution_mode": "Reference"}, "AttributeRequirementLevel": {"group_id": "server", "resolution_mode": "Reference"}, "AttributeSamplingRelevant": {"group_id": "server", "resolution_mode": "Reference"}, "AttributeStability": {"group_id": "server", "resolution_mode": "Reference"}} +item: {"AttributeBrief": {"group_id": "server", "resolution_mode": "Reference"}, "AttributeDeprecated": {"group_id": "server", "resolution_mode": "Reference"}, "AttributeExamples": {"group_id": "server", "resolution_mode": "Reference"}, "AttributeNote": {"group_id": "server", "resolution_mode": "Reference"}, "AttributeSamplingRelevant": {"group_id": "server", "resolution_mode": "Reference"}, "AttributeStability": {"group_id": "server", "resolution_mode": "Reference"}} +item: {"AttributeBrief": {"group_id": "registry.network", "resolution_mode": "Reference"}, "AttributeDeprecated": {"group_id": "registry.network", "resolution_mode": "Reference"}, "AttributeExamples": {"group_id": "registry.network", "resolution_mode": "Reference"}, "AttributeNote": {"group_id": "registry.network", "resolution_mode": "Reference"}, "AttributeRequirementLevel": {"group_id": "registry.network", "resolution_mode": "Reference"}, "AttributeSamplingRelevant": {"group_id": "registry.network", "resolution_mode": "Reference"}, "AttributeStability": {"group_id": "registry.network", "resolution_mode": "Reference"}} +item: {"AttributeBrief": {"group_id": "registry.network", "resolution_mode": "Reference"}, "AttributeDeprecated": {"group_id": "registry.network", "resolution_mode": "Reference"}, "AttributeExamples": {"group_id": "registry.network", "resolution_mode": "Reference"}, "AttributeNote": {"group_id": "registry.network", "resolution_mode": "Reference"}, "AttributeSamplingRelevant": {"group_id": "registry.network", "resolution_mode": "Reference"}, "AttributeStability": {"group_id": "registry.network", "resolution_mode": "Reference"}} +item: {"AttributeBrief": {"group_id": "registry.network", "resolution_mode": "Reference"}, "AttributeDeprecated": {"group_id": "registry.network", "resolution_mode": "Reference"}, "AttributeExamples": {"group_id": "registry.network", "resolution_mode": "Reference"}, "AttributeNote": {"group_id": "registry.network", "resolution_mode": "Reference"}, "AttributeRequirementLevel": {"group_id": "registry.network", "resolution_mode": "Reference"}, "AttributeSamplingRelevant": {"group_id": "registry.network", "resolution_mode": "Reference"}, "AttributeStability": {"group_id": "registry.network", "resolution_mode": "Reference"}} +item: {"AttributeBrief": {"group_id": "registry.network", "resolution_mode": "Reference"}, "AttributeDeprecated": {"group_id": "registry.network", "resolution_mode": "Reference"}, "AttributeExamples": {"group_id": "registry.network", "resolution_mode": "Reference"}, "AttributeNote": {"group_id": "registry.network", "resolution_mode": "Reference"}, "AttributeRequirementLevel": {"group_id": "registry.network", "resolution_mode": "Reference"}, "AttributeSamplingRelevant": {"group_id": "registry.network", "resolution_mode": "Reference"}, "AttributeStability": {"group_id": "registry.network", "resolution_mode": "Reference"}} +item: {"AttributeBrief": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeDeprecated": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeExamples": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeNote": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeSamplingRelevant": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeStability": {"group_id": "registry.db", "resolution_mode": "Reference"}} diff --git a/crates/weaver_forge/expected_output/group/db_cassandra.md b/crates/weaver_forge/expected_output/group/db_cassandra.md new file mode 100644 index 00000000..19431a15 --- /dev/null +++ b/crates/weaver_forge/expected_output/group/db_cassandra.md @@ -0,0 +1,411 @@ +# Group `db.cassandra` (span) + +## Brief + +Call-level attributes for Cassandra + +prefix: + +## Attributes + + +### Attribute `db.system` + +An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. + + +- Requirement Level: Required + +- Tag: connection-level + +- Type: Enum [other_sql, mssql, mssqlcompact, mysql, oracle, db2, postgresql, redshift, hive, cloudscape, hsqldb, progress, maxdb, hanadb, ingres, firstsql, edb, cache, adabas, firebird, derby, filemaker, informix, instantdb, interbase, mariadb, netezza, pervasive, pointbase, sqlite, sybase, teradata, vertica, h2, coldfusion, cassandra, hbase, mongodb, redis, couchbase, couchdb, cosmosdb, dynamodb, neo4j, geode, elasticsearch, memcached, cockroachdb, opensearch, clickhouse, spanner, trino] + + +### Attribute `db.connection_string` + +The connection string used to connect to the database. It is recommended to remove embedded credentials. + + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: Server=(localdb)\v11.0;Integrated Security=true; + + +### Attribute `db.user` + +Username for accessing the database. + + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "readonly_user", + "reporting_user", +] + + +### Attribute `db.jdbc.driver_classname` + +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. + + + +- Requirement Level: Recommended + +- Tag: connection-level-tech-specific + +- Type: string +- Examples: [ + "org.postgresql.Driver", + "com.microsoft.sqlserver.jdbc.SQLServerDriver", +] + + +### Attribute `db.name` + +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). + + + +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). + +- Requirement Level: Conditionally Required - If applicable. + +- Tag: call-level + +- Type: string +- Examples: [ + "customers", + "main", +] + + +### Attribute `db.statement` + +The database statement being executed. + + + +- Requirement Level: Optional + +- Tag: call-level + +- Type: string +- Examples: [ + "SELECT * FROM wuser_table", + "SET mykey \"WuValue\"", +] + + +### Attribute `db.operation` + +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. + + + +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. + +- Requirement Level: Conditionally Required - If `db.statement` is not applicable. + +- Tag: call-level + +- Type: string +- Examples: [ + "findAndModify", + "HMSET", + "SELECT", +] + + +### Attribute `server.address` + +Name of the database host. + + + +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. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "example.com", + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +### Attribute `server.port` + +Server port number. + + +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. + +- Requirement Level: Conditionally Required - If using a port other than the default port for this DBMS and if `server.address` is set. + +- Tag: connection-level + +- Type: int +- Examples: [ + 80, + 8080, + 443, +] + +- Stability: Stable + + +### Attribute `network.peer.address` + +Peer address of the network connection - IP address or Unix domain socket name. + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +### Attribute `network.peer.port` + +Peer port number of the network connection. + + +- Requirement Level: Optional + +- Tag: connection-level + +- Type: int +- Examples: [ + 65123, +] + +- Stability: Stable + + +### Attribute `network.transport` + +[OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). + + + +The value SHOULD be normalized to lowercase. + +Consider always setting the transport when setting a port number, since +a port number is ambiguous without knowing the transport. For example +different processes could be listening on TCP port 12345 and UDP port 12345. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: Enum [tcp, udp, pipe, unix] +- Examples: [ + "tcp", + "udp", +] + +- Stability: Stable + + +### Attribute `network.type` + +[OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. + + +The value SHOULD be normalized to lowercase. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: Enum [ipv4, ipv6] +- Examples: [ + "ipv4", + "ipv6", +] + +- Stability: Stable + + +### Attribute `db.instance.id` + +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`. + + + +- Requirement Level: Optional + +- Tag: connection-level + +- Type: string +- Examples: mysql-e26b99z.example.com + + +### Attribute `db.name` + +The keyspace name in Cassandra. + + + +For Cassandra the `db.name` should be set to the Cassandra keyspace name. + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific-cassandra + +- Type: string +- Examples: [ + "mykeyspace", +] + + +### Attribute `db.cassandra.page_size` + +The fetch size used for paging, i.e. how many rows will be returned at once. + + + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific-cassandra + +- Type: int +- Examples: [ + 5000, +] + + +### Attribute `db.cassandra.consistency_level` + +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). + + + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific-cassandra + +- Type: Enum [all, each_quorum, quorum, local_quorum, one, two, three, local_one, any, serial, local_serial] + + +### Attribute `db.cassandra.table` + +The name of the primary Cassandra table that the operation is acting upon, including the keyspace name (if applicable). + + +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. + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific-cassandra + +- Type: string +- Examples: mytable + + +### Attribute `db.cassandra.idempotence` + +Whether or not the query is idempotent. + + + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific-cassandra + +- Type: boolean + + +### Attribute `db.cassandra.speculative_execution_count` + +The number of times a query was speculatively executed. Not set or `0` if the query was not executed speculatively. + + + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific-cassandra + +- Type: int +- Examples: [ + 0, + 2, +] + + +### Attribute `db.cassandra.coordinator.id` + +The ID of the coordinating node for a query. + + + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific-cassandra + +- Type: string +- Examples: be13faa2-8574-4d71-926d-27f16cf8a7af + + +### Attribute `db.cassandra.coordinator.dc` + +The data center of the coordinating node for a query. + + + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific-cassandra + +- Type: string +- Examples: us-west-2 + + + +## Provenance + +Source: data/trace-database.yaml + +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"AttributeDeprecated": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeRequirementLevel": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeSamplingRelevant": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeStability": {"group_id": "registry.db", "resolution_mode": "Reference"}} +item: {"AttributeBrief": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeDeprecated": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeExamples": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeNote": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeRequirementLevel": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeSamplingRelevant": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeStability": {"group_id": "registry.db", "resolution_mode": "Reference"}} +item: {"AttributeBrief": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeDeprecated": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeExamples": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeNote": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeRequirementLevel": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeSamplingRelevant": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeStability": {"group_id": "registry.db", "resolution_mode": "Reference"}} +item: {"AttributeBrief": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeDeprecated": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeExamples": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeNote": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeRequirementLevel": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeSamplingRelevant": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeStability": {"group_id": "registry.db", "resolution_mode": "Reference"}} +item: {"AttributeBrief": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeDeprecated": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeExamples": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeNote": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeRequirementLevel": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeSamplingRelevant": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeStability": {"group_id": "registry.db", "resolution_mode": "Reference"}} +item: {"AttributeBrief": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeDeprecated": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeExamples": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeNote": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeRequirementLevel": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeSamplingRelevant": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeStability": {"group_id": "registry.db", "resolution_mode": "Reference"}} +item: {"AttributeBrief": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeDeprecated": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeExamples": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeNote": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeRequirementLevel": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeSamplingRelevant": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeStability": {"group_id": "registry.db", "resolution_mode": "Reference"}} +item: {"AttributeBrief": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeDeprecated": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeExamples": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeNote": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeRequirementLevel": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeSamplingRelevant": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeStability": {"group_id": "registry.db", "resolution_mode": "Reference"}} diff --git a/crates/weaver_forge/expected_output/group/db_cosmosdb.md b/crates/weaver_forge/expected_output/group/db_cosmosdb.md new file mode 100644 index 00000000..0ed33248 --- /dev/null +++ b/crates/weaver_forge/expected_output/group/db_cosmosdb.md @@ -0,0 +1,423 @@ +# Group `db.cosmosdb` (span) + +## Brief + +Call-level attributes for Cosmos DB. + +prefix: db.cosmosdb + +## Attributes + + +### Attribute `db.system` + +An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. + + +- Requirement Level: Required + +- Tag: connection-level + +- Type: Enum [other_sql, mssql, mssqlcompact, mysql, oracle, db2, postgresql, redshift, hive, cloudscape, hsqldb, progress, maxdb, hanadb, ingres, firstsql, edb, cache, adabas, firebird, derby, filemaker, informix, instantdb, interbase, mariadb, netezza, pervasive, pointbase, sqlite, sybase, teradata, vertica, h2, coldfusion, cassandra, hbase, mongodb, redis, couchbase, couchdb, cosmosdb, dynamodb, neo4j, geode, elasticsearch, memcached, cockroachdb, opensearch, clickhouse, spanner, trino] + + +### Attribute `db.connection_string` + +The connection string used to connect to the database. It is recommended to remove embedded credentials. + + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: Server=(localdb)\v11.0;Integrated Security=true; + + +### Attribute `db.user` + +Username for accessing the database. + + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "readonly_user", + "reporting_user", +] + + +### Attribute `db.jdbc.driver_classname` + +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. + + + +- Requirement Level: Recommended + +- Tag: connection-level-tech-specific + +- Type: string +- Examples: [ + "org.postgresql.Driver", + "com.microsoft.sqlserver.jdbc.SQLServerDriver", +] + + +### Attribute `db.name` + +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). + + + +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). + +- Requirement Level: Conditionally Required - If applicable. + +- Tag: call-level + +- Type: string +- Examples: [ + "customers", + "main", +] + + +### Attribute `db.statement` + +The database statement being executed. + + + +- Requirement Level: Optional + +- Tag: call-level + +- Type: string +- Examples: [ + "SELECT * FROM wuser_table", + "SET mykey \"WuValue\"", +] + + +### Attribute `db.operation` + +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. + + + +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. + +- Requirement Level: Conditionally Required - If `db.statement` is not applicable. + +- Tag: call-level + +- Type: string +- Examples: [ + "findAndModify", + "HMSET", + "SELECT", +] + + +### Attribute `server.address` + +Name of the database host. + + + +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. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "example.com", + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +### Attribute `server.port` + +Server port number. + + +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. + +- Requirement Level: Conditionally Required - If using a port other than the default port for this DBMS and if `server.address` is set. + +- Tag: connection-level + +- Type: int +- Examples: [ + 80, + 8080, + 443, +] + +- Stability: Stable + + +### Attribute `network.peer.address` + +Peer address of the network connection - IP address or Unix domain socket name. + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +### Attribute `network.peer.port` + +Peer port number of the network connection. + + +- Requirement Level: Optional + +- Tag: connection-level + +- Type: int +- Examples: [ + 65123, +] + +- Stability: Stable + + +### Attribute `network.transport` + +[OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). + + + +The value SHOULD be normalized to lowercase. + +Consider always setting the transport when setting a port number, since +a port number is ambiguous without knowing the transport. For example +different processes could be listening on TCP port 12345 and UDP port 12345. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: Enum [tcp, udp, pipe, unix] +- Examples: [ + "tcp", + "udp", +] + +- Stability: Stable + + +### Attribute `network.type` + +[OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. + + +The value SHOULD be normalized to lowercase. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: Enum [ipv4, ipv6] +- Examples: [ + "ipv4", + "ipv6", +] + +- Stability: Stable + + +### Attribute `db.instance.id` + +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`. + + + +- Requirement Level: Optional + +- Tag: connection-level + +- Type: string +- Examples: mysql-e26b99z.example.com + + +### Attribute `db.cosmosdb.client_id` + +Unique Cosmos client instance id. + + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific + +- Type: string +- Examples: 3ba4827d-4422-483f-b59f-85b74211c11d + + +### Attribute `db.cosmosdb.operation_type` + +CosmosDB Operation Type. + + +- Requirement Level: Conditionally Required - when performing one of the operations in this list + +- Tag: call-level-tech-specific + +- Type: Enum [Invalid, Create, Patch, Read, ReadFeed, Delete, Replace, Execute, Query, Head, HeadFeed, Upsert, Batch, QueryPlan, ExecuteJavaScript] + + +### Attribute `user_agent.original` + +Full user-agent string is generated by Cosmos DB SDK + + +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. + Format Reg-{D (Disabled discovery)}-S(application region)|L(List of preferred regions)|N(None, user did not configure it). + Default value is "NS". + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific + +- Type: string +- 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\\|", +] + +- Stability: Stable + + +### Attribute `db.cosmosdb.connection_mode` + +Cosmos client connection mode. + + +- Requirement Level: Conditionally Required - if not `direct` (or pick gw as default) + +- Tag: call-level-tech-specific + +- Type: Enum [gateway, direct] + + +### Attribute `db.cosmosdb.container` + +Cosmos DB container name. + + +- Requirement Level: Conditionally Required - if available + +- Tag: call-level-tech-specific + +- Type: string +- Examples: anystring + + +### Attribute `db.cosmosdb.request_content_length` + +Request payload size in bytes + + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific + +- Type: int + + +### Attribute `db.cosmosdb.status_code` + +Cosmos DB status code. + + +- Requirement Level: Conditionally Required - if response was received + +- Tag: call-level-tech-specific + +- Type: int +- Examples: [ + 200, + 201, +] + + +### Attribute `db.cosmosdb.sub_status_code` + +Cosmos DB sub status code. + + +- Requirement Level: Conditionally Required - when response was received and contained sub-code. + +- Tag: call-level-tech-specific + +- Type: int +- Examples: [ + 1000, + 1002, +] + + +### Attribute `db.cosmosdb.request_charge` + +RU consumed for that operation + + +- Requirement Level: Conditionally Required - when available + +- Tag: call-level-tech-specific + +- Type: double +- Examples: [ + 46.18, + 1.0, +] + + + +## Provenance + +Source: data/trace-database.yaml + +item: {"AttributeBrief": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeDeprecated": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeExamples": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeNote": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeRequirementLevel": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeSamplingRelevant": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeStability": {"group_id": "registry.db", "resolution_mode": "Reference"}} +item: {"AttributeBrief": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeDeprecated": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeExamples": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeNote": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeSamplingRelevant": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeStability": {"group_id": "registry.db", "resolution_mode": "Reference"}} +item: {"AttributeDeprecated": {"group_id": "registry.user_agent", "resolution_mode": "Reference"}, "AttributeRequirementLevel": {"group_id": "registry.user_agent", "resolution_mode": "Reference"}, "AttributeSamplingRelevant": {"group_id": "registry.user_agent", "resolution_mode": "Reference"}, "AttributeStability": {"group_id": "registry.user_agent", "resolution_mode": "Reference"}} +item: {"AttributeBrief": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeDeprecated": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeExamples": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeNote": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeSamplingRelevant": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeStability": {"group_id": "registry.db", "resolution_mode": "Reference"}} +item: {"AttributeBrief": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeDeprecated": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeExamples": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeNote": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeSamplingRelevant": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeStability": {"group_id": "registry.db", "resolution_mode": "Reference"}} +item: {"AttributeBrief": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeDeprecated": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeExamples": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeNote": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeRequirementLevel": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeSamplingRelevant": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeStability": {"group_id": "registry.db", "resolution_mode": "Reference"}} +item: {"AttributeBrief": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeDeprecated": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeExamples": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeNote": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeSamplingRelevant": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeStability": {"group_id": "registry.db", "resolution_mode": "Reference"}} +item: {"AttributeBrief": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeDeprecated": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeExamples": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeNote": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeSamplingRelevant": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeStability": {"group_id": "registry.db", "resolution_mode": "Reference"}} +item: {"AttributeBrief": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeDeprecated": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeExamples": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeNote": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeSamplingRelevant": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeStability": {"group_id": "registry.db", "resolution_mode": "Reference"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} diff --git a/crates/weaver_forge/expected_output/group/db_couchdb.md b/crates/weaver_forge/expected_output/group/db_couchdb.md new file mode 100644 index 00000000..a87e9ecd --- /dev/null +++ b/crates/weaver_forge/expected_output/group/db_couchdb.md @@ -0,0 +1,302 @@ +# Group `db.couchdb` (span) + +## Brief + +Call-level attributes for CouchDB + +prefix: + +## Attributes + + +### Attribute `db.system` + +An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. + + +- Requirement Level: Required + +- Tag: connection-level + +- Type: Enum [other_sql, mssql, mssqlcompact, mysql, oracle, db2, postgresql, redshift, hive, cloudscape, hsqldb, progress, maxdb, hanadb, ingres, firstsql, edb, cache, adabas, firebird, derby, filemaker, informix, instantdb, interbase, mariadb, netezza, pervasive, pointbase, sqlite, sybase, teradata, vertica, h2, coldfusion, cassandra, hbase, mongodb, redis, couchbase, couchdb, cosmosdb, dynamodb, neo4j, geode, elasticsearch, memcached, cockroachdb, opensearch, clickhouse, spanner, trino] + + +### Attribute `db.connection_string` + +The connection string used to connect to the database. It is recommended to remove embedded credentials. + + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: Server=(localdb)\v11.0;Integrated Security=true; + + +### Attribute `db.user` + +Username for accessing the database. + + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "readonly_user", + "reporting_user", +] + + +### Attribute `db.jdbc.driver_classname` + +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. + + + +- Requirement Level: Recommended + +- Tag: connection-level-tech-specific + +- Type: string +- Examples: [ + "org.postgresql.Driver", + "com.microsoft.sqlserver.jdbc.SQLServerDriver", +] + + +### Attribute `db.name` + +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). + + + +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). + +- Requirement Level: Conditionally Required - If applicable. + +- Tag: call-level + +- Type: string +- Examples: [ + "customers", + "main", +] + + +### Attribute `db.statement` + +The database statement being executed. + + + +- Requirement Level: Optional + +- Tag: call-level + +- Type: string +- Examples: [ + "SELECT * FROM wuser_table", + "SET mykey \"WuValue\"", +] + + +### Attribute `db.operation` + +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. + + + +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. + +- Requirement Level: Conditionally Required - If `db.statement` is not applicable. + +- Tag: call-level + +- Type: string +- Examples: [ + "findAndModify", + "HMSET", + "SELECT", +] + + +### Attribute `server.address` + +Name of the database host. + + + +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. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "example.com", + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +### Attribute `server.port` + +Server port number. + + +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. + +- Requirement Level: Conditionally Required - If using a port other than the default port for this DBMS and if `server.address` is set. + +- Tag: connection-level + +- Type: int +- Examples: [ + 80, + 8080, + 443, +] + +- Stability: Stable + + +### Attribute `network.peer.address` + +Peer address of the network connection - IP address or Unix domain socket name. + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +### Attribute `network.peer.port` + +Peer port number of the network connection. + + +- Requirement Level: Optional + +- Tag: connection-level + +- Type: int +- Examples: [ + 65123, +] + +- Stability: Stable + + +### Attribute `network.transport` + +[OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). + + + +The value SHOULD be normalized to lowercase. + +Consider always setting the transport when setting a port number, since +a port number is ambiguous without knowing the transport. For example +different processes could be listening on TCP port 12345 and UDP port 12345. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: Enum [tcp, udp, pipe, unix] +- Examples: [ + "tcp", + "udp", +] + +- Stability: Stable + + +### Attribute `network.type` + +[OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. + + +The value SHOULD be normalized to lowercase. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: Enum [ipv4, ipv6] +- Examples: [ + "ipv4", + "ipv6", +] + +- Stability: Stable + + +### Attribute `db.instance.id` + +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`. + + + +- Requirement Level: Optional + +- Tag: connection-level + +- Type: string +- Examples: mysql-e26b99z.example.com + + +### Attribute `db.operation` + +The HTTP method + the target REST route. + + + +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). + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific + +- Type: string +- Examples: [ + "GET /{db}/{docid}", +] + + + +## Provenance + +Source: data/trace-database.yaml + +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"AttributeDeprecated": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeRequirementLevel": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeSamplingRelevant": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeStability": {"group_id": "registry.db", "resolution_mode": "Reference"}} diff --git a/crates/weaver_forge/expected_output/group/db_elasticsearch.md b/crates/weaver_forge/expected_output/group/db_elasticsearch.md new file mode 100644 index 00000000..d5ea2e96 --- /dev/null +++ b/crates/weaver_forge/expected_output/group/db_elasticsearch.md @@ -0,0 +1,474 @@ +# Group `db.elasticsearch` (span) + +## Brief + +Call-level attributes for Elasticsearch + +prefix: + +## Attributes + + +### Attribute `db.system` + +An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. + + +- Requirement Level: Required + +- Tag: connection-level + +- Type: Enum [other_sql, mssql, mssqlcompact, mysql, oracle, db2, postgresql, redshift, hive, cloudscape, hsqldb, progress, maxdb, hanadb, ingres, firstsql, edb, cache, adabas, firebird, derby, filemaker, informix, instantdb, interbase, mariadb, netezza, pervasive, pointbase, sqlite, sybase, teradata, vertica, h2, coldfusion, cassandra, hbase, mongodb, redis, couchbase, couchdb, cosmosdb, dynamodb, neo4j, geode, elasticsearch, memcached, cockroachdb, opensearch, clickhouse, spanner, trino] + + +### Attribute `db.connection_string` + +The connection string used to connect to the database. It is recommended to remove embedded credentials. + + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: Server=(localdb)\v11.0;Integrated Security=true; + + +### Attribute `db.user` + +Username for accessing the database. + + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "readonly_user", + "reporting_user", +] + + +### Attribute `db.jdbc.driver_classname` + +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. + + + +- Requirement Level: Recommended + +- Tag: connection-level-tech-specific + +- Type: string +- Examples: [ + "org.postgresql.Driver", + "com.microsoft.sqlserver.jdbc.SQLServerDriver", +] + + +### Attribute `db.name` + +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). + + + +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). + +- Requirement Level: Conditionally Required - If applicable. + +- Tag: call-level + +- Type: string +- Examples: [ + "customers", + "main", +] + + +### Attribute `db.statement` + +The database statement being executed. + + + +- Requirement Level: Optional + +- Tag: call-level + +- Type: string +- Examples: [ + "SELECT * FROM wuser_table", + "SET mykey \"WuValue\"", +] + + +### Attribute `db.operation` + +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. + + + +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. + +- Requirement Level: Conditionally Required - If `db.statement` is not applicable. + +- Tag: call-level + +- Type: string +- Examples: [ + "findAndModify", + "HMSET", + "SELECT", +] + + +### Attribute `server.address` + +Name of the database host. + + + +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. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "example.com", + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +### Attribute `server.port` + +Server port number. + + +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. + +- Requirement Level: Conditionally Required - If using a port other than the default port for this DBMS and if `server.address` is set. + +- Tag: connection-level + +- Type: int +- Examples: [ + 80, + 8080, + 443, +] + +- Stability: Stable + + +### Attribute `network.peer.address` + +Peer address of the network connection - IP address or Unix domain socket name. + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +### Attribute `network.peer.port` + +Peer port number of the network connection. + + +- Requirement Level: Optional + +- Tag: connection-level + +- Type: int +- Examples: [ + 65123, +] + +- Stability: Stable + + +### Attribute `network.transport` + +[OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). + + + +The value SHOULD be normalized to lowercase. + +Consider always setting the transport when setting a port number, since +a port number is ambiguous without knowing the transport. For example +different processes could be listening on TCP port 12345 and UDP port 12345. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: Enum [tcp, udp, pipe, unix] +- Examples: [ + "tcp", + "udp", +] + +- Stability: Stable + + +### Attribute `network.type` + +[OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. + + +The value SHOULD be normalized to lowercase. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: Enum [ipv4, ipv6] +- Examples: [ + "ipv4", + "ipv6", +] + +- Stability: Stable + + +### Attribute `db.instance.id` + +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`. + + + +- Requirement Level: Optional + +- Tag: connection-level + +- Type: string +- Examples: mysql-e26b99z.example.com + + +### Attribute `http.request.method` + +HTTP request method. + + +HTTP request method value SHOULD be "known" to the instrumentation. +By default, this convention defines "known" methods as the ones listed in [RFC9110](https://www.rfc-editor.org/rfc/rfc9110.html#name-methods) +and the PATCH method defined in [RFC5789](https://www.rfc-editor.org/rfc/rfc5789.html). + +If the HTTP request method is not known to instrumentation, it MUST set the `http.request.method` attribute to `_OTHER`. + +If the HTTP instrumentation could end up converting valid HTTP request methods to `_OTHER`, then it MUST provide a way to override +the list of known HTTP methods. If this override is done via environment variable, then the environment variable MUST be named +OTEL_INSTRUMENTATION_HTTP_KNOWN_METHODS and support a comma-separated list of case-sensitive known HTTP methods +(this list MUST be a full override of the default known method, it is not a list of known methods in addition to the defaults). + +HTTP method names are case-sensitive and `http.request.method` attribute value MUST match a known HTTP method name exactly. +Instrumentations for specific web frameworks that consider HTTP methods to be case insensitive, SHOULD populate a canonical equivalent. +Tracing instrumentations that do so, MUST also set `http.request.method_original` to the original value. + +- Requirement Level: Required + +- Tag: call-level-tech-specific + +- Type: Enum [CONNECT, DELETE, GET, HEAD, OPTIONS, PATCH, POST, PUT, TRACE, _OTHER] +- Examples: [ + "GET", + "POST", + "HEAD", +] + +- Stability: Stable + + +### Attribute `db.operation` + +The endpoint identifier for the request. + + +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. + +- Requirement Level: Required + +- Tag: call-level-tech-specific + +- Type: string +- Examples: [ + "search", + "ml.close_job", + "cat.aliases", +] + + +### Attribute `url.full` + +Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986) + + +For network calls, URL usually has `scheme://host[:port][path][?query][#fragment]` format, where the fragment is not transmitted over HTTP, but if it is known, it SHOULD be included nevertheless. +`url.full` MUST NOT contain credentials passed via URL in form of `https://username:password@www.example.com/`. In such case username and password SHOULD be redacted and attribute's value SHOULD be `https://REDACTED:REDACTED@www.example.com/`. +`url.full` SHOULD capture the absolute URL when it is available (or can be reconstructed) and SHOULD NOT be validated or modified except for sanitizing purposes. + +- Requirement Level: Required + +- Tag: call-level-tech-specific + +- Type: string +- Examples: [ + "https://localhost:9200/index/_search?q=user.id:kimchy", +] + +- Stability: Stable + + +### Attribute `db.statement` + +The request body for a [search-type query](https://www.elastic.co/guide/en/elasticsearch/reference/current/search.html), as a json string. + + +- Requirement Level: Optional + +- Tag: call-level-tech-specific + +- Type: string +- Examples: [ + "\"{\\\"query\\\":{\\\"term\\\":{\\\"user.id\\\":\\\"kimchy\\\"}}}\"", +] + + +### Attribute `server.address` + +Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. + + +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. + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific + +- Type: string +- Examples: [ + "example.com", + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +### Attribute `server.port` + +Server port number. + + +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. + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific + +- Type: int +- Examples: [ + 80, + 8080, + 443, +] + +- Stability: Stable + + +### Attribute `db.elasticsearch.cluster.name` + +Represents the identifier of an Elasticsearch cluster. + + + +- Requirement Level: Optional + +- Tag: call-level-tech-specific + +- Type: string +- Examples: [ + "e9106fc68e3044f0b1475b04bf4ffd5f", +] + + +### Attribute `db.elasticsearch.node.name` + +Represents the human-readable identifier of the node/instance to which a request was routed. + + + +- Requirement Level: Optional + +- Tag: call-level-tech-specific + +- Type: string +- Examples: [ + "instance-0000000001", +] + + +### Attribute `db.elasticsearch.path_parts` + +A dynamic value in the url path. + + + +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. + +- Requirement Level: Conditionally Required - when the url has dynamic values + +- Tag: call-level-tech-specific + +- Type: template[string] +- Examples: [ + "db.elasticsearch.path_parts.index=test-index", + "db.elasticsearch.path_parts.doc_id=123", +] + + + +## Provenance + +Source: data/trace-database.yaml + +item: {"AttributeBrief": {"group_id": "registry.http", "resolution_mode": "Reference"}, "AttributeDeprecated": {"group_id": "registry.http", "resolution_mode": "Reference"}, "AttributeExamples": {"group_id": "registry.http", "resolution_mode": "Reference"}, "AttributeNote": {"group_id": "registry.http", "resolution_mode": "Reference"}, "AttributeSamplingRelevant": {"group_id": "registry.http", "resolution_mode": "Reference"}, "AttributeStability": {"group_id": "registry.http", "resolution_mode": "Reference"}} +item: {"AttributeDeprecated": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeNote": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeSamplingRelevant": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeStability": {"group_id": "registry.db", "resolution_mode": "Reference"}} +item: {"AttributeBrief": {"group_id": "registry.url", "resolution_mode": "Reference"}, "AttributeDeprecated": {"group_id": "registry.url", "resolution_mode": "Reference"}, "AttributeNote": {"group_id": "registry.url", "resolution_mode": "Reference"}, "AttributeSamplingRelevant": {"group_id": "registry.url", "resolution_mode": "Reference"}, "AttributeStability": {"group_id": "registry.url", "resolution_mode": "Reference"}} +item: {"AttributeDeprecated": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeNote": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeSamplingRelevant": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeStability": {"group_id": "registry.db", "resolution_mode": "Reference"}} +item: {"AttributeBrief": {"group_id": "server", "resolution_mode": "Reference"}, "AttributeDeprecated": {"group_id": "server", "resolution_mode": "Reference"}, "AttributeExamples": {"group_id": "server", "resolution_mode": "Reference"}, "AttributeNote": {"group_id": "server", "resolution_mode": "Reference"}, "AttributeRequirementLevel": {"group_id": "server", "resolution_mode": "Reference"}, "AttributeSamplingRelevant": {"group_id": "server", "resolution_mode": "Reference"}, "AttributeStability": {"group_id": "server", "resolution_mode": "Reference"}} +item: {"AttributeBrief": {"group_id": "server", "resolution_mode": "Reference"}, "AttributeDeprecated": {"group_id": "server", "resolution_mode": "Reference"}, "AttributeExamples": {"group_id": "server", "resolution_mode": "Reference"}, "AttributeNote": {"group_id": "server", "resolution_mode": "Reference"}, "AttributeRequirementLevel": {"group_id": "server", "resolution_mode": "Reference"}, "AttributeSamplingRelevant": {"group_id": "server", "resolution_mode": "Reference"}, "AttributeStability": {"group_id": "server", "resolution_mode": "Reference"}} +item: {"AttributeBrief": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeDeprecated": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeExamples": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeNote": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeSamplingRelevant": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeStability": {"group_id": "registry.db", "resolution_mode": "Reference"}} +item: {"AttributeBrief": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeDeprecated": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeExamples": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeNote": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeSamplingRelevant": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeStability": {"group_id": "registry.db", "resolution_mode": "Reference"}} +item: {"AttributeBrief": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeDeprecated": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeExamples": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeNote": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeSamplingRelevant": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeStability": {"group_id": "registry.db", "resolution_mode": "Reference"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} diff --git a/crates/weaver_forge/expected_output/group/db_hbase.md b/crates/weaver_forge/expected_output/group/db_hbase.md new file mode 100644 index 00000000..d2436e2d --- /dev/null +++ b/crates/weaver_forge/expected_output/group/db_hbase.md @@ -0,0 +1,302 @@ +# Group `db.hbase` (span) + +## Brief + +Call-level attributes for HBase + +prefix: + +## Attributes + + +### Attribute `db.system` + +An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. + + +- Requirement Level: Required + +- Tag: connection-level + +- Type: Enum [other_sql, mssql, mssqlcompact, mysql, oracle, db2, postgresql, redshift, hive, cloudscape, hsqldb, progress, maxdb, hanadb, ingres, firstsql, edb, cache, adabas, firebird, derby, filemaker, informix, instantdb, interbase, mariadb, netezza, pervasive, pointbase, sqlite, sybase, teradata, vertica, h2, coldfusion, cassandra, hbase, mongodb, redis, couchbase, couchdb, cosmosdb, dynamodb, neo4j, geode, elasticsearch, memcached, cockroachdb, opensearch, clickhouse, spanner, trino] + + +### Attribute `db.connection_string` + +The connection string used to connect to the database. It is recommended to remove embedded credentials. + + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: Server=(localdb)\v11.0;Integrated Security=true; + + +### Attribute `db.user` + +Username for accessing the database. + + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "readonly_user", + "reporting_user", +] + + +### Attribute `db.jdbc.driver_classname` + +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. + + + +- Requirement Level: Recommended + +- Tag: connection-level-tech-specific + +- Type: string +- Examples: [ + "org.postgresql.Driver", + "com.microsoft.sqlserver.jdbc.SQLServerDriver", +] + + +### Attribute `db.name` + +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). + + + +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). + +- Requirement Level: Conditionally Required - If applicable. + +- Tag: call-level + +- Type: string +- Examples: [ + "customers", + "main", +] + + +### Attribute `db.statement` + +The database statement being executed. + + + +- Requirement Level: Optional + +- Tag: call-level + +- Type: string +- Examples: [ + "SELECT * FROM wuser_table", + "SET mykey \"WuValue\"", +] + + +### Attribute `db.operation` + +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. + + + +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. + +- Requirement Level: Conditionally Required - If `db.statement` is not applicable. + +- Tag: call-level + +- Type: string +- Examples: [ + "findAndModify", + "HMSET", + "SELECT", +] + + +### Attribute `server.address` + +Name of the database host. + + + +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. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "example.com", + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +### Attribute `server.port` + +Server port number. + + +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. + +- Requirement Level: Conditionally Required - If using a port other than the default port for this DBMS and if `server.address` is set. + +- Tag: connection-level + +- Type: int +- Examples: [ + 80, + 8080, + 443, +] + +- Stability: Stable + + +### Attribute `network.peer.address` + +Peer address of the network connection - IP address or Unix domain socket name. + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +### Attribute `network.peer.port` + +Peer port number of the network connection. + + +- Requirement Level: Optional + +- Tag: connection-level + +- Type: int +- Examples: [ + 65123, +] + +- Stability: Stable + + +### Attribute `network.transport` + +[OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). + + + +The value SHOULD be normalized to lowercase. + +Consider always setting the transport when setting a port number, since +a port number is ambiguous without knowing the transport. For example +different processes could be listening on TCP port 12345 and UDP port 12345. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: Enum [tcp, udp, pipe, unix] +- Examples: [ + "tcp", + "udp", +] + +- Stability: Stable + + +### Attribute `network.type` + +[OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. + + +The value SHOULD be normalized to lowercase. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: Enum [ipv4, ipv6] +- Examples: [ + "ipv4", + "ipv6", +] + +- Stability: Stable + + +### Attribute `db.instance.id` + +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`. + + + +- Requirement Level: Optional + +- Tag: connection-level + +- Type: string +- Examples: mysql-e26b99z.example.com + + +### Attribute `db.name` + +The HBase namespace. + + + +For HBase the `db.name` should be set to the HBase namespace. + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific + +- Type: string +- Examples: [ + "mynamespace", +] + + + +## Provenance + +Source: data/trace-database.yaml + +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"AttributeDeprecated": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeRequirementLevel": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeSamplingRelevant": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeStability": {"group_id": "registry.db", "resolution_mode": "Reference"}} diff --git a/crates/weaver_forge/expected_output/group/db_mongodb.md b/crates/weaver_forge/expected_output/group/db_mongodb.md new file mode 100644 index 00000000..2a77857e --- /dev/null +++ b/crates/weaver_forge/expected_output/group/db_mongodb.md @@ -0,0 +1,301 @@ +# Group `db.mongodb` (span) + +## Brief + +Call-level attributes for MongoDB + +prefix: + +## Attributes + + +### Attribute `db.system` + +An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. + + +- Requirement Level: Required + +- Tag: connection-level + +- Type: Enum [other_sql, mssql, mssqlcompact, mysql, oracle, db2, postgresql, redshift, hive, cloudscape, hsqldb, progress, maxdb, hanadb, ingres, firstsql, edb, cache, adabas, firebird, derby, filemaker, informix, instantdb, interbase, mariadb, netezza, pervasive, pointbase, sqlite, sybase, teradata, vertica, h2, coldfusion, cassandra, hbase, mongodb, redis, couchbase, couchdb, cosmosdb, dynamodb, neo4j, geode, elasticsearch, memcached, cockroachdb, opensearch, clickhouse, spanner, trino] + + +### Attribute `db.connection_string` + +The connection string used to connect to the database. It is recommended to remove embedded credentials. + + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: Server=(localdb)\v11.0;Integrated Security=true; + + +### Attribute `db.user` + +Username for accessing the database. + + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "readonly_user", + "reporting_user", +] + + +### Attribute `db.jdbc.driver_classname` + +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. + + + +- Requirement Level: Recommended + +- Tag: connection-level-tech-specific + +- Type: string +- Examples: [ + "org.postgresql.Driver", + "com.microsoft.sqlserver.jdbc.SQLServerDriver", +] + + +### Attribute `db.name` + +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). + + + +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). + +- Requirement Level: Conditionally Required - If applicable. + +- Tag: call-level + +- Type: string +- Examples: [ + "customers", + "main", +] + + +### Attribute `db.statement` + +The database statement being executed. + + + +- Requirement Level: Optional + +- Tag: call-level + +- Type: string +- Examples: [ + "SELECT * FROM wuser_table", + "SET mykey \"WuValue\"", +] + + +### Attribute `db.operation` + +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. + + + +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. + +- Requirement Level: Conditionally Required - If `db.statement` is not applicable. + +- Tag: call-level + +- Type: string +- Examples: [ + "findAndModify", + "HMSET", + "SELECT", +] + + +### Attribute `server.address` + +Name of the database host. + + + +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. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "example.com", + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +### Attribute `server.port` + +Server port number. + + +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. + +- Requirement Level: Conditionally Required - If using a port other than the default port for this DBMS and if `server.address` is set. + +- Tag: connection-level + +- Type: int +- Examples: [ + 80, + 8080, + 443, +] + +- Stability: Stable + + +### Attribute `network.peer.address` + +Peer address of the network connection - IP address or Unix domain socket name. + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +### Attribute `network.peer.port` + +Peer port number of the network connection. + + +- Requirement Level: Optional + +- Tag: connection-level + +- Type: int +- Examples: [ + 65123, +] + +- Stability: Stable + + +### Attribute `network.transport` + +[OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). + + + +The value SHOULD be normalized to lowercase. + +Consider always setting the transport when setting a port number, since +a port number is ambiguous without knowing the transport. For example +different processes could be listening on TCP port 12345 and UDP port 12345. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: Enum [tcp, udp, pipe, unix] +- Examples: [ + "tcp", + "udp", +] + +- Stability: Stable + + +### Attribute `network.type` + +[OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. + + +The value SHOULD be normalized to lowercase. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: Enum [ipv4, ipv6] +- Examples: [ + "ipv4", + "ipv6", +] + +- Stability: Stable + + +### Attribute `db.instance.id` + +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`. + + + +- Requirement Level: Optional + +- Tag: connection-level + +- Type: string +- Examples: mysql-e26b99z.example.com + + +### Attribute `db.mongodb.collection` + +The MongoDB collection being accessed within the database stated in `db.name`. + + + +- Requirement Level: Required + +- Tag: call-level-tech-specific + +- Type: string +- Examples: [ + "customers", + "products", +] + + + +## Provenance + +Source: data/trace-database.yaml + +item: {"AttributeBrief": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeDeprecated": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeExamples": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeNote": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeSamplingRelevant": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeStability": {"group_id": "registry.db", "resolution_mode": "Reference"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} diff --git a/crates/weaver_forge/expected_output/group/db_mssql.md b/crates/weaver_forge/expected_output/group/db_mssql.md new file mode 100644 index 00000000..777eed1a --- /dev/null +++ b/crates/weaver_forge/expected_output/group/db_mssql.md @@ -0,0 +1,300 @@ +# Group `db.mssql` (span) + +## Brief + +Connection-level attributes for Microsoft SQL Server + +prefix: + +## Attributes + + +### Attribute `db.system` + +An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. + + +- Requirement Level: Required + +- Tag: connection-level + +- Type: Enum [other_sql, mssql, mssqlcompact, mysql, oracle, db2, postgresql, redshift, hive, cloudscape, hsqldb, progress, maxdb, hanadb, ingres, firstsql, edb, cache, adabas, firebird, derby, filemaker, informix, instantdb, interbase, mariadb, netezza, pervasive, pointbase, sqlite, sybase, teradata, vertica, h2, coldfusion, cassandra, hbase, mongodb, redis, couchbase, couchdb, cosmosdb, dynamodb, neo4j, geode, elasticsearch, memcached, cockroachdb, opensearch, clickhouse, spanner, trino] + + +### Attribute `db.connection_string` + +The connection string used to connect to the database. It is recommended to remove embedded credentials. + + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: Server=(localdb)\v11.0;Integrated Security=true; + + +### Attribute `db.user` + +Username for accessing the database. + + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "readonly_user", + "reporting_user", +] + + +### Attribute `db.jdbc.driver_classname` + +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. + + + +- Requirement Level: Recommended + +- Tag: connection-level-tech-specific + +- Type: string +- Examples: [ + "org.postgresql.Driver", + "com.microsoft.sqlserver.jdbc.SQLServerDriver", +] + + +### Attribute `db.name` + +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). + + + +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). + +- Requirement Level: Conditionally Required - If applicable. + +- Tag: call-level + +- Type: string +- Examples: [ + "customers", + "main", +] + + +### Attribute `db.statement` + +The database statement being executed. + + + +- Requirement Level: Optional + +- Tag: call-level + +- Type: string +- Examples: [ + "SELECT * FROM wuser_table", + "SET mykey \"WuValue\"", +] + + +### Attribute `db.operation` + +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. + + + +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. + +- Requirement Level: Conditionally Required - If `db.statement` is not applicable. + +- Tag: call-level + +- Type: string +- Examples: [ + "findAndModify", + "HMSET", + "SELECT", +] + + +### Attribute `server.address` + +Name of the database host. + + + +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. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "example.com", + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +### Attribute `server.port` + +Server port number. + + +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. + +- Requirement Level: Conditionally Required - If using a port other than the default port for this DBMS and if `server.address` is set. + +- Tag: connection-level + +- Type: int +- Examples: [ + 80, + 8080, + 443, +] + +- Stability: Stable + + +### Attribute `network.peer.address` + +Peer address of the network connection - IP address or Unix domain socket name. + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +### Attribute `network.peer.port` + +Peer port number of the network connection. + + +- Requirement Level: Optional + +- Tag: connection-level + +- Type: int +- Examples: [ + 65123, +] + +- Stability: Stable + + +### Attribute `network.transport` + +[OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). + + + +The value SHOULD be normalized to lowercase. + +Consider always setting the transport when setting a port number, since +a port number is ambiguous without knowing the transport. For example +different processes could be listening on TCP port 12345 and UDP port 12345. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: Enum [tcp, udp, pipe, unix] +- Examples: [ + "tcp", + "udp", +] + +- Stability: Stable + + +### Attribute `network.type` + +[OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. + + +The value SHOULD be normalized to lowercase. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: Enum [ipv4, ipv6] +- Examples: [ + "ipv4", + "ipv6", +] + +- Stability: Stable + + +### Attribute `db.instance.id` + +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`. + + + +- Requirement Level: Optional + +- Tag: connection-level + +- Type: string +- Examples: mysql-e26b99z.example.com + + +### Attribute `db.mssql.instance_name` + +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. + + + +If setting a `db.mssql.instance_name`, `server.port` is no longer required (but still recommended if non-standard). + +- Requirement Level: Recommended + +- Tag: connection-level-tech-specific + +- Type: string +- Examples: MSSQLSERVER + + + +## Provenance + +Source: data/trace-database.yaml + +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"AttributeBrief": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeDeprecated": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeExamples": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeNote": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeRequirementLevel": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeSamplingRelevant": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeStability": {"group_id": "registry.db", "resolution_mode": "Reference"}} diff --git a/crates/weaver_forge/expected_output/group/db_redis.md b/crates/weaver_forge/expected_output/group/db_redis.md new file mode 100644 index 00000000..b49d3844 --- /dev/null +++ b/crates/weaver_forge/expected_output/group/db_redis.md @@ -0,0 +1,321 @@ +# Group `db.redis` (span) + +## Brief + +Call-level attributes for Redis + +prefix: + +## Attributes + + +### Attribute `db.system` + +An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. + + +- Requirement Level: Required + +- Tag: connection-level + +- Type: Enum [other_sql, mssql, mssqlcompact, mysql, oracle, db2, postgresql, redshift, hive, cloudscape, hsqldb, progress, maxdb, hanadb, ingres, firstsql, edb, cache, adabas, firebird, derby, filemaker, informix, instantdb, interbase, mariadb, netezza, pervasive, pointbase, sqlite, sybase, teradata, vertica, h2, coldfusion, cassandra, hbase, mongodb, redis, couchbase, couchdb, cosmosdb, dynamodb, neo4j, geode, elasticsearch, memcached, cockroachdb, opensearch, clickhouse, spanner, trino] + + +### Attribute `db.connection_string` + +The connection string used to connect to the database. It is recommended to remove embedded credentials. + + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: Server=(localdb)\v11.0;Integrated Security=true; + + +### Attribute `db.user` + +Username for accessing the database. + + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "readonly_user", + "reporting_user", +] + + +### Attribute `db.jdbc.driver_classname` + +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. + + + +- Requirement Level: Recommended + +- Tag: connection-level-tech-specific + +- Type: string +- Examples: [ + "org.postgresql.Driver", + "com.microsoft.sqlserver.jdbc.SQLServerDriver", +] + + +### Attribute `db.name` + +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). + + + +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). + +- Requirement Level: Conditionally Required - If applicable. + +- Tag: call-level + +- Type: string +- Examples: [ + "customers", + "main", +] + + +### Attribute `db.statement` + +The database statement being executed. + + + +- Requirement Level: Optional + +- Tag: call-level + +- Type: string +- Examples: [ + "SELECT * FROM wuser_table", + "SET mykey \"WuValue\"", +] + + +### Attribute `db.operation` + +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. + + + +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. + +- Requirement Level: Conditionally Required - If `db.statement` is not applicable. + +- Tag: call-level + +- Type: string +- Examples: [ + "findAndModify", + "HMSET", + "SELECT", +] + + +### Attribute `server.address` + +Name of the database host. + + + +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. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "example.com", + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +### Attribute `server.port` + +Server port number. + + +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. + +- Requirement Level: Conditionally Required - If using a port other than the default port for this DBMS and if `server.address` is set. + +- Tag: connection-level + +- Type: int +- Examples: [ + 80, + 8080, + 443, +] + +- Stability: Stable + + +### Attribute `network.peer.address` + +Peer address of the network connection - IP address or Unix domain socket name. + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +### Attribute `network.peer.port` + +Peer port number of the network connection. + + +- Requirement Level: Optional + +- Tag: connection-level + +- Type: int +- Examples: [ + 65123, +] + +- Stability: Stable + + +### Attribute `network.transport` + +[OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). + + + +The value SHOULD be normalized to lowercase. + +Consider always setting the transport when setting a port number, since +a port number is ambiguous without knowing the transport. For example +different processes could be listening on TCP port 12345 and UDP port 12345. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: Enum [tcp, udp, pipe, unix] +- Examples: [ + "tcp", + "udp", +] + +- Stability: Stable + + +### Attribute `network.type` + +[OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. + + +The value SHOULD be normalized to lowercase. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: Enum [ipv4, ipv6] +- Examples: [ + "ipv4", + "ipv6", +] + +- Stability: Stable + + +### Attribute `db.instance.id` + +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`. + + + +- Requirement Level: Optional + +- Tag: connection-level + +- Type: string +- Examples: mysql-e26b99z.example.com + + +### Attribute `db.redis.database_index` + +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. + + + +- Requirement Level: Conditionally Required - If other than the default database (`0`). + +- Tag: call-level-tech-specific + +- Type: int +- Examples: [ + 0, + 1, + 15, +] + + +### Attribute `db.statement` + +The full syntax of the Redis CLI command. + + + +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`. + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific + +- Type: string +- Examples: [ + "HMSET myhash field1 'Hello' field2 'World'", +] + + + +## Provenance + +Source: data/trace-database.yaml + +item: {"AttributeDeprecated": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeRequirementLevel": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeSamplingRelevant": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeStability": {"group_id": "registry.db", "resolution_mode": "Reference"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"AttributeBrief": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeDeprecated": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeExamples": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeNote": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeSamplingRelevant": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeStability": {"group_id": "registry.db", "resolution_mode": "Reference"}} diff --git a/crates/weaver_forge/expected_output/group/db_sql.md b/crates/weaver_forge/expected_output/group/db_sql.md new file mode 100644 index 00000000..759e1de8 --- /dev/null +++ b/crates/weaver_forge/expected_output/group/db_sql.md @@ -0,0 +1,302 @@ +# Group `db.sql` (span) + +## Brief + +Call-level attributes for SQL databases + +prefix: + +## Attributes + + +### Attribute `db.system` + +An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. + + +- Requirement Level: Required + +- Tag: connection-level + +- Type: Enum [other_sql, mssql, mssqlcompact, mysql, oracle, db2, postgresql, redshift, hive, cloudscape, hsqldb, progress, maxdb, hanadb, ingres, firstsql, edb, cache, adabas, firebird, derby, filemaker, informix, instantdb, interbase, mariadb, netezza, pervasive, pointbase, sqlite, sybase, teradata, vertica, h2, coldfusion, cassandra, hbase, mongodb, redis, couchbase, couchdb, cosmosdb, dynamodb, neo4j, geode, elasticsearch, memcached, cockroachdb, opensearch, clickhouse, spanner, trino] + + +### Attribute `db.connection_string` + +The connection string used to connect to the database. It is recommended to remove embedded credentials. + + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: Server=(localdb)\v11.0;Integrated Security=true; + + +### Attribute `db.user` + +Username for accessing the database. + + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "readonly_user", + "reporting_user", +] + + +### Attribute `db.jdbc.driver_classname` + +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. + + + +- Requirement Level: Recommended + +- Tag: connection-level-tech-specific + +- Type: string +- Examples: [ + "org.postgresql.Driver", + "com.microsoft.sqlserver.jdbc.SQLServerDriver", +] + + +### Attribute `db.name` + +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). + + + +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). + +- Requirement Level: Conditionally Required - If applicable. + +- Tag: call-level + +- Type: string +- Examples: [ + "customers", + "main", +] + + +### Attribute `db.statement` + +The database statement being executed. + + + +- Requirement Level: Optional + +- Tag: call-level + +- Type: string +- Examples: [ + "SELECT * FROM wuser_table", + "SET mykey \"WuValue\"", +] + + +### Attribute `db.operation` + +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. + + + +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. + +- Requirement Level: Conditionally Required - If `db.statement` is not applicable. + +- Tag: call-level + +- Type: string +- Examples: [ + "findAndModify", + "HMSET", + "SELECT", +] + + +### Attribute `server.address` + +Name of the database host. + + + +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. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "example.com", + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +### Attribute `server.port` + +Server port number. + + +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. + +- Requirement Level: Conditionally Required - If using a port other than the default port for this DBMS and if `server.address` is set. + +- Tag: connection-level + +- Type: int +- Examples: [ + 80, + 8080, + 443, +] + +- Stability: Stable + + +### Attribute `network.peer.address` + +Peer address of the network connection - IP address or Unix domain socket name. + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +### Attribute `network.peer.port` + +Peer port number of the network connection. + + +- Requirement Level: Optional + +- Tag: connection-level + +- Type: int +- Examples: [ + 65123, +] + +- Stability: Stable + + +### Attribute `network.transport` + +[OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). + + + +The value SHOULD be normalized to lowercase. + +Consider always setting the transport when setting a port number, since +a port number is ambiguous without knowing the transport. For example +different processes could be listening on TCP port 12345 and UDP port 12345. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: Enum [tcp, udp, pipe, unix] +- Examples: [ + "tcp", + "udp", +] + +- Stability: Stable + + +### Attribute `network.type` + +[OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. + + +The value SHOULD be normalized to lowercase. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: Enum [ipv4, ipv6] +- Examples: [ + "ipv4", + "ipv6", +] + +- Stability: Stable + + +### Attribute `db.instance.id` + +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`. + + + +- Requirement Level: Optional + +- Tag: connection-level + +- Type: string +- Examples: mysql-e26b99z.example.com + + +### Attribute `db.sql.table` + +The name of the primary table that the operation is acting upon, including the database name (if applicable). + + +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. + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific + +- Type: string +- Examples: [ + "public.users", + "customers", +] + + + +## Provenance + +Source: data/trace-database.yaml + +item: {"AttributeBrief": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeDeprecated": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeExamples": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeNote": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeRequirementLevel": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeSamplingRelevant": {"group_id": "registry.db", "resolution_mode": "Reference"}, "AttributeStability": {"group_id": "registry.db", "resolution_mode": "Reference"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "db", "resolution_mode": "Extends"}} diff --git a/crates/weaver_forge/expected_output/group/db_tech.md b/crates/weaver_forge/expected_output/group/db_tech.md new file mode 100644 index 00000000..b06010fe --- /dev/null +++ b/crates/weaver_forge/expected_output/group/db_tech.md @@ -0,0 +1,591 @@ +# Group `db.tech` (span) + +## Brief + +Semantic convention group for specific technologies + +prefix: + +## Attributes + + +### Attribute `db.system` + +An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. + + +- Requirement Level: Required + +- Tag: connection-level + +- Type: Enum [other_sql, mssql, mssqlcompact, mysql, oracle, db2, postgresql, redshift, hive, cloudscape, hsqldb, progress, maxdb, hanadb, ingres, firstsql, edb, cache, adabas, firebird, derby, filemaker, informix, instantdb, interbase, mariadb, netezza, pervasive, pointbase, sqlite, sybase, teradata, vertica, h2, coldfusion, cassandra, hbase, mongodb, redis, couchbase, couchdb, cosmosdb, dynamodb, neo4j, geode, elasticsearch, memcached, cockroachdb, opensearch, clickhouse, spanner, trino] + + +### Attribute `db.connection_string` + +The connection string used to connect to the database. It is recommended to remove embedded credentials. + + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: Server=(localdb)\v11.0;Integrated Security=true; + + +### Attribute `db.user` + +Username for accessing the database. + + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "readonly_user", + "reporting_user", +] + + +### Attribute `db.jdbc.driver_classname` + +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. + + + +- Requirement Level: Recommended + +- Tag: connection-level-tech-specific + +- Type: string +- Examples: [ + "org.postgresql.Driver", + "com.microsoft.sqlserver.jdbc.SQLServerDriver", +] + + +### Attribute `db.name` + +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). + + + +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). + +- Requirement Level: Conditionally Required - If applicable. + +- Tag: call-level + +- Type: string +- Examples: [ + "customers", + "main", +] + + +### Attribute `db.statement` + +The database statement being executed. + + + +- Requirement Level: Optional + +- Tag: call-level + +- Type: string +- Examples: [ + "SELECT * FROM wuser_table", + "SET mykey \"WuValue\"", +] + + +### Attribute `db.operation` + +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. + + + +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. + +- Requirement Level: Conditionally Required - If `db.statement` is not applicable. + +- Tag: call-level + +- Type: string +- Examples: [ + "findAndModify", + "HMSET", + "SELECT", +] + + +### Attribute `server.address` + +Name of the database host. + + + +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. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "example.com", + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +### Attribute `server.port` + +Server port number. + + +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. + +- Requirement Level: Conditionally Required - If using a port other than the default port for this DBMS and if `server.address` is set. + +- Tag: connection-level + +- Type: int +- Examples: [ + 80, + 8080, + 443, +] + +- Stability: Stable + + +### Attribute `network.peer.address` + +Peer address of the network connection - IP address or Unix domain socket name. + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +### Attribute `network.peer.port` + +Peer port number of the network connection. + + +- Requirement Level: Optional + +- Tag: connection-level + +- Type: int +- Examples: [ + 65123, +] + +- Stability: Stable + + +### Attribute `network.transport` + +[OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). + + + +The value SHOULD be normalized to lowercase. + +Consider always setting the transport when setting a port number, since +a port number is ambiguous without knowing the transport. For example +different processes could be listening on TCP port 12345 and UDP port 12345. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: Enum [tcp, udp, pipe, unix] +- Examples: [ + "tcp", + "udp", +] + +- Stability: Stable + + +### Attribute `network.type` + +[OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. + + +The value SHOULD be normalized to lowercase. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: Enum [ipv4, ipv6] +- Examples: [ + "ipv4", + "ipv6", +] + +- Stability: Stable + + +### Attribute `db.instance.id` + +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`. + + + +- Requirement Level: Optional + +- Tag: connection-level + +- Type: string +- Examples: mysql-e26b99z.example.com + + +### Attribute `db.name` + +The keyspace name in Cassandra. + + + +For Cassandra the `db.name` should be set to the Cassandra keyspace name. + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific-cassandra + +- Type: string +- Examples: [ + "mykeyspace", +] + + +### Attribute `db.cassandra.page_size` + +The fetch size used for paging, i.e. how many rows will be returned at once. + + + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific-cassandra + +- Type: int +- Examples: [ + 5000, +] + + +### Attribute `db.cassandra.consistency_level` + +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). + + + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific-cassandra + +- Type: Enum [all, each_quorum, quorum, local_quorum, one, two, three, local_one, any, serial, local_serial] + + +### Attribute `db.cassandra.table` + +The name of the primary Cassandra table that the operation is acting upon, including the keyspace name (if applicable). + + +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. + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific-cassandra + +- Type: string +- Examples: mytable + + +### Attribute `db.cassandra.idempotence` + +Whether or not the query is idempotent. + + + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific-cassandra + +- Type: boolean + + +### Attribute `db.cassandra.speculative_execution_count` + +The number of times a query was speculatively executed. Not set or `0` if the query was not executed speculatively. + + + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific-cassandra + +- Type: int +- Examples: [ + 0, + 2, +] + + +### Attribute `db.cassandra.coordinator.id` + +The ID of the coordinating node for a query. + + + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific-cassandra + +- Type: string +- Examples: be13faa2-8574-4d71-926d-27f16cf8a7af + + +### Attribute `db.cassandra.coordinator.dc` + +The data center of the coordinating node for a query. + + + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific-cassandra + +- Type: string +- Examples: us-west-2 + + +### Attribute `db.redis.database_index` + +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. + + + +- Requirement Level: Conditionally Required - If other than the default database (`0`). + +- Tag: call-level-tech-specific + +- Type: int +- Examples: [ + 0, + 1, + 15, +] + + +### Attribute `db.statement` + +The full syntax of the Redis CLI command. + + + +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`. + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific + +- Type: string +- Examples: [ + "HMSET myhash field1 'Hello' field2 'World'", +] + + +### Attribute `db.mongodb.collection` + +The MongoDB collection being accessed within the database stated in `db.name`. + + + +- Requirement Level: Required + +- Tag: call-level-tech-specific + +- Type: string +- Examples: [ + "customers", + "products", +] + + +### Attribute `db.sql.table` + +The name of the primary table that the operation is acting upon, including the database name (if applicable). + + +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. + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific + +- Type: string +- Examples: [ + "public.users", + "customers", +] + + +### Attribute `db.cosmosdb.client_id` + +Unique Cosmos client instance id. + + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific + +- Type: string +- Examples: 3ba4827d-4422-483f-b59f-85b74211c11d + + +### Attribute `db.cosmosdb.operation_type` + +CosmosDB Operation Type. + + +- Requirement Level: Conditionally Required - when performing one of the operations in this list + +- Tag: call-level-tech-specific + +- Type: Enum [Invalid, Create, Patch, Read, ReadFeed, Delete, Replace, Execute, Query, Head, HeadFeed, Upsert, Batch, QueryPlan, ExecuteJavaScript] + + +### Attribute `user_agent.original` + +Full user-agent string is generated by Cosmos DB SDK + + +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. + Format Reg-{D (Disabled discovery)}-S(application region)|L(List of preferred regions)|N(None, user did not configure it). + Default value is "NS". + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific + +- Type: string +- 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\\|", +] + +- Stability: Stable + + +### Attribute `db.cosmosdb.connection_mode` + +Cosmos client connection mode. + + +- Requirement Level: Conditionally Required - if not `direct` (or pick gw as default) + +- Tag: call-level-tech-specific + +- Type: Enum [gateway, direct] + + +### Attribute `db.cosmosdb.container` + +Cosmos DB container name. + + +- Requirement Level: Conditionally Required - if available + +- Tag: call-level-tech-specific + +- Type: string +- Examples: anystring + + +### Attribute `db.cosmosdb.request_content_length` + +Request payload size in bytes + + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific + +- Type: int + + +### Attribute `db.cosmosdb.status_code` + +Cosmos DB status code. + + +- Requirement Level: Conditionally Required - if response was received + +- Tag: call-level-tech-specific + +- Type: int +- Examples: [ + 200, + 201, +] + + +### Attribute `db.cosmosdb.sub_status_code` + +Cosmos DB sub status code. + + +- Requirement Level: Conditionally Required - when response was received and contained sub-code. + +- Tag: call-level-tech-specific + +- Type: int +- Examples: [ + 1000, + 1002, +] + + +### Attribute `db.cosmosdb.request_charge` + +RU consumed for that operation + + +- Requirement Level: Conditionally Required - when available + +- Tag: call-level-tech-specific + +- Type: double +- Examples: [ + 46.18, + 1.0, +] + + + +## Provenance + +Source: data/trace-database.yaml + diff --git a/crates/weaver_forge/expected_output/group/ios_lifecycle_events.md b/crates/weaver_forge/expected_output/group/ios_lifecycle_events.md new file mode 100644 index 00000000..dff4afab --- /dev/null +++ b/crates/weaver_forge/expected_output/group/ios_lifecycle_events.md @@ -0,0 +1,31 @@ +# Group `ios.lifecycle.events` (event) + +## Brief + +This event represents an occurrence of a lifecycle transition on the iOS platform. + +prefix: ios + +## Attributes + + +### Attribute `ios.state` + +This attribute represents the state the application has transitioned into at the occurrence of the event. + + + +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. + +- Requirement Level: Required + +- Type: Enum [active, inactive, background, foreground, terminate] + +- Stability: Experimental + + + +## Provenance + +Source: data/mobile-events.yaml + diff --git a/crates/weaver_forge/expected_output/group/metric_jvm_class_count.md b/crates/weaver_forge/expected_output/group/metric_jvm_class_count.md new file mode 100644 index 00000000..ebea038e --- /dev/null +++ b/crates/weaver_forge/expected_output/group/metric_jvm_class_count.md @@ -0,0 +1,16 @@ +# Group `metric.jvm.class.count` (metric) + +## Brief + +Number of classes currently loaded. + +prefix: + +## Attributes + + + +## Provenance + +Source: data/jvm-metrics.yaml + diff --git a/crates/weaver_forge/expected_output/group/metric_jvm_class_loaded.md b/crates/weaver_forge/expected_output/group/metric_jvm_class_loaded.md new file mode 100644 index 00000000..b1941970 --- /dev/null +++ b/crates/weaver_forge/expected_output/group/metric_jvm_class_loaded.md @@ -0,0 +1,16 @@ +# Group `metric.jvm.class.loaded` (metric) + +## Brief + +Number of classes loaded since JVM start. + +prefix: + +## Attributes + + + +## Provenance + +Source: data/jvm-metrics.yaml + diff --git a/crates/weaver_forge/expected_output/group/metric_jvm_class_unloaded.md b/crates/weaver_forge/expected_output/group/metric_jvm_class_unloaded.md new file mode 100644 index 00000000..fc095623 --- /dev/null +++ b/crates/weaver_forge/expected_output/group/metric_jvm_class_unloaded.md @@ -0,0 +1,16 @@ +# Group `metric.jvm.class.unloaded` (metric) + +## Brief + +Number of classes unloaded since JVM start. + +prefix: + +## Attributes + + + +## Provenance + +Source: data/jvm-metrics.yaml + diff --git a/crates/weaver_forge/expected_output/group/metric_jvm_cpu_count.md b/crates/weaver_forge/expected_output/group/metric_jvm_cpu_count.md new file mode 100644 index 00000000..e28045ba --- /dev/null +++ b/crates/weaver_forge/expected_output/group/metric_jvm_cpu_count.md @@ -0,0 +1,16 @@ +# Group `metric.jvm.cpu.count` (metric) + +## Brief + +Number of processors available to the Java virtual machine. + +prefix: + +## Attributes + + + +## Provenance + +Source: data/jvm-metrics.yaml + diff --git a/crates/weaver_forge/expected_output/group/metric_jvm_cpu_recent_utilization.md b/crates/weaver_forge/expected_output/group/metric_jvm_cpu_recent_utilization.md new file mode 100644 index 00000000..7a5cc692 --- /dev/null +++ b/crates/weaver_forge/expected_output/group/metric_jvm_cpu_recent_utilization.md @@ -0,0 +1,16 @@ +# Group `metric.jvm.cpu.recent_utilization` (metric) + +## Brief + +Recent CPU utilization for the process as reported by the JVM. + +prefix: + +## Attributes + + + +## Provenance + +Source: data/jvm-metrics.yaml + diff --git a/crates/weaver_forge/expected_output/group/metric_jvm_cpu_time.md b/crates/weaver_forge/expected_output/group/metric_jvm_cpu_time.md new file mode 100644 index 00000000..1a427a9c --- /dev/null +++ b/crates/weaver_forge/expected_output/group/metric_jvm_cpu_time.md @@ -0,0 +1,16 @@ +# Group `metric.jvm.cpu.time` (metric) + +## Brief + +CPU time used by the process as reported by the JVM. + +prefix: + +## Attributes + + + +## Provenance + +Source: data/jvm-metrics.yaml + diff --git a/crates/weaver_forge/expected_output/group/metric_jvm_gc_duration.md b/crates/weaver_forge/expected_output/group/metric_jvm_gc_duration.md new file mode 100644 index 00000000..9e3077cf --- /dev/null +++ b/crates/weaver_forge/expected_output/group/metric_jvm_gc_duration.md @@ -0,0 +1,52 @@ +# Group `metric.jvm.gc.duration` (metric) + +## Brief + +Duration of JVM garbage collection actions. + +prefix: jvm.gc + +## Attributes + + +### Attribute `jvm.gc.name` + +Name of the garbage collector. + + +Garbage collector name is generally obtained via [GarbageCollectionNotificationInfo#getGcName()](https://docs.oracle.com/en/java/javase/11/docs/api/jdk.management/com/sun/management/GarbageCollectionNotificationInfo.html#getGcName()). + +- Requirement Level: Recommended + +- Type: string +- Examples: [ + "G1 Young Generation", + "G1 Old Generation", +] + +- Stability: Stable + + +### Attribute `jvm.gc.action` + +Name of the garbage collector action. + + +Garbage collector action is generally obtained via [GarbageCollectionNotificationInfo#getGcAction()](https://docs.oracle.com/en/java/javase/11/docs/api/jdk.management/com/sun/management/GarbageCollectionNotificationInfo.html#getGcAction()). + +- Requirement Level: Recommended + +- Type: string +- Examples: [ + "end of minor GC", + "end of major GC", +] + +- Stability: Stable + + + +## Provenance + +Source: data/jvm-metrics.yaml + diff --git a/crates/weaver_forge/expected_output/group/metric_jvm_memory_committed.md b/crates/weaver_forge/expected_output/group/metric_jvm_memory_committed.md new file mode 100644 index 00000000..0abfa6d7 --- /dev/null +++ b/crates/weaver_forge/expected_output/group/metric_jvm_memory_committed.md @@ -0,0 +1,53 @@ +# Group `metric.jvm.memory.committed` (metric) + +## Brief + +Measure of memory committed. + +prefix: + +## Attributes + + +### Attribute `jvm.memory.type` + +The type of memory. + + +- Requirement Level: Recommended + +- Type: Enum [heap, non_heap] +- Examples: [ + "heap", + "non_heap", +] + +- Stability: Stable + + +### Attribute `jvm.memory.pool.name` + +Name of the memory pool. + + +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()). + +- Requirement Level: Recommended + +- Type: string +- Examples: [ + "G1 Old Gen", + "G1 Eden space", + "G1 Survivor Space", +] + +- Stability: Stable + + + +## Provenance + +Source: data/jvm-metrics.yaml + +item: {"GroupAttributes": {"group_id": "attributes.jvm.memory", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "attributes.jvm.memory", "resolution_mode": "Extends"}} diff --git a/crates/weaver_forge/expected_output/group/metric_jvm_memory_limit.md b/crates/weaver_forge/expected_output/group/metric_jvm_memory_limit.md new file mode 100644 index 00000000..3883f7d8 --- /dev/null +++ b/crates/weaver_forge/expected_output/group/metric_jvm_memory_limit.md @@ -0,0 +1,53 @@ +# Group `metric.jvm.memory.limit` (metric) + +## Brief + +Measure of max obtainable memory. + +prefix: + +## Attributes + + +### Attribute `jvm.memory.type` + +The type of memory. + + +- Requirement Level: Recommended + +- Type: Enum [heap, non_heap] +- Examples: [ + "heap", + "non_heap", +] + +- Stability: Stable + + +### Attribute `jvm.memory.pool.name` + +Name of the memory pool. + + +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()). + +- Requirement Level: Recommended + +- Type: string +- Examples: [ + "G1 Old Gen", + "G1 Eden space", + "G1 Survivor Space", +] + +- Stability: Stable + + + +## Provenance + +Source: data/jvm-metrics.yaml + +item: {"GroupAttributes": {"group_id": "attributes.jvm.memory", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "attributes.jvm.memory", "resolution_mode": "Extends"}} diff --git a/crates/weaver_forge/expected_output/group/metric_jvm_memory_used.md b/crates/weaver_forge/expected_output/group/metric_jvm_memory_used.md new file mode 100644 index 00000000..8c00a483 --- /dev/null +++ b/crates/weaver_forge/expected_output/group/metric_jvm_memory_used.md @@ -0,0 +1,53 @@ +# Group `metric.jvm.memory.used` (metric) + +## Brief + +Measure of memory used. + +prefix: + +## Attributes + + +### Attribute `jvm.memory.type` + +The type of memory. + + +- Requirement Level: Recommended + +- Type: Enum [heap, non_heap] +- Examples: [ + "heap", + "non_heap", +] + +- Stability: Stable + + +### Attribute `jvm.memory.pool.name` + +Name of the memory pool. + + +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()). + +- Requirement Level: Recommended + +- Type: string +- Examples: [ + "G1 Old Gen", + "G1 Eden space", + "G1 Survivor Space", +] + +- Stability: Stable + + + +## Provenance + +Source: data/jvm-metrics.yaml + +item: {"GroupAttributes": {"group_id": "attributes.jvm.memory", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "attributes.jvm.memory", "resolution_mode": "Extends"}} diff --git a/crates/weaver_forge/expected_output/group/metric_jvm_memory_used_after_last_gc.md b/crates/weaver_forge/expected_output/group/metric_jvm_memory_used_after_last_gc.md new file mode 100644 index 00000000..874dfe2f --- /dev/null +++ b/crates/weaver_forge/expected_output/group/metric_jvm_memory_used_after_last_gc.md @@ -0,0 +1,53 @@ +# Group `metric.jvm.memory.used_after_last_gc` (metric) + +## Brief + +Measure of memory used, as measured after the most recent garbage collection event on this pool. + +prefix: + +## Attributes + + +### Attribute `jvm.memory.type` + +The type of memory. + + +- Requirement Level: Recommended + +- Type: Enum [heap, non_heap] +- Examples: [ + "heap", + "non_heap", +] + +- Stability: Stable + + +### Attribute `jvm.memory.pool.name` + +Name of the memory pool. + + +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()). + +- Requirement Level: Recommended + +- Type: string +- Examples: [ + "G1 Old Gen", + "G1 Eden space", + "G1 Survivor Space", +] + +- Stability: Stable + + + +## Provenance + +Source: data/jvm-metrics.yaml + +item: {"GroupAttributes": {"group_id": "attributes.jvm.memory", "resolution_mode": "Extends"}} +item: {"GroupAttributes": {"group_id": "attributes.jvm.memory", "resolution_mode": "Extends"}} diff --git a/crates/weaver_forge/expected_output/group/metric_jvm_thread_count.md b/crates/weaver_forge/expected_output/group/metric_jvm_thread_count.md new file mode 100644 index 00000000..9cc2263a --- /dev/null +++ b/crates/weaver_forge/expected_output/group/metric_jvm_thread_count.md @@ -0,0 +1,44 @@ +# Group `metric.jvm.thread.count` (metric) + +## Brief + +Number of executing platform threads. + +prefix: + +## Attributes + + +### Attribute `jvm.thread.daemon` + +Whether the thread is daemon or not. + + +- Requirement Level: Recommended + +- Type: boolean + +- Stability: Stable + + +### Attribute `jvm.thread.state` + +State of the thread. + + +- Requirement Level: Recommended + +- Type: Enum [new, runnable, blocked, waiting, timed_waiting, terminated] +- Examples: [ + "runnable", + "blocked", +] + +- Stability: Stable + + + +## Provenance + +Source: data/jvm-metrics.yaml + diff --git a/crates/weaver_forge/expected_output/group/otel_library.md b/crates/weaver_forge/expected_output/group/otel_library.md new file mode 100644 index 00000000..07481562 --- /dev/null +++ b/crates/weaver_forge/expected_output/group/otel_library.md @@ -0,0 +1,44 @@ +# Group `otel.library` (resource) + +## Brief + +Span attributes used by non-OTLP exporters to represent OpenTelemetry Scope's concepts. + +prefix: otel.library + +## Attributes + + +### Attribute `otel.library.name` + + + + +- Requirement Level: Recommended + +- Type: string +- Examples: [ + "io.opentelemetry.contrib.mongodb", +] +- Deprecated: use the `otel.scope.name` attribute. + + +### Attribute `otel.library.version` + + + + +- Requirement Level: Recommended + +- Type: string +- Examples: [ + "1.0.0", +] +- Deprecated: use the `otel.scope.version` attribute. + + + +## Provenance + +Source: data/exporter.yaml + diff --git a/crates/weaver_forge/expected_output/group/otel_scope.md b/crates/weaver_forge/expected_output/group/otel_scope.md new file mode 100644 index 00000000..6249df56 --- /dev/null +++ b/crates/weaver_forge/expected_output/group/otel_scope.md @@ -0,0 +1,46 @@ +# Group `otel.scope` (resource) + +## Brief + +Attributes used by non-OTLP exporters to represent OpenTelemetry Scope's concepts. + +prefix: otel.scope + +## Attributes + + +### Attribute `otel.scope.name` + +The name of the instrumentation scope - (`InstrumentationScope.Name` in OTLP). + + +- Requirement Level: Recommended + +- Type: string +- Examples: [ + "io.opentelemetry.contrib.mongodb", +] + +- Stability: Stable + + +### Attribute `otel.scope.version` + +The version of the instrumentation scope - (`InstrumentationScope.Version` in OTLP). + + +- Requirement Level: Recommended + +- Type: string +- Examples: [ + "1.0.0", +] + +- Stability: Stable + + + +## Provenance + +Source: data/exporter.yaml + diff --git a/crates/weaver_forge/expected_output/group/registry_db.md b/crates/weaver_forge/expected_output/group/registry_db.md new file mode 100644 index 00000000..c01fba5d --- /dev/null +++ b/crates/weaver_forge/expected_output/group/registry_db.md @@ -0,0 +1,478 @@ +# Group `registry.db` (attribute_group) + +## Brief + +This document defines the attributes used to describe telemetry in the context of databases. + +prefix: db + +## Attributes + + +### Attribute `db.cassandra.coordinator.dc` + +The data center of the coordinating node for a query. + + + +- Requirement Level: Recommended + +- Tag: tech-specific-cassandra + +- Type: string +- Examples: us-west-2 + + +### Attribute `db.cassandra.coordinator.id` + +The ID of the coordinating node for a query. + + + +- Requirement Level: Recommended + +- Tag: tech-specific-cassandra + +- Type: string +- Examples: be13faa2-8574-4d71-926d-27f16cf8a7af + + +### Attribute `db.cassandra.consistency_level` + +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). + + + +- Requirement Level: Recommended + +- Tag: tech-specific-cassandra + +- Type: Enum [all, each_quorum, quorum, local_quorum, one, two, three, local_one, any, serial, local_serial] + + +### Attribute `db.cassandra.idempotence` + +Whether or not the query is idempotent. + + + +- Requirement Level: Recommended + +- Tag: tech-specific-cassandra + +- Type: boolean + + +### Attribute `db.cassandra.page_size` + +The fetch size used for paging, i.e. how many rows will be returned at once. + + + +- Requirement Level: Recommended + +- Tag: tech-specific-cassandra + +- Type: int +- Examples: [ + 5000, +] + + +### Attribute `db.cassandra.speculative_execution_count` + +The number of times a query was speculatively executed. Not set or `0` if the query was not executed speculatively. + + + +- Requirement Level: Recommended + +- Tag: tech-specific-cassandra + +- Type: int +- Examples: [ + 0, + 2, +] + + +### Attribute `db.cassandra.table` + +The name of the primary Cassandra table that the operation is acting upon, including the keyspace name (if applicable). + + +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. + +- Requirement Level: Recommended + +- Tag: tech-specific-cassandra + +- Type: string +- Examples: mytable + + +### Attribute `db.connection_string` + +The connection string used to connect to the database. It is recommended to remove embedded credentials. + + + +- Requirement Level: Recommended + +- Tag: db-generic + +- Type: string +- Examples: Server=(localdb)\v11.0;Integrated Security=true; + + +### Attribute `db.cosmosdb.client_id` + +Unique Cosmos client instance id. + + +- Requirement Level: Recommended + +- Tag: tech-specific-cosmosdb + +- Type: string +- Examples: 3ba4827d-4422-483f-b59f-85b74211c11d + + +### Attribute `db.cosmosdb.connection_mode` + +Cosmos client connection mode. + + +- Requirement Level: Recommended + +- Tag: tech-specific-cosmosdb + +- Type: Enum [gateway, direct] + + +### Attribute `db.cosmosdb.container` + +Cosmos DB container name. + + +- Requirement Level: Recommended + +- Tag: tech-specific-cosmosdb + +- Type: string +- Examples: anystring + + +### Attribute `db.cosmosdb.operation_type` + +CosmosDB Operation Type. + + +- Requirement Level: Recommended + +- Tag: tech-specific-cosmosdb + +- Type: Enum [Invalid, Create, Patch, Read, ReadFeed, Delete, Replace, Execute, Query, Head, HeadFeed, Upsert, Batch, QueryPlan, ExecuteJavaScript] + + +### Attribute `db.cosmosdb.request_charge` + +RU consumed for that operation + + +- Requirement Level: Recommended + +- Tag: tech-specific-cosmosdb + +- Type: double +- Examples: [ + 46.18, + 1.0, +] + + +### Attribute `db.cosmosdb.request_content_length` + +Request payload size in bytes + + +- Requirement Level: Recommended + +- Tag: tech-specific-cosmosdb + +- Type: int + + +### Attribute `db.cosmosdb.status_code` + +Cosmos DB status code. + + +- Requirement Level: Recommended + +- Tag: tech-specific-cosmosdb + +- Type: int +- Examples: [ + 200, + 201, +] + + +### Attribute `db.cosmosdb.sub_status_code` + +Cosmos DB sub status code. + + +- Requirement Level: Recommended + +- Tag: tech-specific-cosmosdb + +- Type: int +- Examples: [ + 1000, + 1002, +] + + +### Attribute `db.elasticsearch.cluster.name` + +Represents the identifier of an Elasticsearch cluster. + + + +- Requirement Level: Recommended + +- Tag: tech-specific-elasticsearch + +- Type: string +- Examples: [ + "e9106fc68e3044f0b1475b04bf4ffd5f", +] + + +### Attribute `db.elasticsearch.node.name` + +Represents the human-readable identifier of the node/instance to which a request was routed. + + + +- Requirement Level: Recommended + +- Tag: tech-specific-elasticsearch + +- Type: string +- Examples: [ + "instance-0000000001", +] + + +### Attribute `db.elasticsearch.path_parts` + +A dynamic value in the url path. + + + +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. + +- Requirement Level: Recommended + +- Tag: tech-specific-elasticsearch + +- Type: template[string] +- Examples: [ + "db.elasticsearch.path_parts.index=test-index", + "db.elasticsearch.path_parts.doc_id=123", +] + + +### Attribute `db.jdbc.driver_classname` + +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. + + + +- Requirement Level: Recommended + +- Tag: tech-specific-jdbc + +- Type: string +- Examples: [ + "org.postgresql.Driver", + "com.microsoft.sqlserver.jdbc.SQLServerDriver", +] + + +### Attribute `db.mongodb.collection` + +The MongoDB collection being accessed within the database stated in `db.name`. + + + +- Requirement Level: Recommended + +- Tag: tech-specific-mongodb + +- Type: string +- Examples: [ + "customers", + "products", +] + + +### Attribute `db.mssql.instance_name` + +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. + + + +If setting a `db.mssql.instance_name`, `server.port` is no longer required (but still recommended if non-standard). + +- Requirement Level: Recommended + +- Tag: tech-specific-mssql + +- Type: string +- Examples: MSSQLSERVER + + +### Attribute `db.name` + +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). + + + +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). + +- Requirement Level: Recommended + +- Tag: db-generic + +- Type: string +- Examples: [ + "customers", + "main", +] + + +### Attribute `db.operation` + +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. + + + +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. + +- Requirement Level: Recommended + +- Tag: db-generic + +- Type: string +- Examples: [ + "findAndModify", + "HMSET", + "SELECT", +] + + +### Attribute `db.redis.database_index` + +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. + + + +- Requirement Level: Recommended + +- Tag: tech-specific-redis + +- Type: int +- Examples: [ + 0, + 1, + 15, +] + + +### Attribute `db.sql.table` + +The name of the primary table that the operation is acting upon, including the database name (if applicable). + + +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. + +- Requirement Level: Recommended + +- Tag: tech-specific-sql + +- Type: string +- Examples: [ + "public.users", + "customers", +] + + +### Attribute `db.statement` + +The database statement being executed. + + + +- Requirement Level: Recommended + +- Tag: db-generic + +- Type: string +- Examples: [ + "SELECT * FROM wuser_table", + "SET mykey \"WuValue\"", +] + + +### Attribute `db.system` + +An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. + + +- Requirement Level: Recommended + +- Tag: db-generic + +- Type: Enum [other_sql, mssql, mssqlcompact, mysql, oracle, db2, postgresql, redshift, hive, cloudscape, hsqldb, progress, maxdb, hanadb, ingres, firstsql, edb, cache, adabas, firebird, derby, filemaker, informix, instantdb, interbase, mariadb, netezza, pervasive, pointbase, sqlite, sybase, teradata, vertica, h2, coldfusion, cassandra, hbase, mongodb, redis, couchbase, couchdb, cosmosdb, dynamodb, neo4j, geode, elasticsearch, memcached, cockroachdb, opensearch, clickhouse, spanner, trino] + + +### Attribute `db.user` + +Username for accessing the database. + + + +- Requirement Level: Recommended + +- Tag: db-generic + +- Type: string +- Examples: [ + "readonly_user", + "reporting_user", +] + + +### Attribute `db.instance.id` + +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`. + + + +- Requirement Level: Recommended + +- Tag: db-generic + +- Type: string +- Examples: mysql-e26b99z.example.com + + + +## Provenance + +Source: data/registry-db.yaml + diff --git a/crates/weaver_forge/expected_output/group/registry_http.md b/crates/weaver_forge/expected_output/group/registry_http.md new file mode 100644 index 00000000..f5dff5df --- /dev/null +++ b/crates/weaver_forge/expected_output/group/registry_http.md @@ -0,0 +1,186 @@ +# Group `registry.http` (attribute_group) + +## Brief + +This document defines semantic convention attributes in the HTTP namespace. + +prefix: http + +## Attributes + + +### Attribute `http.request.body.size` + +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. + + + +- Requirement Level: Recommended + +- Type: int +- Examples: 3495 + +- Stability: Experimental + + +### Attribute `http.request.header` + +HTTP request headers, `` being the normalized HTTP Header name (lowercase), the value being the header values. + + + +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. +The `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. +The 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. + +- Requirement Level: Recommended + +- Type: template[string[]] +- Examples: [ + "http.request.header.content-type=[\"application/json\"]", + "http.request.header.x-forwarded-for=[\"1.2.3.4\", \"1.2.3.5\"]", +] + +- Stability: Stable + + +### Attribute `http.request.method` + +HTTP request method. + + +HTTP request method value SHOULD be "known" to the instrumentation. +By default, this convention defines "known" methods as the ones listed in [RFC9110](https://www.rfc-editor.org/rfc/rfc9110.html#name-methods) +and the PATCH method defined in [RFC5789](https://www.rfc-editor.org/rfc/rfc5789.html). + +If the HTTP request method is not known to instrumentation, it MUST set the `http.request.method` attribute to `_OTHER`. + +If the HTTP instrumentation could end up converting valid HTTP request methods to `_OTHER`, then it MUST provide a way to override +the list of known HTTP methods. If this override is done via environment variable, then the environment variable MUST be named +OTEL_INSTRUMENTATION_HTTP_KNOWN_METHODS and support a comma-separated list of case-sensitive known HTTP methods +(this list MUST be a full override of the default known method, it is not a list of known methods in addition to the defaults). + +HTTP method names are case-sensitive and `http.request.method` attribute value MUST match a known HTTP method name exactly. +Instrumentations for specific web frameworks that consider HTTP methods to be case insensitive, SHOULD populate a canonical equivalent. +Tracing instrumentations that do so, MUST also set `http.request.method_original` to the original value. + +- Requirement Level: Recommended + +- Type: Enum [CONNECT, DELETE, GET, HEAD, OPTIONS, PATCH, POST, PUT, TRACE, _OTHER] +- Examples: [ + "GET", + "POST", + "HEAD", +] + +- Stability: Stable + + +### Attribute `http.request.method_original` + +Original HTTP method sent by the client in the request line. + + +- Requirement Level: Recommended + +- Type: string +- Examples: [ + "GeT", + "ACL", + "foo", +] + +- Stability: Stable + + +### Attribute `http.request.resend_count` + +The ordinal number of request resending attempt (for any reason, including redirects). + + + +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). + +- Requirement Level: Recommended + +- Type: int +- Examples: 3 + +- Stability: Stable + + +### Attribute `http.response.body.size` + +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. + + + +- Requirement Level: Recommended + +- Type: int +- Examples: 3495 + +- Stability: Experimental + + +### Attribute `http.response.header` + +HTTP response headers, `` being the normalized HTTP Header name (lowercase), the value being the header values. + + + +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. +Users MAY explicitly configure instrumentations to capture them even though it is not recommended. +The 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. + +- Requirement Level: Recommended + +- Type: template[string[]] +- Examples: [ + "http.response.header.content-type=[\"application/json\"]", + "http.response.header.my-custom-header=[\"abc\", \"def\"]", +] + +- Stability: Stable + + +### Attribute `http.response.status_code` + +[HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). + + +- Requirement Level: Recommended + +- Type: int +- Examples: [ + 200, +] + +- Stability: Stable + + +### Attribute `http.route` + +The matched route, that is, the path template in the format used by the respective server framework. + + + +MUST NOT be populated when this is not supported by the HTTP server framework as the route attribute should have low-cardinality and the URI path can NOT substitute it. +SHOULD include the [application root](/docs/http/http-spans.md#http-server-definitions) if there is one. + +- Requirement Level: Recommended + +- Type: string +- Examples: [ + "/users/:userID?", + "{controller}/{action}/{id?}", +] + +- Stability: Stable + + + +## Provenance + +Source: data/registry-http.yaml + diff --git a/crates/weaver_forge/expected_output/group/registry_network.md b/crates/weaver_forge/expected_output/group/registry_network.md new file mode 100644 index 00000000..8764096d --- /dev/null +++ b/crates/weaver_forge/expected_output/group/registry_network.md @@ -0,0 +1,232 @@ +# Group `registry.network` (attribute_group) + +## Brief + +These attributes may be used for any network related operation. + +prefix: network + +## Attributes + + +### Attribute `network.carrier.icc` + +The ISO 3166-1 alpha-2 2-character country code associated with the mobile carrier network. + + +- Requirement Level: Recommended + +- Type: string +- Examples: DE + + +### Attribute `network.carrier.mcc` + +The mobile carrier country code. + + +- Requirement Level: Recommended + +- Type: string +- Examples: 310 + + +### Attribute `network.carrier.mnc` + +The mobile carrier network code. + + +- Requirement Level: Recommended + +- Type: string +- Examples: 001 + + +### Attribute `network.carrier.name` + +The name of the mobile carrier. + + +- Requirement Level: Recommended + +- Type: string +- Examples: sprint + + +### Attribute `network.connection.subtype` + +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. + + +- Requirement Level: Recommended + +- Type: Enum [gprs, edge, umts, cdma, evdo_0, evdo_a, cdma2000_1xrtt, hsdpa, hsupa, hspa, iden, evdo_b, lte, ehrpd, hspap, gsm, td_scdma, iwlan, nr, nrnsa, lte_ca] +- Examples: LTE + + +### Attribute `network.connection.type` + +The internet connection type. + + +- Requirement Level: Recommended + +- Type: Enum [wifi, wired, cell, unavailable, unknown] +- Examples: wifi + + +### Attribute `network.local.address` + +Local address of the network connection - IP address or Unix domain socket name. + + +- Requirement Level: Recommended + +- Type: string +- Examples: [ + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +### Attribute `network.local.port` + +Local port number of the network connection. + + +- Requirement Level: Recommended + +- Type: int +- Examples: [ + 65123, +] + +- Stability: Stable + + +### Attribute `network.peer.address` + +Peer address of the network connection - IP address or Unix domain socket name. + + +- Requirement Level: Recommended + +- Type: string +- Examples: [ + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +### Attribute `network.peer.port` + +Peer port number of the network connection. + + +- Requirement Level: Recommended + +- Type: int +- Examples: [ + 65123, +] + +- Stability: Stable + + +### Attribute `network.protocol.name` + +[OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. + + +The value SHOULD be normalized to lowercase. + +- Requirement Level: Recommended + +- Type: string +- Examples: [ + "amqp", + "http", + "mqtt", +] + +- Stability: Stable + + +### Attribute `network.protocol.version` + +Version of the protocol specified in `network.protocol.name`. + + +`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`. + +- Requirement Level: Recommended + +- Type: string +- Examples: 3.1.1 + +- Stability: Stable + + +### Attribute `network.transport` + +[OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). + + + +The value SHOULD be normalized to lowercase. + +Consider always setting the transport when setting a port number, since +a port number is ambiguous without knowing the transport. For example +different processes could be listening on TCP port 12345 and UDP port 12345. + +- Requirement Level: Recommended + +- Type: Enum [tcp, udp, pipe, unix] +- Examples: [ + "tcp", + "udp", +] + +- Stability: Stable + + +### Attribute `network.type` + +[OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. + + +The value SHOULD be normalized to lowercase. + +- Requirement Level: Recommended + +- Type: Enum [ipv4, ipv6] +- Examples: [ + "ipv4", + "ipv6", +] + +- Stability: Stable + + +### Attribute `network.io.direction` + +The network IO operation direction. + + +- Requirement Level: Recommended + +- Type: Enum [transmit, receive] +- Examples: [ + "transmit", +] + + + +## Provenance + +Source: data/registry-network.yaml + diff --git a/crates/weaver_forge/expected_output/group/registry_url.md b/crates/weaver_forge/expected_output/group/registry_url.md new file mode 100644 index 00000000..24de4715 --- /dev/null +++ b/crates/weaver_forge/expected_output/group/registry_url.md @@ -0,0 +1,100 @@ +# Group `registry.url` (attribute_group) + +## Brief + +Attributes describing URL. + +prefix: url + +## Attributes + + +### Attribute `url.scheme` + +The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. + + +- Requirement Level: Recommended + +- Type: string +- Examples: [ + "https", + "ftp", + "telnet", +] + +- Stability: Stable + + +### Attribute `url.full` + +Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986) + + +For network calls, URL usually has `scheme://host[:port][path][?query][#fragment]` format, where the fragment is not transmitted over HTTP, but if it is known, it SHOULD be included nevertheless. +`url.full` MUST NOT contain credentials passed via URL in form of `https://username:password@www.example.com/`. In such case username and password SHOULD be redacted and attribute's value SHOULD be `https://REDACTED:REDACTED@www.example.com/`. +`url.full` SHOULD capture the absolute URL when it is available (or can be reconstructed) and SHOULD NOT be validated or modified except for sanitizing purposes. + +- Requirement Level: Recommended + +- Type: string +- Examples: [ + "https://www.foo.bar/search?q=OpenTelemetry#SemConv", + "//localhost", +] + +- Stability: Stable + + +### Attribute `url.path` + +The [URI path](https://www.rfc-editor.org/rfc/rfc3986#section-3.3) component + + +- Requirement Level: Recommended + +- Type: string +- Examples: [ + "/search", +] + +- Stability: Stable + + +### Attribute `url.query` + +The [URI query](https://www.rfc-editor.org/rfc/rfc3986#section-3.4) component + + +Sensitive content provided in query string SHOULD be scrubbed when instrumentations can identify it. + +- Requirement Level: Recommended + +- Type: string +- Examples: [ + "q=OpenTelemetry", +] + +- Stability: Stable + + +### Attribute `url.fragment` + +The [URI fragment](https://www.rfc-editor.org/rfc/rfc3986#section-3.5) component + + +- Requirement Level: Recommended + +- Type: string +- Examples: [ + "SemConv", +] + +- Stability: Stable + + + +## Provenance + +Source: data/registry-url.yaml + diff --git a/crates/weaver_forge/expected_output/group/registry_user_agent.md b/crates/weaver_forge/expected_output/group/registry_user_agent.md new file mode 100644 index 00000000..1110de5a --- /dev/null +++ b/crates/weaver_forge/expected_output/group/registry_user_agent.md @@ -0,0 +1,33 @@ +# Group `registry.user_agent` (attribute_group) + +## Brief + +Describes user-agent attributes. + +prefix: user_agent + +## Attributes + + +### Attribute `user_agent.original` + +Value of the [HTTP User-Agent](https://www.rfc-editor.org/rfc/rfc9110.html#field.user-agent) header sent by the client. + + + +- Requirement Level: Recommended + +- Type: string +- 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", +] + +- Stability: Stable + + + +## Provenance + +Source: data/registry-user-agent.yaml + diff --git a/crates/weaver_forge/expected_output/group/server.md b/crates/weaver_forge/expected_output/group/server.md new file mode 100644 index 00000000..36f1678a --- /dev/null +++ b/crates/weaver_forge/expected_output/group/server.md @@ -0,0 +1,54 @@ +# Group `server` (attribute_group) + +## Brief + +These attributes may be used to describe the server in a connection-based network interaction where there is one side that initiates the connection (the client is the side that initiates the connection). This covers all TCP network interactions since TCP is connection-based and one side initiates the connection (an exception is made for peer-to-peer communication over TCP where the "user-facing" surface of the protocol / API doesn't expose a clear notion of client and server). This also covers UDP network interactions where one side initiates the interaction, e.g. QUIC (HTTP/3) and DNS. + +prefix: server + +## Attributes + + +### Attribute `server.address` + +Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. + + +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. + +- Requirement Level: Recommended + +- Type: string +- Examples: [ + "example.com", + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +### Attribute `server.port` + +Server port number. + + +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. + +- Requirement Level: Recommended + +- Type: int +- Examples: [ + 80, + 8080, + 443, +] + +- Stability: Stable + + + +## Provenance + +Source: data/registry-server.yaml + diff --git a/crates/weaver_forge/expected_output/groups.md b/crates/weaver_forge/expected_output/groups.md new file mode 100644 index 00000000..296a2305 --- /dev/null +++ b/crates/weaver_forge/expected_output/groups.md @@ -0,0 +1,5385 @@ +# Semantic Convention Groups + + +## Group `otel.scope` (resource) + +### Brief + +Attributes used by non-OTLP exporters to represent OpenTelemetry Scope's concepts. + +prefix: otel.scope + +### Attributes + + +#### Attribute `otel.scope.name` + +The name of the instrumentation scope - (`InstrumentationScope.Name` in OTLP). + + +- Requirement Level: Recommended + +- Type: string +- Examples: [ + "io.opentelemetry.contrib.mongodb", +] + +- Stability: Stable + + +#### Attribute `otel.scope.version` + +The version of the instrumentation scope - (`InstrumentationScope.Version` in OTLP). + + +- Requirement Level: Recommended + +- Type: string +- Examples: [ + "1.0.0", +] + +- Stability: Stable + + + +## Group `otel.library` (resource) + +### Brief + +Span attributes used by non-OTLP exporters to represent OpenTelemetry Scope's concepts. + +prefix: otel.library + +### Attributes + + +#### Attribute `otel.library.name` + + + + +- Requirement Level: Recommended + +- Type: string +- Examples: [ + "io.opentelemetry.contrib.mongodb", +] +- Deprecated: use the `otel.scope.name` attribute. + + +#### Attribute `otel.library.version` + + + + +- Requirement Level: Recommended + +- Type: string +- Examples: [ + "1.0.0", +] +- Deprecated: use the `otel.scope.version` attribute. + + + +## Group `attributes.jvm.memory` (attribute_group) + +### Brief + +Describes JVM memory metric attributes. + +prefix: jvm.memory + +### Attributes + + +#### Attribute `jvm.memory.type` + +The type of memory. + + +- Requirement Level: Recommended + +- Type: Enum [heap, non_heap] +- Examples: [ + "heap", + "non_heap", +] + +- Stability: Stable + + +#### Attribute `jvm.memory.pool.name` + +Name of the memory pool. + + +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()). + +- Requirement Level: Recommended + +- Type: string +- Examples: [ + "G1 Old Gen", + "G1 Eden space", + "G1 Survivor Space", +] + +- Stability: Stable + + + +## Group `metric.jvm.memory.used` (metric) + +### Brief + +Measure of memory used. + +prefix: + +### Attributes + + +#### Attribute `jvm.memory.type` + +The type of memory. + + +- Requirement Level: Recommended + +- Type: Enum [heap, non_heap] +- Examples: [ + "heap", + "non_heap", +] + +- Stability: Stable + + +#### Attribute `jvm.memory.pool.name` + +Name of the memory pool. + + +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()). + +- Requirement Level: Recommended + +- Type: string +- Examples: [ + "G1 Old Gen", + "G1 Eden space", + "G1 Survivor Space", +] + +- Stability: Stable + + + +## Group `metric.jvm.memory.committed` (metric) + +### Brief + +Measure of memory committed. + +prefix: + +### Attributes + + +#### Attribute `jvm.memory.type` + +The type of memory. + + +- Requirement Level: Recommended + +- Type: Enum [heap, non_heap] +- Examples: [ + "heap", + "non_heap", +] + +- Stability: Stable + + +#### Attribute `jvm.memory.pool.name` + +Name of the memory pool. + + +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()). + +- Requirement Level: Recommended + +- Type: string +- Examples: [ + "G1 Old Gen", + "G1 Eden space", + "G1 Survivor Space", +] + +- Stability: Stable + + + +## Group `metric.jvm.memory.limit` (metric) + +### Brief + +Measure of max obtainable memory. + +prefix: + +### Attributes + + +#### Attribute `jvm.memory.type` + +The type of memory. + + +- Requirement Level: Recommended + +- Type: Enum [heap, non_heap] +- Examples: [ + "heap", + "non_heap", +] + +- Stability: Stable + + +#### Attribute `jvm.memory.pool.name` + +Name of the memory pool. + + +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()). + +- Requirement Level: Recommended + +- Type: string +- Examples: [ + "G1 Old Gen", + "G1 Eden space", + "G1 Survivor Space", +] + +- Stability: Stable + + + +## Group `metric.jvm.memory.used_after_last_gc` (metric) + +### Brief + +Measure of memory used, as measured after the most recent garbage collection event on this pool. + +prefix: + +### Attributes + + +#### Attribute `jvm.memory.type` + +The type of memory. + + +- Requirement Level: Recommended + +- Type: Enum [heap, non_heap] +- Examples: [ + "heap", + "non_heap", +] + +- Stability: Stable + + +#### Attribute `jvm.memory.pool.name` + +Name of the memory pool. + + +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()). + +- Requirement Level: Recommended + +- Type: string +- Examples: [ + "G1 Old Gen", + "G1 Eden space", + "G1 Survivor Space", +] + +- Stability: Stable + + + +## Group `metric.jvm.gc.duration` (metric) + +### Brief + +Duration of JVM garbage collection actions. + +prefix: jvm.gc + +### Attributes + + +#### Attribute `jvm.gc.name` + +Name of the garbage collector. + + +Garbage collector name is generally obtained via [GarbageCollectionNotificationInfo#getGcName()](https://docs.oracle.com/en/java/javase/11/docs/api/jdk.management/com/sun/management/GarbageCollectionNotificationInfo.html#getGcName()). + +- Requirement Level: Recommended + +- Type: string +- Examples: [ + "G1 Young Generation", + "G1 Old Generation", +] + +- Stability: Stable + + +#### Attribute `jvm.gc.action` + +Name of the garbage collector action. + + +Garbage collector action is generally obtained via [GarbageCollectionNotificationInfo#getGcAction()](https://docs.oracle.com/en/java/javase/11/docs/api/jdk.management/com/sun/management/GarbageCollectionNotificationInfo.html#getGcAction()). + +- Requirement Level: Recommended + +- Type: string +- Examples: [ + "end of minor GC", + "end of major GC", +] + +- Stability: Stable + + + +## Group `metric.jvm.thread.count` (metric) + +### Brief + +Number of executing platform threads. + +prefix: + +### Attributes + + +#### Attribute `jvm.thread.daemon` + +Whether the thread is daemon or not. + + +- Requirement Level: Recommended + +- Type: boolean + +- Stability: Stable + + +#### Attribute `jvm.thread.state` + +State of the thread. + + +- Requirement Level: Recommended + +- Type: Enum [new, runnable, blocked, waiting, timed_waiting, terminated] +- Examples: [ + "runnable", + "blocked", +] + +- Stability: Stable + + + +## Group `metric.jvm.class.loaded` (metric) + +### Brief + +Number of classes loaded since JVM start. + +prefix: + +### Attributes + + + +## Group `metric.jvm.class.unloaded` (metric) + +### Brief + +Number of classes unloaded since JVM start. + +prefix: + +### Attributes + + + +## Group `metric.jvm.class.count` (metric) + +### Brief + +Number of classes currently loaded. + +prefix: + +### Attributes + + + +## Group `metric.jvm.cpu.count` (metric) + +### Brief + +Number of processors available to the Java virtual machine. + +prefix: + +### Attributes + + + +## Group `metric.jvm.cpu.time` (metric) + +### Brief + +CPU time used by the process as reported by the JVM. + +prefix: + +### Attributes + + + +## Group `metric.jvm.cpu.recent_utilization` (metric) + +### Brief + +Recent CPU utilization for the process as reported by the JVM. + +prefix: + +### Attributes + + + +## Group `ios.lifecycle.events` (event) + +### Brief + +This event represents an occurrence of a lifecycle transition on the iOS platform. + +prefix: ios + +### Attributes + + +#### Attribute `ios.state` + +This attribute represents the state the application has transitioned into at the occurrence of the event. + + + +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. + +- Requirement Level: Required + +- Type: Enum [active, inactive, background, foreground, terminate] + +- Stability: Experimental + + + +## Group `android.lifecycle.events` (event) + +### Brief + +This event represents an occurrence of a lifecycle transition on the Android platform. + +prefix: android + +### Attributes + + +#### Attribute `android.state` + +This attribute represents the state the application has transitioned into at the occurrence of the event. + + + +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. + +- Requirement Level: Required + +- Type: Enum [created, background, foreground] + +- Stability: Experimental + + + +## Group `registry.db` (attribute_group) + +### Brief + +This document defines the attributes used to describe telemetry in the context of databases. + +prefix: db + +### Attributes + + +#### Attribute `db.cassandra.coordinator.dc` + +The data center of the coordinating node for a query. + + + +- Requirement Level: Recommended + +- Tag: tech-specific-cassandra + +- Type: string +- Examples: us-west-2 + + +#### Attribute `db.cassandra.coordinator.id` + +The ID of the coordinating node for a query. + + + +- Requirement Level: Recommended + +- Tag: tech-specific-cassandra + +- Type: string +- Examples: be13faa2-8574-4d71-926d-27f16cf8a7af + + +#### Attribute `db.cassandra.consistency_level` + +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). + + + +- Requirement Level: Recommended + +- Tag: tech-specific-cassandra + +- Type: Enum [all, each_quorum, quorum, local_quorum, one, two, three, local_one, any, serial, local_serial] + + +#### Attribute `db.cassandra.idempotence` + +Whether or not the query is idempotent. + + + +- Requirement Level: Recommended + +- Tag: tech-specific-cassandra + +- Type: boolean + + +#### Attribute `db.cassandra.page_size` + +The fetch size used for paging, i.e. how many rows will be returned at once. + + + +- Requirement Level: Recommended + +- Tag: tech-specific-cassandra + +- Type: int +- Examples: [ + 5000, +] + + +#### Attribute `db.cassandra.speculative_execution_count` + +The number of times a query was speculatively executed. Not set or `0` if the query was not executed speculatively. + + + +- Requirement Level: Recommended + +- Tag: tech-specific-cassandra + +- Type: int +- Examples: [ + 0, + 2, +] + + +#### Attribute `db.cassandra.table` + +The name of the primary Cassandra table that the operation is acting upon, including the keyspace name (if applicable). + + +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. + +- Requirement Level: Recommended + +- Tag: tech-specific-cassandra + +- Type: string +- Examples: mytable + + +#### Attribute `db.connection_string` + +The connection string used to connect to the database. It is recommended to remove embedded credentials. + + + +- Requirement Level: Recommended + +- Tag: db-generic + +- Type: string +- Examples: Server=(localdb)\v11.0;Integrated Security=true; + + +#### Attribute `db.cosmosdb.client_id` + +Unique Cosmos client instance id. + + +- Requirement Level: Recommended + +- Tag: tech-specific-cosmosdb + +- Type: string +- Examples: 3ba4827d-4422-483f-b59f-85b74211c11d + + +#### Attribute `db.cosmosdb.connection_mode` + +Cosmos client connection mode. + + +- Requirement Level: Recommended + +- Tag: tech-specific-cosmosdb + +- Type: Enum [gateway, direct] + + +#### Attribute `db.cosmosdb.container` + +Cosmos DB container name. + + +- Requirement Level: Recommended + +- Tag: tech-specific-cosmosdb + +- Type: string +- Examples: anystring + + +#### Attribute `db.cosmosdb.operation_type` + +CosmosDB Operation Type. + + +- Requirement Level: Recommended + +- Tag: tech-specific-cosmosdb + +- Type: Enum [Invalid, Create, Patch, Read, ReadFeed, Delete, Replace, Execute, Query, Head, HeadFeed, Upsert, Batch, QueryPlan, ExecuteJavaScript] + + +#### Attribute `db.cosmosdb.request_charge` + +RU consumed for that operation + + +- Requirement Level: Recommended + +- Tag: tech-specific-cosmosdb + +- Type: double +- Examples: [ + 46.18, + 1.0, +] + + +#### Attribute `db.cosmosdb.request_content_length` + +Request payload size in bytes + + +- Requirement Level: Recommended + +- Tag: tech-specific-cosmosdb + +- Type: int + + +#### Attribute `db.cosmosdb.status_code` + +Cosmos DB status code. + + +- Requirement Level: Recommended + +- Tag: tech-specific-cosmosdb + +- Type: int +- Examples: [ + 200, + 201, +] + + +#### Attribute `db.cosmosdb.sub_status_code` + +Cosmos DB sub status code. + + +- Requirement Level: Recommended + +- Tag: tech-specific-cosmosdb + +- Type: int +- Examples: [ + 1000, + 1002, +] + + +#### Attribute `db.elasticsearch.cluster.name` + +Represents the identifier of an Elasticsearch cluster. + + + +- Requirement Level: Recommended + +- Tag: tech-specific-elasticsearch + +- Type: string +- Examples: [ + "e9106fc68e3044f0b1475b04bf4ffd5f", +] + + +#### Attribute `db.elasticsearch.node.name` + +Represents the human-readable identifier of the node/instance to which a request was routed. + + + +- Requirement Level: Recommended + +- Tag: tech-specific-elasticsearch + +- Type: string +- Examples: [ + "instance-0000000001", +] + + +#### Attribute `db.elasticsearch.path_parts` + +A dynamic value in the url path. + + + +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. + +- Requirement Level: Recommended + +- Tag: tech-specific-elasticsearch + +- Type: template[string] +- Examples: [ + "db.elasticsearch.path_parts.index=test-index", + "db.elasticsearch.path_parts.doc_id=123", +] + + +#### Attribute `db.jdbc.driver_classname` + +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. + + + +- Requirement Level: Recommended + +- Tag: tech-specific-jdbc + +- Type: string +- Examples: [ + "org.postgresql.Driver", + "com.microsoft.sqlserver.jdbc.SQLServerDriver", +] + + +#### Attribute `db.mongodb.collection` + +The MongoDB collection being accessed within the database stated in `db.name`. + + + +- Requirement Level: Recommended + +- Tag: tech-specific-mongodb + +- Type: string +- Examples: [ + "customers", + "products", +] + + +#### Attribute `db.mssql.instance_name` + +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. + + + +If setting a `db.mssql.instance_name`, `server.port` is no longer required (but still recommended if non-standard). + +- Requirement Level: Recommended + +- Tag: tech-specific-mssql + +- Type: string +- Examples: MSSQLSERVER + + +#### Attribute `db.name` + +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). + + + +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). + +- Requirement Level: Recommended + +- Tag: db-generic + +- Type: string +- Examples: [ + "customers", + "main", +] + + +#### Attribute `db.operation` + +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. + + + +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. + +- Requirement Level: Recommended + +- Tag: db-generic + +- Type: string +- Examples: [ + "findAndModify", + "HMSET", + "SELECT", +] + + +#### Attribute `db.redis.database_index` + +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. + + + +- Requirement Level: Recommended + +- Tag: tech-specific-redis + +- Type: int +- Examples: [ + 0, + 1, + 15, +] + + +#### Attribute `db.sql.table` + +The name of the primary table that the operation is acting upon, including the database name (if applicable). + + +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. + +- Requirement Level: Recommended + +- Tag: tech-specific-sql + +- Type: string +- Examples: [ + "public.users", + "customers", +] + + +#### Attribute `db.statement` + +The database statement being executed. + + + +- Requirement Level: Recommended + +- Tag: db-generic + +- Type: string +- Examples: [ + "SELECT * FROM wuser_table", + "SET mykey \"WuValue\"", +] + + +#### Attribute `db.system` + +An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. + + +- Requirement Level: Recommended + +- Tag: db-generic + +- Type: Enum [other_sql, mssql, mssqlcompact, mysql, oracle, db2, postgresql, redshift, hive, cloudscape, hsqldb, progress, maxdb, hanadb, ingres, firstsql, edb, cache, adabas, firebird, derby, filemaker, informix, instantdb, interbase, mariadb, netezza, pervasive, pointbase, sqlite, sybase, teradata, vertica, h2, coldfusion, cassandra, hbase, mongodb, redis, couchbase, couchdb, cosmosdb, dynamodb, neo4j, geode, elasticsearch, memcached, cockroachdb, opensearch, clickhouse, spanner, trino] + + +#### Attribute `db.user` + +Username for accessing the database. + + + +- Requirement Level: Recommended + +- Tag: db-generic + +- Type: string +- Examples: [ + "readonly_user", + "reporting_user", +] + + +#### Attribute `db.instance.id` + +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`. + + + +- Requirement Level: Recommended + +- Tag: db-generic + +- Type: string +- Examples: mysql-e26b99z.example.com + + + +## Group `registry.http` (attribute_group) + +### Brief + +This document defines semantic convention attributes in the HTTP namespace. + +prefix: http + +### Attributes + + +#### Attribute `http.request.body.size` + +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. + + + +- Requirement Level: Recommended + +- Type: int +- Examples: 3495 + +- Stability: Experimental + + +#### Attribute `http.request.header` + +HTTP request headers, `` being the normalized HTTP Header name (lowercase), the value being the header values. + + + +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. +The `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. +The 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. + +- Requirement Level: Recommended + +- Type: template[string[]] +- Examples: [ + "http.request.header.content-type=[\"application/json\"]", + "http.request.header.x-forwarded-for=[\"1.2.3.4\", \"1.2.3.5\"]", +] + +- Stability: Stable + + +#### Attribute `http.request.method` + +HTTP request method. + + +HTTP request method value SHOULD be "known" to the instrumentation. +By default, this convention defines "known" methods as the ones listed in [RFC9110](https://www.rfc-editor.org/rfc/rfc9110.html#name-methods) +and the PATCH method defined in [RFC5789](https://www.rfc-editor.org/rfc/rfc5789.html). + +If the HTTP request method is not known to instrumentation, it MUST set the `http.request.method` attribute to `_OTHER`. + +If the HTTP instrumentation could end up converting valid HTTP request methods to `_OTHER`, then it MUST provide a way to override +the list of known HTTP methods. If this override is done via environment variable, then the environment variable MUST be named +OTEL_INSTRUMENTATION_HTTP_KNOWN_METHODS and support a comma-separated list of case-sensitive known HTTP methods +(this list MUST be a full override of the default known method, it is not a list of known methods in addition to the defaults). + +HTTP method names are case-sensitive and `http.request.method` attribute value MUST match a known HTTP method name exactly. +Instrumentations for specific web frameworks that consider HTTP methods to be case insensitive, SHOULD populate a canonical equivalent. +Tracing instrumentations that do so, MUST also set `http.request.method_original` to the original value. + +- Requirement Level: Recommended + +- Type: Enum [CONNECT, DELETE, GET, HEAD, OPTIONS, PATCH, POST, PUT, TRACE, _OTHER] +- Examples: [ + "GET", + "POST", + "HEAD", +] + +- Stability: Stable + + +#### Attribute `http.request.method_original` + +Original HTTP method sent by the client in the request line. + + +- Requirement Level: Recommended + +- Type: string +- Examples: [ + "GeT", + "ACL", + "foo", +] + +- Stability: Stable + + +#### Attribute `http.request.resend_count` + +The ordinal number of request resending attempt (for any reason, including redirects). + + + +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). + +- Requirement Level: Recommended + +- Type: int +- Examples: 3 + +- Stability: Stable + + +#### Attribute `http.response.body.size` + +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. + + + +- Requirement Level: Recommended + +- Type: int +- Examples: 3495 + +- Stability: Experimental + + +#### Attribute `http.response.header` + +HTTP response headers, `` being the normalized HTTP Header name (lowercase), the value being the header values. + + + +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. +Users MAY explicitly configure instrumentations to capture them even though it is not recommended. +The 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. + +- Requirement Level: Recommended + +- Type: template[string[]] +- Examples: [ + "http.response.header.content-type=[\"application/json\"]", + "http.response.header.my-custom-header=[\"abc\", \"def\"]", +] + +- Stability: Stable + + +#### Attribute `http.response.status_code` + +[HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). + + +- Requirement Level: Recommended + +- Type: int +- Examples: [ + 200, +] + +- Stability: Stable + + +#### Attribute `http.route` + +The matched route, that is, the path template in the format used by the respective server framework. + + + +MUST NOT be populated when this is not supported by the HTTP server framework as the route attribute should have low-cardinality and the URI path can NOT substitute it. +SHOULD include the [application root](/docs/http/http-spans.md#http-server-definitions) if there is one. + +- Requirement Level: Recommended + +- Type: string +- Examples: [ + "/users/:userID?", + "{controller}/{action}/{id?}", +] + +- Stability: Stable + + + +## Group `registry.network` (attribute_group) + +### Brief + +These attributes may be used for any network related operation. + +prefix: network + +### Attributes + + +#### Attribute `network.carrier.icc` + +The ISO 3166-1 alpha-2 2-character country code associated with the mobile carrier network. + + +- Requirement Level: Recommended + +- Type: string +- Examples: DE + + +#### Attribute `network.carrier.mcc` + +The mobile carrier country code. + + +- Requirement Level: Recommended + +- Type: string +- Examples: 310 + + +#### Attribute `network.carrier.mnc` + +The mobile carrier network code. + + +- Requirement Level: Recommended + +- Type: string +- Examples: 001 + + +#### Attribute `network.carrier.name` + +The name of the mobile carrier. + + +- Requirement Level: Recommended + +- Type: string +- Examples: sprint + + +#### Attribute `network.connection.subtype` + +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. + + +- Requirement Level: Recommended + +- Type: Enum [gprs, edge, umts, cdma, evdo_0, evdo_a, cdma2000_1xrtt, hsdpa, hsupa, hspa, iden, evdo_b, lte, ehrpd, hspap, gsm, td_scdma, iwlan, nr, nrnsa, lte_ca] +- Examples: LTE + + +#### Attribute `network.connection.type` + +The internet connection type. + + +- Requirement Level: Recommended + +- Type: Enum [wifi, wired, cell, unavailable, unknown] +- Examples: wifi + + +#### Attribute `network.local.address` + +Local address of the network connection - IP address or Unix domain socket name. + + +- Requirement Level: Recommended + +- Type: string +- Examples: [ + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +#### Attribute `network.local.port` + +Local port number of the network connection. + + +- Requirement Level: Recommended + +- Type: int +- Examples: [ + 65123, +] + +- Stability: Stable + + +#### Attribute `network.peer.address` + +Peer address of the network connection - IP address or Unix domain socket name. + + +- Requirement Level: Recommended + +- Type: string +- Examples: [ + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +#### Attribute `network.peer.port` + +Peer port number of the network connection. + + +- Requirement Level: Recommended + +- Type: int +- Examples: [ + 65123, +] + +- Stability: Stable + + +#### Attribute `network.protocol.name` + +[OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent. + + +The value SHOULD be normalized to lowercase. + +- Requirement Level: Recommended + +- Type: string +- Examples: [ + "amqp", + "http", + "mqtt", +] + +- Stability: Stable + + +#### Attribute `network.protocol.version` + +Version of the protocol specified in `network.protocol.name`. + + +`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`. + +- Requirement Level: Recommended + +- Type: string +- Examples: 3.1.1 + +- Stability: Stable + + +#### Attribute `network.transport` + +[OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). + + + +The value SHOULD be normalized to lowercase. + +Consider always setting the transport when setting a port number, since +a port number is ambiguous without knowing the transport. For example +different processes could be listening on TCP port 12345 and UDP port 12345. + +- Requirement Level: Recommended + +- Type: Enum [tcp, udp, pipe, unix] +- Examples: [ + "tcp", + "udp", +] + +- Stability: Stable + + +#### Attribute `network.type` + +[OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. + + +The value SHOULD be normalized to lowercase. + +- Requirement Level: Recommended + +- Type: Enum [ipv4, ipv6] +- Examples: [ + "ipv4", + "ipv6", +] + +- Stability: Stable + + +#### Attribute `network.io.direction` + +The network IO operation direction. + + +- Requirement Level: Recommended + +- Type: Enum [transmit, receive] +- Examples: [ + "transmit", +] + + + +## Group `server` (attribute_group) + +### Brief + +These attributes may be used to describe the server in a connection-based network interaction where there is one side that initiates the connection (the client is the side that initiates the connection). This covers all TCP network interactions since TCP is connection-based and one side initiates the connection (an exception is made for peer-to-peer communication over TCP where the "user-facing" surface of the protocol / API doesn't expose a clear notion of client and server). This also covers UDP network interactions where one side initiates the interaction, e.g. QUIC (HTTP/3) and DNS. + +prefix: server + +### Attributes + + +#### Attribute `server.address` + +Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. + + +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. + +- Requirement Level: Recommended + +- Type: string +- Examples: [ + "example.com", + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +#### Attribute `server.port` + +Server port number. + + +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. + +- Requirement Level: Recommended + +- Type: int +- Examples: [ + 80, + 8080, + 443, +] + +- Stability: Stable + + + +## Group `registry.url` (attribute_group) + +### Brief + +Attributes describing URL. + +prefix: url + +### Attributes + + +#### Attribute `url.scheme` + +The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. + + +- Requirement Level: Recommended + +- Type: string +- Examples: [ + "https", + "ftp", + "telnet", +] + +- Stability: Stable + + +#### Attribute `url.full` + +Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986) + + +For network calls, URL usually has `scheme://host[:port][path][?query][#fragment]` format, where the fragment is not transmitted over HTTP, but if it is known, it SHOULD be included nevertheless. +`url.full` MUST NOT contain credentials passed via URL in form of `https://username:password@www.example.com/`. In such case username and password SHOULD be redacted and attribute's value SHOULD be `https://REDACTED:REDACTED@www.example.com/`. +`url.full` SHOULD capture the absolute URL when it is available (or can be reconstructed) and SHOULD NOT be validated or modified except for sanitizing purposes. + +- Requirement Level: Recommended + +- Type: string +- Examples: [ + "https://www.foo.bar/search?q=OpenTelemetry#SemConv", + "//localhost", +] + +- Stability: Stable + + +#### Attribute `url.path` + +The [URI path](https://www.rfc-editor.org/rfc/rfc3986#section-3.3) component + + +- Requirement Level: Recommended + +- Type: string +- Examples: [ + "/search", +] + +- Stability: Stable + + +#### Attribute `url.query` + +The [URI query](https://www.rfc-editor.org/rfc/rfc3986#section-3.4) component + + +Sensitive content provided in query string SHOULD be scrubbed when instrumentations can identify it. + +- Requirement Level: Recommended + +- Type: string +- Examples: [ + "q=OpenTelemetry", +] + +- Stability: Stable + + +#### Attribute `url.fragment` + +The [URI fragment](https://www.rfc-editor.org/rfc/rfc3986#section-3.5) component + + +- Requirement Level: Recommended + +- Type: string +- Examples: [ + "SemConv", +] + +- Stability: Stable + + + +## Group `registry.user_agent` (attribute_group) + +### Brief + +Describes user-agent attributes. + +prefix: user_agent + +### Attributes + + +#### Attribute `user_agent.original` + +Value of the [HTTP User-Agent](https://www.rfc-editor.org/rfc/rfc9110.html#field.user-agent) header sent by the client. + + + +- Requirement Level: Recommended + +- Type: string +- 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", +] + +- Stability: Stable + + + +## Group `db` (span) + +### Brief + +This document defines the attributes used to perform database client calls. + +prefix: + +### Attributes + + +#### Attribute `db.system` + +An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. + + +- Requirement Level: Required + +- Tag: connection-level + +- Type: Enum [other_sql, mssql, mssqlcompact, mysql, oracle, db2, postgresql, redshift, hive, cloudscape, hsqldb, progress, maxdb, hanadb, ingres, firstsql, edb, cache, adabas, firebird, derby, filemaker, informix, instantdb, interbase, mariadb, netezza, pervasive, pointbase, sqlite, sybase, teradata, vertica, h2, coldfusion, cassandra, hbase, mongodb, redis, couchbase, couchdb, cosmosdb, dynamodb, neo4j, geode, elasticsearch, memcached, cockroachdb, opensearch, clickhouse, spanner, trino] + + +#### Attribute `db.connection_string` + +The connection string used to connect to the database. It is recommended to remove embedded credentials. + + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: Server=(localdb)\v11.0;Integrated Security=true; + + +#### Attribute `db.user` + +Username for accessing the database. + + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "readonly_user", + "reporting_user", +] + + +#### Attribute `db.jdbc.driver_classname` + +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. + + + +- Requirement Level: Recommended + +- Tag: connection-level-tech-specific + +- Type: string +- Examples: [ + "org.postgresql.Driver", + "com.microsoft.sqlserver.jdbc.SQLServerDriver", +] + + +#### Attribute `db.name` + +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). + + + +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). + +- Requirement Level: Conditionally Required - If applicable. + +- Tag: call-level + +- Type: string +- Examples: [ + "customers", + "main", +] + + +#### Attribute `db.statement` + +The database statement being executed. + + + +- Requirement Level: Optional + +- Tag: call-level + +- Type: string +- Examples: [ + "SELECT * FROM wuser_table", + "SET mykey \"WuValue\"", +] + + +#### Attribute `db.operation` + +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. + + + +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. + +- Requirement Level: Conditionally Required - If `db.statement` is not applicable. + +- Tag: call-level + +- Type: string +- Examples: [ + "findAndModify", + "HMSET", + "SELECT", +] + + +#### Attribute `server.address` + +Name of the database host. + + + +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. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "example.com", + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +#### Attribute `server.port` + +Server port number. + + +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. + +- Requirement Level: Conditionally Required - If using a port other than the default port for this DBMS and if `server.address` is set. + +- Tag: connection-level + +- Type: int +- Examples: [ + 80, + 8080, + 443, +] + +- Stability: Stable + + +#### Attribute `network.peer.address` + +Peer address of the network connection - IP address or Unix domain socket name. + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +#### Attribute `network.peer.port` + +Peer port number of the network connection. + + +- Requirement Level: Optional + +- Tag: connection-level + +- Type: int +- Examples: [ + 65123, +] + +- Stability: Stable + + +#### Attribute `network.transport` + +[OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). + + + +The value SHOULD be normalized to lowercase. + +Consider always setting the transport when setting a port number, since +a port number is ambiguous without knowing the transport. For example +different processes could be listening on TCP port 12345 and UDP port 12345. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: Enum [tcp, udp, pipe, unix] +- Examples: [ + "tcp", + "udp", +] + +- Stability: Stable + + +#### Attribute `network.type` + +[OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. + + +The value SHOULD be normalized to lowercase. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: Enum [ipv4, ipv6] +- Examples: [ + "ipv4", + "ipv6", +] + +- Stability: Stable + + +#### Attribute `db.instance.id` + +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`. + + + +- Requirement Level: Optional + +- Tag: connection-level + +- Type: string +- Examples: mysql-e26b99z.example.com + + + +## Group `db.mssql` (span) + +### Brief + +Connection-level attributes for Microsoft SQL Server + +prefix: + +### Attributes + + +#### Attribute `db.system` + +An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. + + +- Requirement Level: Required + +- Tag: connection-level + +- Type: Enum [other_sql, mssql, mssqlcompact, mysql, oracle, db2, postgresql, redshift, hive, cloudscape, hsqldb, progress, maxdb, hanadb, ingres, firstsql, edb, cache, adabas, firebird, derby, filemaker, informix, instantdb, interbase, mariadb, netezza, pervasive, pointbase, sqlite, sybase, teradata, vertica, h2, coldfusion, cassandra, hbase, mongodb, redis, couchbase, couchdb, cosmosdb, dynamodb, neo4j, geode, elasticsearch, memcached, cockroachdb, opensearch, clickhouse, spanner, trino] + + +#### Attribute `db.connection_string` + +The connection string used to connect to the database. It is recommended to remove embedded credentials. + + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: Server=(localdb)\v11.0;Integrated Security=true; + + +#### Attribute `db.user` + +Username for accessing the database. + + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "readonly_user", + "reporting_user", +] + + +#### Attribute `db.jdbc.driver_classname` + +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. + + + +- Requirement Level: Recommended + +- Tag: connection-level-tech-specific + +- Type: string +- Examples: [ + "org.postgresql.Driver", + "com.microsoft.sqlserver.jdbc.SQLServerDriver", +] + + +#### Attribute `db.name` + +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). + + + +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). + +- Requirement Level: Conditionally Required - If applicable. + +- Tag: call-level + +- Type: string +- Examples: [ + "customers", + "main", +] + + +#### Attribute `db.statement` + +The database statement being executed. + + + +- Requirement Level: Optional + +- Tag: call-level + +- Type: string +- Examples: [ + "SELECT * FROM wuser_table", + "SET mykey \"WuValue\"", +] + + +#### Attribute `db.operation` + +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. + + + +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. + +- Requirement Level: Conditionally Required - If `db.statement` is not applicable. + +- Tag: call-level + +- Type: string +- Examples: [ + "findAndModify", + "HMSET", + "SELECT", +] + + +#### Attribute `server.address` + +Name of the database host. + + + +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. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "example.com", + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +#### Attribute `server.port` + +Server port number. + + +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. + +- Requirement Level: Conditionally Required - If using a port other than the default port for this DBMS and if `server.address` is set. + +- Tag: connection-level + +- Type: int +- Examples: [ + 80, + 8080, + 443, +] + +- Stability: Stable + + +#### Attribute `network.peer.address` + +Peer address of the network connection - IP address or Unix domain socket name. + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +#### Attribute `network.peer.port` + +Peer port number of the network connection. + + +- Requirement Level: Optional + +- Tag: connection-level + +- Type: int +- Examples: [ + 65123, +] + +- Stability: Stable + + +#### Attribute `network.transport` + +[OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). + + + +The value SHOULD be normalized to lowercase. + +Consider always setting the transport when setting a port number, since +a port number is ambiguous without knowing the transport. For example +different processes could be listening on TCP port 12345 and UDP port 12345. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: Enum [tcp, udp, pipe, unix] +- Examples: [ + "tcp", + "udp", +] + +- Stability: Stable + + +#### Attribute `network.type` + +[OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. + + +The value SHOULD be normalized to lowercase. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: Enum [ipv4, ipv6] +- Examples: [ + "ipv4", + "ipv6", +] + +- Stability: Stable + + +#### Attribute `db.instance.id` + +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`. + + + +- Requirement Level: Optional + +- Tag: connection-level + +- Type: string +- Examples: mysql-e26b99z.example.com + + +#### Attribute `db.mssql.instance_name` + +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. + + + +If setting a `db.mssql.instance_name`, `server.port` is no longer required (but still recommended if non-standard). + +- Requirement Level: Recommended + +- Tag: connection-level-tech-specific + +- Type: string +- Examples: MSSQLSERVER + + + +## Group `db.cassandra` (span) + +### Brief + +Call-level attributes for Cassandra + +prefix: + +### Attributes + + +#### Attribute `db.system` + +An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. + + +- Requirement Level: Required + +- Tag: connection-level + +- Type: Enum [other_sql, mssql, mssqlcompact, mysql, oracle, db2, postgresql, redshift, hive, cloudscape, hsqldb, progress, maxdb, hanadb, ingres, firstsql, edb, cache, adabas, firebird, derby, filemaker, informix, instantdb, interbase, mariadb, netezza, pervasive, pointbase, sqlite, sybase, teradata, vertica, h2, coldfusion, cassandra, hbase, mongodb, redis, couchbase, couchdb, cosmosdb, dynamodb, neo4j, geode, elasticsearch, memcached, cockroachdb, opensearch, clickhouse, spanner, trino] + + +#### Attribute `db.connection_string` + +The connection string used to connect to the database. It is recommended to remove embedded credentials. + + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: Server=(localdb)\v11.0;Integrated Security=true; + + +#### Attribute `db.user` + +Username for accessing the database. + + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "readonly_user", + "reporting_user", +] + + +#### Attribute `db.jdbc.driver_classname` + +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. + + + +- Requirement Level: Recommended + +- Tag: connection-level-tech-specific + +- Type: string +- Examples: [ + "org.postgresql.Driver", + "com.microsoft.sqlserver.jdbc.SQLServerDriver", +] + + +#### Attribute `db.name` + +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). + + + +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). + +- Requirement Level: Conditionally Required - If applicable. + +- Tag: call-level + +- Type: string +- Examples: [ + "customers", + "main", +] + + +#### Attribute `db.statement` + +The database statement being executed. + + + +- Requirement Level: Optional + +- Tag: call-level + +- Type: string +- Examples: [ + "SELECT * FROM wuser_table", + "SET mykey \"WuValue\"", +] + + +#### Attribute `db.operation` + +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. + + + +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. + +- Requirement Level: Conditionally Required - If `db.statement` is not applicable. + +- Tag: call-level + +- Type: string +- Examples: [ + "findAndModify", + "HMSET", + "SELECT", +] + + +#### Attribute `server.address` + +Name of the database host. + + + +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. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "example.com", + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +#### Attribute `server.port` + +Server port number. + + +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. + +- Requirement Level: Conditionally Required - If using a port other than the default port for this DBMS and if `server.address` is set. + +- Tag: connection-level + +- Type: int +- Examples: [ + 80, + 8080, + 443, +] + +- Stability: Stable + + +#### Attribute `network.peer.address` + +Peer address of the network connection - IP address or Unix domain socket name. + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +#### Attribute `network.peer.port` + +Peer port number of the network connection. + + +- Requirement Level: Optional + +- Tag: connection-level + +- Type: int +- Examples: [ + 65123, +] + +- Stability: Stable + + +#### Attribute `network.transport` + +[OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). + + + +The value SHOULD be normalized to lowercase. + +Consider always setting the transport when setting a port number, since +a port number is ambiguous without knowing the transport. For example +different processes could be listening on TCP port 12345 and UDP port 12345. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: Enum [tcp, udp, pipe, unix] +- Examples: [ + "tcp", + "udp", +] + +- Stability: Stable + + +#### Attribute `network.type` + +[OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. + + +The value SHOULD be normalized to lowercase. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: Enum [ipv4, ipv6] +- Examples: [ + "ipv4", + "ipv6", +] + +- Stability: Stable + + +#### Attribute `db.instance.id` + +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`. + + + +- Requirement Level: Optional + +- Tag: connection-level + +- Type: string +- Examples: mysql-e26b99z.example.com + + +#### Attribute `db.name` + +The keyspace name in Cassandra. + + + +For Cassandra the `db.name` should be set to the Cassandra keyspace name. + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific-cassandra + +- Type: string +- Examples: [ + "mykeyspace", +] + + +#### Attribute `db.cassandra.page_size` + +The fetch size used for paging, i.e. how many rows will be returned at once. + + + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific-cassandra + +- Type: int +- Examples: [ + 5000, +] + + +#### Attribute `db.cassandra.consistency_level` + +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). + + + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific-cassandra + +- Type: Enum [all, each_quorum, quorum, local_quorum, one, two, three, local_one, any, serial, local_serial] + + +#### Attribute `db.cassandra.table` + +The name of the primary Cassandra table that the operation is acting upon, including the keyspace name (if applicable). + + +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. + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific-cassandra + +- Type: string +- Examples: mytable + + +#### Attribute `db.cassandra.idempotence` + +Whether or not the query is idempotent. + + + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific-cassandra + +- Type: boolean + + +#### Attribute `db.cassandra.speculative_execution_count` + +The number of times a query was speculatively executed. Not set or `0` if the query was not executed speculatively. + + + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific-cassandra + +- Type: int +- Examples: [ + 0, + 2, +] + + +#### Attribute `db.cassandra.coordinator.id` + +The ID of the coordinating node for a query. + + + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific-cassandra + +- Type: string +- Examples: be13faa2-8574-4d71-926d-27f16cf8a7af + + +#### Attribute `db.cassandra.coordinator.dc` + +The data center of the coordinating node for a query. + + + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific-cassandra + +- Type: string +- Examples: us-west-2 + + + +## Group `db.hbase` (span) + +### Brief + +Call-level attributes for HBase + +prefix: + +### Attributes + + +#### Attribute `db.system` + +An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. + + +- Requirement Level: Required + +- Tag: connection-level + +- Type: Enum [other_sql, mssql, mssqlcompact, mysql, oracle, db2, postgresql, redshift, hive, cloudscape, hsqldb, progress, maxdb, hanadb, ingres, firstsql, edb, cache, adabas, firebird, derby, filemaker, informix, instantdb, interbase, mariadb, netezza, pervasive, pointbase, sqlite, sybase, teradata, vertica, h2, coldfusion, cassandra, hbase, mongodb, redis, couchbase, couchdb, cosmosdb, dynamodb, neo4j, geode, elasticsearch, memcached, cockroachdb, opensearch, clickhouse, spanner, trino] + + +#### Attribute `db.connection_string` + +The connection string used to connect to the database. It is recommended to remove embedded credentials. + + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: Server=(localdb)\v11.0;Integrated Security=true; + + +#### Attribute `db.user` + +Username for accessing the database. + + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "readonly_user", + "reporting_user", +] + + +#### Attribute `db.jdbc.driver_classname` + +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. + + + +- Requirement Level: Recommended + +- Tag: connection-level-tech-specific + +- Type: string +- Examples: [ + "org.postgresql.Driver", + "com.microsoft.sqlserver.jdbc.SQLServerDriver", +] + + +#### Attribute `db.name` + +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). + + + +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). + +- Requirement Level: Conditionally Required - If applicable. + +- Tag: call-level + +- Type: string +- Examples: [ + "customers", + "main", +] + + +#### Attribute `db.statement` + +The database statement being executed. + + + +- Requirement Level: Optional + +- Tag: call-level + +- Type: string +- Examples: [ + "SELECT * FROM wuser_table", + "SET mykey \"WuValue\"", +] + + +#### Attribute `db.operation` + +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. + + + +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. + +- Requirement Level: Conditionally Required - If `db.statement` is not applicable. + +- Tag: call-level + +- Type: string +- Examples: [ + "findAndModify", + "HMSET", + "SELECT", +] + + +#### Attribute `server.address` + +Name of the database host. + + + +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. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "example.com", + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +#### Attribute `server.port` + +Server port number. + + +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. + +- Requirement Level: Conditionally Required - If using a port other than the default port for this DBMS and if `server.address` is set. + +- Tag: connection-level + +- Type: int +- Examples: [ + 80, + 8080, + 443, +] + +- Stability: Stable + + +#### Attribute `network.peer.address` + +Peer address of the network connection - IP address or Unix domain socket name. + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +#### Attribute `network.peer.port` + +Peer port number of the network connection. + + +- Requirement Level: Optional + +- Tag: connection-level + +- Type: int +- Examples: [ + 65123, +] + +- Stability: Stable + + +#### Attribute `network.transport` + +[OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). + + + +The value SHOULD be normalized to lowercase. + +Consider always setting the transport when setting a port number, since +a port number is ambiguous without knowing the transport. For example +different processes could be listening on TCP port 12345 and UDP port 12345. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: Enum [tcp, udp, pipe, unix] +- Examples: [ + "tcp", + "udp", +] + +- Stability: Stable + + +#### Attribute `network.type` + +[OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. + + +The value SHOULD be normalized to lowercase. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: Enum [ipv4, ipv6] +- Examples: [ + "ipv4", + "ipv6", +] + +- Stability: Stable + + +#### Attribute `db.instance.id` + +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`. + + + +- Requirement Level: Optional + +- Tag: connection-level + +- Type: string +- Examples: mysql-e26b99z.example.com + + +#### Attribute `db.name` + +The HBase namespace. + + + +For HBase the `db.name` should be set to the HBase namespace. + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific + +- Type: string +- Examples: [ + "mynamespace", +] + + + +## Group `db.couchdb` (span) + +### Brief + +Call-level attributes for CouchDB + +prefix: + +### Attributes + + +#### Attribute `db.system` + +An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. + + +- Requirement Level: Required + +- Tag: connection-level + +- Type: Enum [other_sql, mssql, mssqlcompact, mysql, oracle, db2, postgresql, redshift, hive, cloudscape, hsqldb, progress, maxdb, hanadb, ingres, firstsql, edb, cache, adabas, firebird, derby, filemaker, informix, instantdb, interbase, mariadb, netezza, pervasive, pointbase, sqlite, sybase, teradata, vertica, h2, coldfusion, cassandra, hbase, mongodb, redis, couchbase, couchdb, cosmosdb, dynamodb, neo4j, geode, elasticsearch, memcached, cockroachdb, opensearch, clickhouse, spanner, trino] + + +#### Attribute `db.connection_string` + +The connection string used to connect to the database. It is recommended to remove embedded credentials. + + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: Server=(localdb)\v11.0;Integrated Security=true; + + +#### Attribute `db.user` + +Username for accessing the database. + + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "readonly_user", + "reporting_user", +] + + +#### Attribute `db.jdbc.driver_classname` + +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. + + + +- Requirement Level: Recommended + +- Tag: connection-level-tech-specific + +- Type: string +- Examples: [ + "org.postgresql.Driver", + "com.microsoft.sqlserver.jdbc.SQLServerDriver", +] + + +#### Attribute `db.name` + +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). + + + +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). + +- Requirement Level: Conditionally Required - If applicable. + +- Tag: call-level + +- Type: string +- Examples: [ + "customers", + "main", +] + + +#### Attribute `db.statement` + +The database statement being executed. + + + +- Requirement Level: Optional + +- Tag: call-level + +- Type: string +- Examples: [ + "SELECT * FROM wuser_table", + "SET mykey \"WuValue\"", +] + + +#### Attribute `db.operation` + +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. + + + +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. + +- Requirement Level: Conditionally Required - If `db.statement` is not applicable. + +- Tag: call-level + +- Type: string +- Examples: [ + "findAndModify", + "HMSET", + "SELECT", +] + + +#### Attribute `server.address` + +Name of the database host. + + + +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. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "example.com", + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +#### Attribute `server.port` + +Server port number. + + +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. + +- Requirement Level: Conditionally Required - If using a port other than the default port for this DBMS and if `server.address` is set. + +- Tag: connection-level + +- Type: int +- Examples: [ + 80, + 8080, + 443, +] + +- Stability: Stable + + +#### Attribute `network.peer.address` + +Peer address of the network connection - IP address or Unix domain socket name. + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +#### Attribute `network.peer.port` + +Peer port number of the network connection. + + +- Requirement Level: Optional + +- Tag: connection-level + +- Type: int +- Examples: [ + 65123, +] + +- Stability: Stable + + +#### Attribute `network.transport` + +[OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). + + + +The value SHOULD be normalized to lowercase. + +Consider always setting the transport when setting a port number, since +a port number is ambiguous without knowing the transport. For example +different processes could be listening on TCP port 12345 and UDP port 12345. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: Enum [tcp, udp, pipe, unix] +- Examples: [ + "tcp", + "udp", +] + +- Stability: Stable + + +#### Attribute `network.type` + +[OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. + + +The value SHOULD be normalized to lowercase. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: Enum [ipv4, ipv6] +- Examples: [ + "ipv4", + "ipv6", +] + +- Stability: Stable + + +#### Attribute `db.instance.id` + +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`. + + + +- Requirement Level: Optional + +- Tag: connection-level + +- Type: string +- Examples: mysql-e26b99z.example.com + + +#### Attribute `db.operation` + +The HTTP method + the target REST route. + + + +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). + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific + +- Type: string +- Examples: [ + "GET /{db}/{docid}", +] + + + +## Group `db.redis` (span) + +### Brief + +Call-level attributes for Redis + +prefix: + +### Attributes + + +#### Attribute `db.system` + +An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. + + +- Requirement Level: Required + +- Tag: connection-level + +- Type: Enum [other_sql, mssql, mssqlcompact, mysql, oracle, db2, postgresql, redshift, hive, cloudscape, hsqldb, progress, maxdb, hanadb, ingres, firstsql, edb, cache, adabas, firebird, derby, filemaker, informix, instantdb, interbase, mariadb, netezza, pervasive, pointbase, sqlite, sybase, teradata, vertica, h2, coldfusion, cassandra, hbase, mongodb, redis, couchbase, couchdb, cosmosdb, dynamodb, neo4j, geode, elasticsearch, memcached, cockroachdb, opensearch, clickhouse, spanner, trino] + + +#### Attribute `db.connection_string` + +The connection string used to connect to the database. It is recommended to remove embedded credentials. + + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: Server=(localdb)\v11.0;Integrated Security=true; + + +#### Attribute `db.user` + +Username for accessing the database. + + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "readonly_user", + "reporting_user", +] + + +#### Attribute `db.jdbc.driver_classname` + +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. + + + +- Requirement Level: Recommended + +- Tag: connection-level-tech-specific + +- Type: string +- Examples: [ + "org.postgresql.Driver", + "com.microsoft.sqlserver.jdbc.SQLServerDriver", +] + + +#### Attribute `db.name` + +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). + + + +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). + +- Requirement Level: Conditionally Required - If applicable. + +- Tag: call-level + +- Type: string +- Examples: [ + "customers", + "main", +] + + +#### Attribute `db.statement` + +The database statement being executed. + + + +- Requirement Level: Optional + +- Tag: call-level + +- Type: string +- Examples: [ + "SELECT * FROM wuser_table", + "SET mykey \"WuValue\"", +] + + +#### Attribute `db.operation` + +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. + + + +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. + +- Requirement Level: Conditionally Required - If `db.statement` is not applicable. + +- Tag: call-level + +- Type: string +- Examples: [ + "findAndModify", + "HMSET", + "SELECT", +] + + +#### Attribute `server.address` + +Name of the database host. + + + +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. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "example.com", + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +#### Attribute `server.port` + +Server port number. + + +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. + +- Requirement Level: Conditionally Required - If using a port other than the default port for this DBMS and if `server.address` is set. + +- Tag: connection-level + +- Type: int +- Examples: [ + 80, + 8080, + 443, +] + +- Stability: Stable + + +#### Attribute `network.peer.address` + +Peer address of the network connection - IP address or Unix domain socket name. + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +#### Attribute `network.peer.port` + +Peer port number of the network connection. + + +- Requirement Level: Optional + +- Tag: connection-level + +- Type: int +- Examples: [ + 65123, +] + +- Stability: Stable + + +#### Attribute `network.transport` + +[OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). + + + +The value SHOULD be normalized to lowercase. + +Consider always setting the transport when setting a port number, since +a port number is ambiguous without knowing the transport. For example +different processes could be listening on TCP port 12345 and UDP port 12345. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: Enum [tcp, udp, pipe, unix] +- Examples: [ + "tcp", + "udp", +] + +- Stability: Stable + + +#### Attribute `network.type` + +[OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. + + +The value SHOULD be normalized to lowercase. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: Enum [ipv4, ipv6] +- Examples: [ + "ipv4", + "ipv6", +] + +- Stability: Stable + + +#### Attribute `db.instance.id` + +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`. + + + +- Requirement Level: Optional + +- Tag: connection-level + +- Type: string +- Examples: mysql-e26b99z.example.com + + +#### Attribute `db.redis.database_index` + +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. + + + +- Requirement Level: Conditionally Required - If other than the default database (`0`). + +- Tag: call-level-tech-specific + +- Type: int +- Examples: [ + 0, + 1, + 15, +] + + +#### Attribute `db.statement` + +The full syntax of the Redis CLI command. + + + +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`. + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific + +- Type: string +- Examples: [ + "HMSET myhash field1 'Hello' field2 'World'", +] + + + +## Group `db.mongodb` (span) + +### Brief + +Call-level attributes for MongoDB + +prefix: + +### Attributes + + +#### Attribute `db.system` + +An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. + + +- Requirement Level: Required + +- Tag: connection-level + +- Type: Enum [other_sql, mssql, mssqlcompact, mysql, oracle, db2, postgresql, redshift, hive, cloudscape, hsqldb, progress, maxdb, hanadb, ingres, firstsql, edb, cache, adabas, firebird, derby, filemaker, informix, instantdb, interbase, mariadb, netezza, pervasive, pointbase, sqlite, sybase, teradata, vertica, h2, coldfusion, cassandra, hbase, mongodb, redis, couchbase, couchdb, cosmosdb, dynamodb, neo4j, geode, elasticsearch, memcached, cockroachdb, opensearch, clickhouse, spanner, trino] + + +#### Attribute `db.connection_string` + +The connection string used to connect to the database. It is recommended to remove embedded credentials. + + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: Server=(localdb)\v11.0;Integrated Security=true; + + +#### Attribute `db.user` + +Username for accessing the database. + + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "readonly_user", + "reporting_user", +] + + +#### Attribute `db.jdbc.driver_classname` + +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. + + + +- Requirement Level: Recommended + +- Tag: connection-level-tech-specific + +- Type: string +- Examples: [ + "org.postgresql.Driver", + "com.microsoft.sqlserver.jdbc.SQLServerDriver", +] + + +#### Attribute `db.name` + +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). + + + +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). + +- Requirement Level: Conditionally Required - If applicable. + +- Tag: call-level + +- Type: string +- Examples: [ + "customers", + "main", +] + + +#### Attribute `db.statement` + +The database statement being executed. + + + +- Requirement Level: Optional + +- Tag: call-level + +- Type: string +- Examples: [ + "SELECT * FROM wuser_table", + "SET mykey \"WuValue\"", +] + + +#### Attribute `db.operation` + +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. + + + +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. + +- Requirement Level: Conditionally Required - If `db.statement` is not applicable. + +- Tag: call-level + +- Type: string +- Examples: [ + "findAndModify", + "HMSET", + "SELECT", +] + + +#### Attribute `server.address` + +Name of the database host. + + + +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. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "example.com", + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +#### Attribute `server.port` + +Server port number. + + +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. + +- Requirement Level: Conditionally Required - If using a port other than the default port for this DBMS and if `server.address` is set. + +- Tag: connection-level + +- Type: int +- Examples: [ + 80, + 8080, + 443, +] + +- Stability: Stable + + +#### Attribute `network.peer.address` + +Peer address of the network connection - IP address or Unix domain socket name. + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +#### Attribute `network.peer.port` + +Peer port number of the network connection. + + +- Requirement Level: Optional + +- Tag: connection-level + +- Type: int +- Examples: [ + 65123, +] + +- Stability: Stable + + +#### Attribute `network.transport` + +[OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). + + + +The value SHOULD be normalized to lowercase. + +Consider always setting the transport when setting a port number, since +a port number is ambiguous without knowing the transport. For example +different processes could be listening on TCP port 12345 and UDP port 12345. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: Enum [tcp, udp, pipe, unix] +- Examples: [ + "tcp", + "udp", +] + +- Stability: Stable + + +#### Attribute `network.type` + +[OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. + + +The value SHOULD be normalized to lowercase. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: Enum [ipv4, ipv6] +- Examples: [ + "ipv4", + "ipv6", +] + +- Stability: Stable + + +#### Attribute `db.instance.id` + +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`. + + + +- Requirement Level: Optional + +- Tag: connection-level + +- Type: string +- Examples: mysql-e26b99z.example.com + + +#### Attribute `db.mongodb.collection` + +The MongoDB collection being accessed within the database stated in `db.name`. + + + +- Requirement Level: Required + +- Tag: call-level-tech-specific + +- Type: string +- Examples: [ + "customers", + "products", +] + + + +## Group `db.elasticsearch` (span) + +### Brief + +Call-level attributes for Elasticsearch + +prefix: + +### Attributes + + +#### Attribute `db.system` + +An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. + + +- Requirement Level: Required + +- Tag: connection-level + +- Type: Enum [other_sql, mssql, mssqlcompact, mysql, oracle, db2, postgresql, redshift, hive, cloudscape, hsqldb, progress, maxdb, hanadb, ingres, firstsql, edb, cache, adabas, firebird, derby, filemaker, informix, instantdb, interbase, mariadb, netezza, pervasive, pointbase, sqlite, sybase, teradata, vertica, h2, coldfusion, cassandra, hbase, mongodb, redis, couchbase, couchdb, cosmosdb, dynamodb, neo4j, geode, elasticsearch, memcached, cockroachdb, opensearch, clickhouse, spanner, trino] + + +#### Attribute `db.connection_string` + +The connection string used to connect to the database. It is recommended to remove embedded credentials. + + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: Server=(localdb)\v11.0;Integrated Security=true; + + +#### Attribute `db.user` + +Username for accessing the database. + + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "readonly_user", + "reporting_user", +] + + +#### Attribute `db.jdbc.driver_classname` + +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. + + + +- Requirement Level: Recommended + +- Tag: connection-level-tech-specific + +- Type: string +- Examples: [ + "org.postgresql.Driver", + "com.microsoft.sqlserver.jdbc.SQLServerDriver", +] + + +#### Attribute `db.name` + +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). + + + +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). + +- Requirement Level: Conditionally Required - If applicable. + +- Tag: call-level + +- Type: string +- Examples: [ + "customers", + "main", +] + + +#### Attribute `db.statement` + +The database statement being executed. + + + +- Requirement Level: Optional + +- Tag: call-level + +- Type: string +- Examples: [ + "SELECT * FROM wuser_table", + "SET mykey \"WuValue\"", +] + + +#### Attribute `db.operation` + +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. + + + +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. + +- Requirement Level: Conditionally Required - If `db.statement` is not applicable. + +- Tag: call-level + +- Type: string +- Examples: [ + "findAndModify", + "HMSET", + "SELECT", +] + + +#### Attribute `server.address` + +Name of the database host. + + + +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. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "example.com", + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +#### Attribute `server.port` + +Server port number. + + +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. + +- Requirement Level: Conditionally Required - If using a port other than the default port for this DBMS and if `server.address` is set. + +- Tag: connection-level + +- Type: int +- Examples: [ + 80, + 8080, + 443, +] + +- Stability: Stable + + +#### Attribute `network.peer.address` + +Peer address of the network connection - IP address or Unix domain socket name. + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +#### Attribute `network.peer.port` + +Peer port number of the network connection. + + +- Requirement Level: Optional + +- Tag: connection-level + +- Type: int +- Examples: [ + 65123, +] + +- Stability: Stable + + +#### Attribute `network.transport` + +[OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). + + + +The value SHOULD be normalized to lowercase. + +Consider always setting the transport when setting a port number, since +a port number is ambiguous without knowing the transport. For example +different processes could be listening on TCP port 12345 and UDP port 12345. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: Enum [tcp, udp, pipe, unix] +- Examples: [ + "tcp", + "udp", +] + +- Stability: Stable + + +#### Attribute `network.type` + +[OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. + + +The value SHOULD be normalized to lowercase. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: Enum [ipv4, ipv6] +- Examples: [ + "ipv4", + "ipv6", +] + +- Stability: Stable + + +#### Attribute `db.instance.id` + +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`. + + + +- Requirement Level: Optional + +- Tag: connection-level + +- Type: string +- Examples: mysql-e26b99z.example.com + + +#### Attribute `http.request.method` + +HTTP request method. + + +HTTP request method value SHOULD be "known" to the instrumentation. +By default, this convention defines "known" methods as the ones listed in [RFC9110](https://www.rfc-editor.org/rfc/rfc9110.html#name-methods) +and the PATCH method defined in [RFC5789](https://www.rfc-editor.org/rfc/rfc5789.html). + +If the HTTP request method is not known to instrumentation, it MUST set the `http.request.method` attribute to `_OTHER`. + +If the HTTP instrumentation could end up converting valid HTTP request methods to `_OTHER`, then it MUST provide a way to override +the list of known HTTP methods. If this override is done via environment variable, then the environment variable MUST be named +OTEL_INSTRUMENTATION_HTTP_KNOWN_METHODS and support a comma-separated list of case-sensitive known HTTP methods +(this list MUST be a full override of the default known method, it is not a list of known methods in addition to the defaults). + +HTTP method names are case-sensitive and `http.request.method` attribute value MUST match a known HTTP method name exactly. +Instrumentations for specific web frameworks that consider HTTP methods to be case insensitive, SHOULD populate a canonical equivalent. +Tracing instrumentations that do so, MUST also set `http.request.method_original` to the original value. + +- Requirement Level: Required + +- Tag: call-level-tech-specific + +- Type: Enum [CONNECT, DELETE, GET, HEAD, OPTIONS, PATCH, POST, PUT, TRACE, _OTHER] +- Examples: [ + "GET", + "POST", + "HEAD", +] + +- Stability: Stable + + +#### Attribute `db.operation` + +The endpoint identifier for the request. + + +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. + +- Requirement Level: Required + +- Tag: call-level-tech-specific + +- Type: string +- Examples: [ + "search", + "ml.close_job", + "cat.aliases", +] + + +#### Attribute `url.full` + +Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986) + + +For network calls, URL usually has `scheme://host[:port][path][?query][#fragment]` format, where the fragment is not transmitted over HTTP, but if it is known, it SHOULD be included nevertheless. +`url.full` MUST NOT contain credentials passed via URL in form of `https://username:password@www.example.com/`. In such case username and password SHOULD be redacted and attribute's value SHOULD be `https://REDACTED:REDACTED@www.example.com/`. +`url.full` SHOULD capture the absolute URL when it is available (or can be reconstructed) and SHOULD NOT be validated or modified except for sanitizing purposes. + +- Requirement Level: Required + +- Tag: call-level-tech-specific + +- Type: string +- Examples: [ + "https://localhost:9200/index/_search?q=user.id:kimchy", +] + +- Stability: Stable + + +#### Attribute `db.statement` + +The request body for a [search-type query](https://www.elastic.co/guide/en/elasticsearch/reference/current/search.html), as a json string. + + +- Requirement Level: Optional + +- Tag: call-level-tech-specific + +- Type: string +- Examples: [ + "\"{\\\"query\\\":{\\\"term\\\":{\\\"user.id\\\":\\\"kimchy\\\"}}}\"", +] + + +#### Attribute `server.address` + +Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. + + +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. + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific + +- Type: string +- Examples: [ + "example.com", + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +#### Attribute `server.port` + +Server port number. + + +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. + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific + +- Type: int +- Examples: [ + 80, + 8080, + 443, +] + +- Stability: Stable + + +#### Attribute `db.elasticsearch.cluster.name` + +Represents the identifier of an Elasticsearch cluster. + + + +- Requirement Level: Optional + +- Tag: call-level-tech-specific + +- Type: string +- Examples: [ + "e9106fc68e3044f0b1475b04bf4ffd5f", +] + + +#### Attribute `db.elasticsearch.node.name` + +Represents the human-readable identifier of the node/instance to which a request was routed. + + + +- Requirement Level: Optional + +- Tag: call-level-tech-specific + +- Type: string +- Examples: [ + "instance-0000000001", +] + + +#### Attribute `db.elasticsearch.path_parts` + +A dynamic value in the url path. + + + +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. + +- Requirement Level: Conditionally Required - when the url has dynamic values + +- Tag: call-level-tech-specific + +- Type: template[string] +- Examples: [ + "db.elasticsearch.path_parts.index=test-index", + "db.elasticsearch.path_parts.doc_id=123", +] + + + +## Group `db.sql` (span) + +### Brief + +Call-level attributes for SQL databases + +prefix: + +### Attributes + + +#### Attribute `db.system` + +An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. + + +- Requirement Level: Required + +- Tag: connection-level + +- Type: Enum [other_sql, mssql, mssqlcompact, mysql, oracle, db2, postgresql, redshift, hive, cloudscape, hsqldb, progress, maxdb, hanadb, ingres, firstsql, edb, cache, adabas, firebird, derby, filemaker, informix, instantdb, interbase, mariadb, netezza, pervasive, pointbase, sqlite, sybase, teradata, vertica, h2, coldfusion, cassandra, hbase, mongodb, redis, couchbase, couchdb, cosmosdb, dynamodb, neo4j, geode, elasticsearch, memcached, cockroachdb, opensearch, clickhouse, spanner, trino] + + +#### Attribute `db.connection_string` + +The connection string used to connect to the database. It is recommended to remove embedded credentials. + + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: Server=(localdb)\v11.0;Integrated Security=true; + + +#### Attribute `db.user` + +Username for accessing the database. + + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "readonly_user", + "reporting_user", +] + + +#### Attribute `db.jdbc.driver_classname` + +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. + + + +- Requirement Level: Recommended + +- Tag: connection-level-tech-specific + +- Type: string +- Examples: [ + "org.postgresql.Driver", + "com.microsoft.sqlserver.jdbc.SQLServerDriver", +] + + +#### Attribute `db.name` + +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). + + + +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). + +- Requirement Level: Conditionally Required - If applicable. + +- Tag: call-level + +- Type: string +- Examples: [ + "customers", + "main", +] + + +#### Attribute `db.statement` + +The database statement being executed. + + + +- Requirement Level: Optional + +- Tag: call-level + +- Type: string +- Examples: [ + "SELECT * FROM wuser_table", + "SET mykey \"WuValue\"", +] + + +#### Attribute `db.operation` + +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. + + + +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. + +- Requirement Level: Conditionally Required - If `db.statement` is not applicable. + +- Tag: call-level + +- Type: string +- Examples: [ + "findAndModify", + "HMSET", + "SELECT", +] + + +#### Attribute `server.address` + +Name of the database host. + + + +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. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "example.com", + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +#### Attribute `server.port` + +Server port number. + + +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. + +- Requirement Level: Conditionally Required - If using a port other than the default port for this DBMS and if `server.address` is set. + +- Tag: connection-level + +- Type: int +- Examples: [ + 80, + 8080, + 443, +] + +- Stability: Stable + + +#### Attribute `network.peer.address` + +Peer address of the network connection - IP address or Unix domain socket name. + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +#### Attribute `network.peer.port` + +Peer port number of the network connection. + + +- Requirement Level: Optional + +- Tag: connection-level + +- Type: int +- Examples: [ + 65123, +] + +- Stability: Stable + + +#### Attribute `network.transport` + +[OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). + + + +The value SHOULD be normalized to lowercase. + +Consider always setting the transport when setting a port number, since +a port number is ambiguous without knowing the transport. For example +different processes could be listening on TCP port 12345 and UDP port 12345. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: Enum [tcp, udp, pipe, unix] +- Examples: [ + "tcp", + "udp", +] + +- Stability: Stable + + +#### Attribute `network.type` + +[OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. + + +The value SHOULD be normalized to lowercase. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: Enum [ipv4, ipv6] +- Examples: [ + "ipv4", + "ipv6", +] + +- Stability: Stable + + +#### Attribute `db.instance.id` + +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`. + + + +- Requirement Level: Optional + +- Tag: connection-level + +- Type: string +- Examples: mysql-e26b99z.example.com + + +#### Attribute `db.sql.table` + +The name of the primary table that the operation is acting upon, including the database name (if applicable). + + +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. + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific + +- Type: string +- Examples: [ + "public.users", + "customers", +] + + + +## Group `db.cosmosdb` (span) + +### Brief + +Call-level attributes for Cosmos DB. + +prefix: db.cosmosdb + +### Attributes + + +#### Attribute `db.system` + +An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. + + +- Requirement Level: Required + +- Tag: connection-level + +- Type: Enum [other_sql, mssql, mssqlcompact, mysql, oracle, db2, postgresql, redshift, hive, cloudscape, hsqldb, progress, maxdb, hanadb, ingres, firstsql, edb, cache, adabas, firebird, derby, filemaker, informix, instantdb, interbase, mariadb, netezza, pervasive, pointbase, sqlite, sybase, teradata, vertica, h2, coldfusion, cassandra, hbase, mongodb, redis, couchbase, couchdb, cosmosdb, dynamodb, neo4j, geode, elasticsearch, memcached, cockroachdb, opensearch, clickhouse, spanner, trino] + + +#### Attribute `db.connection_string` + +The connection string used to connect to the database. It is recommended to remove embedded credentials. + + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: Server=(localdb)\v11.0;Integrated Security=true; + + +#### Attribute `db.user` + +Username for accessing the database. + + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "readonly_user", + "reporting_user", +] + + +#### Attribute `db.jdbc.driver_classname` + +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. + + + +- Requirement Level: Recommended + +- Tag: connection-level-tech-specific + +- Type: string +- Examples: [ + "org.postgresql.Driver", + "com.microsoft.sqlserver.jdbc.SQLServerDriver", +] + + +#### Attribute `db.name` + +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). + + + +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). + +- Requirement Level: Conditionally Required - If applicable. + +- Tag: call-level + +- Type: string +- Examples: [ + "customers", + "main", +] + + +#### Attribute `db.statement` + +The database statement being executed. + + + +- Requirement Level: Optional + +- Tag: call-level + +- Type: string +- Examples: [ + "SELECT * FROM wuser_table", + "SET mykey \"WuValue\"", +] + + +#### Attribute `db.operation` + +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. + + + +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. + +- Requirement Level: Conditionally Required - If `db.statement` is not applicable. + +- Tag: call-level + +- Type: string +- Examples: [ + "findAndModify", + "HMSET", + "SELECT", +] + + +#### Attribute `server.address` + +Name of the database host. + + + +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. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "example.com", + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +#### Attribute `server.port` + +Server port number. + + +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. + +- Requirement Level: Conditionally Required - If using a port other than the default port for this DBMS and if `server.address` is set. + +- Tag: connection-level + +- Type: int +- Examples: [ + 80, + 8080, + 443, +] + +- Stability: Stable + + +#### Attribute `network.peer.address` + +Peer address of the network connection - IP address or Unix domain socket name. + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +#### Attribute `network.peer.port` + +Peer port number of the network connection. + + +- Requirement Level: Optional + +- Tag: connection-level + +- Type: int +- Examples: [ + 65123, +] + +- Stability: Stable + + +#### Attribute `network.transport` + +[OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). + + + +The value SHOULD be normalized to lowercase. + +Consider always setting the transport when setting a port number, since +a port number is ambiguous without knowing the transport. For example +different processes could be listening on TCP port 12345 and UDP port 12345. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: Enum [tcp, udp, pipe, unix] +- Examples: [ + "tcp", + "udp", +] + +- Stability: Stable + + +#### Attribute `network.type` + +[OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. + + +The value SHOULD be normalized to lowercase. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: Enum [ipv4, ipv6] +- Examples: [ + "ipv4", + "ipv6", +] + +- Stability: Stable + + +#### Attribute `db.instance.id` + +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`. + + + +- Requirement Level: Optional + +- Tag: connection-level + +- Type: string +- Examples: mysql-e26b99z.example.com + + +#### Attribute `db.cosmosdb.client_id` + +Unique Cosmos client instance id. + + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific + +- Type: string +- Examples: 3ba4827d-4422-483f-b59f-85b74211c11d + + +#### Attribute `db.cosmosdb.operation_type` + +CosmosDB Operation Type. + + +- Requirement Level: Conditionally Required - when performing one of the operations in this list + +- Tag: call-level-tech-specific + +- Type: Enum [Invalid, Create, Patch, Read, ReadFeed, Delete, Replace, Execute, Query, Head, HeadFeed, Upsert, Batch, QueryPlan, ExecuteJavaScript] + + +#### Attribute `user_agent.original` + +Full user-agent string is generated by Cosmos DB SDK + + +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. + Format Reg-{D (Disabled discovery)}-S(application region)|L(List of preferred regions)|N(None, user did not configure it). + Default value is "NS". + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific + +- Type: string +- 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\\|", +] + +- Stability: Stable + + +#### Attribute `db.cosmosdb.connection_mode` + +Cosmos client connection mode. + + +- Requirement Level: Conditionally Required - if not `direct` (or pick gw as default) + +- Tag: call-level-tech-specific + +- Type: Enum [gateway, direct] + + +#### Attribute `db.cosmosdb.container` + +Cosmos DB container name. + + +- Requirement Level: Conditionally Required - if available + +- Tag: call-level-tech-specific + +- Type: string +- Examples: anystring + + +#### Attribute `db.cosmosdb.request_content_length` + +Request payload size in bytes + + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific + +- Type: int + + +#### Attribute `db.cosmosdb.status_code` + +Cosmos DB status code. + + +- Requirement Level: Conditionally Required - if response was received + +- Tag: call-level-tech-specific + +- Type: int +- Examples: [ + 200, + 201, +] + + +#### Attribute `db.cosmosdb.sub_status_code` + +Cosmos DB sub status code. + + +- Requirement Level: Conditionally Required - when response was received and contained sub-code. + +- Tag: call-level-tech-specific + +- Type: int +- Examples: [ + 1000, + 1002, +] + + +#### Attribute `db.cosmosdb.request_charge` + +RU consumed for that operation + + +- Requirement Level: Conditionally Required - when available + +- Tag: call-level-tech-specific + +- Type: double +- Examples: [ + 46.18, + 1.0, +] + + + +## Group `db.tech` (span) + +### Brief + +Semantic convention group for specific technologies + +prefix: + +### Attributes + + +#### Attribute `db.system` + +An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. + + +- Requirement Level: Required + +- Tag: connection-level + +- Type: Enum [other_sql, mssql, mssqlcompact, mysql, oracle, db2, postgresql, redshift, hive, cloudscape, hsqldb, progress, maxdb, hanadb, ingres, firstsql, edb, cache, adabas, firebird, derby, filemaker, informix, instantdb, interbase, mariadb, netezza, pervasive, pointbase, sqlite, sybase, teradata, vertica, h2, coldfusion, cassandra, hbase, mongodb, redis, couchbase, couchdb, cosmosdb, dynamodb, neo4j, geode, elasticsearch, memcached, cockroachdb, opensearch, clickhouse, spanner, trino] + + +#### Attribute `db.connection_string` + +The connection string used to connect to the database. It is recommended to remove embedded credentials. + + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: Server=(localdb)\v11.0;Integrated Security=true; + + +#### Attribute `db.user` + +Username for accessing the database. + + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "readonly_user", + "reporting_user", +] + + +#### Attribute `db.jdbc.driver_classname` + +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. + + + +- Requirement Level: Recommended + +- Tag: connection-level-tech-specific + +- Type: string +- Examples: [ + "org.postgresql.Driver", + "com.microsoft.sqlserver.jdbc.SQLServerDriver", +] + + +#### Attribute `db.name` + +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). + + + +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). + +- Requirement Level: Conditionally Required - If applicable. + +- Tag: call-level + +- Type: string +- Examples: [ + "customers", + "main", +] + + +#### Attribute `db.statement` + +The database statement being executed. + + + +- Requirement Level: Optional + +- Tag: call-level + +- Type: string +- Examples: [ + "SELECT * FROM wuser_table", + "SET mykey \"WuValue\"", +] + + +#### Attribute `db.operation` + +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. + + + +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. + +- Requirement Level: Conditionally Required - If `db.statement` is not applicable. + +- Tag: call-level + +- Type: string +- Examples: [ + "findAndModify", + "HMSET", + "SELECT", +] + + +#### Attribute `server.address` + +Name of the database host. + + + +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. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "example.com", + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +#### Attribute `server.port` + +Server port number. + + +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. + +- Requirement Level: Conditionally Required - If using a port other than the default port for this DBMS and if `server.address` is set. + +- Tag: connection-level + +- Type: int +- Examples: [ + 80, + 8080, + 443, +] + +- Stability: Stable + + +#### Attribute `network.peer.address` + +Peer address of the network connection - IP address or Unix domain socket name. + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +#### Attribute `network.peer.port` + +Peer port number of the network connection. + + +- Requirement Level: Optional + +- Tag: connection-level + +- Type: int +- Examples: [ + 65123, +] + +- Stability: Stable + + +#### Attribute `network.transport` + +[OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). + + + +The value SHOULD be normalized to lowercase. + +Consider always setting the transport when setting a port number, since +a port number is ambiguous without knowing the transport. For example +different processes could be listening on TCP port 12345 and UDP port 12345. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: Enum [tcp, udp, pipe, unix] +- Examples: [ + "tcp", + "udp", +] + +- Stability: Stable + + +#### Attribute `network.type` + +[OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. + + +The value SHOULD be normalized to lowercase. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: Enum [ipv4, ipv6] +- Examples: [ + "ipv4", + "ipv6", +] + +- Stability: Stable + + +#### Attribute `db.instance.id` + +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`. + + + +- Requirement Level: Optional + +- Tag: connection-level + +- Type: string +- Examples: mysql-e26b99z.example.com + + +#### Attribute `db.name` + +The keyspace name in Cassandra. + + + +For Cassandra the `db.name` should be set to the Cassandra keyspace name. + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific-cassandra + +- Type: string +- Examples: [ + "mykeyspace", +] + + +#### Attribute `db.cassandra.page_size` + +The fetch size used for paging, i.e. how many rows will be returned at once. + + + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific-cassandra + +- Type: int +- Examples: [ + 5000, +] + + +#### Attribute `db.cassandra.consistency_level` + +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). + + + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific-cassandra + +- Type: Enum [all, each_quorum, quorum, local_quorum, one, two, three, local_one, any, serial, local_serial] + + +#### Attribute `db.cassandra.table` + +The name of the primary Cassandra table that the operation is acting upon, including the keyspace name (if applicable). + + +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. + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific-cassandra + +- Type: string +- Examples: mytable + + +#### Attribute `db.cassandra.idempotence` + +Whether or not the query is idempotent. + + + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific-cassandra + +- Type: boolean + + +#### Attribute `db.cassandra.speculative_execution_count` + +The number of times a query was speculatively executed. Not set or `0` if the query was not executed speculatively. + + + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific-cassandra + +- Type: int +- Examples: [ + 0, + 2, +] + + +#### Attribute `db.cassandra.coordinator.id` + +The ID of the coordinating node for a query. + + + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific-cassandra + +- Type: string +- Examples: be13faa2-8574-4d71-926d-27f16cf8a7af + + +#### Attribute `db.cassandra.coordinator.dc` + +The data center of the coordinating node for a query. + + + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific-cassandra + +- Type: string +- Examples: us-west-2 + + +#### Attribute `db.redis.database_index` + +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. + + + +- Requirement Level: Conditionally Required - If other than the default database (`0`). + +- Tag: call-level-tech-specific + +- Type: int +- Examples: [ + 0, + 1, + 15, +] + + +#### Attribute `db.statement` + +The full syntax of the Redis CLI command. + + + +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`. + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific + +- Type: string +- Examples: [ + "HMSET myhash field1 'Hello' field2 'World'", +] + + +#### Attribute `db.mongodb.collection` + +The MongoDB collection being accessed within the database stated in `db.name`. + + + +- Requirement Level: Required + +- Tag: call-level-tech-specific + +- Type: string +- Examples: [ + "customers", + "products", +] + + +#### Attribute `db.sql.table` + +The name of the primary table that the operation is acting upon, including the database name (if applicable). + + +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. + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific + +- Type: string +- Examples: [ + "public.users", + "customers", +] + + +#### Attribute `db.cosmosdb.client_id` + +Unique Cosmos client instance id. + + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific + +- Type: string +- Examples: 3ba4827d-4422-483f-b59f-85b74211c11d + + +#### Attribute `db.cosmosdb.operation_type` + +CosmosDB Operation Type. + + +- Requirement Level: Conditionally Required - when performing one of the operations in this list + +- Tag: call-level-tech-specific + +- Type: Enum [Invalid, Create, Patch, Read, ReadFeed, Delete, Replace, Execute, Query, Head, HeadFeed, Upsert, Batch, QueryPlan, ExecuteJavaScript] + + +#### Attribute `user_agent.original` + +Full user-agent string is generated by Cosmos DB SDK + + +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. + Format Reg-{D (Disabled discovery)}-S(application region)|L(List of preferred regions)|N(None, user did not configure it). + Default value is "NS". + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific + +- Type: string +- 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\\|", +] + +- Stability: Stable + + +#### Attribute `db.cosmosdb.connection_mode` + +Cosmos client connection mode. + + +- Requirement Level: Conditionally Required - if not `direct` (or pick gw as default) + +- Tag: call-level-tech-specific + +- Type: Enum [gateway, direct] + + +#### Attribute `db.cosmosdb.container` + +Cosmos DB container name. + + +- Requirement Level: Conditionally Required - if available + +- Tag: call-level-tech-specific + +- Type: string +- Examples: anystring + + +#### Attribute `db.cosmosdb.request_content_length` + +Request payload size in bytes + + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific + +- Type: int + + +#### Attribute `db.cosmosdb.status_code` + +Cosmos DB status code. + + +- Requirement Level: Conditionally Required - if response was received + +- Tag: call-level-tech-specific + +- Type: int +- Examples: [ + 200, + 201, +] + + +#### Attribute `db.cosmosdb.sub_status_code` + +Cosmos DB sub status code. + + +- Requirement Level: Conditionally Required - when response was received and contained sub-code. + +- Tag: call-level-tech-specific + +- Type: int +- Examples: [ + 1000, + 1002, +] + + +#### Attribute `db.cosmosdb.request_charge` + +RU consumed for that operation + + +- Requirement Level: Conditionally Required - when available + +- Tag: call-level-tech-specific + +- Type: double +- Examples: [ + 46.18, + 1.0, +] + + diff --git a/crates/weaver_forge/expected_output/metric/metric_jvm_class_count.md b/crates/weaver_forge/expected_output/metric/metric_jvm_class_count.md new file mode 100644 index 00000000..052e9335 --- /dev/null +++ b/crates/weaver_forge/expected_output/metric/metric_jvm_class_count.md @@ -0,0 +1,16 @@ +## Group `metric.jvm.class.count` (metric) + +### Brief + +Number of classes currently loaded. + + + +Prefix: +Metric: jvm.class.count +Instrument: updowncounter +Unit: {class} +Stability: Stable + +### Attributes + diff --git a/crates/weaver_forge/expected_output/metric/metric_jvm_class_loaded.md b/crates/weaver_forge/expected_output/metric/metric_jvm_class_loaded.md new file mode 100644 index 00000000..d82ce127 --- /dev/null +++ b/crates/weaver_forge/expected_output/metric/metric_jvm_class_loaded.md @@ -0,0 +1,16 @@ +## Group `metric.jvm.class.loaded` (metric) + +### Brief + +Number of classes loaded since JVM start. + + + +Prefix: +Metric: jvm.class.loaded +Instrument: counter +Unit: {class} +Stability: Stable + +### Attributes + diff --git a/crates/weaver_forge/expected_output/metric/metric_jvm_class_unloaded.md b/crates/weaver_forge/expected_output/metric/metric_jvm_class_unloaded.md new file mode 100644 index 00000000..8c5cb1c8 --- /dev/null +++ b/crates/weaver_forge/expected_output/metric/metric_jvm_class_unloaded.md @@ -0,0 +1,16 @@ +## Group `metric.jvm.class.unloaded` (metric) + +### Brief + +Number of classes unloaded since JVM start. + + + +Prefix: +Metric: jvm.class.unloaded +Instrument: counter +Unit: {class} +Stability: Stable + +### Attributes + diff --git a/crates/weaver_forge/expected_output/metric/metric_jvm_cpu_count.md b/crates/weaver_forge/expected_output/metric/metric_jvm_cpu_count.md new file mode 100644 index 00000000..a4f5168a --- /dev/null +++ b/crates/weaver_forge/expected_output/metric/metric_jvm_cpu_count.md @@ -0,0 +1,16 @@ +## Group `metric.jvm.cpu.count` (metric) + +### Brief + +Number of processors available to the Java virtual machine. + + + +Prefix: +Metric: jvm.cpu.count +Instrument: updowncounter +Unit: {cpu} +Stability: Stable + +### Attributes + diff --git a/crates/weaver_forge/expected_output/metric/metric_jvm_cpu_recent_utilization.md b/crates/weaver_forge/expected_output/metric/metric_jvm_cpu_recent_utilization.md new file mode 100644 index 00000000..1b01d182 --- /dev/null +++ b/crates/weaver_forge/expected_output/metric/metric_jvm_cpu_recent_utilization.md @@ -0,0 +1,16 @@ +## Group `metric.jvm.cpu.recent_utilization` (metric) + +### Brief + +Recent CPU utilization for the process as reported by the JVM. + +The value range is [0.0,1.0]. This utilization is not defined as being for the specific interval since last measurement (unlike `system.cpu.utilization`). [Reference](https://docs.oracle.com/en/java/javase/17/docs/api/jdk.management/com/sun/management/OperatingSystemMXBean.html#getProcessCpuLoad()). + +Prefix: +Metric: jvm.cpu.recent_utilization +Instrument: gauge +Unit: 1 +Stability: Stable + +### Attributes + diff --git a/crates/weaver_forge/expected_output/metric/metric_jvm_cpu_time.md b/crates/weaver_forge/expected_output/metric/metric_jvm_cpu_time.md new file mode 100644 index 00000000..92e917a8 --- /dev/null +++ b/crates/weaver_forge/expected_output/metric/metric_jvm_cpu_time.md @@ -0,0 +1,16 @@ +## Group `metric.jvm.cpu.time` (metric) + +### Brief + +CPU time used by the process as reported by the JVM. + + + +Prefix: +Metric: jvm.cpu.time +Instrument: counter +Unit: s +Stability: Stable + +### Attributes + diff --git a/crates/weaver_forge/expected_output/metric/metric_jvm_gc_duration.md b/crates/weaver_forge/expected_output/metric/metric_jvm_gc_duration.md new file mode 100644 index 00000000..42faa7c2 --- /dev/null +++ b/crates/weaver_forge/expected_output/metric/metric_jvm_gc_duration.md @@ -0,0 +1,53 @@ +## Group `metric.jvm.gc.duration` (metric) + +### Brief + +Duration of JVM garbage collection actions. + + + +Prefix: jvm.gc +Metric: jvm.gc.duration +Instrument: histogram +Unit: s +Stability: Stable + +### Attributes + + +#### Attribute `jvm.gc.name` + +Name of the garbage collector. + + +Garbage collector name is generally obtained via [GarbageCollectionNotificationInfo#getGcName()](https://docs.oracle.com/en/java/javase/11/docs/api/jdk.management/com/sun/management/GarbageCollectionNotificationInfo.html#getGcName()). + +- Requirement Level: Recommended + +- Type: string +- Examples: [ + "G1 Young Generation", + "G1 Old Generation", +] + +- Stability: Stable + + +#### Attribute `jvm.gc.action` + +Name of the garbage collector action. + + +Garbage collector action is generally obtained via [GarbageCollectionNotificationInfo#getGcAction()](https://docs.oracle.com/en/java/javase/11/docs/api/jdk.management/com/sun/management/GarbageCollectionNotificationInfo.html#getGcAction()). + +- Requirement Level: Recommended + +- Type: string +- Examples: [ + "end of minor GC", + "end of major GC", +] + +- Stability: Stable + + \ No newline at end of file diff --git a/crates/weaver_forge/expected_output/metric/metric_jvm_memory_committed.md b/crates/weaver_forge/expected_output/metric/metric_jvm_memory_committed.md new file mode 100644 index 00000000..1708ad6d --- /dev/null +++ b/crates/weaver_forge/expected_output/metric/metric_jvm_memory_committed.md @@ -0,0 +1,52 @@ +## Group `metric.jvm.memory.committed` (metric) + +### Brief + +Measure of memory committed. + + + +Prefix: +Metric: jvm.memory.committed +Instrument: updowncounter +Unit: By +Stability: Stable + +### Attributes + + +#### Attribute `jvm.memory.type` + +The type of memory. + + +- Requirement Level: Recommended + +- Type: Enum [heap, non_heap] +- Examples: [ + "heap", + "non_heap", +] + +- Stability: Stable + + +#### Attribute `jvm.memory.pool.name` + +Name of the memory pool. + + +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()). + +- Requirement Level: Recommended + +- Type: string +- Examples: [ + "G1 Old Gen", + "G1 Eden space", + "G1 Survivor Space", +] + +- Stability: Stable + + \ No newline at end of file diff --git a/crates/weaver_forge/expected_output/metric/metric_jvm_memory_limit.md b/crates/weaver_forge/expected_output/metric/metric_jvm_memory_limit.md new file mode 100644 index 00000000..d2dca2c7 --- /dev/null +++ b/crates/weaver_forge/expected_output/metric/metric_jvm_memory_limit.md @@ -0,0 +1,52 @@ +## Group `metric.jvm.memory.limit` (metric) + +### Brief + +Measure of max obtainable memory. + + + +Prefix: +Metric: jvm.memory.limit +Instrument: updowncounter +Unit: By +Stability: Stable + +### Attributes + + +#### Attribute `jvm.memory.type` + +The type of memory. + + +- Requirement Level: Recommended + +- Type: Enum [heap, non_heap] +- Examples: [ + "heap", + "non_heap", +] + +- Stability: Stable + + +#### Attribute `jvm.memory.pool.name` + +Name of the memory pool. + + +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()). + +- Requirement Level: Recommended + +- Type: string +- Examples: [ + "G1 Old Gen", + "G1 Eden space", + "G1 Survivor Space", +] + +- Stability: Stable + + \ No newline at end of file diff --git a/crates/weaver_forge/expected_output/metric/metric_jvm_memory_used.md b/crates/weaver_forge/expected_output/metric/metric_jvm_memory_used.md new file mode 100644 index 00000000..66ec1681 --- /dev/null +++ b/crates/weaver_forge/expected_output/metric/metric_jvm_memory_used.md @@ -0,0 +1,52 @@ +## Group `metric.jvm.memory.used` (metric) + +### Brief + +Measure of memory used. + + + +Prefix: +Metric: jvm.memory.used +Instrument: updowncounter +Unit: By +Stability: Stable + +### Attributes + + +#### Attribute `jvm.memory.type` + +The type of memory. + + +- Requirement Level: Recommended + +- Type: Enum [heap, non_heap] +- Examples: [ + "heap", + "non_heap", +] + +- Stability: Stable + + +#### Attribute `jvm.memory.pool.name` + +Name of the memory pool. + + +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()). + +- Requirement Level: Recommended + +- Type: string +- Examples: [ + "G1 Old Gen", + "G1 Eden space", + "G1 Survivor Space", +] + +- Stability: Stable + + \ No newline at end of file diff --git a/crates/weaver_forge/expected_output/metric/metric_jvm_memory_used_after_last_gc.md b/crates/weaver_forge/expected_output/metric/metric_jvm_memory_used_after_last_gc.md new file mode 100644 index 00000000..6f71ae44 --- /dev/null +++ b/crates/weaver_forge/expected_output/metric/metric_jvm_memory_used_after_last_gc.md @@ -0,0 +1,52 @@ +## Group `metric.jvm.memory.used_after_last_gc` (metric) + +### Brief + +Measure of memory used, as measured after the most recent garbage collection event on this pool. + + + +Prefix: +Metric: jvm.memory.used_after_last_gc +Instrument: updowncounter +Unit: By +Stability: Stable + +### Attributes + + +#### Attribute `jvm.memory.type` + +The type of memory. + + +- Requirement Level: Recommended + +- Type: Enum [heap, non_heap] +- Examples: [ + "heap", + "non_heap", +] + +- Stability: Stable + + +#### Attribute `jvm.memory.pool.name` + +Name of the memory pool. + + +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()). + +- Requirement Level: Recommended + +- Type: string +- Examples: [ + "G1 Old Gen", + "G1 Eden space", + "G1 Survivor Space", +] + +- Stability: Stable + + \ No newline at end of file diff --git a/crates/weaver_forge/expected_output/metric/metric_jvm_thread_count.md b/crates/weaver_forge/expected_output/metric/metric_jvm_thread_count.md new file mode 100644 index 00000000..03ec08d1 --- /dev/null +++ b/crates/weaver_forge/expected_output/metric/metric_jvm_thread_count.md @@ -0,0 +1,45 @@ +## Group `metric.jvm.thread.count` (metric) + +### Brief + +Number of executing platform threads. + + + +Prefix: +Metric: jvm.thread.count +Instrument: updowncounter +Unit: {thread} +Stability: Stable + +### Attributes + + +#### Attribute `jvm.thread.daemon` + +Whether the thread is daemon or not. + + +- Requirement Level: Recommended + +- Type: boolean + +- Stability: Stable + + +#### Attribute `jvm.thread.state` + +State of the thread. + + +- Requirement Level: Recommended + +- Type: Enum [new, runnable, blocked, waiting, timed_waiting, terminated] +- Examples: [ + "runnable", + "blocked", +] + +- Stability: Stable + + \ No newline at end of file diff --git a/crates/weaver_forge/expected_output/metric_groups.md b/crates/weaver_forge/expected_output/metric_groups.md new file mode 100644 index 00000000..28eae3a2 --- /dev/null +++ b/crates/weaver_forge/expected_output/metric_groups.md @@ -0,0 +1,2 @@ +# Semantic Convention Metric Group Groups + diff --git a/crates/weaver_forge/expected_output/metrics.md b/crates/weaver_forge/expected_output/metrics.md new file mode 100644 index 00000000..f255e743 --- /dev/null +++ b/crates/weaver_forge/expected_output/metrics.md @@ -0,0 +1,423 @@ +# Semantic Convention Metric Groups + + +## Group `metric.jvm.memory.used` (metric) + +### Brief + +Measure of memory used. + + + +Prefix: +Metric: jvm.memory.used +Instrument: updowncounter +Unit: By +Stability: Stable + +### Attributes + + +#### Attribute `jvm.memory.type` + +The type of memory. + + +- Requirement Level: Recommended + +- Type: Enum [heap, non_heap] +- Examples: [ + "heap", + "non_heap", +] + +- Stability: Stable + + +#### Attribute `jvm.memory.pool.name` + +Name of the memory pool. + + +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()). + +- Requirement Level: Recommended + +- Type: string +- Examples: [ + "G1 Old Gen", + "G1 Eden space", + "G1 Survivor Space", +] + +- Stability: Stable + + + +## Group `metric.jvm.memory.committed` (metric) + +### Brief + +Measure of memory committed. + + + +Prefix: +Metric: jvm.memory.committed +Instrument: updowncounter +Unit: By +Stability: Stable + +### Attributes + + +#### Attribute `jvm.memory.type` + +The type of memory. + + +- Requirement Level: Recommended + +- Type: Enum [heap, non_heap] +- Examples: [ + "heap", + "non_heap", +] + +- Stability: Stable + + +#### Attribute `jvm.memory.pool.name` + +Name of the memory pool. + + +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()). + +- Requirement Level: Recommended + +- Type: string +- Examples: [ + "G1 Old Gen", + "G1 Eden space", + "G1 Survivor Space", +] + +- Stability: Stable + + + +## Group `metric.jvm.memory.limit` (metric) + +### Brief + +Measure of max obtainable memory. + + + +Prefix: +Metric: jvm.memory.limit +Instrument: updowncounter +Unit: By +Stability: Stable + +### Attributes + + +#### Attribute `jvm.memory.type` + +The type of memory. + + +- Requirement Level: Recommended + +- Type: Enum [heap, non_heap] +- Examples: [ + "heap", + "non_heap", +] + +- Stability: Stable + + +#### Attribute `jvm.memory.pool.name` + +Name of the memory pool. + + +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()). + +- Requirement Level: Recommended + +- Type: string +- Examples: [ + "G1 Old Gen", + "G1 Eden space", + "G1 Survivor Space", +] + +- Stability: Stable + + + +## Group `metric.jvm.memory.used_after_last_gc` (metric) + +### Brief + +Measure of memory used, as measured after the most recent garbage collection event on this pool. + + + +Prefix: +Metric: jvm.memory.used_after_last_gc +Instrument: updowncounter +Unit: By +Stability: Stable + +### Attributes + + +#### Attribute `jvm.memory.type` + +The type of memory. + + +- Requirement Level: Recommended + +- Type: Enum [heap, non_heap] +- Examples: [ + "heap", + "non_heap", +] + +- Stability: Stable + + +#### Attribute `jvm.memory.pool.name` + +Name of the memory pool. + + +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()). + +- Requirement Level: Recommended + +- Type: string +- Examples: [ + "G1 Old Gen", + "G1 Eden space", + "G1 Survivor Space", +] + +- Stability: Stable + + + +## Group `metric.jvm.gc.duration` (metric) + +### Brief + +Duration of JVM garbage collection actions. + + + +Prefix: jvm.gc +Metric: jvm.gc.duration +Instrument: histogram +Unit: s +Stability: Stable + +### Attributes + + +#### Attribute `jvm.gc.name` + +Name of the garbage collector. + + +Garbage collector name is generally obtained via [GarbageCollectionNotificationInfo#getGcName()](https://docs.oracle.com/en/java/javase/11/docs/api/jdk.management/com/sun/management/GarbageCollectionNotificationInfo.html#getGcName()). + +- Requirement Level: Recommended + +- Type: string +- Examples: [ + "G1 Young Generation", + "G1 Old Generation", +] + +- Stability: Stable + + +#### Attribute `jvm.gc.action` + +Name of the garbage collector action. + + +Garbage collector action is generally obtained via [GarbageCollectionNotificationInfo#getGcAction()](https://docs.oracle.com/en/java/javase/11/docs/api/jdk.management/com/sun/management/GarbageCollectionNotificationInfo.html#getGcAction()). + +- Requirement Level: Recommended + +- Type: string +- Examples: [ + "end of minor GC", + "end of major GC", +] + +- Stability: Stable + + + +## Group `metric.jvm.thread.count` (metric) + +### Brief + +Number of executing platform threads. + + + +Prefix: +Metric: jvm.thread.count +Instrument: updowncounter +Unit: {thread} +Stability: Stable + +### Attributes + + +#### Attribute `jvm.thread.daemon` + +Whether the thread is daemon or not. + + +- Requirement Level: Recommended + +- Type: boolean + +- Stability: Stable + + +#### Attribute `jvm.thread.state` + +State of the thread. + + +- Requirement Level: Recommended + +- Type: Enum [new, runnable, blocked, waiting, timed_waiting, terminated] +- Examples: [ + "runnable", + "blocked", +] + +- Stability: Stable + + + +## Group `metric.jvm.class.loaded` (metric) + +### Brief + +Number of classes loaded since JVM start. + + + +Prefix: +Metric: jvm.class.loaded +Instrument: counter +Unit: {class} +Stability: Stable + +### Attributes + + + +## Group `metric.jvm.class.unloaded` (metric) + +### Brief + +Number of classes unloaded since JVM start. + + + +Prefix: +Metric: jvm.class.unloaded +Instrument: counter +Unit: {class} +Stability: Stable + +### Attributes + + + +## Group `metric.jvm.class.count` (metric) + +### Brief + +Number of classes currently loaded. + + + +Prefix: +Metric: jvm.class.count +Instrument: updowncounter +Unit: {class} +Stability: Stable + +### Attributes + + + +## Group `metric.jvm.cpu.count` (metric) + +### Brief + +Number of processors available to the Java virtual machine. + + + +Prefix: +Metric: jvm.cpu.count +Instrument: updowncounter +Unit: {cpu} +Stability: Stable + +### Attributes + + + +## Group `metric.jvm.cpu.time` (metric) + +### Brief + +CPU time used by the process as reported by the JVM. + + + +Prefix: +Metric: jvm.cpu.time +Instrument: counter +Unit: s +Stability: Stable + +### Attributes + + + +## Group `metric.jvm.cpu.recent_utilization` (metric) + +### Brief + +Recent CPU utilization for the process as reported by the JVM. + +The value range is [0.0,1.0]. This utilization is not defined as being for the specific interval since last measurement (unlike `system.cpu.utilization`). [Reference](https://docs.oracle.com/en/java/javase/17/docs/api/jdk.management/com/sun/management/OperatingSystemMXBean.html#getProcessCpuLoad()). + +Prefix: +Metric: jvm.cpu.recent_utilization +Instrument: gauge +Unit: 1 +Stability: Stable + +### Attributes + + + \ No newline at end of file diff --git a/crates/weaver_forge/expected_output/registry.md b/crates/weaver_forge/expected_output/registry.md new file mode 100644 index 00000000..e26e8cc5 --- /dev/null +++ b/crates/weaver_forge/expected_output/registry.md @@ -0,0 +1,58 @@ +# Semantic Convention Registry + +Url: + +# Attribute Groups + +- [attributes.jvm.memory](attribute_group/attributes_jvm_memory.md) +- [registry.db](attribute_group/registry_db.md) +- [registry.http](attribute_group/registry_http.md) +- [registry.network](attribute_group/registry_network.md) +- [server](attribute_group/server.md) +- [registry.url](attribute_group/registry_url.md) +- [registry.user_agent](attribute_group/registry_user_agent.md) + +# Events + +- [ios.lifecycle.events](event/ios_lifecycle_events.md) +- [android.lifecycle.events](event/android_lifecycle_events.md) + +# Metrics + +- [metric.jvm.memory.used](metric/metric_jvm_memory_used.md) +- [metric.jvm.memory.committed](metric/metric_jvm_memory_committed.md) +- [metric.jvm.memory.limit](metric/metric_jvm_memory_limit.md) +- [metric.jvm.memory.used_after_last_gc](metric/metric_jvm_memory_used_after_last_gc.md) +- [metric.jvm.gc.duration](metric/metric_jvm_gc_duration.md) +- [metric.jvm.thread.count](metric/metric_jvm_thread_count.md) +- [metric.jvm.class.loaded](metric/metric_jvm_class_loaded.md) +- [metric.jvm.class.unloaded](metric/metric_jvm_class_unloaded.md) +- [metric.jvm.class.count](metric/metric_jvm_class_count.md) +- [metric.jvm.cpu.count](metric/metric_jvm_cpu_count.md) +- [metric.jvm.cpu.time](metric/metric_jvm_cpu_time.md) +- [metric.jvm.cpu.recent_utilization](metric/metric_jvm_cpu_recent_utilization.md) + +# Metric Groups + + +# Resource + +- [otel.scope](resource/otel_scope.md) +- [otel.library](resource/otel_library.md) + +# Scope + + +# Span + +- [db](span/db.md) +- [db.mssql](span/db_mssql.md) +- [db.cassandra](span/db_cassandra.md) +- [db.hbase](span/db_hbase.md) +- [db.couchdb](span/db_couchdb.md) +- [db.redis](span/db_redis.md) +- [db.mongodb](span/db_mongodb.md) +- [db.elasticsearch](span/db_elasticsearch.md) +- [db.sql](span/db_sql.md) +- [db.cosmosdb](span/db_cosmosdb.md) +- [db.tech](span/db_tech.md) \ No newline at end of file diff --git a/crates/weaver_forge/expected_output/resource/otel_library.md b/crates/weaver_forge/expected_output/resource/otel_library.md new file mode 100644 index 00000000..cc192999 --- /dev/null +++ b/crates/weaver_forge/expected_output/resource/otel_library.md @@ -0,0 +1,39 @@ +## Group `otel.library` (resource) + +### Brief + +Span attributes used by non-OTLP exporters to represent OpenTelemetry Scope's concepts. + +prefix: otel.library + +### Attributes + + +#### Attribute `otel.library.name` + + + + +- Requirement Level: Recommended + +- Type: string +- Examples: [ + "io.opentelemetry.contrib.mongodb", +] +- Deprecated: use the `otel.scope.name` attribute. + + +#### Attribute `otel.library.version` + + + + +- Requirement Level: Recommended + +- Type: string +- Examples: [ + "1.0.0", +] +- Deprecated: use the `otel.scope.version` attribute. + + \ No newline at end of file diff --git a/crates/weaver_forge/expected_output/resource/otel_scope.md b/crates/weaver_forge/expected_output/resource/otel_scope.md new file mode 100644 index 00000000..9fcb8e68 --- /dev/null +++ b/crates/weaver_forge/expected_output/resource/otel_scope.md @@ -0,0 +1,41 @@ +## Group `otel.scope` (resource) + +### Brief + +Attributes used by non-OTLP exporters to represent OpenTelemetry Scope's concepts. + +prefix: otel.scope + +### Attributes + + +#### Attribute `otel.scope.name` + +The name of the instrumentation scope - (`InstrumentationScope.Name` in OTLP). + + +- Requirement Level: Recommended + +- Type: string +- Examples: [ + "io.opentelemetry.contrib.mongodb", +] + +- Stability: Stable + + +#### Attribute `otel.scope.version` + +The version of the instrumentation scope - (`InstrumentationScope.Version` in OTLP). + + +- Requirement Level: Recommended + +- Type: string +- Examples: [ + "1.0.0", +] + +- Stability: Stable + + \ No newline at end of file diff --git a/crates/weaver_forge/expected_output/resources.md b/crates/weaver_forge/expected_output/resources.md new file mode 100644 index 00000000..1554f001 --- /dev/null +++ b/crates/weaver_forge/expected_output/resources.md @@ -0,0 +1,85 @@ +# Semantic Convention Resource Groups + + +## Group `otel.scope` (resource) + +### Brief + +Attributes used by non-OTLP exporters to represent OpenTelemetry Scope's concepts. + +prefix: otel.scope + +### Attributes + + +#### Attribute `otel.scope.name` + +The name of the instrumentation scope - (`InstrumentationScope.Name` in OTLP). + + +- Requirement Level: Recommended + +- Type: string +- Examples: [ + "io.opentelemetry.contrib.mongodb", +] + +- Stability: Stable + + +#### Attribute `otel.scope.version` + +The version of the instrumentation scope - (`InstrumentationScope.Version` in OTLP). + + +- Requirement Level: Recommended + +- Type: string +- Examples: [ + "1.0.0", +] + +- Stability: Stable + + + +## Group `otel.library` (resource) + +### Brief + +Span attributes used by non-OTLP exporters to represent OpenTelemetry Scope's concepts. + +prefix: otel.library + +### Attributes + + +#### Attribute `otel.library.name` + + + + +- Requirement Level: Recommended + +- Type: string +- Examples: [ + "io.opentelemetry.contrib.mongodb", +] +- Deprecated: use the `otel.scope.name` attribute. + + +#### Attribute `otel.library.version` + + + + +- Requirement Level: Recommended + +- Type: string +- Examples: [ + "1.0.0", +] +- Deprecated: use the `otel.scope.version` attribute. + + + \ No newline at end of file diff --git a/crates/weaver_forge/expected_output/span/db.md b/crates/weaver_forge/expected_output/span/db.md new file mode 100644 index 00000000..8b6ec00a --- /dev/null +++ b/crates/weaver_forge/expected_output/span/db.md @@ -0,0 +1,267 @@ +## Group `db` (span) + +### Brief + +This document defines the attributes used to perform database client calls. + + + +Prefix: +Kind: client + +### Attributes + + +#### Attribute `db.system` + +An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. + + +- Requirement Level: Required + +- Tag: connection-level + +- Type: Enum [other_sql, mssql, mssqlcompact, mysql, oracle, db2, postgresql, redshift, hive, cloudscape, hsqldb, progress, maxdb, hanadb, ingres, firstsql, edb, cache, adabas, firebird, derby, filemaker, informix, instantdb, interbase, mariadb, netezza, pervasive, pointbase, sqlite, sybase, teradata, vertica, h2, coldfusion, cassandra, hbase, mongodb, redis, couchbase, couchdb, cosmosdb, dynamodb, neo4j, geode, elasticsearch, memcached, cockroachdb, opensearch, clickhouse, spanner, trino] + + +#### Attribute `db.connection_string` + +The connection string used to connect to the database. It is recommended to remove embedded credentials. + + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: Server=(localdb)\v11.0;Integrated Security=true; + + +#### Attribute `db.user` + +Username for accessing the database. + + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "readonly_user", + "reporting_user", +] + + +#### Attribute `db.jdbc.driver_classname` + +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. + + + +- Requirement Level: Recommended + +- Tag: connection-level-tech-specific + +- Type: string +- Examples: [ + "org.postgresql.Driver", + "com.microsoft.sqlserver.jdbc.SQLServerDriver", +] + + +#### Attribute `db.name` + +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). + + + +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). + +- Requirement Level: Conditionally Required - If applicable. + +- Tag: call-level + +- Type: string +- Examples: [ + "customers", + "main", +] + + +#### Attribute `db.statement` + +The database statement being executed. + + + +- Requirement Level: Optional + +- Tag: call-level + +- Type: string +- Examples: [ + "SELECT * FROM wuser_table", + "SET mykey \"WuValue\"", +] + + +#### Attribute `db.operation` + +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. + + + +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. + +- Requirement Level: Conditionally Required - If `db.statement` is not applicable. + +- Tag: call-level + +- Type: string +- Examples: [ + "findAndModify", + "HMSET", + "SELECT", +] + + +#### Attribute `server.address` + +Name of the database host. + + + +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. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "example.com", + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +#### Attribute `server.port` + +Server port number. + + +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. + +- Requirement Level: Conditionally Required - If using a port other than the default port for this DBMS and if `server.address` is set. + +- Tag: connection-level + +- Type: int +- Examples: [ + 80, + 8080, + 443, +] + +- Stability: Stable + + +#### Attribute `network.peer.address` + +Peer address of the network connection - IP address or Unix domain socket name. + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +#### Attribute `network.peer.port` + +Peer port number of the network connection. + + +- Requirement Level: Optional + +- Tag: connection-level + +- Type: int +- Examples: [ + 65123, +] + +- Stability: Stable + + +#### Attribute `network.transport` + +[OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). + + + +The value SHOULD be normalized to lowercase. + +Consider always setting the transport when setting a port number, since +a port number is ambiguous without knowing the transport. For example +different processes could be listening on TCP port 12345 and UDP port 12345. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: Enum [tcp, udp, pipe, unix] +- Examples: [ + "tcp", + "udp", +] + +- Stability: Stable + + +#### Attribute `network.type` + +[OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. + + +The value SHOULD be normalized to lowercase. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: Enum [ipv4, ipv6] +- Examples: [ + "ipv4", + "ipv6", +] + +- Stability: Stable + + +#### Attribute `db.instance.id` + +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`. + + + +- Requirement Level: Optional + +- Tag: connection-level + +- Type: string +- Examples: mysql-e26b99z.example.com + + \ No newline at end of file diff --git a/crates/weaver_forge/expected_output/span/db_cassandra.md b/crates/weaver_forge/expected_output/span/db_cassandra.md new file mode 100644 index 00000000..9aa1d6ab --- /dev/null +++ b/crates/weaver_forge/expected_output/span/db_cassandra.md @@ -0,0 +1,387 @@ +## Group `db.cassandra` (span) + +### Brief + +Call-level attributes for Cassandra + + + +Prefix: +Kind: none + +### Attributes + + +#### Attribute `db.system` + +An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. + + +- Requirement Level: Required + +- Tag: connection-level + +- Type: Enum [other_sql, mssql, mssqlcompact, mysql, oracle, db2, postgresql, redshift, hive, cloudscape, hsqldb, progress, maxdb, hanadb, ingres, firstsql, edb, cache, adabas, firebird, derby, filemaker, informix, instantdb, interbase, mariadb, netezza, pervasive, pointbase, sqlite, sybase, teradata, vertica, h2, coldfusion, cassandra, hbase, mongodb, redis, couchbase, couchdb, cosmosdb, dynamodb, neo4j, geode, elasticsearch, memcached, cockroachdb, opensearch, clickhouse, spanner, trino] + + +#### Attribute `db.connection_string` + +The connection string used to connect to the database. It is recommended to remove embedded credentials. + + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: Server=(localdb)\v11.0;Integrated Security=true; + + +#### Attribute `db.user` + +Username for accessing the database. + + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "readonly_user", + "reporting_user", +] + + +#### Attribute `db.jdbc.driver_classname` + +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. + + + +- Requirement Level: Recommended + +- Tag: connection-level-tech-specific + +- Type: string +- Examples: [ + "org.postgresql.Driver", + "com.microsoft.sqlserver.jdbc.SQLServerDriver", +] + + +#### Attribute `db.name` + +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). + + + +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). + +- Requirement Level: Conditionally Required - If applicable. + +- Tag: call-level + +- Type: string +- Examples: [ + "customers", + "main", +] + + +#### Attribute `db.statement` + +The database statement being executed. + + + +- Requirement Level: Optional + +- Tag: call-level + +- Type: string +- Examples: [ + "SELECT * FROM wuser_table", + "SET mykey \"WuValue\"", +] + + +#### Attribute `db.operation` + +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. + + + +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. + +- Requirement Level: Conditionally Required - If `db.statement` is not applicable. + +- Tag: call-level + +- Type: string +- Examples: [ + "findAndModify", + "HMSET", + "SELECT", +] + + +#### Attribute `server.address` + +Name of the database host. + + + +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. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "example.com", + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +#### Attribute `server.port` + +Server port number. + + +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. + +- Requirement Level: Conditionally Required - If using a port other than the default port for this DBMS and if `server.address` is set. + +- Tag: connection-level + +- Type: int +- Examples: [ + 80, + 8080, + 443, +] + +- Stability: Stable + + +#### Attribute `network.peer.address` + +Peer address of the network connection - IP address or Unix domain socket name. + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +#### Attribute `network.peer.port` + +Peer port number of the network connection. + + +- Requirement Level: Optional + +- Tag: connection-level + +- Type: int +- Examples: [ + 65123, +] + +- Stability: Stable + + +#### Attribute `network.transport` + +[OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). + + + +The value SHOULD be normalized to lowercase. + +Consider always setting the transport when setting a port number, since +a port number is ambiguous without knowing the transport. For example +different processes could be listening on TCP port 12345 and UDP port 12345. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: Enum [tcp, udp, pipe, unix] +- Examples: [ + "tcp", + "udp", +] + +- Stability: Stable + + +#### Attribute `network.type` + +[OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. + + +The value SHOULD be normalized to lowercase. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: Enum [ipv4, ipv6] +- Examples: [ + "ipv4", + "ipv6", +] + +- Stability: Stable + + +#### Attribute `db.instance.id` + +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`. + + + +- Requirement Level: Optional + +- Tag: connection-level + +- Type: string +- Examples: mysql-e26b99z.example.com + + +#### Attribute `db.name` + +The keyspace name in Cassandra. + + + +For Cassandra the `db.name` should be set to the Cassandra keyspace name. + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific-cassandra + +- Type: string +- Examples: [ + "mykeyspace", +] + + +#### Attribute `db.cassandra.page_size` + +The fetch size used for paging, i.e. how many rows will be returned at once. + + + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific-cassandra + +- Type: int +- Examples: [ + 5000, +] + + +#### Attribute `db.cassandra.consistency_level` + +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). + + + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific-cassandra + +- Type: Enum [all, each_quorum, quorum, local_quorum, one, two, three, local_one, any, serial, local_serial] + + +#### Attribute `db.cassandra.table` + +The name of the primary Cassandra table that the operation is acting upon, including the keyspace name (if applicable). + + +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. + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific-cassandra + +- Type: string +- Examples: mytable + + +#### Attribute `db.cassandra.idempotence` + +Whether or not the query is idempotent. + + + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific-cassandra + +- Type: boolean + + +#### Attribute `db.cassandra.speculative_execution_count` + +The number of times a query was speculatively executed. Not set or `0` if the query was not executed speculatively. + + + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific-cassandra + +- Type: int +- Examples: [ + 0, + 2, +] + + +#### Attribute `db.cassandra.coordinator.id` + +The ID of the coordinating node for a query. + + + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific-cassandra + +- Type: string +- Examples: be13faa2-8574-4d71-926d-27f16cf8a7af + + +#### Attribute `db.cassandra.coordinator.dc` + +The data center of the coordinating node for a query. + + + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific-cassandra + +- Type: string +- Examples: us-west-2 + + \ No newline at end of file diff --git a/crates/weaver_forge/expected_output/span/db_cosmosdb.md b/crates/weaver_forge/expected_output/span/db_cosmosdb.md new file mode 100644 index 00000000..0cc5d926 --- /dev/null +++ b/crates/weaver_forge/expected_output/span/db_cosmosdb.md @@ -0,0 +1,398 @@ +## Group `db.cosmosdb` (span) + +### Brief + +Call-level attributes for Cosmos DB. + + + +Prefix: db.cosmosdb +Kind: none + +### Attributes + + +#### Attribute `db.system` + +An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. + + +- Requirement Level: Required + +- Tag: connection-level + +- Type: Enum [other_sql, mssql, mssqlcompact, mysql, oracle, db2, postgresql, redshift, hive, cloudscape, hsqldb, progress, maxdb, hanadb, ingres, firstsql, edb, cache, adabas, firebird, derby, filemaker, informix, instantdb, interbase, mariadb, netezza, pervasive, pointbase, sqlite, sybase, teradata, vertica, h2, coldfusion, cassandra, hbase, mongodb, redis, couchbase, couchdb, cosmosdb, dynamodb, neo4j, geode, elasticsearch, memcached, cockroachdb, opensearch, clickhouse, spanner, trino] + + +#### Attribute `db.connection_string` + +The connection string used to connect to the database. It is recommended to remove embedded credentials. + + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: Server=(localdb)\v11.0;Integrated Security=true; + + +#### Attribute `db.user` + +Username for accessing the database. + + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "readonly_user", + "reporting_user", +] + + +#### Attribute `db.jdbc.driver_classname` + +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. + + + +- Requirement Level: Recommended + +- Tag: connection-level-tech-specific + +- Type: string +- Examples: [ + "org.postgresql.Driver", + "com.microsoft.sqlserver.jdbc.SQLServerDriver", +] + + +#### Attribute `db.name` + +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). + + + +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). + +- Requirement Level: Conditionally Required - If applicable. + +- Tag: call-level + +- Type: string +- Examples: [ + "customers", + "main", +] + + +#### Attribute `db.statement` + +The database statement being executed. + + + +- Requirement Level: Optional + +- Tag: call-level + +- Type: string +- Examples: [ + "SELECT * FROM wuser_table", + "SET mykey \"WuValue\"", +] + + +#### Attribute `db.operation` + +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. + + + +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. + +- Requirement Level: Conditionally Required - If `db.statement` is not applicable. + +- Tag: call-level + +- Type: string +- Examples: [ + "findAndModify", + "HMSET", + "SELECT", +] + + +#### Attribute `server.address` + +Name of the database host. + + + +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. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "example.com", + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +#### Attribute `server.port` + +Server port number. + + +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. + +- Requirement Level: Conditionally Required - If using a port other than the default port for this DBMS and if `server.address` is set. + +- Tag: connection-level + +- Type: int +- Examples: [ + 80, + 8080, + 443, +] + +- Stability: Stable + + +#### Attribute `network.peer.address` + +Peer address of the network connection - IP address or Unix domain socket name. + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +#### Attribute `network.peer.port` + +Peer port number of the network connection. + + +- Requirement Level: Optional + +- Tag: connection-level + +- Type: int +- Examples: [ + 65123, +] + +- Stability: Stable + + +#### Attribute `network.transport` + +[OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). + + + +The value SHOULD be normalized to lowercase. + +Consider always setting the transport when setting a port number, since +a port number is ambiguous without knowing the transport. For example +different processes could be listening on TCP port 12345 and UDP port 12345. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: Enum [tcp, udp, pipe, unix] +- Examples: [ + "tcp", + "udp", +] + +- Stability: Stable + + +#### Attribute `network.type` + +[OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. + + +The value SHOULD be normalized to lowercase. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: Enum [ipv4, ipv6] +- Examples: [ + "ipv4", + "ipv6", +] + +- Stability: Stable + + +#### Attribute `db.instance.id` + +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`. + + + +- Requirement Level: Optional + +- Tag: connection-level + +- Type: string +- Examples: mysql-e26b99z.example.com + + +#### Attribute `db.cosmosdb.client_id` + +Unique Cosmos client instance id. + + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific + +- Type: string +- Examples: 3ba4827d-4422-483f-b59f-85b74211c11d + + +#### Attribute `db.cosmosdb.operation_type` + +CosmosDB Operation Type. + + +- Requirement Level: Conditionally Required - when performing one of the operations in this list + +- Tag: call-level-tech-specific + +- Type: Enum [Invalid, Create, Patch, Read, ReadFeed, Delete, Replace, Execute, Query, Head, HeadFeed, Upsert, Batch, QueryPlan, ExecuteJavaScript] + + +#### Attribute `user_agent.original` + +Full user-agent string is generated by Cosmos DB SDK + + +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. + Format Reg-{D (Disabled discovery)}-S(application region)|L(List of preferred regions)|N(None, user did not configure it). + Default value is "NS". + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific + +- Type: string +- 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\\|", +] + +- Stability: Stable + + +#### Attribute `db.cosmosdb.connection_mode` + +Cosmos client connection mode. + + +- Requirement Level: Conditionally Required - if not `direct` (or pick gw as default) + +- Tag: call-level-tech-specific + +- Type: Enum [gateway, direct] + + +#### Attribute `db.cosmosdb.container` + +Cosmos DB container name. + + +- Requirement Level: Conditionally Required - if available + +- Tag: call-level-tech-specific + +- Type: string +- Examples: anystring + + +#### Attribute `db.cosmosdb.request_content_length` + +Request payload size in bytes + + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific + +- Type: int + + +#### Attribute `db.cosmosdb.status_code` + +Cosmos DB status code. + + +- Requirement Level: Conditionally Required - if response was received + +- Tag: call-level-tech-specific + +- Type: int +- Examples: [ + 200, + 201, +] + + +#### Attribute `db.cosmosdb.sub_status_code` + +Cosmos DB sub status code. + + +- Requirement Level: Conditionally Required - when response was received and contained sub-code. + +- Tag: call-level-tech-specific + +- Type: int +- Examples: [ + 1000, + 1002, +] + + +#### Attribute `db.cosmosdb.request_charge` + +RU consumed for that operation + + +- Requirement Level: Conditionally Required - when available + +- Tag: call-level-tech-specific + +- Type: double +- Examples: [ + 46.18, + 1.0, +] + + \ No newline at end of file diff --git a/crates/weaver_forge/expected_output/span/db_couchdb.md b/crates/weaver_forge/expected_output/span/db_couchdb.md new file mode 100644 index 00000000..16d4bf4d --- /dev/null +++ b/crates/weaver_forge/expected_output/span/db_couchdb.md @@ -0,0 +1,285 @@ +## Group `db.couchdb` (span) + +### Brief + +Call-level attributes for CouchDB + + + +Prefix: +Kind: none + +### Attributes + + +#### Attribute `db.system` + +An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. + + +- Requirement Level: Required + +- Tag: connection-level + +- Type: Enum [other_sql, mssql, mssqlcompact, mysql, oracle, db2, postgresql, redshift, hive, cloudscape, hsqldb, progress, maxdb, hanadb, ingres, firstsql, edb, cache, adabas, firebird, derby, filemaker, informix, instantdb, interbase, mariadb, netezza, pervasive, pointbase, sqlite, sybase, teradata, vertica, h2, coldfusion, cassandra, hbase, mongodb, redis, couchbase, couchdb, cosmosdb, dynamodb, neo4j, geode, elasticsearch, memcached, cockroachdb, opensearch, clickhouse, spanner, trino] + + +#### Attribute `db.connection_string` + +The connection string used to connect to the database. It is recommended to remove embedded credentials. + + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: Server=(localdb)\v11.0;Integrated Security=true; + + +#### Attribute `db.user` + +Username for accessing the database. + + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "readonly_user", + "reporting_user", +] + + +#### Attribute `db.jdbc.driver_classname` + +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. + + + +- Requirement Level: Recommended + +- Tag: connection-level-tech-specific + +- Type: string +- Examples: [ + "org.postgresql.Driver", + "com.microsoft.sqlserver.jdbc.SQLServerDriver", +] + + +#### Attribute `db.name` + +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). + + + +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). + +- Requirement Level: Conditionally Required - If applicable. + +- Tag: call-level + +- Type: string +- Examples: [ + "customers", + "main", +] + + +#### Attribute `db.statement` + +The database statement being executed. + + + +- Requirement Level: Optional + +- Tag: call-level + +- Type: string +- Examples: [ + "SELECT * FROM wuser_table", + "SET mykey \"WuValue\"", +] + + +#### Attribute `db.operation` + +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. + + + +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. + +- Requirement Level: Conditionally Required - If `db.statement` is not applicable. + +- Tag: call-level + +- Type: string +- Examples: [ + "findAndModify", + "HMSET", + "SELECT", +] + + +#### Attribute `server.address` + +Name of the database host. + + + +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. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "example.com", + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +#### Attribute `server.port` + +Server port number. + + +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. + +- Requirement Level: Conditionally Required - If using a port other than the default port for this DBMS and if `server.address` is set. + +- Tag: connection-level + +- Type: int +- Examples: [ + 80, + 8080, + 443, +] + +- Stability: Stable + + +#### Attribute `network.peer.address` + +Peer address of the network connection - IP address or Unix domain socket name. + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +#### Attribute `network.peer.port` + +Peer port number of the network connection. + + +- Requirement Level: Optional + +- Tag: connection-level + +- Type: int +- Examples: [ + 65123, +] + +- Stability: Stable + + +#### Attribute `network.transport` + +[OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). + + + +The value SHOULD be normalized to lowercase. + +Consider always setting the transport when setting a port number, since +a port number is ambiguous without knowing the transport. For example +different processes could be listening on TCP port 12345 and UDP port 12345. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: Enum [tcp, udp, pipe, unix] +- Examples: [ + "tcp", + "udp", +] + +- Stability: Stable + + +#### Attribute `network.type` + +[OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. + + +The value SHOULD be normalized to lowercase. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: Enum [ipv4, ipv6] +- Examples: [ + "ipv4", + "ipv6", +] + +- Stability: Stable + + +#### Attribute `db.instance.id` + +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`. + + + +- Requirement Level: Optional + +- Tag: connection-level + +- Type: string +- Examples: mysql-e26b99z.example.com + + +#### Attribute `db.operation` + +The HTTP method + the target REST route. + + + +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). + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific + +- Type: string +- Examples: [ + "GET /{db}/{docid}", +] + + \ No newline at end of file diff --git a/crates/weaver_forge/expected_output/span/db_elasticsearch.md b/crates/weaver_forge/expected_output/span/db_elasticsearch.md new file mode 100644 index 00000000..786397f8 --- /dev/null +++ b/crates/weaver_forge/expected_output/span/db_elasticsearch.md @@ -0,0 +1,449 @@ +## Group `db.elasticsearch` (span) + +### Brief + +Call-level attributes for Elasticsearch + + + +Prefix: +Kind: none + +### Attributes + + +#### Attribute `db.system` + +An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. + + +- Requirement Level: Required + +- Tag: connection-level + +- Type: Enum [other_sql, mssql, mssqlcompact, mysql, oracle, db2, postgresql, redshift, hive, cloudscape, hsqldb, progress, maxdb, hanadb, ingres, firstsql, edb, cache, adabas, firebird, derby, filemaker, informix, instantdb, interbase, mariadb, netezza, pervasive, pointbase, sqlite, sybase, teradata, vertica, h2, coldfusion, cassandra, hbase, mongodb, redis, couchbase, couchdb, cosmosdb, dynamodb, neo4j, geode, elasticsearch, memcached, cockroachdb, opensearch, clickhouse, spanner, trino] + + +#### Attribute `db.connection_string` + +The connection string used to connect to the database. It is recommended to remove embedded credentials. + + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: Server=(localdb)\v11.0;Integrated Security=true; + + +#### Attribute `db.user` + +Username for accessing the database. + + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "readonly_user", + "reporting_user", +] + + +#### Attribute `db.jdbc.driver_classname` + +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. + + + +- Requirement Level: Recommended + +- Tag: connection-level-tech-specific + +- Type: string +- Examples: [ + "org.postgresql.Driver", + "com.microsoft.sqlserver.jdbc.SQLServerDriver", +] + + +#### Attribute `db.name` + +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). + + + +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). + +- Requirement Level: Conditionally Required - If applicable. + +- Tag: call-level + +- Type: string +- Examples: [ + "customers", + "main", +] + + +#### Attribute `db.statement` + +The database statement being executed. + + + +- Requirement Level: Optional + +- Tag: call-level + +- Type: string +- Examples: [ + "SELECT * FROM wuser_table", + "SET mykey \"WuValue\"", +] + + +#### Attribute `db.operation` + +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. + + + +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. + +- Requirement Level: Conditionally Required - If `db.statement` is not applicable. + +- Tag: call-level + +- Type: string +- Examples: [ + "findAndModify", + "HMSET", + "SELECT", +] + + +#### Attribute `server.address` + +Name of the database host. + + + +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. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "example.com", + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +#### Attribute `server.port` + +Server port number. + + +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. + +- Requirement Level: Conditionally Required - If using a port other than the default port for this DBMS and if `server.address` is set. + +- Tag: connection-level + +- Type: int +- Examples: [ + 80, + 8080, + 443, +] + +- Stability: Stable + + +#### Attribute `network.peer.address` + +Peer address of the network connection - IP address or Unix domain socket name. + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +#### Attribute `network.peer.port` + +Peer port number of the network connection. + + +- Requirement Level: Optional + +- Tag: connection-level + +- Type: int +- Examples: [ + 65123, +] + +- Stability: Stable + + +#### Attribute `network.transport` + +[OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). + + + +The value SHOULD be normalized to lowercase. + +Consider always setting the transport when setting a port number, since +a port number is ambiguous without knowing the transport. For example +different processes could be listening on TCP port 12345 and UDP port 12345. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: Enum [tcp, udp, pipe, unix] +- Examples: [ + "tcp", + "udp", +] + +- Stability: Stable + + +#### Attribute `network.type` + +[OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. + + +The value SHOULD be normalized to lowercase. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: Enum [ipv4, ipv6] +- Examples: [ + "ipv4", + "ipv6", +] + +- Stability: Stable + + +#### Attribute `db.instance.id` + +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`. + + + +- Requirement Level: Optional + +- Tag: connection-level + +- Type: string +- Examples: mysql-e26b99z.example.com + + +#### Attribute `http.request.method` + +HTTP request method. + + +HTTP request method value SHOULD be "known" to the instrumentation. +By default, this convention defines "known" methods as the ones listed in [RFC9110](https://www.rfc-editor.org/rfc/rfc9110.html#name-methods) +and the PATCH method defined in [RFC5789](https://www.rfc-editor.org/rfc/rfc5789.html). + +If the HTTP request method is not known to instrumentation, it MUST set the `http.request.method` attribute to `_OTHER`. + +If the HTTP instrumentation could end up converting valid HTTP request methods to `_OTHER`, then it MUST provide a way to override +the list of known HTTP methods. If this override is done via environment variable, then the environment variable MUST be named +OTEL_INSTRUMENTATION_HTTP_KNOWN_METHODS and support a comma-separated list of case-sensitive known HTTP methods +(this list MUST be a full override of the default known method, it is not a list of known methods in addition to the defaults). + +HTTP method names are case-sensitive and `http.request.method` attribute value MUST match a known HTTP method name exactly. +Instrumentations for specific web frameworks that consider HTTP methods to be case insensitive, SHOULD populate a canonical equivalent. +Tracing instrumentations that do so, MUST also set `http.request.method_original` to the original value. + +- Requirement Level: Required + +- Tag: call-level-tech-specific + +- Type: Enum [CONNECT, DELETE, GET, HEAD, OPTIONS, PATCH, POST, PUT, TRACE, _OTHER] +- Examples: [ + "GET", + "POST", + "HEAD", +] + +- Stability: Stable + + +#### Attribute `db.operation` + +The endpoint identifier for the request. + + +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. + +- Requirement Level: Required + +- Tag: call-level-tech-specific + +- Type: string +- Examples: [ + "search", + "ml.close_job", + "cat.aliases", +] + + +#### Attribute `url.full` + +Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986) + + +For network calls, URL usually has `scheme://host[:port][path][?query][#fragment]` format, where the fragment is not transmitted over HTTP, but if it is known, it SHOULD be included nevertheless. +`url.full` MUST NOT contain credentials passed via URL in form of `https://username:password@www.example.com/`. In such case username and password SHOULD be redacted and attribute's value SHOULD be `https://REDACTED:REDACTED@www.example.com/`. +`url.full` SHOULD capture the absolute URL when it is available (or can be reconstructed) and SHOULD NOT be validated or modified except for sanitizing purposes. + +- Requirement Level: Required + +- Tag: call-level-tech-specific + +- Type: string +- Examples: [ + "https://localhost:9200/index/_search?q=user.id:kimchy", +] + +- Stability: Stable + + +#### Attribute `db.statement` + +The request body for a [search-type query](https://www.elastic.co/guide/en/elasticsearch/reference/current/search.html), as a json string. + + +- Requirement Level: Optional + +- Tag: call-level-tech-specific + +- Type: string +- Examples: [ + "\"{\\\"query\\\":{\\\"term\\\":{\\\"user.id\\\":\\\"kimchy\\\"}}}\"", +] + + +#### Attribute `server.address` + +Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. + + +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. + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific + +- Type: string +- Examples: [ + "example.com", + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +#### Attribute `server.port` + +Server port number. + + +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. + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific + +- Type: int +- Examples: [ + 80, + 8080, + 443, +] + +- Stability: Stable + + +#### Attribute `db.elasticsearch.cluster.name` + +Represents the identifier of an Elasticsearch cluster. + + + +- Requirement Level: Optional + +- Tag: call-level-tech-specific + +- Type: string +- Examples: [ + "e9106fc68e3044f0b1475b04bf4ffd5f", +] + + +#### Attribute `db.elasticsearch.node.name` + +Represents the human-readable identifier of the node/instance to which a request was routed. + + + +- Requirement Level: Optional + +- Tag: call-level-tech-specific + +- Type: string +- Examples: [ + "instance-0000000001", +] + + +#### Attribute `db.elasticsearch.path_parts` + +A dynamic value in the url path. + + + +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. + +- Requirement Level: Conditionally Required - when the url has dynamic values + +- Tag: call-level-tech-specific + +- Type: template[string] +- Examples: [ + "db.elasticsearch.path_parts.index=test-index", + "db.elasticsearch.path_parts.doc_id=123", +] + + \ No newline at end of file diff --git a/crates/weaver_forge/expected_output/span/db_hbase.md b/crates/weaver_forge/expected_output/span/db_hbase.md new file mode 100644 index 00000000..0fee4f9c --- /dev/null +++ b/crates/weaver_forge/expected_output/span/db_hbase.md @@ -0,0 +1,285 @@ +## Group `db.hbase` (span) + +### Brief + +Call-level attributes for HBase + + + +Prefix: +Kind: none + +### Attributes + + +#### Attribute `db.system` + +An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. + + +- Requirement Level: Required + +- Tag: connection-level + +- Type: Enum [other_sql, mssql, mssqlcompact, mysql, oracle, db2, postgresql, redshift, hive, cloudscape, hsqldb, progress, maxdb, hanadb, ingres, firstsql, edb, cache, adabas, firebird, derby, filemaker, informix, instantdb, interbase, mariadb, netezza, pervasive, pointbase, sqlite, sybase, teradata, vertica, h2, coldfusion, cassandra, hbase, mongodb, redis, couchbase, couchdb, cosmosdb, dynamodb, neo4j, geode, elasticsearch, memcached, cockroachdb, opensearch, clickhouse, spanner, trino] + + +#### Attribute `db.connection_string` + +The connection string used to connect to the database. It is recommended to remove embedded credentials. + + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: Server=(localdb)\v11.0;Integrated Security=true; + + +#### Attribute `db.user` + +Username for accessing the database. + + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "readonly_user", + "reporting_user", +] + + +#### Attribute `db.jdbc.driver_classname` + +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. + + + +- Requirement Level: Recommended + +- Tag: connection-level-tech-specific + +- Type: string +- Examples: [ + "org.postgresql.Driver", + "com.microsoft.sqlserver.jdbc.SQLServerDriver", +] + + +#### Attribute `db.name` + +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). + + + +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). + +- Requirement Level: Conditionally Required - If applicable. + +- Tag: call-level + +- Type: string +- Examples: [ + "customers", + "main", +] + + +#### Attribute `db.statement` + +The database statement being executed. + + + +- Requirement Level: Optional + +- Tag: call-level + +- Type: string +- Examples: [ + "SELECT * FROM wuser_table", + "SET mykey \"WuValue\"", +] + + +#### Attribute `db.operation` + +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. + + + +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. + +- Requirement Level: Conditionally Required - If `db.statement` is not applicable. + +- Tag: call-level + +- Type: string +- Examples: [ + "findAndModify", + "HMSET", + "SELECT", +] + + +#### Attribute `server.address` + +Name of the database host. + + + +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. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "example.com", + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +#### Attribute `server.port` + +Server port number. + + +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. + +- Requirement Level: Conditionally Required - If using a port other than the default port for this DBMS and if `server.address` is set. + +- Tag: connection-level + +- Type: int +- Examples: [ + 80, + 8080, + 443, +] + +- Stability: Stable + + +#### Attribute `network.peer.address` + +Peer address of the network connection - IP address or Unix domain socket name. + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +#### Attribute `network.peer.port` + +Peer port number of the network connection. + + +- Requirement Level: Optional + +- Tag: connection-level + +- Type: int +- Examples: [ + 65123, +] + +- Stability: Stable + + +#### Attribute `network.transport` + +[OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). + + + +The value SHOULD be normalized to lowercase. + +Consider always setting the transport when setting a port number, since +a port number is ambiguous without knowing the transport. For example +different processes could be listening on TCP port 12345 and UDP port 12345. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: Enum [tcp, udp, pipe, unix] +- Examples: [ + "tcp", + "udp", +] + +- Stability: Stable + + +#### Attribute `network.type` + +[OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. + + +The value SHOULD be normalized to lowercase. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: Enum [ipv4, ipv6] +- Examples: [ + "ipv4", + "ipv6", +] + +- Stability: Stable + + +#### Attribute `db.instance.id` + +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`. + + + +- Requirement Level: Optional + +- Tag: connection-level + +- Type: string +- Examples: mysql-e26b99z.example.com + + +#### Attribute `db.name` + +The HBase namespace. + + + +For HBase the `db.name` should be set to the HBase namespace. + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific + +- Type: string +- Examples: [ + "mynamespace", +] + + \ No newline at end of file diff --git a/crates/weaver_forge/expected_output/span/db_mongodb.md b/crates/weaver_forge/expected_output/span/db_mongodb.md new file mode 100644 index 00000000..57458795 --- /dev/null +++ b/crates/weaver_forge/expected_output/span/db_mongodb.md @@ -0,0 +1,284 @@ +## Group `db.mongodb` (span) + +### Brief + +Call-level attributes for MongoDB + + + +Prefix: +Kind: none + +### Attributes + + +#### Attribute `db.system` + +An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. + + +- Requirement Level: Required + +- Tag: connection-level + +- Type: Enum [other_sql, mssql, mssqlcompact, mysql, oracle, db2, postgresql, redshift, hive, cloudscape, hsqldb, progress, maxdb, hanadb, ingres, firstsql, edb, cache, adabas, firebird, derby, filemaker, informix, instantdb, interbase, mariadb, netezza, pervasive, pointbase, sqlite, sybase, teradata, vertica, h2, coldfusion, cassandra, hbase, mongodb, redis, couchbase, couchdb, cosmosdb, dynamodb, neo4j, geode, elasticsearch, memcached, cockroachdb, opensearch, clickhouse, spanner, trino] + + +#### Attribute `db.connection_string` + +The connection string used to connect to the database. It is recommended to remove embedded credentials. + + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: Server=(localdb)\v11.0;Integrated Security=true; + + +#### Attribute `db.user` + +Username for accessing the database. + + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "readonly_user", + "reporting_user", +] + + +#### Attribute `db.jdbc.driver_classname` + +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. + + + +- Requirement Level: Recommended + +- Tag: connection-level-tech-specific + +- Type: string +- Examples: [ + "org.postgresql.Driver", + "com.microsoft.sqlserver.jdbc.SQLServerDriver", +] + + +#### Attribute `db.name` + +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). + + + +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). + +- Requirement Level: Conditionally Required - If applicable. + +- Tag: call-level + +- Type: string +- Examples: [ + "customers", + "main", +] + + +#### Attribute `db.statement` + +The database statement being executed. + + + +- Requirement Level: Optional + +- Tag: call-level + +- Type: string +- Examples: [ + "SELECT * FROM wuser_table", + "SET mykey \"WuValue\"", +] + + +#### Attribute `db.operation` + +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. + + + +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. + +- Requirement Level: Conditionally Required - If `db.statement` is not applicable. + +- Tag: call-level + +- Type: string +- Examples: [ + "findAndModify", + "HMSET", + "SELECT", +] + + +#### Attribute `server.address` + +Name of the database host. + + + +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. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "example.com", + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +#### Attribute `server.port` + +Server port number. + + +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. + +- Requirement Level: Conditionally Required - If using a port other than the default port for this DBMS and if `server.address` is set. + +- Tag: connection-level + +- Type: int +- Examples: [ + 80, + 8080, + 443, +] + +- Stability: Stable + + +#### Attribute `network.peer.address` + +Peer address of the network connection - IP address or Unix domain socket name. + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +#### Attribute `network.peer.port` + +Peer port number of the network connection. + + +- Requirement Level: Optional + +- Tag: connection-level + +- Type: int +- Examples: [ + 65123, +] + +- Stability: Stable + + +#### Attribute `network.transport` + +[OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). + + + +The value SHOULD be normalized to lowercase. + +Consider always setting the transport when setting a port number, since +a port number is ambiguous without knowing the transport. For example +different processes could be listening on TCP port 12345 and UDP port 12345. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: Enum [tcp, udp, pipe, unix] +- Examples: [ + "tcp", + "udp", +] + +- Stability: Stable + + +#### Attribute `network.type` + +[OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. + + +The value SHOULD be normalized to lowercase. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: Enum [ipv4, ipv6] +- Examples: [ + "ipv4", + "ipv6", +] + +- Stability: Stable + + +#### Attribute `db.instance.id` + +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`. + + + +- Requirement Level: Optional + +- Tag: connection-level + +- Type: string +- Examples: mysql-e26b99z.example.com + + +#### Attribute `db.mongodb.collection` + +The MongoDB collection being accessed within the database stated in `db.name`. + + + +- Requirement Level: Required + +- Tag: call-level-tech-specific + +- Type: string +- Examples: [ + "customers", + "products", +] + + \ No newline at end of file diff --git a/crates/weaver_forge/expected_output/span/db_mssql.md b/crates/weaver_forge/expected_output/span/db_mssql.md new file mode 100644 index 00000000..8ecd58f9 --- /dev/null +++ b/crates/weaver_forge/expected_output/span/db_mssql.md @@ -0,0 +1,283 @@ +## Group `db.mssql` (span) + +### Brief + +Connection-level attributes for Microsoft SQL Server + + + +Prefix: +Kind: none + +### Attributes + + +#### Attribute `db.system` + +An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. + + +- Requirement Level: Required + +- Tag: connection-level + +- Type: Enum [other_sql, mssql, mssqlcompact, mysql, oracle, db2, postgresql, redshift, hive, cloudscape, hsqldb, progress, maxdb, hanadb, ingres, firstsql, edb, cache, adabas, firebird, derby, filemaker, informix, instantdb, interbase, mariadb, netezza, pervasive, pointbase, sqlite, sybase, teradata, vertica, h2, coldfusion, cassandra, hbase, mongodb, redis, couchbase, couchdb, cosmosdb, dynamodb, neo4j, geode, elasticsearch, memcached, cockroachdb, opensearch, clickhouse, spanner, trino] + + +#### Attribute `db.connection_string` + +The connection string used to connect to the database. It is recommended to remove embedded credentials. + + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: Server=(localdb)\v11.0;Integrated Security=true; + + +#### Attribute `db.user` + +Username for accessing the database. + + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "readonly_user", + "reporting_user", +] + + +#### Attribute `db.jdbc.driver_classname` + +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. + + + +- Requirement Level: Recommended + +- Tag: connection-level-tech-specific + +- Type: string +- Examples: [ + "org.postgresql.Driver", + "com.microsoft.sqlserver.jdbc.SQLServerDriver", +] + + +#### Attribute `db.name` + +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). + + + +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). + +- Requirement Level: Conditionally Required - If applicable. + +- Tag: call-level + +- Type: string +- Examples: [ + "customers", + "main", +] + + +#### Attribute `db.statement` + +The database statement being executed. + + + +- Requirement Level: Optional + +- Tag: call-level + +- Type: string +- Examples: [ + "SELECT * FROM wuser_table", + "SET mykey \"WuValue\"", +] + + +#### Attribute `db.operation` + +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. + + + +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. + +- Requirement Level: Conditionally Required - If `db.statement` is not applicable. + +- Tag: call-level + +- Type: string +- Examples: [ + "findAndModify", + "HMSET", + "SELECT", +] + + +#### Attribute `server.address` + +Name of the database host. + + + +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. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "example.com", + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +#### Attribute `server.port` + +Server port number. + + +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. + +- Requirement Level: Conditionally Required - If using a port other than the default port for this DBMS and if `server.address` is set. + +- Tag: connection-level + +- Type: int +- Examples: [ + 80, + 8080, + 443, +] + +- Stability: Stable + + +#### Attribute `network.peer.address` + +Peer address of the network connection - IP address or Unix domain socket name. + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +#### Attribute `network.peer.port` + +Peer port number of the network connection. + + +- Requirement Level: Optional + +- Tag: connection-level + +- Type: int +- Examples: [ + 65123, +] + +- Stability: Stable + + +#### Attribute `network.transport` + +[OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). + + + +The value SHOULD be normalized to lowercase. + +Consider always setting the transport when setting a port number, since +a port number is ambiguous without knowing the transport. For example +different processes could be listening on TCP port 12345 and UDP port 12345. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: Enum [tcp, udp, pipe, unix] +- Examples: [ + "tcp", + "udp", +] + +- Stability: Stable + + +#### Attribute `network.type` + +[OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. + + +The value SHOULD be normalized to lowercase. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: Enum [ipv4, ipv6] +- Examples: [ + "ipv4", + "ipv6", +] + +- Stability: Stable + + +#### Attribute `db.instance.id` + +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`. + + + +- Requirement Level: Optional + +- Tag: connection-level + +- Type: string +- Examples: mysql-e26b99z.example.com + + +#### Attribute `db.mssql.instance_name` + +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. + + + +If setting a `db.mssql.instance_name`, `server.port` is no longer required (but still recommended if non-standard). + +- Requirement Level: Recommended + +- Tag: connection-level-tech-specific + +- Type: string +- Examples: MSSQLSERVER + + \ No newline at end of file diff --git a/crates/weaver_forge/expected_output/span/db_redis.md b/crates/weaver_forge/expected_output/span/db_redis.md new file mode 100644 index 00000000..f4b00461 --- /dev/null +++ b/crates/weaver_forge/expected_output/span/db_redis.md @@ -0,0 +1,303 @@ +## Group `db.redis` (span) + +### Brief + +Call-level attributes for Redis + + + +Prefix: +Kind: none + +### Attributes + + +#### Attribute `db.system` + +An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. + + +- Requirement Level: Required + +- Tag: connection-level + +- Type: Enum [other_sql, mssql, mssqlcompact, mysql, oracle, db2, postgresql, redshift, hive, cloudscape, hsqldb, progress, maxdb, hanadb, ingres, firstsql, edb, cache, adabas, firebird, derby, filemaker, informix, instantdb, interbase, mariadb, netezza, pervasive, pointbase, sqlite, sybase, teradata, vertica, h2, coldfusion, cassandra, hbase, mongodb, redis, couchbase, couchdb, cosmosdb, dynamodb, neo4j, geode, elasticsearch, memcached, cockroachdb, opensearch, clickhouse, spanner, trino] + + +#### Attribute `db.connection_string` + +The connection string used to connect to the database. It is recommended to remove embedded credentials. + + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: Server=(localdb)\v11.0;Integrated Security=true; + + +#### Attribute `db.user` + +Username for accessing the database. + + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "readonly_user", + "reporting_user", +] + + +#### Attribute `db.jdbc.driver_classname` + +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. + + + +- Requirement Level: Recommended + +- Tag: connection-level-tech-specific + +- Type: string +- Examples: [ + "org.postgresql.Driver", + "com.microsoft.sqlserver.jdbc.SQLServerDriver", +] + + +#### Attribute `db.name` + +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). + + + +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). + +- Requirement Level: Conditionally Required - If applicable. + +- Tag: call-level + +- Type: string +- Examples: [ + "customers", + "main", +] + + +#### Attribute `db.statement` + +The database statement being executed. + + + +- Requirement Level: Optional + +- Tag: call-level + +- Type: string +- Examples: [ + "SELECT * FROM wuser_table", + "SET mykey \"WuValue\"", +] + + +#### Attribute `db.operation` + +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. + + + +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. + +- Requirement Level: Conditionally Required - If `db.statement` is not applicable. + +- Tag: call-level + +- Type: string +- Examples: [ + "findAndModify", + "HMSET", + "SELECT", +] + + +#### Attribute `server.address` + +Name of the database host. + + + +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. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "example.com", + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +#### Attribute `server.port` + +Server port number. + + +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. + +- Requirement Level: Conditionally Required - If using a port other than the default port for this DBMS and if `server.address` is set. + +- Tag: connection-level + +- Type: int +- Examples: [ + 80, + 8080, + 443, +] + +- Stability: Stable + + +#### Attribute `network.peer.address` + +Peer address of the network connection - IP address or Unix domain socket name. + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +#### Attribute `network.peer.port` + +Peer port number of the network connection. + + +- Requirement Level: Optional + +- Tag: connection-level + +- Type: int +- Examples: [ + 65123, +] + +- Stability: Stable + + +#### Attribute `network.transport` + +[OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). + + + +The value SHOULD be normalized to lowercase. + +Consider always setting the transport when setting a port number, since +a port number is ambiguous without knowing the transport. For example +different processes could be listening on TCP port 12345 and UDP port 12345. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: Enum [tcp, udp, pipe, unix] +- Examples: [ + "tcp", + "udp", +] + +- Stability: Stable + + +#### Attribute `network.type` + +[OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. + + +The value SHOULD be normalized to lowercase. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: Enum [ipv4, ipv6] +- Examples: [ + "ipv4", + "ipv6", +] + +- Stability: Stable + + +#### Attribute `db.instance.id` + +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`. + + + +- Requirement Level: Optional + +- Tag: connection-level + +- Type: string +- Examples: mysql-e26b99z.example.com + + +#### Attribute `db.redis.database_index` + +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. + + + +- Requirement Level: Conditionally Required - If other than the default database (`0`). + +- Tag: call-level-tech-specific + +- Type: int +- Examples: [ + 0, + 1, + 15, +] + + +#### Attribute `db.statement` + +The full syntax of the Redis CLI command. + + + +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`. + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific + +- Type: string +- Examples: [ + "HMSET myhash field1 'Hello' field2 'World'", +] + + \ No newline at end of file diff --git a/crates/weaver_forge/expected_output/span/db_sql.md b/crates/weaver_forge/expected_output/span/db_sql.md new file mode 100644 index 00000000..a4572016 --- /dev/null +++ b/crates/weaver_forge/expected_output/span/db_sql.md @@ -0,0 +1,285 @@ +## Group `db.sql` (span) + +### Brief + +Call-level attributes for SQL databases + + + +Prefix: +Kind: none + +### Attributes + + +#### Attribute `db.system` + +An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. + + +- Requirement Level: Required + +- Tag: connection-level + +- Type: Enum [other_sql, mssql, mssqlcompact, mysql, oracle, db2, postgresql, redshift, hive, cloudscape, hsqldb, progress, maxdb, hanadb, ingres, firstsql, edb, cache, adabas, firebird, derby, filemaker, informix, instantdb, interbase, mariadb, netezza, pervasive, pointbase, sqlite, sybase, teradata, vertica, h2, coldfusion, cassandra, hbase, mongodb, redis, couchbase, couchdb, cosmosdb, dynamodb, neo4j, geode, elasticsearch, memcached, cockroachdb, opensearch, clickhouse, spanner, trino] + + +#### Attribute `db.connection_string` + +The connection string used to connect to the database. It is recommended to remove embedded credentials. + + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: Server=(localdb)\v11.0;Integrated Security=true; + + +#### Attribute `db.user` + +Username for accessing the database. + + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "readonly_user", + "reporting_user", +] + + +#### Attribute `db.jdbc.driver_classname` + +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. + + + +- Requirement Level: Recommended + +- Tag: connection-level-tech-specific + +- Type: string +- Examples: [ + "org.postgresql.Driver", + "com.microsoft.sqlserver.jdbc.SQLServerDriver", +] + + +#### Attribute `db.name` + +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). + + + +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). + +- Requirement Level: Conditionally Required - If applicable. + +- Tag: call-level + +- Type: string +- Examples: [ + "customers", + "main", +] + + +#### Attribute `db.statement` + +The database statement being executed. + + + +- Requirement Level: Optional + +- Tag: call-level + +- Type: string +- Examples: [ + "SELECT * FROM wuser_table", + "SET mykey \"WuValue\"", +] + + +#### Attribute `db.operation` + +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. + + + +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. + +- Requirement Level: Conditionally Required - If `db.statement` is not applicable. + +- Tag: call-level + +- Type: string +- Examples: [ + "findAndModify", + "HMSET", + "SELECT", +] + + +#### Attribute `server.address` + +Name of the database host. + + + +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. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "example.com", + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +#### Attribute `server.port` + +Server port number. + + +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. + +- Requirement Level: Conditionally Required - If using a port other than the default port for this DBMS and if `server.address` is set. + +- Tag: connection-level + +- Type: int +- Examples: [ + 80, + 8080, + 443, +] + +- Stability: Stable + + +#### Attribute `network.peer.address` + +Peer address of the network connection - IP address or Unix domain socket name. + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +#### Attribute `network.peer.port` + +Peer port number of the network connection. + + +- Requirement Level: Optional + +- Tag: connection-level + +- Type: int +- Examples: [ + 65123, +] + +- Stability: Stable + + +#### Attribute `network.transport` + +[OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). + + + +The value SHOULD be normalized to lowercase. + +Consider always setting the transport when setting a port number, since +a port number is ambiguous without knowing the transport. For example +different processes could be listening on TCP port 12345 and UDP port 12345. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: Enum [tcp, udp, pipe, unix] +- Examples: [ + "tcp", + "udp", +] + +- Stability: Stable + + +#### Attribute `network.type` + +[OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. + + +The value SHOULD be normalized to lowercase. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: Enum [ipv4, ipv6] +- Examples: [ + "ipv4", + "ipv6", +] + +- Stability: Stable + + +#### Attribute `db.instance.id` + +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`. + + + +- Requirement Level: Optional + +- Tag: connection-level + +- Type: string +- Examples: mysql-e26b99z.example.com + + +#### Attribute `db.sql.table` + +The name of the primary table that the operation is acting upon, including the database name (if applicable). + + +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. + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific + +- Type: string +- Examples: [ + "public.users", + "customers", +] + + \ No newline at end of file diff --git a/crates/weaver_forge/expected_output/span/db_tech.md b/crates/weaver_forge/expected_output/span/db_tech.md new file mode 100644 index 00000000..353b5e9c --- /dev/null +++ b/crates/weaver_forge/expected_output/span/db_tech.md @@ -0,0 +1,589 @@ +## Group `db.tech` (span) + +### Brief + +Semantic convention group for specific technologies + + + +Prefix: +Kind: none + +### Attributes + + +#### Attribute `db.system` + +An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. + + +- Requirement Level: Required + +- Tag: connection-level + +- Type: Enum [other_sql, mssql, mssqlcompact, mysql, oracle, db2, postgresql, redshift, hive, cloudscape, hsqldb, progress, maxdb, hanadb, ingres, firstsql, edb, cache, adabas, firebird, derby, filemaker, informix, instantdb, interbase, mariadb, netezza, pervasive, pointbase, sqlite, sybase, teradata, vertica, h2, coldfusion, cassandra, hbase, mongodb, redis, couchbase, couchdb, cosmosdb, dynamodb, neo4j, geode, elasticsearch, memcached, cockroachdb, opensearch, clickhouse, spanner, trino] + + +#### Attribute `db.connection_string` + +The connection string used to connect to the database. It is recommended to remove embedded credentials. + + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: Server=(localdb)\v11.0;Integrated Security=true; + + +#### Attribute `db.user` + +Username for accessing the database. + + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "readonly_user", + "reporting_user", +] + + +#### Attribute `db.jdbc.driver_classname` + +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. + + + +- Requirement Level: Recommended + +- Tag: connection-level-tech-specific + +- Type: string +- Examples: [ + "org.postgresql.Driver", + "com.microsoft.sqlserver.jdbc.SQLServerDriver", +] + + +#### Attribute `db.name` + +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). + + + +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). + +- Requirement Level: Conditionally Required - If applicable. + +- Tag: call-level + +- Type: string +- Examples: [ + "customers", + "main", +] + + +#### Attribute `db.statement` + +The database statement being executed. + + + +- Requirement Level: Optional + +- Tag: call-level + +- Type: string +- Examples: [ + "SELECT * FROM wuser_table", + "SET mykey \"WuValue\"", +] + + +#### Attribute `db.operation` + +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. + + + +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. + +- Requirement Level: Conditionally Required - If `db.statement` is not applicable. + +- Tag: call-level + +- Type: string +- Examples: [ + "findAndModify", + "HMSET", + "SELECT", +] + + +#### Attribute `server.address` + +Name of the database host. + + + +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. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "example.com", + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +#### Attribute `server.port` + +Server port number. + + +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. + +- Requirement Level: Conditionally Required - If using a port other than the default port for this DBMS and if `server.address` is set. + +- Tag: connection-level + +- Type: int +- Examples: [ + 80, + 8080, + 443, +] + +- Stability: Stable + + +#### Attribute `network.peer.address` + +Peer address of the network connection - IP address or Unix domain socket name. + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +#### Attribute `network.peer.port` + +Peer port number of the network connection. + + +- Requirement Level: Optional + +- Tag: connection-level + +- Type: int +- Examples: [ + 65123, +] + +- Stability: Stable + + +#### Attribute `network.transport` + +[OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). + + + +The value SHOULD be normalized to lowercase. + +Consider always setting the transport when setting a port number, since +a port number is ambiguous without knowing the transport. For example +different processes could be listening on TCP port 12345 and UDP port 12345. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: Enum [tcp, udp, pipe, unix] +- Examples: [ + "tcp", + "udp", +] + +- Stability: Stable + + +#### Attribute `network.type` + +[OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. + + +The value SHOULD be normalized to lowercase. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: Enum [ipv4, ipv6] +- Examples: [ + "ipv4", + "ipv6", +] + +- Stability: Stable + + +#### Attribute `db.instance.id` + +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`. + + + +- Requirement Level: Optional + +- Tag: connection-level + +- Type: string +- Examples: mysql-e26b99z.example.com + + +#### Attribute `db.name` + +The keyspace name in Cassandra. + + + +For Cassandra the `db.name` should be set to the Cassandra keyspace name. + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific-cassandra + +- Type: string +- Examples: [ + "mykeyspace", +] + + +#### Attribute `db.cassandra.page_size` + +The fetch size used for paging, i.e. how many rows will be returned at once. + + + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific-cassandra + +- Type: int +- Examples: [ + 5000, +] + + +#### Attribute `db.cassandra.consistency_level` + +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). + + + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific-cassandra + +- Type: Enum [all, each_quorum, quorum, local_quorum, one, two, three, local_one, any, serial, local_serial] + + +#### Attribute `db.cassandra.table` + +The name of the primary Cassandra table that the operation is acting upon, including the keyspace name (if applicable). + + +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. + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific-cassandra + +- Type: string +- Examples: mytable + + +#### Attribute `db.cassandra.idempotence` + +Whether or not the query is idempotent. + + + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific-cassandra + +- Type: boolean + + +#### Attribute `db.cassandra.speculative_execution_count` + +The number of times a query was speculatively executed. Not set or `0` if the query was not executed speculatively. + + + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific-cassandra + +- Type: int +- Examples: [ + 0, + 2, +] + + +#### Attribute `db.cassandra.coordinator.id` + +The ID of the coordinating node for a query. + + + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific-cassandra + +- Type: string +- Examples: be13faa2-8574-4d71-926d-27f16cf8a7af + + +#### Attribute `db.cassandra.coordinator.dc` + +The data center of the coordinating node for a query. + + + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific-cassandra + +- Type: string +- Examples: us-west-2 + + +#### Attribute `db.redis.database_index` + +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. + + + +- Requirement Level: Conditionally Required - If other than the default database (`0`). + +- Tag: call-level-tech-specific + +- Type: int +- Examples: [ + 0, + 1, + 15, +] + + +#### Attribute `db.statement` + +The full syntax of the Redis CLI command. + + + +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`. + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific + +- Type: string +- Examples: [ + "HMSET myhash field1 'Hello' field2 'World'", +] + + +#### Attribute `db.mongodb.collection` + +The MongoDB collection being accessed within the database stated in `db.name`. + + + +- Requirement Level: Required + +- Tag: call-level-tech-specific + +- Type: string +- Examples: [ + "customers", + "products", +] + + +#### Attribute `db.sql.table` + +The name of the primary table that the operation is acting upon, including the database name (if applicable). + + +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. + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific + +- Type: string +- Examples: [ + "public.users", + "customers", +] + + +#### Attribute `db.cosmosdb.client_id` + +Unique Cosmos client instance id. + + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific + +- Type: string +- Examples: 3ba4827d-4422-483f-b59f-85b74211c11d + + +#### Attribute `db.cosmosdb.operation_type` + +CosmosDB Operation Type. + + +- Requirement Level: Conditionally Required - when performing one of the operations in this list + +- Tag: call-level-tech-specific + +- Type: Enum [Invalid, Create, Patch, Read, ReadFeed, Delete, Replace, Execute, Query, Head, HeadFeed, Upsert, Batch, QueryPlan, ExecuteJavaScript] + + +#### Attribute `user_agent.original` + +Full user-agent string is generated by Cosmos DB SDK + + +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. + Format Reg-{D (Disabled discovery)}-S(application region)|L(List of preferred regions)|N(None, user did not configure it). + Default value is "NS". + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific + +- Type: string +- 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\\|", +] + +- Stability: Stable + + +#### Attribute `db.cosmosdb.connection_mode` + +Cosmos client connection mode. + + +- Requirement Level: Conditionally Required - if not `direct` (or pick gw as default) + +- Tag: call-level-tech-specific + +- Type: Enum [gateway, direct] + + +#### Attribute `db.cosmosdb.container` + +Cosmos DB container name. + + +- Requirement Level: Conditionally Required - if available + +- Tag: call-level-tech-specific + +- Type: string +- Examples: anystring + + +#### Attribute `db.cosmosdb.request_content_length` + +Request payload size in bytes + + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific + +- Type: int + + +#### Attribute `db.cosmosdb.status_code` + +Cosmos DB status code. + + +- Requirement Level: Conditionally Required - if response was received + +- Tag: call-level-tech-specific + +- Type: int +- Examples: [ + 200, + 201, +] + + +#### Attribute `db.cosmosdb.sub_status_code` + +Cosmos DB sub status code. + + +- Requirement Level: Conditionally Required - when response was received and contained sub-code. + +- Tag: call-level-tech-specific + +- Type: int +- Examples: [ + 1000, + 1002, +] + + +#### Attribute `db.cosmosdb.request_charge` + +RU consumed for that operation + + +- Requirement Level: Conditionally Required - when available + +- Tag: call-level-tech-specific + +- Type: double +- Examples: [ + 46.18, + 1.0, +] + + \ No newline at end of file diff --git a/crates/weaver_forge/expected_output/spans.md b/crates/weaver_forge/expected_output/spans.md new file mode 100644 index 00000000..281e94a9 --- /dev/null +++ b/crates/weaver_forge/expected_output/spans.md @@ -0,0 +1,3829 @@ +# Semantic Convention Span Groups + + +## Group `db` (span) + +### Brief + +This document defines the attributes used to perform database client calls. + + + +Prefix: +Kind: client + +### Attributes + + +#### Attribute `db.system` + +An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. + + +- Requirement Level: Required + +- Tag: connection-level + +- Type: Enum [other_sql, mssql, mssqlcompact, mysql, oracle, db2, postgresql, redshift, hive, cloudscape, hsqldb, progress, maxdb, hanadb, ingres, firstsql, edb, cache, adabas, firebird, derby, filemaker, informix, instantdb, interbase, mariadb, netezza, pervasive, pointbase, sqlite, sybase, teradata, vertica, h2, coldfusion, cassandra, hbase, mongodb, redis, couchbase, couchdb, cosmosdb, dynamodb, neo4j, geode, elasticsearch, memcached, cockroachdb, opensearch, clickhouse, spanner, trino] + + +#### Attribute `db.connection_string` + +The connection string used to connect to the database. It is recommended to remove embedded credentials. + + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: Server=(localdb)\v11.0;Integrated Security=true; + + +#### Attribute `db.user` + +Username for accessing the database. + + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "readonly_user", + "reporting_user", +] + + +#### Attribute `db.jdbc.driver_classname` + +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. + + + +- Requirement Level: Recommended + +- Tag: connection-level-tech-specific + +- Type: string +- Examples: [ + "org.postgresql.Driver", + "com.microsoft.sqlserver.jdbc.SQLServerDriver", +] + + +#### Attribute `db.name` + +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). + + + +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). + +- Requirement Level: Conditionally Required - If applicable. + +- Tag: call-level + +- Type: string +- Examples: [ + "customers", + "main", +] + + +#### Attribute `db.statement` + +The database statement being executed. + + + +- Requirement Level: Optional + +- Tag: call-level + +- Type: string +- Examples: [ + "SELECT * FROM wuser_table", + "SET mykey \"WuValue\"", +] + + +#### Attribute `db.operation` + +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. + + + +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. + +- Requirement Level: Conditionally Required - If `db.statement` is not applicable. + +- Tag: call-level + +- Type: string +- Examples: [ + "findAndModify", + "HMSET", + "SELECT", +] + + +#### Attribute `server.address` + +Name of the database host. + + + +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. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "example.com", + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +#### Attribute `server.port` + +Server port number. + + +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. + +- Requirement Level: Conditionally Required - If using a port other than the default port for this DBMS and if `server.address` is set. + +- Tag: connection-level + +- Type: int +- Examples: [ + 80, + 8080, + 443, +] + +- Stability: Stable + + +#### Attribute `network.peer.address` + +Peer address of the network connection - IP address or Unix domain socket name. + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +#### Attribute `network.peer.port` + +Peer port number of the network connection. + + +- Requirement Level: Optional + +- Tag: connection-level + +- Type: int +- Examples: [ + 65123, +] + +- Stability: Stable + + +#### Attribute `network.transport` + +[OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). + + + +The value SHOULD be normalized to lowercase. + +Consider always setting the transport when setting a port number, since +a port number is ambiguous without knowing the transport. For example +different processes could be listening on TCP port 12345 and UDP port 12345. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: Enum [tcp, udp, pipe, unix] +- Examples: [ + "tcp", + "udp", +] + +- Stability: Stable + + +#### Attribute `network.type` + +[OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. + + +The value SHOULD be normalized to lowercase. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: Enum [ipv4, ipv6] +- Examples: [ + "ipv4", + "ipv6", +] + +- Stability: Stable + + +#### Attribute `db.instance.id` + +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`. + + + +- Requirement Level: Optional + +- Tag: connection-level + +- Type: string +- Examples: mysql-e26b99z.example.com + + + +## Group `db.mssql` (span) + +### Brief + +Connection-level attributes for Microsoft SQL Server + + + +Prefix: +Kind: none + +### Attributes + + +#### Attribute `db.system` + +An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. + + +- Requirement Level: Required + +- Tag: connection-level + +- Type: Enum [other_sql, mssql, mssqlcompact, mysql, oracle, db2, postgresql, redshift, hive, cloudscape, hsqldb, progress, maxdb, hanadb, ingres, firstsql, edb, cache, adabas, firebird, derby, filemaker, informix, instantdb, interbase, mariadb, netezza, pervasive, pointbase, sqlite, sybase, teradata, vertica, h2, coldfusion, cassandra, hbase, mongodb, redis, couchbase, couchdb, cosmosdb, dynamodb, neo4j, geode, elasticsearch, memcached, cockroachdb, opensearch, clickhouse, spanner, trino] + + +#### Attribute `db.connection_string` + +The connection string used to connect to the database. It is recommended to remove embedded credentials. + + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: Server=(localdb)\v11.0;Integrated Security=true; + + +#### Attribute `db.user` + +Username for accessing the database. + + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "readonly_user", + "reporting_user", +] + + +#### Attribute `db.jdbc.driver_classname` + +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. + + + +- Requirement Level: Recommended + +- Tag: connection-level-tech-specific + +- Type: string +- Examples: [ + "org.postgresql.Driver", + "com.microsoft.sqlserver.jdbc.SQLServerDriver", +] + + +#### Attribute `db.name` + +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). + + + +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). + +- Requirement Level: Conditionally Required - If applicable. + +- Tag: call-level + +- Type: string +- Examples: [ + "customers", + "main", +] + + +#### Attribute `db.statement` + +The database statement being executed. + + + +- Requirement Level: Optional + +- Tag: call-level + +- Type: string +- Examples: [ + "SELECT * FROM wuser_table", + "SET mykey \"WuValue\"", +] + + +#### Attribute `db.operation` + +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. + + + +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. + +- Requirement Level: Conditionally Required - If `db.statement` is not applicable. + +- Tag: call-level + +- Type: string +- Examples: [ + "findAndModify", + "HMSET", + "SELECT", +] + + +#### Attribute `server.address` + +Name of the database host. + + + +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. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "example.com", + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +#### Attribute `server.port` + +Server port number. + + +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. + +- Requirement Level: Conditionally Required - If using a port other than the default port for this DBMS and if `server.address` is set. + +- Tag: connection-level + +- Type: int +- Examples: [ + 80, + 8080, + 443, +] + +- Stability: Stable + + +#### Attribute `network.peer.address` + +Peer address of the network connection - IP address or Unix domain socket name. + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +#### Attribute `network.peer.port` + +Peer port number of the network connection. + + +- Requirement Level: Optional + +- Tag: connection-level + +- Type: int +- Examples: [ + 65123, +] + +- Stability: Stable + + +#### Attribute `network.transport` + +[OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). + + + +The value SHOULD be normalized to lowercase. + +Consider always setting the transport when setting a port number, since +a port number is ambiguous without knowing the transport. For example +different processes could be listening on TCP port 12345 and UDP port 12345. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: Enum [tcp, udp, pipe, unix] +- Examples: [ + "tcp", + "udp", +] + +- Stability: Stable + + +#### Attribute `network.type` + +[OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. + + +The value SHOULD be normalized to lowercase. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: Enum [ipv4, ipv6] +- Examples: [ + "ipv4", + "ipv6", +] + +- Stability: Stable + + +#### Attribute `db.instance.id` + +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`. + + + +- Requirement Level: Optional + +- Tag: connection-level + +- Type: string +- Examples: mysql-e26b99z.example.com + + +#### Attribute `db.mssql.instance_name` + +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. + + + +If setting a `db.mssql.instance_name`, `server.port` is no longer required (but still recommended if non-standard). + +- Requirement Level: Recommended + +- Tag: connection-level-tech-specific + +- Type: string +- Examples: MSSQLSERVER + + + +## Group `db.cassandra` (span) + +### Brief + +Call-level attributes for Cassandra + + + +Prefix: +Kind: none + +### Attributes + + +#### Attribute `db.system` + +An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. + + +- Requirement Level: Required + +- Tag: connection-level + +- Type: Enum [other_sql, mssql, mssqlcompact, mysql, oracle, db2, postgresql, redshift, hive, cloudscape, hsqldb, progress, maxdb, hanadb, ingres, firstsql, edb, cache, adabas, firebird, derby, filemaker, informix, instantdb, interbase, mariadb, netezza, pervasive, pointbase, sqlite, sybase, teradata, vertica, h2, coldfusion, cassandra, hbase, mongodb, redis, couchbase, couchdb, cosmosdb, dynamodb, neo4j, geode, elasticsearch, memcached, cockroachdb, opensearch, clickhouse, spanner, trino] + + +#### Attribute `db.connection_string` + +The connection string used to connect to the database. It is recommended to remove embedded credentials. + + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: Server=(localdb)\v11.0;Integrated Security=true; + + +#### Attribute `db.user` + +Username for accessing the database. + + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "readonly_user", + "reporting_user", +] + + +#### Attribute `db.jdbc.driver_classname` + +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. + + + +- Requirement Level: Recommended + +- Tag: connection-level-tech-specific + +- Type: string +- Examples: [ + "org.postgresql.Driver", + "com.microsoft.sqlserver.jdbc.SQLServerDriver", +] + + +#### Attribute `db.name` + +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). + + + +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). + +- Requirement Level: Conditionally Required - If applicable. + +- Tag: call-level + +- Type: string +- Examples: [ + "customers", + "main", +] + + +#### Attribute `db.statement` + +The database statement being executed. + + + +- Requirement Level: Optional + +- Tag: call-level + +- Type: string +- Examples: [ + "SELECT * FROM wuser_table", + "SET mykey \"WuValue\"", +] + + +#### Attribute `db.operation` + +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. + + + +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. + +- Requirement Level: Conditionally Required - If `db.statement` is not applicable. + +- Tag: call-level + +- Type: string +- Examples: [ + "findAndModify", + "HMSET", + "SELECT", +] + + +#### Attribute `server.address` + +Name of the database host. + + + +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. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "example.com", + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +#### Attribute `server.port` + +Server port number. + + +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. + +- Requirement Level: Conditionally Required - If using a port other than the default port for this DBMS and if `server.address` is set. + +- Tag: connection-level + +- Type: int +- Examples: [ + 80, + 8080, + 443, +] + +- Stability: Stable + + +#### Attribute `network.peer.address` + +Peer address of the network connection - IP address or Unix domain socket name. + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +#### Attribute `network.peer.port` + +Peer port number of the network connection. + + +- Requirement Level: Optional + +- Tag: connection-level + +- Type: int +- Examples: [ + 65123, +] + +- Stability: Stable + + +#### Attribute `network.transport` + +[OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). + + + +The value SHOULD be normalized to lowercase. + +Consider always setting the transport when setting a port number, since +a port number is ambiguous without knowing the transport. For example +different processes could be listening on TCP port 12345 and UDP port 12345. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: Enum [tcp, udp, pipe, unix] +- Examples: [ + "tcp", + "udp", +] + +- Stability: Stable + + +#### Attribute `network.type` + +[OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. + + +The value SHOULD be normalized to lowercase. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: Enum [ipv4, ipv6] +- Examples: [ + "ipv4", + "ipv6", +] + +- Stability: Stable + + +#### Attribute `db.instance.id` + +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`. + + + +- Requirement Level: Optional + +- Tag: connection-level + +- Type: string +- Examples: mysql-e26b99z.example.com + + +#### Attribute `db.name` + +The keyspace name in Cassandra. + + + +For Cassandra the `db.name` should be set to the Cassandra keyspace name. + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific-cassandra + +- Type: string +- Examples: [ + "mykeyspace", +] + + +#### Attribute `db.cassandra.page_size` + +The fetch size used for paging, i.e. how many rows will be returned at once. + + + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific-cassandra + +- Type: int +- Examples: [ + 5000, +] + + +#### Attribute `db.cassandra.consistency_level` + +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). + + + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific-cassandra + +- Type: Enum [all, each_quorum, quorum, local_quorum, one, two, three, local_one, any, serial, local_serial] + + +#### Attribute `db.cassandra.table` + +The name of the primary Cassandra table that the operation is acting upon, including the keyspace name (if applicable). + + +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. + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific-cassandra + +- Type: string +- Examples: mytable + + +#### Attribute `db.cassandra.idempotence` + +Whether or not the query is idempotent. + + + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific-cassandra + +- Type: boolean + + +#### Attribute `db.cassandra.speculative_execution_count` + +The number of times a query was speculatively executed. Not set or `0` if the query was not executed speculatively. + + + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific-cassandra + +- Type: int +- Examples: [ + 0, + 2, +] + + +#### Attribute `db.cassandra.coordinator.id` + +The ID of the coordinating node for a query. + + + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific-cassandra + +- Type: string +- Examples: be13faa2-8574-4d71-926d-27f16cf8a7af + + +#### Attribute `db.cassandra.coordinator.dc` + +The data center of the coordinating node for a query. + + + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific-cassandra + +- Type: string +- Examples: us-west-2 + + + +## Group `db.hbase` (span) + +### Brief + +Call-level attributes for HBase + + + +Prefix: +Kind: none + +### Attributes + + +#### Attribute `db.system` + +An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. + + +- Requirement Level: Required + +- Tag: connection-level + +- Type: Enum [other_sql, mssql, mssqlcompact, mysql, oracle, db2, postgresql, redshift, hive, cloudscape, hsqldb, progress, maxdb, hanadb, ingres, firstsql, edb, cache, adabas, firebird, derby, filemaker, informix, instantdb, interbase, mariadb, netezza, pervasive, pointbase, sqlite, sybase, teradata, vertica, h2, coldfusion, cassandra, hbase, mongodb, redis, couchbase, couchdb, cosmosdb, dynamodb, neo4j, geode, elasticsearch, memcached, cockroachdb, opensearch, clickhouse, spanner, trino] + + +#### Attribute `db.connection_string` + +The connection string used to connect to the database. It is recommended to remove embedded credentials. + + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: Server=(localdb)\v11.0;Integrated Security=true; + + +#### Attribute `db.user` + +Username for accessing the database. + + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "readonly_user", + "reporting_user", +] + + +#### Attribute `db.jdbc.driver_classname` + +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. + + + +- Requirement Level: Recommended + +- Tag: connection-level-tech-specific + +- Type: string +- Examples: [ + "org.postgresql.Driver", + "com.microsoft.sqlserver.jdbc.SQLServerDriver", +] + + +#### Attribute `db.name` + +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). + + + +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). + +- Requirement Level: Conditionally Required - If applicable. + +- Tag: call-level + +- Type: string +- Examples: [ + "customers", + "main", +] + + +#### Attribute `db.statement` + +The database statement being executed. + + + +- Requirement Level: Optional + +- Tag: call-level + +- Type: string +- Examples: [ + "SELECT * FROM wuser_table", + "SET mykey \"WuValue\"", +] + + +#### Attribute `db.operation` + +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. + + + +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. + +- Requirement Level: Conditionally Required - If `db.statement` is not applicable. + +- Tag: call-level + +- Type: string +- Examples: [ + "findAndModify", + "HMSET", + "SELECT", +] + + +#### Attribute `server.address` + +Name of the database host. + + + +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. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "example.com", + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +#### Attribute `server.port` + +Server port number. + + +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. + +- Requirement Level: Conditionally Required - If using a port other than the default port for this DBMS and if `server.address` is set. + +- Tag: connection-level + +- Type: int +- Examples: [ + 80, + 8080, + 443, +] + +- Stability: Stable + + +#### Attribute `network.peer.address` + +Peer address of the network connection - IP address or Unix domain socket name. + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +#### Attribute `network.peer.port` + +Peer port number of the network connection. + + +- Requirement Level: Optional + +- Tag: connection-level + +- Type: int +- Examples: [ + 65123, +] + +- Stability: Stable + + +#### Attribute `network.transport` + +[OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). + + + +The value SHOULD be normalized to lowercase. + +Consider always setting the transport when setting a port number, since +a port number is ambiguous without knowing the transport. For example +different processes could be listening on TCP port 12345 and UDP port 12345. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: Enum [tcp, udp, pipe, unix] +- Examples: [ + "tcp", + "udp", +] + +- Stability: Stable + + +#### Attribute `network.type` + +[OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. + + +The value SHOULD be normalized to lowercase. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: Enum [ipv4, ipv6] +- Examples: [ + "ipv4", + "ipv6", +] + +- Stability: Stable + + +#### Attribute `db.instance.id` + +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`. + + + +- Requirement Level: Optional + +- Tag: connection-level + +- Type: string +- Examples: mysql-e26b99z.example.com + + +#### Attribute `db.name` + +The HBase namespace. + + + +For HBase the `db.name` should be set to the HBase namespace. + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific + +- Type: string +- Examples: [ + "mynamespace", +] + + + +## Group `db.couchdb` (span) + +### Brief + +Call-level attributes for CouchDB + + + +Prefix: +Kind: none + +### Attributes + + +#### Attribute `db.system` + +An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. + + +- Requirement Level: Required + +- Tag: connection-level + +- Type: Enum [other_sql, mssql, mssqlcompact, mysql, oracle, db2, postgresql, redshift, hive, cloudscape, hsqldb, progress, maxdb, hanadb, ingres, firstsql, edb, cache, adabas, firebird, derby, filemaker, informix, instantdb, interbase, mariadb, netezza, pervasive, pointbase, sqlite, sybase, teradata, vertica, h2, coldfusion, cassandra, hbase, mongodb, redis, couchbase, couchdb, cosmosdb, dynamodb, neo4j, geode, elasticsearch, memcached, cockroachdb, opensearch, clickhouse, spanner, trino] + + +#### Attribute `db.connection_string` + +The connection string used to connect to the database. It is recommended to remove embedded credentials. + + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: Server=(localdb)\v11.0;Integrated Security=true; + + +#### Attribute `db.user` + +Username for accessing the database. + + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "readonly_user", + "reporting_user", +] + + +#### Attribute `db.jdbc.driver_classname` + +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. + + + +- Requirement Level: Recommended + +- Tag: connection-level-tech-specific + +- Type: string +- Examples: [ + "org.postgresql.Driver", + "com.microsoft.sqlserver.jdbc.SQLServerDriver", +] + + +#### Attribute `db.name` + +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). + + + +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). + +- Requirement Level: Conditionally Required - If applicable. + +- Tag: call-level + +- Type: string +- Examples: [ + "customers", + "main", +] + + +#### Attribute `db.statement` + +The database statement being executed. + + + +- Requirement Level: Optional + +- Tag: call-level + +- Type: string +- Examples: [ + "SELECT * FROM wuser_table", + "SET mykey \"WuValue\"", +] + + +#### Attribute `db.operation` + +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. + + + +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. + +- Requirement Level: Conditionally Required - If `db.statement` is not applicable. + +- Tag: call-level + +- Type: string +- Examples: [ + "findAndModify", + "HMSET", + "SELECT", +] + + +#### Attribute `server.address` + +Name of the database host. + + + +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. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "example.com", + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +#### Attribute `server.port` + +Server port number. + + +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. + +- Requirement Level: Conditionally Required - If using a port other than the default port for this DBMS and if `server.address` is set. + +- Tag: connection-level + +- Type: int +- Examples: [ + 80, + 8080, + 443, +] + +- Stability: Stable + + +#### Attribute `network.peer.address` + +Peer address of the network connection - IP address or Unix domain socket name. + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +#### Attribute `network.peer.port` + +Peer port number of the network connection. + + +- Requirement Level: Optional + +- Tag: connection-level + +- Type: int +- Examples: [ + 65123, +] + +- Stability: Stable + + +#### Attribute `network.transport` + +[OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). + + + +The value SHOULD be normalized to lowercase. + +Consider always setting the transport when setting a port number, since +a port number is ambiguous without knowing the transport. For example +different processes could be listening on TCP port 12345 and UDP port 12345. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: Enum [tcp, udp, pipe, unix] +- Examples: [ + "tcp", + "udp", +] + +- Stability: Stable + + +#### Attribute `network.type` + +[OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. + + +The value SHOULD be normalized to lowercase. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: Enum [ipv4, ipv6] +- Examples: [ + "ipv4", + "ipv6", +] + +- Stability: Stable + + +#### Attribute `db.instance.id` + +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`. + + + +- Requirement Level: Optional + +- Tag: connection-level + +- Type: string +- Examples: mysql-e26b99z.example.com + + +#### Attribute `db.operation` + +The HTTP method + the target REST route. + + + +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). + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific + +- Type: string +- Examples: [ + "GET /{db}/{docid}", +] + + + +## Group `db.redis` (span) + +### Brief + +Call-level attributes for Redis + + + +Prefix: +Kind: none + +### Attributes + + +#### Attribute `db.system` + +An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. + + +- Requirement Level: Required + +- Tag: connection-level + +- Type: Enum [other_sql, mssql, mssqlcompact, mysql, oracle, db2, postgresql, redshift, hive, cloudscape, hsqldb, progress, maxdb, hanadb, ingres, firstsql, edb, cache, adabas, firebird, derby, filemaker, informix, instantdb, interbase, mariadb, netezza, pervasive, pointbase, sqlite, sybase, teradata, vertica, h2, coldfusion, cassandra, hbase, mongodb, redis, couchbase, couchdb, cosmosdb, dynamodb, neo4j, geode, elasticsearch, memcached, cockroachdb, opensearch, clickhouse, spanner, trino] + + +#### Attribute `db.connection_string` + +The connection string used to connect to the database. It is recommended to remove embedded credentials. + + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: Server=(localdb)\v11.0;Integrated Security=true; + + +#### Attribute `db.user` + +Username for accessing the database. + + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "readonly_user", + "reporting_user", +] + + +#### Attribute `db.jdbc.driver_classname` + +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. + + + +- Requirement Level: Recommended + +- Tag: connection-level-tech-specific + +- Type: string +- Examples: [ + "org.postgresql.Driver", + "com.microsoft.sqlserver.jdbc.SQLServerDriver", +] + + +#### Attribute `db.name` + +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). + + + +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). + +- Requirement Level: Conditionally Required - If applicable. + +- Tag: call-level + +- Type: string +- Examples: [ + "customers", + "main", +] + + +#### Attribute `db.statement` + +The database statement being executed. + + + +- Requirement Level: Optional + +- Tag: call-level + +- Type: string +- Examples: [ + "SELECT * FROM wuser_table", + "SET mykey \"WuValue\"", +] + + +#### Attribute `db.operation` + +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. + + + +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. + +- Requirement Level: Conditionally Required - If `db.statement` is not applicable. + +- Tag: call-level + +- Type: string +- Examples: [ + "findAndModify", + "HMSET", + "SELECT", +] + + +#### Attribute `server.address` + +Name of the database host. + + + +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. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "example.com", + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +#### Attribute `server.port` + +Server port number. + + +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. + +- Requirement Level: Conditionally Required - If using a port other than the default port for this DBMS and if `server.address` is set. + +- Tag: connection-level + +- Type: int +- Examples: [ + 80, + 8080, + 443, +] + +- Stability: Stable + + +#### Attribute `network.peer.address` + +Peer address of the network connection - IP address or Unix domain socket name. + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +#### Attribute `network.peer.port` + +Peer port number of the network connection. + + +- Requirement Level: Optional + +- Tag: connection-level + +- Type: int +- Examples: [ + 65123, +] + +- Stability: Stable + + +#### Attribute `network.transport` + +[OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). + + + +The value SHOULD be normalized to lowercase. + +Consider always setting the transport when setting a port number, since +a port number is ambiguous without knowing the transport. For example +different processes could be listening on TCP port 12345 and UDP port 12345. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: Enum [tcp, udp, pipe, unix] +- Examples: [ + "tcp", + "udp", +] + +- Stability: Stable + + +#### Attribute `network.type` + +[OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. + + +The value SHOULD be normalized to lowercase. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: Enum [ipv4, ipv6] +- Examples: [ + "ipv4", + "ipv6", +] + +- Stability: Stable + + +#### Attribute `db.instance.id` + +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`. + + + +- Requirement Level: Optional + +- Tag: connection-level + +- Type: string +- Examples: mysql-e26b99z.example.com + + +#### Attribute `db.redis.database_index` + +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. + + + +- Requirement Level: Conditionally Required - If other than the default database (`0`). + +- Tag: call-level-tech-specific + +- Type: int +- Examples: [ + 0, + 1, + 15, +] + + +#### Attribute `db.statement` + +The full syntax of the Redis CLI command. + + + +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`. + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific + +- Type: string +- Examples: [ + "HMSET myhash field1 'Hello' field2 'World'", +] + + + +## Group `db.mongodb` (span) + +### Brief + +Call-level attributes for MongoDB + + + +Prefix: +Kind: none + +### Attributes + + +#### Attribute `db.system` + +An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. + + +- Requirement Level: Required + +- Tag: connection-level + +- Type: Enum [other_sql, mssql, mssqlcompact, mysql, oracle, db2, postgresql, redshift, hive, cloudscape, hsqldb, progress, maxdb, hanadb, ingres, firstsql, edb, cache, adabas, firebird, derby, filemaker, informix, instantdb, interbase, mariadb, netezza, pervasive, pointbase, sqlite, sybase, teradata, vertica, h2, coldfusion, cassandra, hbase, mongodb, redis, couchbase, couchdb, cosmosdb, dynamodb, neo4j, geode, elasticsearch, memcached, cockroachdb, opensearch, clickhouse, spanner, trino] + + +#### Attribute `db.connection_string` + +The connection string used to connect to the database. It is recommended to remove embedded credentials. + + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: Server=(localdb)\v11.0;Integrated Security=true; + + +#### Attribute `db.user` + +Username for accessing the database. + + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "readonly_user", + "reporting_user", +] + + +#### Attribute `db.jdbc.driver_classname` + +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. + + + +- Requirement Level: Recommended + +- Tag: connection-level-tech-specific + +- Type: string +- Examples: [ + "org.postgresql.Driver", + "com.microsoft.sqlserver.jdbc.SQLServerDriver", +] + + +#### Attribute `db.name` + +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). + + + +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). + +- Requirement Level: Conditionally Required - If applicable. + +- Tag: call-level + +- Type: string +- Examples: [ + "customers", + "main", +] + + +#### Attribute `db.statement` + +The database statement being executed. + + + +- Requirement Level: Optional + +- Tag: call-level + +- Type: string +- Examples: [ + "SELECT * FROM wuser_table", + "SET mykey \"WuValue\"", +] + + +#### Attribute `db.operation` + +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. + + + +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. + +- Requirement Level: Conditionally Required - If `db.statement` is not applicable. + +- Tag: call-level + +- Type: string +- Examples: [ + "findAndModify", + "HMSET", + "SELECT", +] + + +#### Attribute `server.address` + +Name of the database host. + + + +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. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "example.com", + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +#### Attribute `server.port` + +Server port number. + + +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. + +- Requirement Level: Conditionally Required - If using a port other than the default port for this DBMS and if `server.address` is set. + +- Tag: connection-level + +- Type: int +- Examples: [ + 80, + 8080, + 443, +] + +- Stability: Stable + + +#### Attribute `network.peer.address` + +Peer address of the network connection - IP address or Unix domain socket name. + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +#### Attribute `network.peer.port` + +Peer port number of the network connection. + + +- Requirement Level: Optional + +- Tag: connection-level + +- Type: int +- Examples: [ + 65123, +] + +- Stability: Stable + + +#### Attribute `network.transport` + +[OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). + + + +The value SHOULD be normalized to lowercase. + +Consider always setting the transport when setting a port number, since +a port number is ambiguous without knowing the transport. For example +different processes could be listening on TCP port 12345 and UDP port 12345. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: Enum [tcp, udp, pipe, unix] +- Examples: [ + "tcp", + "udp", +] + +- Stability: Stable + + +#### Attribute `network.type` + +[OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. + + +The value SHOULD be normalized to lowercase. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: Enum [ipv4, ipv6] +- Examples: [ + "ipv4", + "ipv6", +] + +- Stability: Stable + + +#### Attribute `db.instance.id` + +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`. + + + +- Requirement Level: Optional + +- Tag: connection-level + +- Type: string +- Examples: mysql-e26b99z.example.com + + +#### Attribute `db.mongodb.collection` + +The MongoDB collection being accessed within the database stated in `db.name`. + + + +- Requirement Level: Required + +- Tag: call-level-tech-specific + +- Type: string +- Examples: [ + "customers", + "products", +] + + + +## Group `db.elasticsearch` (span) + +### Brief + +Call-level attributes for Elasticsearch + + + +Prefix: +Kind: none + +### Attributes + + +#### Attribute `db.system` + +An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. + + +- Requirement Level: Required + +- Tag: connection-level + +- Type: Enum [other_sql, mssql, mssqlcompact, mysql, oracle, db2, postgresql, redshift, hive, cloudscape, hsqldb, progress, maxdb, hanadb, ingres, firstsql, edb, cache, adabas, firebird, derby, filemaker, informix, instantdb, interbase, mariadb, netezza, pervasive, pointbase, sqlite, sybase, teradata, vertica, h2, coldfusion, cassandra, hbase, mongodb, redis, couchbase, couchdb, cosmosdb, dynamodb, neo4j, geode, elasticsearch, memcached, cockroachdb, opensearch, clickhouse, spanner, trino] + + +#### Attribute `db.connection_string` + +The connection string used to connect to the database. It is recommended to remove embedded credentials. + + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: Server=(localdb)\v11.0;Integrated Security=true; + + +#### Attribute `db.user` + +Username for accessing the database. + + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "readonly_user", + "reporting_user", +] + + +#### Attribute `db.jdbc.driver_classname` + +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. + + + +- Requirement Level: Recommended + +- Tag: connection-level-tech-specific + +- Type: string +- Examples: [ + "org.postgresql.Driver", + "com.microsoft.sqlserver.jdbc.SQLServerDriver", +] + + +#### Attribute `db.name` + +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). + + + +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). + +- Requirement Level: Conditionally Required - If applicable. + +- Tag: call-level + +- Type: string +- Examples: [ + "customers", + "main", +] + + +#### Attribute `db.statement` + +The database statement being executed. + + + +- Requirement Level: Optional + +- Tag: call-level + +- Type: string +- Examples: [ + "SELECT * FROM wuser_table", + "SET mykey \"WuValue\"", +] + + +#### Attribute `db.operation` + +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. + + + +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. + +- Requirement Level: Conditionally Required - If `db.statement` is not applicable. + +- Tag: call-level + +- Type: string +- Examples: [ + "findAndModify", + "HMSET", + "SELECT", +] + + +#### Attribute `server.address` + +Name of the database host. + + + +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. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "example.com", + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +#### Attribute `server.port` + +Server port number. + + +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. + +- Requirement Level: Conditionally Required - If using a port other than the default port for this DBMS and if `server.address` is set. + +- Tag: connection-level + +- Type: int +- Examples: [ + 80, + 8080, + 443, +] + +- Stability: Stable + + +#### Attribute `network.peer.address` + +Peer address of the network connection - IP address or Unix domain socket name. + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +#### Attribute `network.peer.port` + +Peer port number of the network connection. + + +- Requirement Level: Optional + +- Tag: connection-level + +- Type: int +- Examples: [ + 65123, +] + +- Stability: Stable + + +#### Attribute `network.transport` + +[OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). + + + +The value SHOULD be normalized to lowercase. + +Consider always setting the transport when setting a port number, since +a port number is ambiguous without knowing the transport. For example +different processes could be listening on TCP port 12345 and UDP port 12345. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: Enum [tcp, udp, pipe, unix] +- Examples: [ + "tcp", + "udp", +] + +- Stability: Stable + + +#### Attribute `network.type` + +[OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. + + +The value SHOULD be normalized to lowercase. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: Enum [ipv4, ipv6] +- Examples: [ + "ipv4", + "ipv6", +] + +- Stability: Stable + + +#### Attribute `db.instance.id` + +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`. + + + +- Requirement Level: Optional + +- Tag: connection-level + +- Type: string +- Examples: mysql-e26b99z.example.com + + +#### Attribute `http.request.method` + +HTTP request method. + + +HTTP request method value SHOULD be "known" to the instrumentation. +By default, this convention defines "known" methods as the ones listed in [RFC9110](https://www.rfc-editor.org/rfc/rfc9110.html#name-methods) +and the PATCH method defined in [RFC5789](https://www.rfc-editor.org/rfc/rfc5789.html). + +If the HTTP request method is not known to instrumentation, it MUST set the `http.request.method` attribute to `_OTHER`. + +If the HTTP instrumentation could end up converting valid HTTP request methods to `_OTHER`, then it MUST provide a way to override +the list of known HTTP methods. If this override is done via environment variable, then the environment variable MUST be named +OTEL_INSTRUMENTATION_HTTP_KNOWN_METHODS and support a comma-separated list of case-sensitive known HTTP methods +(this list MUST be a full override of the default known method, it is not a list of known methods in addition to the defaults). + +HTTP method names are case-sensitive and `http.request.method` attribute value MUST match a known HTTP method name exactly. +Instrumentations for specific web frameworks that consider HTTP methods to be case insensitive, SHOULD populate a canonical equivalent. +Tracing instrumentations that do so, MUST also set `http.request.method_original` to the original value. + +- Requirement Level: Required + +- Tag: call-level-tech-specific + +- Type: Enum [CONNECT, DELETE, GET, HEAD, OPTIONS, PATCH, POST, PUT, TRACE, _OTHER] +- Examples: [ + "GET", + "POST", + "HEAD", +] + +- Stability: Stable + + +#### Attribute `db.operation` + +The endpoint identifier for the request. + + +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. + +- Requirement Level: Required + +- Tag: call-level-tech-specific + +- Type: string +- Examples: [ + "search", + "ml.close_job", + "cat.aliases", +] + + +#### Attribute `url.full` + +Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986) + + +For network calls, URL usually has `scheme://host[:port][path][?query][#fragment]` format, where the fragment is not transmitted over HTTP, but if it is known, it SHOULD be included nevertheless. +`url.full` MUST NOT contain credentials passed via URL in form of `https://username:password@www.example.com/`. In such case username and password SHOULD be redacted and attribute's value SHOULD be `https://REDACTED:REDACTED@www.example.com/`. +`url.full` SHOULD capture the absolute URL when it is available (or can be reconstructed) and SHOULD NOT be validated or modified except for sanitizing purposes. + +- Requirement Level: Required + +- Tag: call-level-tech-specific + +- Type: string +- Examples: [ + "https://localhost:9200/index/_search?q=user.id:kimchy", +] + +- Stability: Stable + + +#### Attribute `db.statement` + +The request body for a [search-type query](https://www.elastic.co/guide/en/elasticsearch/reference/current/search.html), as a json string. + + +- Requirement Level: Optional + +- Tag: call-level-tech-specific + +- Type: string +- Examples: [ + "\"{\\\"query\\\":{\\\"term\\\":{\\\"user.id\\\":\\\"kimchy\\\"}}}\"", +] + + +#### Attribute `server.address` + +Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. + + +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. + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific + +- Type: string +- Examples: [ + "example.com", + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +#### Attribute `server.port` + +Server port number. + + +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. + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific + +- Type: int +- Examples: [ + 80, + 8080, + 443, +] + +- Stability: Stable + + +#### Attribute `db.elasticsearch.cluster.name` + +Represents the identifier of an Elasticsearch cluster. + + + +- Requirement Level: Optional + +- Tag: call-level-tech-specific + +- Type: string +- Examples: [ + "e9106fc68e3044f0b1475b04bf4ffd5f", +] + + +#### Attribute `db.elasticsearch.node.name` + +Represents the human-readable identifier of the node/instance to which a request was routed. + + + +- Requirement Level: Optional + +- Tag: call-level-tech-specific + +- Type: string +- Examples: [ + "instance-0000000001", +] + + +#### Attribute `db.elasticsearch.path_parts` + +A dynamic value in the url path. + + + +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. + +- Requirement Level: Conditionally Required - when the url has dynamic values + +- Tag: call-level-tech-specific + +- Type: template[string] +- Examples: [ + "db.elasticsearch.path_parts.index=test-index", + "db.elasticsearch.path_parts.doc_id=123", +] + + + +## Group `db.sql` (span) + +### Brief + +Call-level attributes for SQL databases + + + +Prefix: +Kind: none + +### Attributes + + +#### Attribute `db.system` + +An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. + + +- Requirement Level: Required + +- Tag: connection-level + +- Type: Enum [other_sql, mssql, mssqlcompact, mysql, oracle, db2, postgresql, redshift, hive, cloudscape, hsqldb, progress, maxdb, hanadb, ingres, firstsql, edb, cache, adabas, firebird, derby, filemaker, informix, instantdb, interbase, mariadb, netezza, pervasive, pointbase, sqlite, sybase, teradata, vertica, h2, coldfusion, cassandra, hbase, mongodb, redis, couchbase, couchdb, cosmosdb, dynamodb, neo4j, geode, elasticsearch, memcached, cockroachdb, opensearch, clickhouse, spanner, trino] + + +#### Attribute `db.connection_string` + +The connection string used to connect to the database. It is recommended to remove embedded credentials. + + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: Server=(localdb)\v11.0;Integrated Security=true; + + +#### Attribute `db.user` + +Username for accessing the database. + + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "readonly_user", + "reporting_user", +] + + +#### Attribute `db.jdbc.driver_classname` + +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. + + + +- Requirement Level: Recommended + +- Tag: connection-level-tech-specific + +- Type: string +- Examples: [ + "org.postgresql.Driver", + "com.microsoft.sqlserver.jdbc.SQLServerDriver", +] + + +#### Attribute `db.name` + +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). + + + +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). + +- Requirement Level: Conditionally Required - If applicable. + +- Tag: call-level + +- Type: string +- Examples: [ + "customers", + "main", +] + + +#### Attribute `db.statement` + +The database statement being executed. + + + +- Requirement Level: Optional + +- Tag: call-level + +- Type: string +- Examples: [ + "SELECT * FROM wuser_table", + "SET mykey \"WuValue\"", +] + + +#### Attribute `db.operation` + +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. + + + +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. + +- Requirement Level: Conditionally Required - If `db.statement` is not applicable. + +- Tag: call-level + +- Type: string +- Examples: [ + "findAndModify", + "HMSET", + "SELECT", +] + + +#### Attribute `server.address` + +Name of the database host. + + + +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. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "example.com", + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +#### Attribute `server.port` + +Server port number. + + +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. + +- Requirement Level: Conditionally Required - If using a port other than the default port for this DBMS and if `server.address` is set. + +- Tag: connection-level + +- Type: int +- Examples: [ + 80, + 8080, + 443, +] + +- Stability: Stable + + +#### Attribute `network.peer.address` + +Peer address of the network connection - IP address or Unix domain socket name. + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +#### Attribute `network.peer.port` + +Peer port number of the network connection. + + +- Requirement Level: Optional + +- Tag: connection-level + +- Type: int +- Examples: [ + 65123, +] + +- Stability: Stable + + +#### Attribute `network.transport` + +[OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). + + + +The value SHOULD be normalized to lowercase. + +Consider always setting the transport when setting a port number, since +a port number is ambiguous without knowing the transport. For example +different processes could be listening on TCP port 12345 and UDP port 12345. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: Enum [tcp, udp, pipe, unix] +- Examples: [ + "tcp", + "udp", +] + +- Stability: Stable + + +#### Attribute `network.type` + +[OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. + + +The value SHOULD be normalized to lowercase. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: Enum [ipv4, ipv6] +- Examples: [ + "ipv4", + "ipv6", +] + +- Stability: Stable + + +#### Attribute `db.instance.id` + +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`. + + + +- Requirement Level: Optional + +- Tag: connection-level + +- Type: string +- Examples: mysql-e26b99z.example.com + + +#### Attribute `db.sql.table` + +The name of the primary table that the operation is acting upon, including the database name (if applicable). + + +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. + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific + +- Type: string +- Examples: [ + "public.users", + "customers", +] + + + +## Group `db.cosmosdb` (span) + +### Brief + +Call-level attributes for Cosmos DB. + + + +Prefix: db.cosmosdb +Kind: none + +### Attributes + + +#### Attribute `db.system` + +An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. + + +- Requirement Level: Required + +- Tag: connection-level + +- Type: Enum [other_sql, mssql, mssqlcompact, mysql, oracle, db2, postgresql, redshift, hive, cloudscape, hsqldb, progress, maxdb, hanadb, ingres, firstsql, edb, cache, adabas, firebird, derby, filemaker, informix, instantdb, interbase, mariadb, netezza, pervasive, pointbase, sqlite, sybase, teradata, vertica, h2, coldfusion, cassandra, hbase, mongodb, redis, couchbase, couchdb, cosmosdb, dynamodb, neo4j, geode, elasticsearch, memcached, cockroachdb, opensearch, clickhouse, spanner, trino] + + +#### Attribute `db.connection_string` + +The connection string used to connect to the database. It is recommended to remove embedded credentials. + + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: Server=(localdb)\v11.0;Integrated Security=true; + + +#### Attribute `db.user` + +Username for accessing the database. + + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "readonly_user", + "reporting_user", +] + + +#### Attribute `db.jdbc.driver_classname` + +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. + + + +- Requirement Level: Recommended + +- Tag: connection-level-tech-specific + +- Type: string +- Examples: [ + "org.postgresql.Driver", + "com.microsoft.sqlserver.jdbc.SQLServerDriver", +] + + +#### Attribute `db.name` + +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). + + + +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). + +- Requirement Level: Conditionally Required - If applicable. + +- Tag: call-level + +- Type: string +- Examples: [ + "customers", + "main", +] + + +#### Attribute `db.statement` + +The database statement being executed. + + + +- Requirement Level: Optional + +- Tag: call-level + +- Type: string +- Examples: [ + "SELECT * FROM wuser_table", + "SET mykey \"WuValue\"", +] + + +#### Attribute `db.operation` + +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. + + + +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. + +- Requirement Level: Conditionally Required - If `db.statement` is not applicable. + +- Tag: call-level + +- Type: string +- Examples: [ + "findAndModify", + "HMSET", + "SELECT", +] + + +#### Attribute `server.address` + +Name of the database host. + + + +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. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "example.com", + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +#### Attribute `server.port` + +Server port number. + + +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. + +- Requirement Level: Conditionally Required - If using a port other than the default port for this DBMS and if `server.address` is set. + +- Tag: connection-level + +- Type: int +- Examples: [ + 80, + 8080, + 443, +] + +- Stability: Stable + + +#### Attribute `network.peer.address` + +Peer address of the network connection - IP address or Unix domain socket name. + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +#### Attribute `network.peer.port` + +Peer port number of the network connection. + + +- Requirement Level: Optional + +- Tag: connection-level + +- Type: int +- Examples: [ + 65123, +] + +- Stability: Stable + + +#### Attribute `network.transport` + +[OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). + + + +The value SHOULD be normalized to lowercase. + +Consider always setting the transport when setting a port number, since +a port number is ambiguous without knowing the transport. For example +different processes could be listening on TCP port 12345 and UDP port 12345. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: Enum [tcp, udp, pipe, unix] +- Examples: [ + "tcp", + "udp", +] + +- Stability: Stable + + +#### Attribute `network.type` + +[OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. + + +The value SHOULD be normalized to lowercase. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: Enum [ipv4, ipv6] +- Examples: [ + "ipv4", + "ipv6", +] + +- Stability: Stable + + +#### Attribute `db.instance.id` + +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`. + + + +- Requirement Level: Optional + +- Tag: connection-level + +- Type: string +- Examples: mysql-e26b99z.example.com + + +#### Attribute `db.cosmosdb.client_id` + +Unique Cosmos client instance id. + + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific + +- Type: string +- Examples: 3ba4827d-4422-483f-b59f-85b74211c11d + + +#### Attribute `db.cosmosdb.operation_type` + +CosmosDB Operation Type. + + +- Requirement Level: Conditionally Required - when performing one of the operations in this list + +- Tag: call-level-tech-specific + +- Type: Enum [Invalid, Create, Patch, Read, ReadFeed, Delete, Replace, Execute, Query, Head, HeadFeed, Upsert, Batch, QueryPlan, ExecuteJavaScript] + + +#### Attribute `user_agent.original` + +Full user-agent string is generated by Cosmos DB SDK + + +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. + Format Reg-{D (Disabled discovery)}-S(application region)|L(List of preferred regions)|N(None, user did not configure it). + Default value is "NS". + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific + +- Type: string +- 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\\|", +] + +- Stability: Stable + + +#### Attribute `db.cosmosdb.connection_mode` + +Cosmos client connection mode. + + +- Requirement Level: Conditionally Required - if not `direct` (or pick gw as default) + +- Tag: call-level-tech-specific + +- Type: Enum [gateway, direct] + + +#### Attribute `db.cosmosdb.container` + +Cosmos DB container name. + + +- Requirement Level: Conditionally Required - if available + +- Tag: call-level-tech-specific + +- Type: string +- Examples: anystring + + +#### Attribute `db.cosmosdb.request_content_length` + +Request payload size in bytes + + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific + +- Type: int + + +#### Attribute `db.cosmosdb.status_code` + +Cosmos DB status code. + + +- Requirement Level: Conditionally Required - if response was received + +- Tag: call-level-tech-specific + +- Type: int +- Examples: [ + 200, + 201, +] + + +#### Attribute `db.cosmosdb.sub_status_code` + +Cosmos DB sub status code. + + +- Requirement Level: Conditionally Required - when response was received and contained sub-code. + +- Tag: call-level-tech-specific + +- Type: int +- Examples: [ + 1000, + 1002, +] + + +#### Attribute `db.cosmosdb.request_charge` + +RU consumed for that operation + + +- Requirement Level: Conditionally Required - when available + +- Tag: call-level-tech-specific + +- Type: double +- Examples: [ + 46.18, + 1.0, +] + + + +## Group `db.tech` (span) + +### Brief + +Semantic convention group for specific technologies + + + +Prefix: +Kind: none + +### Attributes + + +#### Attribute `db.system` + +An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. + + +- Requirement Level: Required + +- Tag: connection-level + +- Type: Enum [other_sql, mssql, mssqlcompact, mysql, oracle, db2, postgresql, redshift, hive, cloudscape, hsqldb, progress, maxdb, hanadb, ingres, firstsql, edb, cache, adabas, firebird, derby, filemaker, informix, instantdb, interbase, mariadb, netezza, pervasive, pointbase, sqlite, sybase, teradata, vertica, h2, coldfusion, cassandra, hbase, mongodb, redis, couchbase, couchdb, cosmosdb, dynamodb, neo4j, geode, elasticsearch, memcached, cockroachdb, opensearch, clickhouse, spanner, trino] + + +#### Attribute `db.connection_string` + +The connection string used to connect to the database. It is recommended to remove embedded credentials. + + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: Server=(localdb)\v11.0;Integrated Security=true; + + +#### Attribute `db.user` + +Username for accessing the database. + + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "readonly_user", + "reporting_user", +] + + +#### Attribute `db.jdbc.driver_classname` + +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. + + + +- Requirement Level: Recommended + +- Tag: connection-level-tech-specific + +- Type: string +- Examples: [ + "org.postgresql.Driver", + "com.microsoft.sqlserver.jdbc.SQLServerDriver", +] + + +#### Attribute `db.name` + +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). + + + +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). + +- Requirement Level: Conditionally Required - If applicable. + +- Tag: call-level + +- Type: string +- Examples: [ + "customers", + "main", +] + + +#### Attribute `db.statement` + +The database statement being executed. + + + +- Requirement Level: Optional + +- Tag: call-level + +- Type: string +- Examples: [ + "SELECT * FROM wuser_table", + "SET mykey \"WuValue\"", +] + + +#### Attribute `db.operation` + +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. + + + +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. + +- Requirement Level: Conditionally Required - If `db.statement` is not applicable. + +- Tag: call-level + +- Type: string +- Examples: [ + "findAndModify", + "HMSET", + "SELECT", +] + + +#### Attribute `server.address` + +Name of the database host. + + + +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. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "example.com", + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +#### Attribute `server.port` + +Server port number. + + +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. + +- Requirement Level: Conditionally Required - If using a port other than the default port for this DBMS and if `server.address` is set. + +- Tag: connection-level + +- Type: int +- Examples: [ + 80, + 8080, + 443, +] + +- Stability: Stable + + +#### Attribute `network.peer.address` + +Peer address of the network connection - IP address or Unix domain socket name. + + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: string +- Examples: [ + "10.1.2.80", + "/tmp/my.sock", +] + +- Stability: Stable + + +#### Attribute `network.peer.port` + +Peer port number of the network connection. + + +- Requirement Level: Optional + +- Tag: connection-level + +- Type: int +- Examples: [ + 65123, +] + +- Stability: Stable + + +#### Attribute `network.transport` + +[OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). + + + +The value SHOULD be normalized to lowercase. + +Consider always setting the transport when setting a port number, since +a port number is ambiguous without knowing the transport. For example +different processes could be listening on TCP port 12345 and UDP port 12345. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: Enum [tcp, udp, pipe, unix] +- Examples: [ + "tcp", + "udp", +] + +- Stability: Stable + + +#### Attribute `network.type` + +[OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. + + +The value SHOULD be normalized to lowercase. + +- Requirement Level: Recommended + +- Tag: connection-level + +- Type: Enum [ipv4, ipv6] +- Examples: [ + "ipv4", + "ipv6", +] + +- Stability: Stable + + +#### Attribute `db.instance.id` + +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`. + + + +- Requirement Level: Optional + +- Tag: connection-level + +- Type: string +- Examples: mysql-e26b99z.example.com + + +#### Attribute `db.name` + +The keyspace name in Cassandra. + + + +For Cassandra the `db.name` should be set to the Cassandra keyspace name. + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific-cassandra + +- Type: string +- Examples: [ + "mykeyspace", +] + + +#### Attribute `db.cassandra.page_size` + +The fetch size used for paging, i.e. how many rows will be returned at once. + + + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific-cassandra + +- Type: int +- Examples: [ + 5000, +] + + +#### Attribute `db.cassandra.consistency_level` + +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). + + + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific-cassandra + +- Type: Enum [all, each_quorum, quorum, local_quorum, one, two, three, local_one, any, serial, local_serial] + + +#### Attribute `db.cassandra.table` + +The name of the primary Cassandra table that the operation is acting upon, including the keyspace name (if applicable). + + +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. + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific-cassandra + +- Type: string +- Examples: mytable + + +#### Attribute `db.cassandra.idempotence` + +Whether or not the query is idempotent. + + + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific-cassandra + +- Type: boolean + + +#### Attribute `db.cassandra.speculative_execution_count` + +The number of times a query was speculatively executed. Not set or `0` if the query was not executed speculatively. + + + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific-cassandra + +- Type: int +- Examples: [ + 0, + 2, +] + + +#### Attribute `db.cassandra.coordinator.id` + +The ID of the coordinating node for a query. + + + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific-cassandra + +- Type: string +- Examples: be13faa2-8574-4d71-926d-27f16cf8a7af + + +#### Attribute `db.cassandra.coordinator.dc` + +The data center of the coordinating node for a query. + + + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific-cassandra + +- Type: string +- Examples: us-west-2 + + +#### Attribute `db.redis.database_index` + +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. + + + +- Requirement Level: Conditionally Required - If other than the default database (`0`). + +- Tag: call-level-tech-specific + +- Type: int +- Examples: [ + 0, + 1, + 15, +] + + +#### Attribute `db.statement` + +The full syntax of the Redis CLI command. + + + +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`. + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific + +- Type: string +- Examples: [ + "HMSET myhash field1 'Hello' field2 'World'", +] + + +#### Attribute `db.mongodb.collection` + +The MongoDB collection being accessed within the database stated in `db.name`. + + + +- Requirement Level: Required + +- Tag: call-level-tech-specific + +- Type: string +- Examples: [ + "customers", + "products", +] + + +#### Attribute `db.sql.table` + +The name of the primary table that the operation is acting upon, including the database name (if applicable). + + +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. + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific + +- Type: string +- Examples: [ + "public.users", + "customers", +] + + +#### Attribute `db.cosmosdb.client_id` + +Unique Cosmos client instance id. + + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific + +- Type: string +- Examples: 3ba4827d-4422-483f-b59f-85b74211c11d + + +#### Attribute `db.cosmosdb.operation_type` + +CosmosDB Operation Type. + + +- Requirement Level: Conditionally Required - when performing one of the operations in this list + +- Tag: call-level-tech-specific + +- Type: Enum [Invalid, Create, Patch, Read, ReadFeed, Delete, Replace, Execute, Query, Head, HeadFeed, Upsert, Batch, QueryPlan, ExecuteJavaScript] + + +#### Attribute `user_agent.original` + +Full user-agent string is generated by Cosmos DB SDK + + +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. + Format Reg-{D (Disabled discovery)}-S(application region)|L(List of preferred regions)|N(None, user did not configure it). + Default value is "NS". + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific + +- Type: string +- 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\\|", +] + +- Stability: Stable + + +#### Attribute `db.cosmosdb.connection_mode` + +Cosmos client connection mode. + + +- Requirement Level: Conditionally Required - if not `direct` (or pick gw as default) + +- Tag: call-level-tech-specific + +- Type: Enum [gateway, direct] + + +#### Attribute `db.cosmosdb.container` + +Cosmos DB container name. + + +- Requirement Level: Conditionally Required - if available + +- Tag: call-level-tech-specific + +- Type: string +- Examples: anystring + + +#### Attribute `db.cosmosdb.request_content_length` + +Request payload size in bytes + + +- Requirement Level: Recommended + +- Tag: call-level-tech-specific + +- Type: int + + +#### Attribute `db.cosmosdb.status_code` + +Cosmos DB status code. + + +- Requirement Level: Conditionally Required - if response was received + +- Tag: call-level-tech-specific + +- Type: int +- Examples: [ + 200, + 201, +] + + +#### Attribute `db.cosmosdb.sub_status_code` + +Cosmos DB sub status code. + + +- Requirement Level: Conditionally Required - when response was received and contained sub-code. + +- Tag: call-level-tech-specific + +- Type: int +- Examples: [ + 1000, + 1002, +] + + +#### Attribute `db.cosmosdb.request_charge` + +RU consumed for that operation + + +- Requirement Level: Conditionally Required - when available + +- Tag: call-level-tech-specific + +- Type: double +- Examples: [ + 46.18, + 1.0, +] + + + \ No newline at end of file diff --git a/crates/weaver_forge/src/extensions/attributes.rs b/crates/weaver_forge/src/extensions/attributes.rs deleted file mode 100644 index b5e9e70e..00000000 --- a/crates/weaver_forge/src/extensions/attributes.rs +++ /dev/null @@ -1,9 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 - -//! - -use minijinja::{Error, State, Value}; - -pub fn attributes(_state: &State, v: Value) -> Result { - Ok(v) -} diff --git a/crates/weaver_forge/src/extensions/mod.rs b/crates/weaver_forge/src/extensions/mod.rs index 1c28856e..a7dbebee 100644 --- a/crates/weaver_forge/src/extensions/mod.rs +++ b/crates/weaver_forge/src/extensions/mod.rs @@ -1,5 +1,4 @@ // SPDX-License-Identifier: Apache-2.0 //! Custom filters used by the template engine. -pub mod attributes; pub mod case_converter; diff --git a/crates/weaver_forge/src/lib.rs b/crates/weaver_forge/src/lib.rs index 1de90086..c1939c20 100644 --- a/crates/weaver_forge/src/lib.rs +++ b/crates/weaver_forge/src/lib.rs @@ -33,7 +33,6 @@ use weaver_resolved_schema::registry::Registry; use weaver_semconv::group::GroupType; use crate::config::TargetConfig; -use crate::extensions::attributes::attributes; use crate::extensions::case_converter::case_converter; use crate::registry::{TemplateGroup, TemplateRegistry}; use crate::Error::{ @@ -379,8 +378,6 @@ impl TemplateEngine { case_converter(self.target_config.field_name.clone()), ); - env.add_filter("attributes", attributes); - // env.add_filter("unique_attributes", extensions::unique_attributes); // env.add_filter("instrument", extensions::instrument); // env.add_filter("required", extensions::required); @@ -668,6 +665,10 @@ impl TemplateEngine { #[cfg(test)] mod tests { + use std::collections::HashSet; + use std::fs; + use std::path::Path; + use walkdir::WalkDir; use weaver_logger::TestLogger; use weaver_resolver::SchemaResolver; use weaver_semconv::SemConvRegistry; @@ -689,13 +690,54 @@ mod tests { logger, &schema.registries[0], &schema.catalog, - "output".into(), + "observed_output".into(), ) .expect("Failed to generate registry assets"); - // let mut env = Environment::new(); - // env.add_template("hello.txt", "Hello {{ name }}!").unwrap(); - // let template = env.get_template("hello.txt").unwrap(); - // println!("{}", template.render(context! { name => "World" }).unwrap()); + assert!(cmp_dir("expected_output", "observed_output").unwrap()); + } + + fn cmp_dir>(expected_dir: P, observed_dir: P) -> std::io::Result { + let mut expected_files = HashSet::new(); + let mut observed_files = HashSet::new(); + + // Walk through the first directory and add files to files1 set + for entry in WalkDir::new(&expected_dir).into_iter().filter_map(|e| e.ok()) { + let path = entry.path(); + if path.is_file() { + let relative_path = path.strip_prefix(&expected_dir).unwrap(); + _ = expected_files.insert(relative_path.to_path_buf()); + } + } + + // Walk through the second directory and add files to files2 set + for entry in WalkDir::new(&observed_dir).into_iter().filter_map(|e| e.ok()) { + let path = entry.path(); + if path.is_file() { + let relative_path = path.strip_prefix(&observed_dir).unwrap(); + _ = observed_files.insert(relative_path.to_path_buf()); + } + } + + // Assume directories are identical until proven otherwise + let mut are_identical = true; + + // Compare files in both sets + for file in expected_files.intersection(&observed_files) { + let file1_content = fs::read_to_string(expected_dir.as_ref().join(file))?; + let file2_content = fs::read_to_string(observed_dir.as_ref().join(file))?; + + if file1_content != file2_content { + are_identical = false; + break; + } + } + + // If any file is unique to one directory, they are not identical + if !expected_files.difference(&observed_files).collect::>().is_empty() || !observed_files.difference(&expected_files).collect::>().is_empty() { + are_identical = false; + } + + Ok(are_identical) } } diff --git a/crates/weaver_resolver/Cargo.toml b/crates/weaver_resolver/Cargo.toml index 632f5c4f..2d2e81fe 100644 --- a/crates/weaver_resolver/Cargo.toml +++ b/crates/weaver_resolver/Cargo.toml @@ -19,9 +19,9 @@ regex.workspace = true thiserror.workspace = true rayon.workspace = true serde_json.workspace = true +walkdir.workspace = true url = "2.5.0" -walkdir = "2.4.0" serde = { version = "1.0.196", features = ["derive"] } [dev-dependencies] From 45697ef374366bb6c0ebcee839b5c9706b047d86 Mon Sep 17 00:00:00 2001 From: Laurent Querel Date: Wed, 6 Mar 2024 23:24:43 -0800 Subject: [PATCH 17/20] feature(registry): improve unit test to check the generated markdown --- crates/weaver_forge/src/lib.rs | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/crates/weaver_forge/src/lib.rs b/crates/weaver_forge/src/lib.rs index c1939c20..75844dd6 100644 --- a/crates/weaver_forge/src/lib.rs +++ b/crates/weaver_forge/src/lib.rs @@ -702,7 +702,10 @@ mod tests { let mut observed_files = HashSet::new(); // Walk through the first directory and add files to files1 set - for entry in WalkDir::new(&expected_dir).into_iter().filter_map(|e| e.ok()) { + for entry in WalkDir::new(&expected_dir) + .into_iter() + .filter_map(|e| e.ok()) + { let path = entry.path(); if path.is_file() { let relative_path = path.strip_prefix(&expected_dir).unwrap(); @@ -711,7 +714,10 @@ mod tests { } // Walk through the second directory and add files to files2 set - for entry in WalkDir::new(&observed_dir).into_iter().filter_map(|e| e.ok()) { + for entry in WalkDir::new(&observed_dir) + .into_iter() + .filter_map(|e| e.ok()) + { let path = entry.path(); if path.is_file() { let relative_path = path.strip_prefix(&observed_dir).unwrap(); @@ -729,12 +735,25 @@ mod tests { if file1_content != file2_content { are_identical = false; + eprintln!( + "Files {:?} and {:?} are different", + expected_dir.as_ref().join(file), + observed_dir.as_ref().join(file) + ); break; } } // If any file is unique to one directory, they are not identical - if !expected_files.difference(&observed_files).collect::>().is_empty() || !observed_files.difference(&expected_files).collect::>().is_empty() { + if !expected_files + .difference(&observed_files) + .collect::>() + .is_empty() + || !observed_files + .difference(&expected_files) + .collect::>() + .is_empty() + { are_identical = false; } From 8d789de92dbccb812a39735faaa3545591e1d40a Mon Sep 17 00:00:00 2001 From: Laurent Querel Date: Thu, 7 Mar 2024 10:17:13 -0800 Subject: [PATCH 18/20] doc(template): add documentation to describe the template engine. --- README.md | 1 + docs/template-engine.md | 152 ++++++++++++++++++++++++++++++++++++++++ docs/template.md | 51 -------------- 3 files changed, 153 insertions(+), 51 deletions(-) create mode 100644 docs/template-engine.md delete mode 100644 docs/template.md diff --git a/README.md b/README.md index 213ece0e..adafd45d 100644 --- a/README.md +++ b/README.md @@ -186,6 +186,7 @@ Below is a diagram detailing the primary components of the OpenTelemetry Weaver ## Links Internal links: +- [Template Engine](docs/template-engine.md) - [Component Telemetry Schema](docs/component-telemetry-schema.md) (proposal) - [Resolved Telemetry Schema](docs/resolved-telemetry-schema.md) (proposal) - [Internal crates interdependencies](docs/dependencies.md) diff --git a/docs/template-engine.md b/docs/template-engine.md new file mode 100644 index 00000000..734ebdcc --- /dev/null +++ b/docs/template-engine.md @@ -0,0 +1,152 @@ +# Template Engine + +OTel Weaver is capable of generating documentation or code from a semantic +convention registry or a telemetry schema (not yet implemented). To do this, +OTel Weaver uses a template engine compatible with the Jinja2 syntax (see the +[MiniJinja](https://github.com/mitsuhiko/minijinja) project for more details). +A set of filters, functions, tests, and naming conventions have been added to +the classic Jinja logic to make the task easier for template authors. + +## Template Directory Structure and Naming Conventions + +By default, the OTel Weaver tool expects to find a templates directory in the +current directory. + +```plaintext +templates/ + registry/ + markdown/ <-- All the files in this directory are optional + attribute_group.md <-- will be evaluated for each attribute group + attribute_groups.md <-- will be evaluated once with all attribute groups + event.md <-- will be evaluated for each event + events.md <-- will be evaluated once with all events + group.md <-- will be evaluated for each group + groups.md <-- will be evaluated once with all groups + metric.md <-- will be evaluated for each metric + metrics.md <-- will be evaluated once with all metrics + metric_group.md <-- will be evaluated for each metric group + metric_groups.md <-- will be evaluated once with all metric groups + registry.md <-- will be evaluated once with the entire registry + resource.md <-- will be evaluated for each resource + resources.md <-- will be evaluated once with all resources + scope.md <-- will be evaluated for each scope + scopes.md <-- will be evaluated once with all scopes + span.md <-- will be evaluated for each span + spans.md <-- will be evaluated once with all spans + weaver.yaml <-- weaver configuration file (optional) + any_other_name.md <-- will be evaluated once with the entire registry + any_sub_dir/ <-- By default outputs to the same directory structure + any_file.md <-- will be evaluated once with the entire registry + html/ + ... + schema/ + sdk-go/ + ... + sdk-rust/ + ... +``` + +The command `weaver generate registry markdown` will generate the markdown +files. + +When the name of a file (excluding the extension) matches a recognized pattern +(e.g., attribute_group, groups, ...), OTel Weaver extracts the objects from the +registry and passes them to the template at the time of its evaluation. +Depending on the nature of the pattern, the template is evaluated as many times +as there are objects that match or only once if the pattern corresponds to a +set of objects. By default, the name of the file that will be generated from +the template will be that of the template, but it is possible within the +template to dynamically redefine the name of the produced file. + +For example, the following snippet redefine the name of the file that will be +produced from the template: + +```jinja +{%- set file_name = group.id | file_name -%} +{{- template.set_file_name("span/" ~ file_name ~ ".md") -}} +``` + +> Note: Other naming conventions might be introduced in the future to facilitate +the generation of assets (e.g., groups_per_prefix.md could be used to call the +template with a list of groups sharing the same prefix). + +## Configuration File + +The configuration file `weaver.yaml` is optional. It allows configuring the +following options: + +```yaml +# Configuration of the naming convention filters. This is optional. +# Example: {{ group.id | file_name }} will be evaluated as group_id +file_name: snake_case +function_name: PascalCase +arg_name: camelCase +struct_name: PascalCase +field_name: PascalCase + +# Configuration of the type mapping. This is useful to generate code in a +# specific language. This is optional. +# Example: {{ attribute.type | type_mapping }} will be evaluated as int64 +# if the semconv attribute type is int. +type_mapping: + int: int64 + double: double + boolean: bool + string: string + "int[]": "[]int64" + "double[]": "[]double" + "boolean[]": "[]bool" + "string[]": "[]string" + # other mappings... + +# Configuration of the template engine (optional) +template_syntax: + block_start: "{%" + block_end: "%}" + variable_start: "{{" + variable_end: "}}" + comment_start: "{#" + comment_end: "#}" +``` + +Supported case converters: +- lowercase +- UPPERCASE +- PascalCase +- camelCase +- snake_case +- SCREAMING_SNAKE_CASE +- kebab-case +- SCREAMING-KEBAB-CASE + +## Custom Filters + +All the filters available in the MiniJinja template engine are available. In +addition, OTel Weaver provides a set of custom filters to facilitate the +generation of assets. + +The following filters are available: +- `file_name`: Converts a string to a file name. +- `function_name`: Converts a string to a function name. +- `arg_name`: Converts a string to an argument name. +- `struct_name`: Converts a string to a struct name. +- `field_name`: Converts a string to a field name. +- `type_mapping`: Converts a semantic convention type to a language type. + +> Note: Other filters might be introduced in the future. + +## Custom Functions + +All the functions available in the MiniJinja template engine are available. In +addition, OTel Weaver provides a set of custom functions to facilitate the +generation of assets. + +Not yet implemented. + +## Custom Tests + +All the tests available in the MiniJinja template engine are available. In +addition, OTel Weaver provides a set of custom tests to facilitate the +generation of assets. + +Not yet implemented. \ No newline at end of file diff --git a/docs/template.md b/docs/template.md deleted file mode 100644 index b86df8ac..00000000 --- a/docs/template.md +++ /dev/null @@ -1,51 +0,0 @@ -# Template - -## Description - -Based on the template engine [Tera](https://keats.github.io/tera/) (inspired by Jinja2 and Django templates). - -## Custom Filters - -format filters - -### file_name -Format the value as a file name based on the config.yaml file -defined in the root of the template directory for a given language. - -### function_name -Format the value as a function name based on the config.yaml file -defined in the root of the template directory for a given language. - -### arg_name -Format the value as a function argument name based on the config.yaml file -defined in the root of the template directory for a given language. - -### struct_name -Format the value as a struct name based on the config.yaml file -defined in the root of the template directory for a given language. - -### field_name -Format the value as a field name based on the config.yaml file -defined in the root of the template directory for a given language. - -### unique_attributes - -ToDo attributes(recursive=true, required=true, unique=true, not_required=true, with_value=true, without_value=true) - -### instrument -### required -### not_required -### value -### with_value -### without_value -### comment -### type_mapping - -## Custom Functions - -config - -## Customer Testers - -required -not_required From 7eece9827b4248c252d3a34343cd22c2b83d117c Mon Sep 17 00:00:00 2001 From: Laurent Querel Date: Thu, 7 Mar 2024 10:19:31 -0800 Subject: [PATCH 19/20] chore(build): update cargo lock --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 175ac67b..b5605e1f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -209,9 +209,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.15.3" +version = "3.15.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ea184aa71bb362a1157c896979544cc23974e08fd265f29ea96b59f0b4a555b" +checksum = "7ff69b9dd49fd426c69a0db9fc04dd934cdb6645ff000864d98f7e2af8830eaa" [[package]] name = "byteorder" From 935aed183440c4bc0d9be98ff57b949399b7b736 Mon Sep 17 00:00:00 2001 From: Laurent Querel Date: Fri, 8 Mar 2024 08:57:05 -0800 Subject: [PATCH 20/20] chore(build): fix merge issue. --- Cargo.lock | 6 +++--- Cargo.toml | 2 +- crates/weaver_resolver/Cargo.toml | 3 +-- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e6cbf176..61f83429 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -528,7 +528,7 @@ dependencies = [ "proc-macro2", "quote", "strsim 0.10.0", - "syn 2.0.51", + "syn 2.0.52", ] [[package]] @@ -539,7 +539,7 @@ checksum = "a668eda54683121533a393014d8692171709ff57a7d61f187b6e782719f8933f" dependencies = [ "darling_core", "quote", - "syn 2.0.51", + "syn 2.0.52", ] [[package]] @@ -3704,7 +3704,7 @@ dependencies = [ "proc-macro2", "quote", "regex", - "syn 2.0.51", + "syn 2.0.52", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 709dd388..0366ed5c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -54,7 +54,7 @@ weaver_semconv = { path = "crates/weaver_semconv" } weaver_schema = { path = "crates/weaver_schema" } weaver_cache = { path = "crates/weaver_cache" } -clap = { version = "4.5.1", features = ["derive"] } +clap = { version = "4.5.2", features = ["derive"] } crossterm = "0.27.0" ratatui = "0.26.1" tui-textarea = "0.4.0" diff --git a/crates/weaver_resolver/Cargo.toml b/crates/weaver_resolver/Cargo.toml index 278f039c..b3fb8729 100644 --- a/crates/weaver_resolver/Cargo.toml +++ b/crates/weaver_resolver/Cargo.toml @@ -22,8 +22,7 @@ serde_json.workspace = true walkdir.workspace = true url = "2.5.0" -walkdir = "2.5.0" -serde = { version = "1.0.196", features = ["derive"] } +serde = { version = "1.0.197", features = ["derive"] } [dev-dependencies] glob = "0.3.1" \ No newline at end of file