From cb9cd58c4bd589cfd9785c6d156da6a9aef3bd92 Mon Sep 17 00:00:00 2001 From: Laurent Querel Date: Fri, 5 Jul 2024 21:51:10 -0700 Subject: [PATCH 01/29] feat(forge): Support hierarchical weaver config --- Cargo.lock | 1 + Cargo.toml | 1 + Dockerfile | 2 +- crates/weaver_forge/Cargo.toml | 1 + crates/weaver_forge/src/config.rs | 193 ++++++++++++++++-- crates/weaver_forge/src/extensions/case.rs | 8 +- crates/weaver_forge/src/extensions/code.rs | 8 +- crates/weaver_forge/src/extensions/util.rs | 6 +- crates/weaver_forge/src/lib.rs | 91 +++++---- .../templates/registry/test/weaver.yaml | 0 .../templates/registry/weaver.yaml | 0 .../diagnostic_templates}/ansi/errors.txt.j2 | 0 .../diagnostic_templates}/ansi/weaver.yaml | 0 .../gh_workflow_command/errors.txt.j2 | 0 .../gh_workflow_command/weaver.yaml | 0 .../diagnostic_templates}/json/errors.json.j2 | 0 .../diagnostic_templates}/json/weaver.yaml | 0 defaults/weaver_config/weaver.yaml | 22 ++ src/diagnostic/mod.rs | 2 +- 19 files changed, 265 insertions(+), 70 deletions(-) create mode 100644 crates/weaver_forge/templates/registry/test/weaver.yaml create mode 100644 crates/weaver_forge/templates/registry/weaver.yaml rename {default_diagnostic_templates => defaults/diagnostic_templates}/ansi/errors.txt.j2 (100%) rename {default_diagnostic_templates => defaults/diagnostic_templates}/ansi/weaver.yaml (100%) rename {default_diagnostic_templates => defaults/diagnostic_templates}/gh_workflow_command/errors.txt.j2 (100%) rename {default_diagnostic_templates => defaults/diagnostic_templates}/gh_workflow_command/weaver.yaml (100%) rename {default_diagnostic_templates => defaults/diagnostic_templates}/json/errors.json.j2 (100%) rename {default_diagnostic_templates => defaults/diagnostic_templates}/json/weaver.yaml (100%) create mode 100644 defaults/weaver_config/weaver.yaml diff --git a/Cargo.lock b/Cargo.lock index b7d05e64..babc4219 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3907,6 +3907,7 @@ name = "weaver_forge" version = "0.5.0" dependencies = [ "convert_case", + "dirs", "globset", "include_dir", "indexmap", diff --git a/Cargo.toml b/Cargo.toml index f6720eb6..6322812b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -52,6 +52,7 @@ miette = { version = "7.2.0", features = ["fancy", "serde"] } include_dir = "0.7.4" tempdir = "0.3.7" schemars = "0.8.21" +dirs = "5.0.1" # Features definition ========================================================= [features] diff --git a/Dockerfile b/Dockerfile index 5cc108aa..45ff3d65 100644 --- a/Dockerfile +++ b/Dockerfile @@ -11,7 +11,7 @@ COPY crates /build/crates COPY data /build/data COPY src /build/src COPY tests /build/tests -COPY default_diagnostic_templates /build/default_diagnostic_templates +COPY defaults /build/defaults # Don't build release, so we get template debugging output. RUN cargo build diff --git a/crates/weaver_forge/Cargo.toml b/crates/weaver_forge/Cargo.toml index 1a852d69..57f05a28 100644 --- a/crates/weaver_forge/Cargo.toml +++ b/crates/weaver_forge/Cargo.toml @@ -39,6 +39,7 @@ globset.workspace = true miette.workspace = true include_dir.workspace = true schemars.workspace = true +dirs.workspace = true [dev-dependencies] opentelemetry = { version = "0.22.0", features = ["trace", "metrics", "logs", "otel_unstable"] } diff --git a/crates/weaver_forge/src/config.rs b/crates/weaver_forge/src/config.rs index 545ba608..1cf64b72 100644 --- a/crates/weaver_forge/src/config.rs +++ b/crates/weaver_forge/src/config.rs @@ -1,13 +1,13 @@ // SPDX-License-Identifier: Apache-2.0 -//! Configuration for the template crate. +//! Weaver Configuration Definition. use std::collections::HashMap; -use std::path::Path; +use std::path::{Path, PathBuf}; use std::sync::OnceLock; -use convert_case::Boundary::{DigitLower, DigitUpper, Hyphen, LowerDigit, Space, UpperDigit}; use convert_case::{Case, Casing, Converter, Pattern}; +use convert_case::Boundary::{DigitLower, DigitUpper, Hyphen, LowerDigit, Space, UpperDigit}; use globset::{Glob, GlobSet, GlobSetBuilder}; use serde::Deserialize; use serde_yaml::Value; @@ -17,6 +17,8 @@ use crate::error::Error::InvalidConfigFile; use crate::file_loader::FileLoader; use crate::WEAVER_YAML; +const DEFAULT_WEAVER_CONFIG: &'static str = include_str!("../../../defaults/weaver_config/weaver.yaml"); + /// Case convention for naming of functions and structs. #[derive(Deserialize, Clone, Debug)] #[allow(clippy::enum_variant_names)] @@ -50,9 +52,9 @@ pub enum CaseConvention { ScreamingKebabCase, } -/// Target specific configuration. +/// Weaver configuration. #[derive(Deserialize, Debug, Default)] -pub(crate) struct TargetConfig { +pub(crate) struct WeaverConfig { /// Case convention used to name a file. #[serde(default)] pub(crate) file_name: CaseConvention, @@ -69,11 +71,10 @@ pub(crate) struct TargetConfig { #[serde(default)] pub(crate) field_name: CaseConvention, /// Type mapping for target specific types (OTel types -> Target language types). - #[serde(default)] - pub(crate) type_mapping: HashMap, + /// Deprecated: Use `text_maps` instead. + pub(crate) type_mapping: Option>, /// Configuration of the `text_map` filter. - #[serde(default)] - pub(crate) text_maps: HashMap>, + pub(crate) text_maps: Option>>, /// Configuration for the template syntax. #[serde(default)] pub(crate) template_syntax: TemplateSyntax, @@ -83,8 +84,7 @@ pub(crate) struct TargetConfig { /// Parameters for the templates. /// These parameters can be overridden by parameters passed to the CLI. - #[serde(default)] - pub(crate) params: HashMap, + pub(crate) params: Option>, /// Configuration for the templates. #[serde(default = "default_templates")] @@ -92,8 +92,7 @@ pub(crate) struct TargetConfig { /// List of acronyms to be considered as unmodifiable words in the case /// conversion. - #[serde(default)] - pub(crate) acronyms: Vec, + pub(crate) acronyms: Option>, } fn default_templates() -> Vec { @@ -301,6 +300,20 @@ impl Default for TemplateSyntax { } } +impl TemplateSyntax { + /// Override the current `TemplateSyntax` with the `TemplateSyntax` passed as argument. + /// The merge is done in place. The `TemplateSyntax` passed as argument will be consumed and + /// used to override the current `TemplateSyntax`. + pub fn override_with(&mut self, other: TemplateSyntax) { + self.block_start = other.block_start; + self.block_end = other.block_end; + self.variable_start = other.variable_start; + self.variable_end = other.variable_end; + self.comment_start = other.comment_start; + self.comment_end = other.comment_end; + } +} + /// Whitespace control configuration for the template engine. #[derive(Deserialize, Debug, Clone, Default)] pub struct WhitespaceControl { @@ -315,6 +328,17 @@ pub struct WhitespaceControl { pub keep_trailing_newline: bool, } +impl WhitespaceControl { + /// Override the current `WhitespaceControl` with the `WhitespaceControl` passed as argument. + /// The merge is done in place. The `WhitespaceControl` passed as argument will be consumed and + /// used to override the current `WhitespaceControl`. + pub fn override_with(&mut self, other: WhitespaceControl) { + self.trim_blocks = other.trim_blocks; + self.lstrip_blocks = other.lstrip_blocks; + self.keep_trailing_newline = other.keep_trailing_newline; + } +} + impl Default for CaseConvention { /// Default case convention is PascalCase fn default() -> Self { @@ -387,8 +411,8 @@ impl CaseConvention { } } -impl TargetConfig { - pub(crate) fn try_new(loader: &dyn FileLoader) -> Result { +impl WeaverConfig { + pub(crate) fn try_new(loader: &dyn FileLoader) -> Result { let weaver_file = loader .load_file(WEAVER_YAML) .map_err(|e| InvalidConfigFile { @@ -401,8 +425,59 @@ impl TargetConfig { error: e.to_string(), }) } else { - Ok(TargetConfig::default()) + Ok(WeaverConfig::default()) + } + } + + /// Loads the Weaver configuration based on the following order: + /// + /// - the target directory, + /// - the parent directory (i.e., the directory containing all targets), + /// - the $HOME/.weaver/weaver.yaml directory, + /// - and finally the defaults/weaver_config directory embedded in the Weaver binary. + /// + /// A local definition should override any corresponding definition in the parent directory, + /// which itself can override the corresponding entry in the home directory (i.e., defined per + /// user), and finally, the Weaver application binary (i.e., defined by Weaver authors). This + /// hierarchical structure should allow for configuration at the target level, across all + /// targets, at the user level, and even reuse of configurations defined within the Weaver + /// application binary. + /// + /// This method can fail if any of the configuration file is not a valid YAML file or if the + /// configuration file can't be deserialized into a `WeaverConfig` struct. + pub(crate) fn try_new_2(home_dir: Option, loader: &dyn FileLoader) -> Result { + // Init the weaver config with the embedded defaults + let mut config = serde_yaml::from_str(DEFAULT_WEAVER_CONFIG).map_err(|e| InvalidConfigFile { + config_file: WEAVER_YAML.into(), + error: e.to_string(), + })?; + + // Override the defaults with the weaver.yaml file present in the user's home directory + // if it exists. + if let Some(home_dir) = home_dir { + let home_config = home_dir.join(".weaver/weaver.yaml"); + if home_config.exists() { + let home_config_file = std::fs::File::open(home_config.clone()).map_err(|e| InvalidConfigFile { + config_file: home_config.clone(), + error: e.to_string(), + })?; + let home_config: WeaverConfig = serde_yaml::from_reader(home_config_file) + .map_err(|e| InvalidConfigFile { + config_file: home_config.clone(), + error: e.to_string(), + })?; + } } + + // Override the config with the weaver.yaml file present in the parent directory of the + // target directory if it exists. + + // Override the config with the weaver.yaml file present in the target directory if it + // exists. + // deserialize in place, i.e. in the existing config + + + Ok(config) } /// Return a template matcher for the target configuration. @@ -423,4 +498,90 @@ impl TargetConfig { glob_set, }) } + + /// Override the current `WeaverConfig` with the `WeaverConfig` passed as argument. + /// The merge is done in place. The `WeaverConfig` passed as argument will be consumed and used + /// to override the current `WeaverConfig`. + pub fn override_with(&mut self, other: WeaverConfig) { + self.file_name = other.file_name; + self.function_name = other.function_name; + self.arg_name = other.arg_name; + self.struct_name = other.struct_name; + self.field_name = other.field_name; + if other.type_mapping.is_some() { + self.type_mapping = other.type_mapping; + } + if other.text_maps.is_some() { + self.text_maps = other.text_maps; + } + self.template_syntax.override_with(other.template_syntax); + self.whitespace_control.override_with(other.whitespace_control); + if other.params.is_some() { + self.params = other.params; + } + self.templates = other.templates; + if other.acronyms.is_some() { + self.acronyms = other.acronyms; + } + } } + +#[cfg(test)] +mod tests { + use std::collections::HashMap; + use crate::config::{DEFAULT_WEAVER_CONFIG, WeaverConfig}; + use crate::file_loader::FileSystemFileLoader; + + #[test] + fn test_override_with() { + // Tests params overrides. + // If defined in both, the local configuration should override the parent configuration. + let mut parent: WeaverConfig = serde_yaml::from_str("params: {a: 1, b: 2}").unwrap(); + let local: WeaverConfig = serde_yaml::from_str("params: {a: 3}").unwrap(); + parent.override_with(local); + assert_eq!(parent.params, Some([("a".to_owned(), 3.into())].iter().cloned().collect())); + let mut parent: WeaverConfig = WeaverConfig::default(); + let local: WeaverConfig = serde_yaml::from_str("params: {a: 3}").unwrap(); + parent.override_with(local); + assert_eq!(parent.params, Some([("a".to_owned(), 3.into())].iter().cloned().collect())); + let mut parent: WeaverConfig = serde_yaml::from_str("params: {a: 1, b: 2}").unwrap(); + let local= WeaverConfig::default(); + parent.override_with(local); + assert_eq!(parent.params, Some([("a".to_owned(), 1.into()), ("b".to_owned(), 2.into())].iter().cloned().collect())); + let mut parent: WeaverConfig = serde_yaml::from_str("params: {a: 1, b: 2}").unwrap(); + let local: WeaverConfig = serde_yaml::from_str("params: {}").unwrap(); + parent.override_with(local); + assert_eq!(parent.params, Some(HashMap::default())); + + // Tests templates overrides. + + // Tests acronyms overrides. + // If defined in both, the local configuration should override the parent configuration. + let mut parent: WeaverConfig = serde_yaml::from_str("acronyms: ['iOS', 'API', 'URL']").unwrap(); + let local: WeaverConfig = serde_yaml::from_str("acronyms: ['iOS']").unwrap(); + parent.override_with(local); + assert_eq!(parent.acronyms, Some(vec!["iOS".to_owned()])); + let mut parent = WeaverConfig::default(); + let local: WeaverConfig = serde_yaml::from_str("acronyms: ['iOS', 'API', 'URL']").unwrap(); + parent.override_with(local); + assert_eq!(parent.acronyms, Some(vec!["iOS".to_owned(), "API".to_owned(), "URL".to_owned()])); + let mut parent: WeaverConfig = serde_yaml::from_str("acronyms: ['iOS', 'API', 'URL']").unwrap(); + let local = WeaverConfig::default(); + parent.override_with(local); + assert_eq!(parent.acronyms, Some(vec!["iOS".to_owned(), "API".to_owned(), "URL".to_owned()])); + let mut parent: WeaverConfig = serde_yaml::from_str("acronyms: ['iOS', 'API', 'URL']").unwrap(); + let local: WeaverConfig = serde_yaml::from_str("acronyms: []").unwrap(); + parent.override_with(local); + assert_eq!(parent.acronyms, Some(vec![])); + } + + #[test] + fn test_try_new() -> Result<(), Box> { + let loader = FileSystemFileLoader::try_new("templates/registry".into(), "test")?; + let config = WeaverConfig::try_new_2(dirs::home_dir(), &loader) + .expect("Failed to load the Weaver configuration"); + + dbg!(config); + Ok(()) + } +} \ No newline at end of file diff --git a/crates/weaver_forge/src/extensions/case.rs b/crates/weaver_forge/src/extensions/case.rs index 064ad31d..a6c49b5f 100644 --- a/crates/weaver_forge/src/extensions/case.rs +++ b/crates/weaver_forge/src/extensions/case.rs @@ -2,11 +2,11 @@ //! Case converter filters used by the template engine. -use crate::config::{CaseConvention, TargetConfig}; +use crate::config::{CaseConvention, WeaverConfig}; use minijinja::Environment; /// Add case converter filters to the environment. -pub(crate) fn add_filters(env: &mut Environment<'_>, target_config: &TargetConfig) { +pub(crate) fn add_filters(env: &mut Environment<'_>, target_config: &WeaverConfig) { env.add_filter("lower_case", case_converter(CaseConvention::LowerCase)); env.add_filter("upper_case", case_converter(CaseConvention::UpperCase)); env.add_filter("title_case", case_converter(CaseConvention::TitleCase)); @@ -121,13 +121,13 @@ pub(crate) fn capitalize_first(input: &str) -> String { #[cfg(test)] mod tests { - use crate::config::TargetConfig; + use crate::config::WeaverConfig; use crate::extensions::case::add_filters; use minijinja::Environment; #[test] fn test_case_converter() { - let target_config = TargetConfig::default(); + let target_config = WeaverConfig::default(); let mut env = Environment::new(); let ctx = serde_json::Value::Null; diff --git a/crates/weaver_forge/src/extensions/code.rs b/crates/weaver_forge/src/extensions/code.rs index 5f4b4fcc..007344a4 100644 --- a/crates/weaver_forge/src/extensions/code.rs +++ b/crates/weaver_forge/src/extensions/code.rs @@ -4,13 +4,13 @@ use std::collections::HashMap; -use crate::config::TargetConfig; +use crate::config::WeaverConfig; use minijinja::{Environment, Value}; /// Add code-oriented filters to the environment. -pub(crate) fn add_filters(env: &mut Environment<'_>, config: &TargetConfig) { - env.add_filter("type_mapping", type_mapping(config.type_mapping.clone())); - env.add_filter("map_text", map_text(config.text_maps.clone())); +pub(crate) fn add_filters(env: &mut Environment<'_>, config: &WeaverConfig) { + env.add_filter("type_mapping", type_mapping(config.type_mapping.clone().unwrap_or_default())); + env.add_filter("map_text", map_text(config.text_maps.clone().unwrap_or_default())); env.add_filter("comment_with_prefix", comment_with_prefix); env.add_filter("markdown_to_html", markdown_to_html); } diff --git a/crates/weaver_forge/src/extensions/util.rs b/crates/weaver_forge/src/extensions/util.rs index 42f3b71f..d9444e38 100644 --- a/crates/weaver_forge/src/extensions/util.rs +++ b/crates/weaver_forge/src/extensions/util.rs @@ -2,15 +2,15 @@ //! Set of utility filters and tests used by the Weaver project. -use crate::config::TargetConfig; +use crate::config::WeaverConfig; use minijinja::{Environment, ErrorKind, Value}; use regex::Regex; use std::collections::HashMap; use std::sync::OnceLock; /// Add utility filters and tests to the environment. -pub(crate) fn add_filters(env: &mut Environment<'_>, target_config: &TargetConfig) { - env.add_filter("acronym", acronym(target_config.acronyms.clone())); +pub(crate) fn add_filters(env: &mut Environment<'_>, target_config: &WeaverConfig) { + env.add_filter("acronym", acronym(target_config.acronyms.clone().unwrap_or_default())); env.add_filter("flatten", flatten); env.add_filter("split_id", split_id); } diff --git a/crates/weaver_forge/src/lib.rs b/crates/weaver_forge/src/lib.rs index 77b8a051..c9dff817 100644 --- a/crates/weaver_forge/src/lib.rs +++ b/crates/weaver_forge/src/lib.rs @@ -11,9 +11,9 @@ use std::path::{Path, PathBuf}; use std::sync::{Arc, Mutex}; use jaq_interpret::Val; +use minijinja::{Environment, ErrorKind, State, Value}; use minijinja::syntax::SyntaxConfig; use minijinja::value::{from_args, Object}; -use minijinja::{Environment, ErrorKind, State, Value}; use rayon::iter::IntoParallelIterator; use rayon::iter::ParallelIterator; use serde::Serialize; @@ -26,7 +26,7 @@ use error::Error::{ use weaver_common::error::handle_errors; use weaver_common::Logger; -use crate::config::{ApplicationMode, Params, TargetConfig}; +use crate::config::{ApplicationMode, Params, WeaverConfig}; use crate::debug::error_summary; use crate::error::Error::InvalidConfigFile; use crate::extensions::{ansi, case, code, otel, util}; @@ -77,7 +77,7 @@ impl Object for TemplateObject { args: &[Value], ) -> Result { if name == "set_file_name" { - let (file_name,): (&str,) = from_args(args)?; + let (file_name, ): (&str,) = from_args(args)?; file_name.clone_into(&mut self.file_name.lock().expect("Lock poisoned")); Ok(Value::from("")) } else { @@ -127,7 +127,7 @@ pub struct TemplateEngine { file_loader: Arc, /// Target configuration - target_config: TargetConfig, + target_config: WeaverConfig, } /// Global context for the template engine. @@ -166,12 +166,14 @@ impl TemplateEngine { loader: impl FileLoader + Send + Sync + 'static, params: Params, ) -> Result { - let mut target_config = TargetConfig::try_new(&loader)?; + let mut target_config = WeaverConfig::try_new(&loader)?; // Override the params defined in the `weaver.yaml` file with the params provided // in the command line. for (name, value) in params.params { - _ = target_config.params.insert(name, value); + _ = target_config.params + .get_or_insert_with(HashMap::new) + .insert(name, value); } Ok(Self { @@ -241,20 +243,27 @@ impl TemplateEngine { let (jq_vars, jq_ctx): (Vec, Vec) = self .target_config .params - .iter() - .filter_map(|(k, v)| { - let json_value = match serde_json::to_value(v) { - Ok(json_value) => json_value, - Err(e) => { - errors.push(ContextSerializationFailed { - error: e.to_string(), - }); - return None; - } - }; - Some((k.clone(), json_value)) - }) - .unzip(); + .as_ref() + .map_or_else( + || (Vec::new(), Vec::new()), // If self.target_config.params is None, return empty vectors + |params| { + params + .iter() + .filter_map(|(k, v)| { + let json_value = match serde_json::to_value(v) { + Ok(json_value) => json_value, + Err(e) => { + errors.push(ContextSerializationFailed { + error: e.to_string(), + }); + return None; + } + }; + Some((k.clone(), json_value)) + }) + .unzip() + }, + ); // Process all files in parallel // - Filter the files that match the template pattern @@ -290,7 +299,7 @@ impl TemplateEngine { ApplicationMode::Single => { if filtered_result.is_null() || (filtered_result.is_array() - && filtered_result.as_array().expect("is_array").is_empty()) + && filtered_result.as_array().expect("is_array").is_empty()) { // Skip the template evaluation if the filtered result is null or an empty array continue; @@ -300,8 +309,8 @@ impl TemplateEngine { NewContext { ctx: &filtered_result, } - .try_into() - .ok()?, + .try_into() + .ok()?, relative_path.as_path(), output_directive, output_dir, @@ -337,8 +346,8 @@ impl TemplateEngine { NewContext { ctx: &filtered_result, } - .try_into() - .ok()?, + .try_into() + .ok()?, relative_path.as_path(), output_directive, output_dir, @@ -385,7 +394,7 @@ impl TemplateEngine { engine.add_global("template", Value::from_object(template_object.clone())); engine.add_global( "params", - Value::from_object(ParamsObject::new(self.target_config.params.clone())), + Value::from_object(ParamsObject::new(self.target_config.params.clone().unwrap_or_default())), ); let template = engine.get_template(template_file).map_err(|e| { @@ -516,8 +525,8 @@ mod tests { use crate::debug::print_dedup_errors; use crate::extensions::case::case_converter; use crate::file_loader::FileSystemFileLoader; - use crate::registry::ResolvedRegistry; use crate::OutputDirective; + use crate::registry::ResolvedRegistry; #[test] fn test_case_converter() { @@ -668,12 +677,12 @@ mod tests { schema.registry(registry_id).expect("registry not found"), schema.catalog(), ) - .unwrap_or_else(|e| { - panic!( - "Failed to create the context for the template evaluation: {:?}", - e - ) - }); + .unwrap_or_else(|e| { + panic!( + "Failed to create the context for the template evaluation: {:?}", + e + ) + }); engine .generate( @@ -708,12 +717,12 @@ mod tests { schema.registry(registry_id).expect("registry not found"), schema.catalog(), ) - .unwrap_or_else(|e| { - panic!( - "Failed to create the context for the template evaluation: {:?}", - e - ) - }); + .unwrap_or_else(|e| { + panic!( + "Failed to create the context for the template evaluation: {:?}", + e + ) + }); engine .generate( @@ -729,8 +738,8 @@ mod tests { assert!(diff_dir( "whitespace_control_templates/test/expected_output", - "whitespace_control_templates/test/observed_output" + "whitespace_control_templates/test/observed_output", ) - .unwrap()); + .unwrap()); } } diff --git a/crates/weaver_forge/templates/registry/test/weaver.yaml b/crates/weaver_forge/templates/registry/test/weaver.yaml new file mode 100644 index 00000000..e69de29b diff --git a/crates/weaver_forge/templates/registry/weaver.yaml b/crates/weaver_forge/templates/registry/weaver.yaml new file mode 100644 index 00000000..e69de29b diff --git a/default_diagnostic_templates/ansi/errors.txt.j2 b/defaults/diagnostic_templates/ansi/errors.txt.j2 similarity index 100% rename from default_diagnostic_templates/ansi/errors.txt.j2 rename to defaults/diagnostic_templates/ansi/errors.txt.j2 diff --git a/default_diagnostic_templates/ansi/weaver.yaml b/defaults/diagnostic_templates/ansi/weaver.yaml similarity index 100% rename from default_diagnostic_templates/ansi/weaver.yaml rename to defaults/diagnostic_templates/ansi/weaver.yaml diff --git a/default_diagnostic_templates/gh_workflow_command/errors.txt.j2 b/defaults/diagnostic_templates/gh_workflow_command/errors.txt.j2 similarity index 100% rename from default_diagnostic_templates/gh_workflow_command/errors.txt.j2 rename to defaults/diagnostic_templates/gh_workflow_command/errors.txt.j2 diff --git a/default_diagnostic_templates/gh_workflow_command/weaver.yaml b/defaults/diagnostic_templates/gh_workflow_command/weaver.yaml similarity index 100% rename from default_diagnostic_templates/gh_workflow_command/weaver.yaml rename to defaults/diagnostic_templates/gh_workflow_command/weaver.yaml diff --git a/default_diagnostic_templates/json/errors.json.j2 b/defaults/diagnostic_templates/json/errors.json.j2 similarity index 100% rename from default_diagnostic_templates/json/errors.json.j2 rename to defaults/diagnostic_templates/json/errors.json.j2 diff --git a/default_diagnostic_templates/json/weaver.yaml b/defaults/diagnostic_templates/json/weaver.yaml similarity index 100% rename from default_diagnostic_templates/json/weaver.yaml rename to defaults/diagnostic_templates/json/weaver.yaml diff --git a/defaults/weaver_config/weaver.yaml b/defaults/weaver_config/weaver.yaml new file mode 100644 index 00000000..05fae55e --- /dev/null +++ b/defaults/weaver_config/weaver.yaml @@ -0,0 +1,22 @@ +# This file contains the default configuration used by Weaver. +# +# Weaver allows local configuration for a particular target as well as global +# configuration. It looks for configuration files in the target directory, the +# parent directory (i.e., the directory containing all the targets), the +# `$HOME/.weaver/weaver.yaml` directory, and finally in the +# `defaults/weaver_config` directory (embedded in the Weaver binary). A local +# definition overrides the corresponding definition that may be present in the +# parent directory, which itself may redefine the corresponding entry in the +# home directory (i.e., defined per user), and finally in the Weaver application +# binary (i.e., defined by Weaver authors). With this structure, we can specify +# configuration per target, for all targets, and even reuse a configuration +# defined in the binary of the Weaver application. + +# Default template syntax. +template_syntax: + block_start: "{%" + block_end: "%}" + variable_start: "{{" + variable_end: "}}" + comment_start: "{#" + comment_end: "#}" diff --git a/src/diagnostic/mod.rs b/src/diagnostic/mod.rs index e1fe343e..b2903f80 100644 --- a/src/diagnostic/mod.rs +++ b/src/diagnostic/mod.rs @@ -15,7 +15,7 @@ use weaver_common::Logger; /// Embedded default diagnostic templates pub(crate) static DEFAULT_DIAGNOSTIC_TEMPLATES: Dir<'_> = - include_dir!("default_diagnostic_templates"); + include_dir!("defaults/diagnostic_templates"); /// Errors emitted by the `diagnostic` sub-commands #[derive(thiserror::Error, Debug, Serialize, Diagnostic)] From b8faa77e4398f4bf3283fc1f453f30364c3e5a46 Mon Sep 17 00:00:00 2001 From: Laurent Querel Date: Sun, 7 Jul 2024 21:34:56 -0700 Subject: [PATCH 02/29] feat(forge): Test override_with --- crates/weaver_forge/src/config.rs | 343 +++++++++--------- crates/weaver_forge/src/lib.rs | 22 +- .../test/weaver.yaml | 47 +++ 3 files changed, 236 insertions(+), 176 deletions(-) diff --git a/crates/weaver_forge/src/config.rs b/crates/weaver_forge/src/config.rs index 1cf64b72..c7056379 100644 --- a/crates/weaver_forge/src/config.rs +++ b/crates/weaver_forge/src/config.rs @@ -56,18 +56,28 @@ pub enum CaseConvention { #[derive(Deserialize, Debug, Default)] pub(crate) struct WeaverConfig { /// Case convention used to name a file. + /// Open question: Do we keep this? It's probably easier for author's templates to use directly + /// the case conversion filters than to rely on this configuration. #[serde(default)] pub(crate) file_name: CaseConvention, /// Case convention used to name a function. + /// Open question: Do we keep this? It's probably easier for author's templates to use directly + /// the case conversion filters than to rely on this configuration. #[serde(default)] pub(crate) function_name: CaseConvention, /// Case convention used to name a function argument. + /// Open question: Do we keep this? It's probably easier for author's templates to use directly + /// the case conversion filters than to rely on this configuration. #[serde(default)] pub(crate) arg_name: CaseConvention, /// Case convention used to name a struct. + /// Open question: Do we keep this? It's probably easier for author's templates to use directly + /// the case conversion filters than to rely on this configuration. #[serde(default)] pub(crate) struct_name: CaseConvention, /// Case convention used to name a struct field. + /// Open question: Do we keep this? It's probably easier for author's templates to use directly + /// the case conversion filters than to rely on this configuration. #[serde(default)] pub(crate) field_name: CaseConvention, /// Type mapping for target specific types (OTel types -> Target language types). @@ -87,94 +97,13 @@ pub(crate) struct WeaverConfig { pub(crate) params: Option>, /// Configuration for the templates. - #[serde(default = "default_templates")] - pub(crate) templates: Vec, + pub(crate) templates: Option>, /// List of acronyms to be considered as unmodifiable words in the case /// conversion. pub(crate) acronyms: Option>, } -fn default_templates() -> Vec { - vec![ - TemplateConfig { - pattern: Glob::new("**/registry.md").expect("Invalid pattern"), - filter: ".".to_owned(), - application_mode: ApplicationMode::Single, - }, - TemplateConfig { - pattern: Glob::new("**/attribute_group.md").expect("Invalid pattern"), - filter: ".groups[] | select(.type == \"attribute_group\")".to_owned(), - application_mode: ApplicationMode::Each, - }, - TemplateConfig { - pattern: Glob::new("**/attribute_groups.md").expect("Invalid pattern"), - filter: ".groups[] | select(.type == \"attribute_group\")".to_owned(), - application_mode: ApplicationMode::Single, - }, - TemplateConfig { - pattern: Glob::new("**/event.md").expect("Invalid pattern"), - filter: ".groups[] | select(.type == \"event\")".to_owned(), - application_mode: ApplicationMode::Each, - }, - TemplateConfig { - pattern: Glob::new("**/events.md").expect("Invalid pattern"), - filter: ".groups[] | select(.type == \"event\")".to_owned(), - application_mode: ApplicationMode::Single, - }, - TemplateConfig { - pattern: Glob::new("**/group.md").expect("Invalid pattern"), - filter: ".groups".to_owned(), - application_mode: ApplicationMode::Each, - }, - TemplateConfig { - pattern: Glob::new("**/groups.md").expect("Invalid pattern"), - filter: ".groups".to_owned(), - application_mode: ApplicationMode::Single, - }, - TemplateConfig { - pattern: Glob::new("**/metric.md").expect("Invalid pattern"), - filter: ".groups[] | select(.type == \"metric\")".to_owned(), - application_mode: ApplicationMode::Each, - }, - TemplateConfig { - pattern: Glob::new("**/metrics.md").expect("Invalid pattern"), - filter: ".groups[] | select(.type == \"metric\")".to_owned(), - application_mode: ApplicationMode::Single, - }, - TemplateConfig { - pattern: Glob::new("**/resource.md").expect("Invalid pattern"), - filter: ".groups[] | select(.type == \"resource\")".to_owned(), - application_mode: ApplicationMode::Each, - }, - TemplateConfig { - pattern: Glob::new("**/resources.md").expect("Invalid pattern"), - filter: ".groups[] | select(.type == \"resource\")".to_owned(), - application_mode: ApplicationMode::Single, - }, - TemplateConfig { - pattern: Glob::new("**/scope.md").expect("Invalid pattern"), - filter: ".groups[] | select(.type == \"scope\")".to_owned(), - application_mode: ApplicationMode::Each, - }, - TemplateConfig { - pattern: Glob::new("**/scopes.md").expect("Invalid pattern"), - filter: ".groups[] | select(.type == \"scope\")".to_owned(), - application_mode: ApplicationMode::Single, - }, - TemplateConfig { - pattern: Glob::new("**/span.md").expect("Invalid pattern"), - filter: ".groups[] | select(.type == \"span\")".to_owned(), - application_mode: ApplicationMode::Each, - }, - TemplateConfig { - pattern: Glob::new("**/spans.md").expect("Invalid pattern"), - filter: ".groups[] | select(.type == \"span\")".to_owned(), - application_mode: ApplicationMode::Single, - }, - ] -} - /// Parameters defined in the command line via the `--params` argument. #[derive(Deserialize, Debug, Clone, Default)] pub struct Params { @@ -185,7 +114,7 @@ pub struct Params { /// Application mode defining how to apply a template on the result of a /// filter applied on a registry. -#[derive(Deserialize, Debug)] +#[derive(Deserialize, Debug, PartialEq)] #[serde(rename_all = "snake_case")] pub enum ApplicationMode { /// Apply the template to the output of the filter as a whole. @@ -235,69 +164,20 @@ impl<'a> TemplateMatcher<'a> { } /// Syntax configuration for the template engine. -#[derive(Deserialize, Debug, Clone)] +#[derive(Deserialize, Debug, Clone, Default)] pub struct TemplateSyntax { /// The start of a block. - #[serde(default = "default_block_start")] - pub block_start: String, + pub block_start: Option, /// The end of a block. - #[serde(default = "default_block_end")] - pub block_end: String, + pub block_end: Option, /// The start of a variable. - #[serde(default = "default_variable_start")] - pub variable_start: String, + pub variable_start: Option, /// The end of a variable. - #[serde(default = "default_variable_end")] - pub variable_end: String, + pub variable_end: Option, /// The start of a comment. - #[serde(default = "default_comment_start")] - pub comment_start: String, + pub comment_start: Option, /// The end of a comment. - #[serde(default = "default_comment_end")] - pub comment_end: String, -} - -/// Default block start delimiter. -fn default_block_start() -> String { - "{%".to_owned() -} - -/// Default block end delimiter. -fn default_block_end() -> String { - "%}".to_owned() -} - -/// Default variable start delimiter. -fn default_variable_start() -> String { - "{{".to_owned() -} - -/// Default variable end delimiter. -fn default_variable_end() -> String { - "}}".to_owned() -} - -/// Default comment start delimiter. -fn default_comment_start() -> String { - "{#".to_owned() -} - -/// Default comment end delimiter. -fn default_comment_end() -> String { - "#}".to_owned() -} - -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(), - } - } + pub comment_end: Option, } impl TemplateSyntax { @@ -305,12 +185,24 @@ impl TemplateSyntax { /// The merge is done in place. The `TemplateSyntax` passed as argument will be consumed and /// used to override the current `TemplateSyntax`. pub fn override_with(&mut self, other: TemplateSyntax) { - self.block_start = other.block_start; - self.block_end = other.block_end; - self.variable_start = other.variable_start; - self.variable_end = other.variable_end; - self.comment_start = other.comment_start; - self.comment_end = other.comment_end; + if other.block_start.is_some() { + self.block_start = other.block_start; + } + if other.block_end.is_some() { + self.block_end = other.block_end; + } + if other.variable_start.is_some() { + self.variable_start = other.variable_start; + } + if other.variable_end.is_some() { + self.variable_end = other.variable_end; + } + if other.comment_start.is_some() { + self.comment_start = other.comment_start; + } + if other.comment_end.is_some() { + self.comment_end = other.comment_end; + } } } @@ -319,13 +211,13 @@ impl TemplateSyntax { pub struct WhitespaceControl { /// Configures the behavior of the first newline after a block. /// See - pub trim_blocks: bool, + pub trim_blocks: Option, /// Configures the behavior of leading spaces and tabs from the start of a line to a block. /// See - pub lstrip_blocks: bool, + pub lstrip_blocks: Option, /// Configures whether trailing newline are preserved when rendering templates. /// See - pub keep_trailing_newline: bool, + pub keep_trailing_newline: Option, } impl WhitespaceControl { @@ -333,9 +225,15 @@ impl WhitespaceControl { /// The merge is done in place. The `WhitespaceControl` passed as argument will be consumed and /// used to override the current `WhitespaceControl`. pub fn override_with(&mut self, other: WhitespaceControl) { - self.trim_blocks = other.trim_blocks; - self.lstrip_blocks = other.lstrip_blocks; - self.keep_trailing_newline = other.keep_trailing_newline; + if other.trim_blocks.is_some() { + self.trim_blocks = other.trim_blocks; + } + if other.lstrip_blocks.is_some() { + self.lstrip_blocks = other.lstrip_blocks; + } + if other.keep_trailing_newline.is_some() { + self.keep_trailing_newline = other.keep_trailing_newline; + } } } @@ -482,21 +380,28 @@ impl WeaverConfig { /// Return a template matcher for the target configuration. pub fn template_matcher(&self) -> Result, Error> { - let mut builder = GlobSetBuilder::new(); + if let Some(templates) = &self.templates { + let mut builder = GlobSetBuilder::new(); - self.templates.iter().for_each(|template| { - _ = builder.add(template.pattern.clone()); - }); + templates.iter().for_each(|template| { + _ = builder.add(template.pattern.clone()); + }); - builder - .build() - .map_err(|e| Error::InvalidTemplatePattern { - error: e.to_string(), - }) - .map(|glob_set| TemplateMatcher { - templates: &self.templates, - glob_set, + builder + .build() + .map_err(|e| Error::InvalidTemplatePattern { + error: e.to_string(), + }) + .map(|glob_set| TemplateMatcher { + templates: &templates, + glob_set, + }) + } else { + Ok(TemplateMatcher { + templates: &[], + glob_set: GlobSet::empty(), }) + } } /// Override the current `WeaverConfig` with the `WeaverConfig` passed as argument. @@ -519,7 +424,9 @@ impl WeaverConfig { if other.params.is_some() { self.params = other.params; } - self.templates = other.templates; + if other.templates.is_some() { + self.templates = other.templates; + } if other.acronyms.is_some() { self.acronyms = other.acronyms; } @@ -529,11 +436,83 @@ impl WeaverConfig { #[cfg(test)] mod tests { use std::collections::HashMap; - use crate::config::{DEFAULT_WEAVER_CONFIG, WeaverConfig}; + use crate::config::{ApplicationMode, DEFAULT_WEAVER_CONFIG, WeaverConfig}; use crate::file_loader::FileSystemFileLoader; #[test] fn test_override_with() { + // Tests type_mapping overrides. + // If defined in both, the local configuration should override the parent configuration. + let mut parent: WeaverConfig = serde_yaml::from_str("type_mapping: {a: \"b\", c: \"d\"}").unwrap(); + let local: WeaverConfig = serde_yaml::from_str("type_mapping: {a: \"e\"}").unwrap(); + parent.override_with(local); + assert_eq!(parent.type_mapping, Some([("a".to_owned(), "e".to_owned())].iter().cloned().collect())); + let mut parent: WeaverConfig = WeaverConfig::default(); + let local: WeaverConfig = serde_yaml::from_str("type_mapping: {a: \"e\"}").unwrap(); + parent.override_with(local); + assert_eq!(parent.type_mapping, Some([("a".to_owned(), "e".to_owned())].iter().cloned().collect())); + let mut parent: WeaverConfig = serde_yaml::from_str("type_mapping: {a: \"b\", c: \"d\"}").unwrap(); + let local = WeaverConfig::default(); + parent.override_with(local); + assert_eq!(parent.type_mapping, Some([("a".to_owned(), "b".to_owned()), ("c".to_owned(), "d".to_owned())].iter().cloned().collect())); + + // Tests text_maps overrides. + // If defined in both, the local configuration should override the parent configuration. + let mut parent: WeaverConfig = serde_yaml::from_str("text_maps: {a: {b: \"c\"}, d: {e: \"f\"}}").unwrap(); + let local: WeaverConfig = serde_yaml::from_str("text_maps: {a: {b: \"g\"}}").unwrap(); + parent.override_with(local); + assert_eq!(parent.text_maps, Some([("a".to_owned(), [("b".to_owned(), "g".to_owned())].iter().cloned().collect())].iter().cloned().collect())); + let mut parent: WeaverConfig = WeaverConfig::default(); + let local: WeaverConfig = serde_yaml::from_str("text_maps: {a: {b: \"g\"}}").unwrap(); + parent.override_with(local); + assert_eq!(parent.text_maps, Some([("a".to_owned(), [("b".to_owned(), "g".to_owned())].iter().cloned().collect())].iter().cloned().collect())); + let mut parent: WeaverConfig = serde_yaml::from_str("text_maps: {a: {b: \"c\"}, d: {e: \"f\"}}").unwrap(); + let local = WeaverConfig::default(); + parent.override_with(local); + assert_eq!(parent.text_maps, Some([("a".to_owned(), [("b".to_owned(), "c".to_owned())].iter().cloned().collect()), ("d".to_owned(), [("e".to_owned(), "f".to_owned())].iter().cloned().collect())].iter().cloned().collect())); + + // Tests template syntax overrides. + // If defined in both, the local configuration should override the parent configuration. + let mut parent: WeaverConfig = serde_yaml::from_str("template_syntax: {block_start: \"{{\", block_end: \"}}\", variable_start: \"#\"}").unwrap(); + let local: WeaverConfig = serde_yaml::from_str("template_syntax: {block_start: \"[[\", block_end: \"]]\"}").unwrap(); + parent.override_with(local); + assert_eq!(parent.template_syntax.block_start, Some("[[".to_owned())); + assert_eq!(parent.template_syntax.block_end, Some("]]".to_owned())); + assert_eq!(parent.template_syntax.variable_start, Some("#".to_owned())); + let mut parent: WeaverConfig = WeaverConfig::default(); + let local: WeaverConfig = serde_yaml::from_str("template_syntax: {block_start: \"[[\", block_end: \"]]\"}").unwrap(); + parent.override_with(local); + assert_eq!(parent.template_syntax.block_start, Some("[[".to_owned())); + assert_eq!(parent.template_syntax.block_end, Some("]]".to_owned())); + assert_eq!(parent.template_syntax.variable_start, None); + let mut parent: WeaverConfig = serde_yaml::from_str("template_syntax: {block_start: \"{{\", block_end: \"}}\", variable_start: \"#\"}").unwrap(); + let local = WeaverConfig::default(); + parent.override_with(local); + assert_eq!(parent.template_syntax.block_start, Some("{{".to_owned())); + assert_eq!(parent.template_syntax.block_end, Some("}}".to_owned())); + assert_eq!(parent.template_syntax.variable_start, Some("#".to_owned())); + + // Tests whitespace control overrides. + // If defined in both, the local configuration should override the parent configuration. + let mut parent: WeaverConfig = serde_yaml::from_str("whitespace_control: {trim_blocks: true, lstrip_blocks: true}").unwrap(); + let local: WeaverConfig = serde_yaml::from_str("whitespace_control: {lstrip_blocks: false}").unwrap(); + parent.override_with(local); + assert_eq!(parent.whitespace_control.trim_blocks, Some(true)); + assert_eq!(parent.whitespace_control.lstrip_blocks, Some(false)); + assert_eq!(parent.whitespace_control.keep_trailing_newline, None); + let mut parent: WeaverConfig = WeaverConfig::default(); + let local: WeaverConfig = serde_yaml::from_str("whitespace_control: {trim_blocks: true, lstrip_blocks: true, keep_trailing_newline: true}").unwrap(); + parent.override_with(local); + assert_eq!(parent.whitespace_control.trim_blocks, Some(true)); + assert_eq!(parent.whitespace_control.lstrip_blocks, Some(true)); + assert_eq!(parent.whitespace_control.keep_trailing_newline, Some(true)); + let mut parent: WeaverConfig = serde_yaml::from_str("whitespace_control: {trim_blocks: true, lstrip_blocks: true}").unwrap(); + let local = WeaverConfig::default(); + parent.override_with(local); + assert_eq!(parent.whitespace_control.trim_blocks, Some(true)); + assert_eq!(parent.whitespace_control.lstrip_blocks, Some(true)); + assert_eq!(parent.whitespace_control.keep_trailing_newline, None); + // Tests params overrides. // If defined in both, the local configuration should override the parent configuration. let mut parent: WeaverConfig = serde_yaml::from_str("params: {a: 1, b: 2}").unwrap(); @@ -554,6 +533,40 @@ mod tests { assert_eq!(parent.params, Some(HashMap::default())); // Tests templates overrides. + // If defined in both, the local configuration should override the parent configuration. + let mut parent: WeaverConfig = serde_yaml::from_str("templates: [{pattern: \"**/parent.md\", filter: \".\", application_mode: \"single\"}]").unwrap(); + let local: WeaverConfig = serde_yaml::from_str("templates: [{pattern: \"**/local.md\", filter: \".\", application_mode: \"each\"}]").unwrap(); + parent.override_with(local); + assert!(parent.templates.is_some()); + let templates = parent.templates.unwrap(); + assert_eq!(templates.len(), 1); + assert_eq!(templates[0].pattern.to_string(), "**/local.md"); + assert_eq!(templates[0].filter, "."); + assert_eq!(templates[0].application_mode, ApplicationMode::Each); + let mut parent: WeaverConfig = WeaverConfig::default(); + let local: WeaverConfig = serde_yaml::from_str("templates: [{pattern: \"**/local.md\", filter: \".\", application_mode: \"each\"}]").unwrap(); + parent.override_with(local); + assert!(parent.templates.is_some()); + let templates = parent.templates.unwrap(); + assert_eq!(templates.len(), 1); + assert_eq!(templates[0].pattern.to_string(), "**/local.md"); + assert_eq!(templates[0].filter, "."); + assert_eq!(templates[0].application_mode, ApplicationMode::Each); + let mut parent: WeaverConfig = serde_yaml::from_str("templates: [{pattern: \"**/parent.md\", filter: \".\", application_mode: \"single\"}]").unwrap(); + let local = WeaverConfig::default(); + parent.override_with(local); + assert!(parent.templates.is_some()); + let templates = parent.templates.unwrap(); + assert_eq!(templates.len(), 1); + assert_eq!(templates[0].pattern.to_string(), "**/parent.md"); + assert_eq!(templates[0].filter, "."); + assert_eq!(templates[0].application_mode, ApplicationMode::Single); + let mut parent: WeaverConfig = serde_yaml::from_str("templates: [{pattern: \"**/parent.md\", filter: \".\", application_mode: \"single\"}]").unwrap(); + let local: WeaverConfig = serde_yaml::from_str("templates: []").unwrap(); + parent.override_with(local); + assert!(parent.templates.is_some()); + let templates = parent.templates.unwrap(); + assert_eq!(templates.len(), 0); // Tests acronyms overrides. // If defined in both, the local configuration should override the parent configuration. diff --git a/crates/weaver_forge/src/lib.rs b/crates/weaver_forge/src/lib.rs index c9dff817..bf649ed2 100644 --- a/crates/weaver_forge/src/lib.rs +++ b/crates/weaver_forge/src/lib.rs @@ -439,16 +439,16 @@ impl TemplateEngine { let syntax = SyntaxConfig::builder() .block_delimiters( - Cow::Owned(template_syntax.block_start), - Cow::Owned(template_syntax.block_end), + Cow::Owned(template_syntax.block_start.unwrap_or_else(|| "{%".to_owned())), + Cow::Owned(template_syntax.block_end.unwrap_or_else(|| "%}".to_owned())), ) .variable_delimiters( - Cow::Owned(template_syntax.variable_start), - Cow::Owned(template_syntax.variable_end), + Cow::Owned(template_syntax.variable_start.unwrap_or_else(|| "{{".to_owned())), + Cow::Owned(template_syntax.variable_end.unwrap_or_else(|| "}}".to_owned())), ) .comment_delimiters( - Cow::Owned(template_syntax.comment_start), - Cow::Owned(template_syntax.comment_end), + Cow::Owned(template_syntax.comment_start.unwrap_or_else(|| "{#".to_owned())), + Cow::Owned(template_syntax.comment_end.unwrap_or_else(|| "#}".to_owned())), ) .build() .map_err(|e| InvalidConfigFile { @@ -468,9 +468,9 @@ impl TemplateEngine { // Jinja whitespace control // https://docs.rs/minijinja/latest/minijinja/syntax/index.html#whitespace-control let whitespace_control = self.target_config.whitespace_control.clone(); - env.set_trim_blocks(whitespace_control.trim_blocks); - env.set_lstrip_blocks(whitespace_control.lstrip_blocks); - env.set_keep_trailing_newline(whitespace_control.keep_trailing_newline); + env.set_trim_blocks(whitespace_control.trim_blocks.unwrap_or_default()); + env.set_lstrip_blocks(whitespace_control.lstrip_blocks.unwrap_or_default()); + env.set_keep_trailing_newline(whitespace_control.keep_trailing_newline.unwrap_or_default()); code::add_filters(&mut env, &self.target_config); ansi::add_filters(&mut env); @@ -661,11 +661,11 @@ mod tests { // Add a template configuration for converter.md on top // of the default template configuration. This is useful // for test coverage purposes. - engine.target_config.templates.push(TemplateConfig { + engine.target_config.templates = Some(vec![TemplateConfig { pattern: Glob::new("converter.md").unwrap(), filter: ".".to_owned(), application_mode: ApplicationMode::Single, - }); + }]); let registry_id = "default"; let mut registry = SemConvRegistry::try_from_path_pattern(registry_id, "data/*.yaml") diff --git a/crates/weaver_forge/whitespace_control_templates/test/weaver.yaml b/crates/weaver_forge/whitespace_control_templates/test/weaver.yaml index 618921bd..1c3f4246 100644 --- a/crates/weaver_forge/whitespace_control_templates/test/weaver.yaml +++ b/crates/weaver_forge/whitespace_control_templates/test/weaver.yaml @@ -20,3 +20,50 @@ whitespace_control: trim_blocks: true lstrip_blocks: true keep_trailing_newline: true + +templates: + - pattern: "**/registry.md" + filter: "." + application_mode: single + - pattern: "**/attribute_group.md" + filter: ".groups[] | select(.type == \"attribute_group\")" + application_mode: each + - pattern: "**/attribute_groups.md" + filter: ".groups[] | select(.type == \"attribute_group\")" + application_mode: single + - pattern: "**/event.md" + filter: ".groups[] | select(.type == \"event\")" + application_mode: each + - pattern: "**/events.md" + filter: ".groups[] | select(.type == \"event\")" + application_mode: single + - pattern: "**/group.md" + filter: ".groups" + application_mode: each + - pattern: "**/groups.md" + filter: ".groups" + application_mode: single + - pattern: "**/metric.md" + filter: ".groups[] | select(.type == \"metric\")" + application_mode: each + - pattern: "**/metrics.md" + filter: ".groups[] | select(.type == \"metric\")" + application_mode: single + - pattern: "**/resource.md" + filter: ".groups[] | select(.type == \"resource\")" + application_mode: each + - pattern: "**/resources.md" + filter: ".groups[] | select(.type == \"resource\")" + application_mode: single + - pattern: "**/scope.md" + filter: ".groups[] | select(.type == \"scope\")" + application_mode: each + - pattern: "**/scopes.md" + filter: ".groups[] | select(.type == \"scope\")" + application_mode: single + - pattern: "**/span.md" + filter: ".groups[] | select(.type == \"span\")" + application_mode: each + - pattern: "**/spans.md" + filter: ".groups[] | select(.type == \"span\")" + application_mode: single \ No newline at end of file From da7b6c7974ca75e24239d83f03323591ec9e393f Mon Sep 17 00:00:00 2001 From: Laurent Querel Date: Tue, 9 Jul 2024 18:17:21 -0700 Subject: [PATCH 03/29] feat(forge): Implement better UX for templates and config. --- Cargo.lock | 161 ++++---- Cargo.toml | 3 +- crates/weaver_codegen_test/build.rs | 5 +- crates/weaver_forge/Cargo.toml | 1 - crates/weaver_forge/src/config.rs | 359 ++++++++++++------ crates/weaver_forge/src/extensions/code.rs | 10 +- crates/weaver_forge/src/extensions/util.rs | 5 +- crates/weaver_forge/src/file_loader.rs | 122 +++--- crates/weaver_forge/src/lib.rs | 98 +++-- .../templates/registry/test/weaver.yaml | 0 .../templates/registry/weaver.yaml | 7 + .../templates/registry/xyz/weaver.yaml | 8 + crates/weaver_semconv_gen/src/lib.rs | 2 +- src/main.rs | 7 +- src/registry/generate.rs | 11 +- src/registry/update_markdown.rs | 3 +- tests/registry_check.rs | 1 - tests/registry_generate.rs | 3 +- 18 files changed, 489 insertions(+), 317 deletions(-) delete mode 100644 crates/weaver_forge/templates/registry/test/weaver.yaml create mode 100644 crates/weaver_forge/templates/registry/xyz/weaver.yaml diff --git a/Cargo.lock b/Cargo.lock index babc4219..dab5aebf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -145,9 +145,9 @@ dependencies = [ [[package]] name = "async-trait" -version = "0.1.80" +version = "0.1.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca" +checksum = "6e0c28dcc82d7c8ead5cb13beb15405b57b8546e93215673ff8ca0349a028107" dependencies = [ "proc-macro2", "quote", @@ -284,9 +284,9 @@ checksum = "a3e368af43e418a04d52505cf3dbc23dda4e3407ae2fa99fd0e4f308ce546acc" [[package]] name = "cc" -version = "1.0.104" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74b6a57f98764a267ff415d50a25e6e166f3831a5071af4995296ea97d210490" +checksum = "eaff6f8ce506b9773fa786672d63fc7a191ffea1be33f72bbd4aeacefca9ffc8" [[package]] name = "cfg-if" @@ -305,7 +305,7 @@ dependencies = [ "js-sys", "num-traits", "wasm-bindgen", - "windows-targets 0.52.5", + "windows-targets 0.52.6", ] [[package]] @@ -341,9 +341,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.8" +version = "4.5.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84b3edb18336f4df585bc9aa31dd99c036dfa5dc5e9a2939a722a188f3a8970d" +checksum = "64acc1846d54c1fe936a78dc189c34e28d3f5afc348403f28ecf53660b9b8462" dependencies = [ "clap_builder", "clap_derive", @@ -351,9 +351,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.8" +version = "4.5.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1c09dd5ada6c6c78075d6fd0da3f90d8080651e2d6cc8eb2f1aaa4034ced708" +checksum = "6fb8393d67ba2e7bfaf28a23458e4e2b543cc73a99595511eb207fdb8aede942" dependencies = [ "anstream", "anstyle", @@ -862,9 +862,9 @@ dependencies = [ [[package]] name = "gix-actor" -version = "0.31.3" +version = "0.31.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0f52455500a0fac1fd62a1cf42d9121cfddef8cb3ded2f9e7adb5775deb1fc9" +checksum = "d9b8ee65074b2bbb91d9d97c15d172ea75043aefebf9869b5b329149dc76501c" dependencies = [ "bstr", "gix-date", @@ -1196,9 +1196,9 @@ dependencies = [ [[package]] name = "gix-object" -version = "0.42.2" +version = "0.42.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fe2dc4a41191c680c942e6ebd630c8107005983c4679214fdb1007dcf5ae1df" +checksum = "25da2f46b4e7c2fa7b413ce4dffb87f69eaf89c2057e386491f4c55cadbfe386" dependencies = [ "bstr", "gix-actor", @@ -1703,9 +1703,9 @@ checksum = "5c3b1f728c459d27b12448862017b96ad4767b1ec2ec5e6434e99f1577f085b8" [[package]] name = "hyper" -version = "1.4.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4fe55fb7a772d59a5ff1dfbff4fe0258d19b89fec4b233e75d35d5d2316badc" +checksum = "50dfd22e0e76d0f662d429a5f80fcaf3855009297eab6a0a9f8543834744ba05" dependencies = [ "bytes", "futures-channel", @@ -1731,7 +1731,7 @@ dependencies = [ "http", "hyper", "hyper-util", - "rustls 0.23.10", + "rustls", "rustls-pki-types", "tokio", "tokio-rustls", @@ -1926,9 +1926,9 @@ dependencies = [ [[package]] name = "jaq-std" -version = "1.5.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fddeea4693478ff1ed94db36cc93342f00a29b8331c7aa70eaf413babec067af" +checksum = "d6e83f491752a1bbc4fa05a8e80d4ce1139119f9c3fd8e3400b604776c2e0129" dependencies = [ "bincode", "jaq-parse", @@ -2429,7 +2429,7 @@ dependencies = [ "libc", "redox_syscall 0.5.2", "smallvec", - "windows-targets 0.52.5", + "windows-targets 0.52.6", ] [[package]] @@ -2605,7 +2605,7 @@ dependencies = [ "quinn-proto", "quinn-udp", "rustc-hash", - "rustls 0.23.10", + "rustls", "thiserror", "tokio", "tracing", @@ -2621,7 +2621,7 @@ dependencies = [ "rand 0.8.5", "ring", "rustc-hash", - "rustls 0.23.10", + "rustls", "slab", "thiserror", "tinyvec", @@ -2865,7 +2865,7 @@ dependencies = [ "percent-encoding", "pin-project-lite", "quinn", - "rustls 0.23.10", + "rustls", "rustls-pemfile", "rustls-pki-types", "serde", @@ -2926,24 +2926,11 @@ dependencies = [ [[package]] name = "rustls" -version = "0.22.4" +version = "0.23.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf4ef73721ac7bcd79b2b315da7779d8fc09718c6b3d2d1b2d94850eb8c18432" +checksum = "4828ea528154ae444e5a642dbb7d5623354030dc9822b83fd9bb79683c7399d0" dependencies = [ "log", - "ring", - "rustls-pki-types", - "rustls-webpki", - "subtle", - "zeroize", -] - -[[package]] -name = "rustls" -version = "0.23.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05cff451f60db80f490f3c182b77c35260baace73209e9cdbbe526bfe3a4d402" -dependencies = [ "once_cell", "ring", "rustls-pki-types", @@ -2970,9 +2957,9 @@ checksum = "976295e77ce332211c0d24d92c0e83e50f5c5f046d11082cea19f3df13a3562d" [[package]] name = "rustls-webpki" -version = "0.102.4" +version = "0.102.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff448f7e92e913c4b7d4c6d8e4540a1724b319b4152b8aef6d4cf8339712b33e" +checksum = "f9a6fccd794a42c2c105b513a2f62bc3fd8f3ba57a4593677ceb0bd035164d78" dependencies = [ "ring", "rustls-pki-types", @@ -3061,18 +3048,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.203" +version = "1.0.204" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094" +checksum = "bc76f558e0cbb2a839d37354c575f1dc3fdc6546b5be373ba43d95f231bf7c12" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.203" +version = "1.0.204" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" +checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222" dependencies = [ "proc-macro2", "quote", @@ -3271,9 +3258,9 @@ checksum = "b7401a30af6cb5818bb64852270bb722533397edcfc7344954a38f420819ece2" [[package]] name = "syn" -version = "2.0.68" +version = "2.0.70" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "901fa70d88b9d6c98022e23b4136f9f3e54e4662c3bc1bd1d84a42a9a0f0c1e9" +checksum = "2f0209b68b3613b093e0ec905354eccaedcfe83b8cb37cbdeae64026c3064c16" dependencies = [ "proc-macro2", "quote", @@ -3411,9 +3398,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.6.1" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c55115c6fbe2d2bef26eb09ad74bde02d8255476fc0c7b515ef09fbb35742d82" +checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" dependencies = [ "tinyvec_macros", ] @@ -3445,7 +3432,7 @@ version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4" dependencies = [ - "rustls 0.23.10", + "rustls", "rustls-pki-types", "tokio", ] @@ -3486,9 +3473,9 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.22.14" +version = "0.22.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f21c7aaf97f1bd9ca9d4f9e73b0a6c74bd5afef56f2bc931943a6e1c37e04e38" +checksum = "d59a3a72298453f564e2b111fa896f8d07fabb36f51f06d7e875fc5e0b5a3ef1" dependencies = [ "indexmap", "serde", @@ -3647,17 +3634,16 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "ureq" -version = "2.9.7" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d11a831e3c0b56e438a28308e7c810799e3c118417f342d30ecec080105395cd" +checksum = "72139d247e5f97a3eff96229a7ae85ead5328a39efe76f8bf5a06313d505b6ea" dependencies = [ "base64 0.22.1", "flate2", "log", "once_cell", - "rustls 0.22.4", + "rustls", "rustls-pki-types", - "rustls-webpki", "url", "webpki-roots", ] @@ -3687,9 +3673,9 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.9.1" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5de17fd2f7da591098415cff336e12965a28061ddace43b59cb3c430179c9439" +checksum = "81dfa00651efa65069b0b6b651f4aaa31ba9e3c3ce0137aaad053604ee7e0314" dependencies = [ "getrandom", "rand 0.8.5", @@ -3907,7 +3893,6 @@ name = "weaver_forge" version = "0.5.0" dependencies = [ "convert_case", - "dirs", "globset", "include_dir", "indexmap", @@ -4068,7 +4053,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" dependencies = [ - "windows-targets 0.52.5", + "windows-targets 0.52.6", ] [[package]] @@ -4086,7 +4071,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.5", + "windows-targets 0.52.6", ] [[package]] @@ -4106,18 +4091,18 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.52.5", - "windows_aarch64_msvc 0.52.5", - "windows_i686_gnu 0.52.5", + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", "windows_i686_gnullvm", - "windows_i686_msvc 0.52.5", - "windows_x86_64_gnu 0.52.5", - "windows_x86_64_gnullvm 0.52.5", - "windows_x86_64_msvc 0.52.5", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", ] [[package]] @@ -4128,9 +4113,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_msvc" @@ -4140,9 +4125,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_i686_gnu" @@ -4152,15 +4137,15 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" [[package]] name = "windows_i686_gnullvm" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_msvc" @@ -4170,9 +4155,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_x86_64_gnu" @@ -4182,9 +4167,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnullvm" @@ -4194,9 +4179,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_msvc" @@ -4206,9 +4191,9 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" @@ -4239,18 +4224,18 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.7.34" +version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae87e3fcd617500e5d106f0380cf7b77f3c6092aae37191433159dda23cfb087" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.7.34" +version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15e934569e47891f7d9411f1a451d947a60e000ab3bd24fbb970f000387d1b3b" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index 6322812b..64317f90 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -184,7 +184,8 @@ redundant_feature_names = "warn" ref_option_ref = "warn" rest_pat_in_fully_bound_structs = "warn" same_functions_in_if_condition = "warn" -self_named_module_files = "warn" +# disabled due to false positives +# self_named_module_files = "warn" semicolon_if_nothing_returned = "warn" single_match_else = "warn" string_add = "warn" diff --git a/crates/weaver_codegen_test/build.rs b/crates/weaver_codegen_test/build.rs index 9f9dbf11..edd4de35 100644 --- a/crates/weaver_codegen_test/build.rs +++ b/crates/weaver_codegen_test/build.rs @@ -22,9 +22,8 @@ use weaver_semconv::path::RegistryPath; use weaver_semconv::registry::SemConvRegistry; const SEMCONV_REGISTRY_PATH: &str = "./semconv_registry/"; -const TEMPLATES_PATH: &str = "./templates/registry/"; +const TEMPLATES_PATH: &str = "./templates/registry/rust"; const REGISTRY_ID: &str = "test"; -const TARGET: &str = "rust"; fn main() { // Tell Cargo when to rerun this build script @@ -49,7 +48,7 @@ fn main() { let schema = SchemaResolver::resolve_semantic_convention_registry(&mut registry) .unwrap_or_else(|e| process_error(&logger, e)); - let loader = FileSystemFileLoader::try_new(TEMPLATES_PATH.into(), TARGET) + let loader = FileSystemFileLoader::try_new(TEMPLATES_PATH.into()) .unwrap_or_else(|e| process_error(&logger, e)); let engine = TemplateEngine::try_new(loader, Params::default()) .unwrap_or_else(|e| process_error(&logger, e)); diff --git a/crates/weaver_forge/Cargo.toml b/crates/weaver_forge/Cargo.toml index 57f05a28..1a852d69 100644 --- a/crates/weaver_forge/Cargo.toml +++ b/crates/weaver_forge/Cargo.toml @@ -39,7 +39,6 @@ globset.workspace = true miette.workspace = true include_dir.workspace = true schemars.workspace = true -dirs.workspace = true [dev-dependencies] opentelemetry = { version = "0.22.0", features = ["trace", "metrics", "logs", "otel_unstable"] } diff --git a/crates/weaver_forge/src/config.rs b/crates/weaver_forge/src/config.rs index c7056379..36042df5 100644 --- a/crates/weaver_forge/src/config.rs +++ b/crates/weaver_forge/src/config.rs @@ -3,21 +3,18 @@ //! Weaver Configuration Definition. use std::collections::HashMap; -use std::path::{Path, PathBuf}; +use std::path::Path; use std::sync::OnceLock; -use convert_case::{Case, Casing, Converter, Pattern}; use convert_case::Boundary::{DigitLower, DigitUpper, Hyphen, LowerDigit, Space, UpperDigit}; +use convert_case::{Case, Casing, Converter, Pattern}; use globset::{Glob, GlobSet, GlobSetBuilder}; use serde::Deserialize; use serde_yaml::Value; use crate::error::Error; use crate::error::Error::InvalidConfigFile; -use crate::file_loader::FileLoader; -use crate::WEAVER_YAML; - -const DEFAULT_WEAVER_CONFIG: &'static str = include_str!("../../../defaults/weaver_config/weaver.yaml"); +use crate::file_loader::FileContent; /// Case convention for naming of functions and structs. #[derive(Deserialize, Clone, Debug)] @@ -53,7 +50,7 @@ pub enum CaseConvention { } /// Weaver configuration. -#[derive(Deserialize, Debug, Default)] +#[derive(Deserialize, Debug)] pub(crate) struct WeaverConfig { /// Case convention used to name a file. /// Open question: Do we keep this? It's probably easier for author's templates to use directly @@ -309,72 +306,56 @@ impl CaseConvention { } } -impl WeaverConfig { - pub(crate) fn try_new(loader: &dyn FileLoader) -> Result { - let weaver_file = loader - .load_file(WEAVER_YAML) - .map_err(|e| InvalidConfigFile { - config_file: WEAVER_YAML.into(), - error: e.to_string(), - })?; - if let Some(weaver_file) = weaver_file { - serde_yaml::from_str(&weaver_file).map_err(|e| InvalidConfigFile { - config_file: WEAVER_YAML.into(), - error: e.to_string(), - }) - } else { - Ok(WeaverConfig::default()) +impl Default for WeaverConfig { + fn default() -> Self { + Self { + file_name: Default::default(), + function_name: Default::default(), + arg_name: Default::default(), + struct_name: Default::default(), + field_name: Default::default(), + type_mapping: None, + text_maps: None, + template_syntax: TemplateSyntax { + block_start: Some("{%".to_owned()), + block_end: Some("%}".to_owned()), + variable_start: Some("{{".to_owned()), + variable_end: Some("}}".to_owned()), + comment_start: Some("{#".to_owned()), + comment_end: Some("#}".to_owned()), + }, + whitespace_control: Default::default(), + params: None, + templates: None, + acronyms: None, } } +} - /// Loads the Weaver configuration based on the following order: - /// - /// - the target directory, - /// - the parent directory (i.e., the directory containing all targets), - /// - the $HOME/.weaver/weaver.yaml directory, - /// - and finally the defaults/weaver_config directory embedded in the Weaver binary. - /// - /// A local definition should override any corresponding definition in the parent directory, - /// which itself can override the corresponding entry in the home directory (i.e., defined per - /// user), and finally, the Weaver application binary (i.e., defined by Weaver authors). This - /// hierarchical structure should allow for configuration at the target level, across all - /// targets, at the user level, and even reuse of configurations defined within the Weaver - /// application binary. +impl WeaverConfig { + /// Builds the Weaver configuration from a collection of configurations passed in parameter. + /// The first configuration in the slice is loaded, then if present, the second configuration + /// overrides the first one, and so on. This process is named "configuration resolution". /// - /// This method can fail if any of the configuration file is not a valid YAML file or if the - /// configuration file can't be deserialized into a `WeaverConfig` struct. - pub(crate) fn try_new_2(home_dir: Option, loader: &dyn FileLoader) -> Result { - // Init the weaver config with the embedded defaults - let mut config = serde_yaml::from_str(DEFAULT_WEAVER_CONFIG).map_err(|e| InvalidConfigFile { - config_file: WEAVER_YAML.into(), - error: e.to_string(), - })?; - - // Override the defaults with the weaver.yaml file present in the user's home directory - // if it exists. - if let Some(home_dir) = home_dir { - let home_config = home_dir.join(".weaver/weaver.yaml"); - if home_config.exists() { - let home_config_file = std::fs::File::open(home_config.clone()).map_err(|e| InvalidConfigFile { - config_file: home_config.clone(), + /// This method can fail if any of the configuration content is not a valid YAML file or if the + /// configuration content can't be deserialized into a `WeaverConfig` struct. + pub(crate) fn resolve_from(configs: &[FileContent]) -> Result { + // The default configuration is used as a base for the resolution. + let mut config = WeaverConfig::default(); + if configs.is_empty() { + return Ok(WeaverConfig::default()); + } + + // Each configuration is loaded and merged into the current configuration. + for conf in configs { + let conf: WeaverConfig = + serde_yaml::from_str(&conf.content).map_err(|e| InvalidConfigFile { + config_file: conf.path.clone(), error: e.to_string(), })?; - let home_config: WeaverConfig = serde_yaml::from_reader(home_config_file) - .map_err(|e| InvalidConfigFile { - config_file: home_config.clone(), - error: e.to_string(), - })?; - } + config.override_with(conf); } - // Override the config with the weaver.yaml file present in the parent directory of the - // target directory if it exists. - - // Override the config with the weaver.yaml file present in the target directory if it - // exists. - // deserialize in place, i.e. in the existing config - - Ok(config) } @@ -383,9 +364,9 @@ impl WeaverConfig { if let Some(templates) = &self.templates { let mut builder = GlobSetBuilder::new(); - templates.iter().for_each(|template| { + for template in templates.iter() { _ = builder.add(template.pattern.clone()); - }); + } builder .build() @@ -393,7 +374,7 @@ impl WeaverConfig { error: e.to_string(), }) .map(|glob_set| TemplateMatcher { - templates: &templates, + templates, glob_set, }) } else { @@ -420,7 +401,8 @@ impl WeaverConfig { self.text_maps = other.text_maps; } self.template_syntax.override_with(other.template_syntax); - self.whitespace_control.override_with(other.whitespace_control); + self.whitespace_control + .override_with(other.whitespace_control); if other.params.is_some() { self.params = other.params; } @@ -436,66 +418,136 @@ impl WeaverConfig { #[cfg(test)] mod tests { use std::collections::HashMap; - use crate::config::{ApplicationMode, DEFAULT_WEAVER_CONFIG, WeaverConfig}; - use crate::file_loader::FileSystemFileLoader; + + use crate::config::{ApplicationMode, WeaverConfig}; + use crate::file_loader::FileContent; #[test] - fn test_override_with() { - // Tests type_mapping overrides. + fn test_type_mapping_override_with() { // If defined in both, the local configuration should override the parent configuration. - let mut parent: WeaverConfig = serde_yaml::from_str("type_mapping: {a: \"b\", c: \"d\"}").unwrap(); + let mut parent: WeaverConfig = + serde_yaml::from_str("type_mapping: {a: \"b\", c: \"d\"}").unwrap(); let local: WeaverConfig = serde_yaml::from_str("type_mapping: {a: \"e\"}").unwrap(); parent.override_with(local); - assert_eq!(parent.type_mapping, Some([("a".to_owned(), "e".to_owned())].iter().cloned().collect())); + assert_eq!( + parent.type_mapping, + Some([("a".to_owned(), "e".to_owned())].iter().cloned().collect()) + ); let mut parent: WeaverConfig = WeaverConfig::default(); let local: WeaverConfig = serde_yaml::from_str("type_mapping: {a: \"e\"}").unwrap(); parent.override_with(local); - assert_eq!(parent.type_mapping, Some([("a".to_owned(), "e".to_owned())].iter().cloned().collect())); - let mut parent: WeaverConfig = serde_yaml::from_str("type_mapping: {a: \"b\", c: \"d\"}").unwrap(); + assert_eq!( + parent.type_mapping, + Some([("a".to_owned(), "e".to_owned())].iter().cloned().collect()) + ); + let mut parent: WeaverConfig = + serde_yaml::from_str("type_mapping: {a: \"b\", c: \"d\"}").unwrap(); let local = WeaverConfig::default(); parent.override_with(local); - assert_eq!(parent.type_mapping, Some([("a".to_owned(), "b".to_owned()), ("c".to_owned(), "d".to_owned())].iter().cloned().collect())); + assert_eq!( + parent.type_mapping, + Some( + [ + ("a".to_owned(), "b".to_owned()), + ("c".to_owned(), "d".to_owned()) + ] + .iter() + .cloned() + .collect() + ) + ); + } - // Tests text_maps overrides. + #[test] + fn test_text_maps_override_with() { // If defined in both, the local configuration should override the parent configuration. - let mut parent: WeaverConfig = serde_yaml::from_str("text_maps: {a: {b: \"c\"}, d: {e: \"f\"}}").unwrap(); + let mut parent: WeaverConfig = + serde_yaml::from_str("text_maps: {a: {b: \"c\"}, d: {e: \"f\"}}").unwrap(); let local: WeaverConfig = serde_yaml::from_str("text_maps: {a: {b: \"g\"}}").unwrap(); parent.override_with(local); - assert_eq!(parent.text_maps, Some([("a".to_owned(), [("b".to_owned(), "g".to_owned())].iter().cloned().collect())].iter().cloned().collect())); + assert_eq!( + parent.text_maps, + Some( + [( + "a".to_owned(), + [("b".to_owned(), "g".to_owned())].iter().cloned().collect() + )] + .iter() + .cloned() + .collect() + ) + ); let mut parent: WeaverConfig = WeaverConfig::default(); let local: WeaverConfig = serde_yaml::from_str("text_maps: {a: {b: \"g\"}}").unwrap(); parent.override_with(local); - assert_eq!(parent.text_maps, Some([("a".to_owned(), [("b".to_owned(), "g".to_owned())].iter().cloned().collect())].iter().cloned().collect())); - let mut parent: WeaverConfig = serde_yaml::from_str("text_maps: {a: {b: \"c\"}, d: {e: \"f\"}}").unwrap(); + assert_eq!( + parent.text_maps, + Some( + [( + "a".to_owned(), + [("b".to_owned(), "g".to_owned())].iter().cloned().collect() + )] + .iter() + .cloned() + .collect() + ) + ); + let mut parent: WeaverConfig = + serde_yaml::from_str("text_maps: {a: {b: \"c\"}, d: {e: \"f\"}}").unwrap(); let local = WeaverConfig::default(); parent.override_with(local); - assert_eq!(parent.text_maps, Some([("a".to_owned(), [("b".to_owned(), "c".to_owned())].iter().cloned().collect()), ("d".to_owned(), [("e".to_owned(), "f".to_owned())].iter().cloned().collect())].iter().cloned().collect())); + assert_eq!( + parent.text_maps, + Some( + [ + ( + "a".to_owned(), + [("b".to_owned(), "c".to_owned())].iter().cloned().collect() + ), + ( + "d".to_owned(), + [("e".to_owned(), "f".to_owned())].iter().cloned().collect() + ) + ] + .iter() + .cloned() + .collect() + ) + ); + } - // Tests template syntax overrides. + #[test] + fn test_template_syntax_override_with() { // If defined in both, the local configuration should override the parent configuration. - let mut parent: WeaverConfig = serde_yaml::from_str("template_syntax: {block_start: \"{{\", block_end: \"}}\", variable_start: \"#\"}").unwrap(); - let local: WeaverConfig = serde_yaml::from_str("template_syntax: {block_start: \"[[\", block_end: \"]]\"}").unwrap(); + let mut parent: WeaverConfig = serde_yaml::from_str( + "template_syntax: {block_start: \"{{\", block_end: \"}}\", variable_start: \"#\"}", + ) + .unwrap(); + let local: WeaverConfig = + serde_yaml::from_str("template_syntax: {block_start: \"[[\", block_end: \"]]\"}") + .unwrap(); parent.override_with(local); assert_eq!(parent.template_syntax.block_start, Some("[[".to_owned())); assert_eq!(parent.template_syntax.block_end, Some("]]".to_owned())); assert_eq!(parent.template_syntax.variable_start, Some("#".to_owned())); let mut parent: WeaverConfig = WeaverConfig::default(); - let local: WeaverConfig = serde_yaml::from_str("template_syntax: {block_start: \"[[\", block_end: \"]]\"}").unwrap(); + let local: WeaverConfig = + serde_yaml::from_str("template_syntax: {block_start: \"[[\", block_end: \"]]\"}") + .unwrap(); parent.override_with(local); assert_eq!(parent.template_syntax.block_start, Some("[[".to_owned())); assert_eq!(parent.template_syntax.block_end, Some("]]".to_owned())); - assert_eq!(parent.template_syntax.variable_start, None); - let mut parent: WeaverConfig = serde_yaml::from_str("template_syntax: {block_start: \"{{\", block_end: \"}}\", variable_start: \"#\"}").unwrap(); - let local = WeaverConfig::default(); - parent.override_with(local); - assert_eq!(parent.template_syntax.block_start, Some("{{".to_owned())); - assert_eq!(parent.template_syntax.block_end, Some("}}".to_owned())); - assert_eq!(parent.template_syntax.variable_start, Some("#".to_owned())); + assert_eq!(parent.template_syntax.variable_start, Some("{{".to_owned())); + } - // Tests whitespace control overrides. + #[test] + fn test_whitespace_control_override_with() { // If defined in both, the local configuration should override the parent configuration. - let mut parent: WeaverConfig = serde_yaml::from_str("whitespace_control: {trim_blocks: true, lstrip_blocks: true}").unwrap(); - let local: WeaverConfig = serde_yaml::from_str("whitespace_control: {lstrip_blocks: false}").unwrap(); + let mut parent: WeaverConfig = + serde_yaml::from_str("whitespace_control: {trim_blocks: true, lstrip_blocks: true}") + .unwrap(); + let local: WeaverConfig = + serde_yaml::from_str("whitespace_control: {lstrip_blocks: false}").unwrap(); parent.override_with(local); assert_eq!(parent.whitespace_control.trim_blocks, Some(true)); assert_eq!(parent.whitespace_control.lstrip_blocks, Some(false)); @@ -506,36 +558,62 @@ mod tests { assert_eq!(parent.whitespace_control.trim_blocks, Some(true)); assert_eq!(parent.whitespace_control.lstrip_blocks, Some(true)); assert_eq!(parent.whitespace_control.keep_trailing_newline, Some(true)); - let mut parent: WeaverConfig = serde_yaml::from_str("whitespace_control: {trim_blocks: true, lstrip_blocks: true}").unwrap(); + let mut parent: WeaverConfig = + serde_yaml::from_str("whitespace_control: {trim_blocks: true, lstrip_blocks: true}") + .unwrap(); let local = WeaverConfig::default(); parent.override_with(local); assert_eq!(parent.whitespace_control.trim_blocks, Some(true)); assert_eq!(parent.whitespace_control.lstrip_blocks, Some(true)); assert_eq!(parent.whitespace_control.keep_trailing_newline, None); + } - // Tests params overrides. + #[test] + fn test_params_override_with() { // If defined in both, the local configuration should override the parent configuration. let mut parent: WeaverConfig = serde_yaml::from_str("params: {a: 1, b: 2}").unwrap(); let local: WeaverConfig = serde_yaml::from_str("params: {a: 3}").unwrap(); parent.override_with(local); - assert_eq!(parent.params, Some([("a".to_owned(), 3.into())].iter().cloned().collect())); + assert_eq!( + parent.params, + Some([("a".to_owned(), 3.into())].iter().cloned().collect()) + ); let mut parent: WeaverConfig = WeaverConfig::default(); let local: WeaverConfig = serde_yaml::from_str("params: {a: 3}").unwrap(); parent.override_with(local); - assert_eq!(parent.params, Some([("a".to_owned(), 3.into())].iter().cloned().collect())); + assert_eq!( + parent.params, + Some([("a".to_owned(), 3.into())].iter().cloned().collect()) + ); let mut parent: WeaverConfig = serde_yaml::from_str("params: {a: 1, b: 2}").unwrap(); - let local= WeaverConfig::default(); + let local = WeaverConfig::default(); parent.override_with(local); - assert_eq!(parent.params, Some([("a".to_owned(), 1.into()), ("b".to_owned(), 2.into())].iter().cloned().collect())); + assert_eq!( + parent.params, + Some( + [("a".to_owned(), 1.into()), ("b".to_owned(), 2.into())] + .iter() + .cloned() + .collect() + ) + ); let mut parent: WeaverConfig = serde_yaml::from_str("params: {a: 1, b: 2}").unwrap(); let local: WeaverConfig = serde_yaml::from_str("params: {}").unwrap(); parent.override_with(local); assert_eq!(parent.params, Some(HashMap::default())); + } - // Tests templates overrides. + #[test] + fn test_templates_override_with() { // If defined in both, the local configuration should override the parent configuration. - let mut parent: WeaverConfig = serde_yaml::from_str("templates: [{pattern: \"**/parent.md\", filter: \".\", application_mode: \"single\"}]").unwrap(); - let local: WeaverConfig = serde_yaml::from_str("templates: [{pattern: \"**/local.md\", filter: \".\", application_mode: \"each\"}]").unwrap(); + let mut parent: WeaverConfig = serde_yaml::from_str( + "templates: [{pattern: \"**/parent.md\", filter: \".\", application_mode: \"single\"}]", + ) + .unwrap(); + let local: WeaverConfig = serde_yaml::from_str( + "templates: [{pattern: \"**/local.md\", filter: \".\", application_mode: \"each\"}]", + ) + .unwrap(); parent.override_with(local); assert!(parent.templates.is_some()); let templates = parent.templates.unwrap(); @@ -544,7 +622,10 @@ mod tests { assert_eq!(templates[0].filter, "."); assert_eq!(templates[0].application_mode, ApplicationMode::Each); let mut parent: WeaverConfig = WeaverConfig::default(); - let local: WeaverConfig = serde_yaml::from_str("templates: [{pattern: \"**/local.md\", filter: \".\", application_mode: \"each\"}]").unwrap(); + let local: WeaverConfig = serde_yaml::from_str( + "templates: [{pattern: \"**/local.md\", filter: \".\", application_mode: \"each\"}]", + ) + .unwrap(); parent.override_with(local); assert!(parent.templates.is_some()); let templates = parent.templates.unwrap(); @@ -552,7 +633,10 @@ mod tests { assert_eq!(templates[0].pattern.to_string(), "**/local.md"); assert_eq!(templates[0].filter, "."); assert_eq!(templates[0].application_mode, ApplicationMode::Each); - let mut parent: WeaverConfig = serde_yaml::from_str("templates: [{pattern: \"**/parent.md\", filter: \".\", application_mode: \"single\"}]").unwrap(); + let mut parent: WeaverConfig = serde_yaml::from_str( + "templates: [{pattern: \"**/parent.md\", filter: \".\", application_mode: \"single\"}]", + ) + .unwrap(); let local = WeaverConfig::default(); parent.override_with(local); assert!(parent.templates.is_some()); @@ -561,28 +645,42 @@ mod tests { assert_eq!(templates[0].pattern.to_string(), "**/parent.md"); assert_eq!(templates[0].filter, "."); assert_eq!(templates[0].application_mode, ApplicationMode::Single); - let mut parent: WeaverConfig = serde_yaml::from_str("templates: [{pattern: \"**/parent.md\", filter: \".\", application_mode: \"single\"}]").unwrap(); + let mut parent: WeaverConfig = serde_yaml::from_str( + "templates: [{pattern: \"**/parent.md\", filter: \".\", application_mode: \"single\"}]", + ) + .unwrap(); let local: WeaverConfig = serde_yaml::from_str("templates: []").unwrap(); parent.override_with(local); assert!(parent.templates.is_some()); let templates = parent.templates.unwrap(); assert_eq!(templates.len(), 0); + } - // Tests acronyms overrides. + #[test] + fn test_acronyms_override_with() { // If defined in both, the local configuration should override the parent configuration. - let mut parent: WeaverConfig = serde_yaml::from_str("acronyms: ['iOS', 'API', 'URL']").unwrap(); + let mut parent: WeaverConfig = + serde_yaml::from_str("acronyms: ['iOS', 'API', 'URL']").unwrap(); let local: WeaverConfig = serde_yaml::from_str("acronyms: ['iOS']").unwrap(); parent.override_with(local); assert_eq!(parent.acronyms, Some(vec!["iOS".to_owned()])); let mut parent = WeaverConfig::default(); let local: WeaverConfig = serde_yaml::from_str("acronyms: ['iOS', 'API', 'URL']").unwrap(); parent.override_with(local); - assert_eq!(parent.acronyms, Some(vec!["iOS".to_owned(), "API".to_owned(), "URL".to_owned()])); - let mut parent: WeaverConfig = serde_yaml::from_str("acronyms: ['iOS', 'API', 'URL']").unwrap(); + assert_eq!( + parent.acronyms, + Some(vec!["iOS".to_owned(), "API".to_owned(), "URL".to_owned()]) + ); + let mut parent: WeaverConfig = + serde_yaml::from_str("acronyms: ['iOS', 'API', 'URL']").unwrap(); let local = WeaverConfig::default(); parent.override_with(local); - assert_eq!(parent.acronyms, Some(vec!["iOS".to_owned(), "API".to_owned(), "URL".to_owned()])); - let mut parent: WeaverConfig = serde_yaml::from_str("acronyms: ['iOS', 'API', 'URL']").unwrap(); + assert_eq!( + parent.acronyms, + Some(vec!["iOS".to_owned(), "API".to_owned(), "URL".to_owned()]) + ); + let mut parent: WeaverConfig = + serde_yaml::from_str("acronyms: ['iOS', 'API', 'URL']").unwrap(); let local: WeaverConfig = serde_yaml::from_str("acronyms: []").unwrap(); parent.override_with(local); assert_eq!(parent.acronyms, Some(vec![])); @@ -590,11 +688,30 @@ mod tests { #[test] fn test_try_new() -> Result<(), Box> { - let loader = FileSystemFileLoader::try_new("templates/registry".into(), "test")?; - let config = WeaverConfig::try_new_2(dirs::home_dir(), &loader) - .expect("Failed to load the Weaver configuration"); + let configs = vec![ + FileContent::try_from_path("templates/registry/weaver.yaml").unwrap(), + FileContent::try_from_path("templates/registry/xyz/weaver.yaml").unwrap(), + ]; + let config = + WeaverConfig::resolve_from(&configs).expect("Failed to load the Weaver configuration"); + + assert!(config.text_maps.is_none()); + + assert_eq!(config.template_syntax.block_start, Some(">".to_owned())); + assert_eq!(config.template_syntax.block_end, Some("<<".to_owned())); + assert_eq!(config.template_syntax.variable_start, Some("{{".to_owned())); + assert_eq!(config.template_syntax.variable_end, Some("}}".to_owned())); + assert_eq!(config.template_syntax.comment_start, Some("{#".to_owned())); + assert_eq!(config.template_syntax.comment_end, Some("#}".to_owned())); + + assert_eq!(config.whitespace_control.trim_blocks, Some(true)); + assert_eq!(config.whitespace_control.lstrip_blocks, Some(false)); + assert_eq!(config.whitespace_control.keep_trailing_newline, Some(true)); + + assert!(config.params.is_none()); + assert!(config.templates.is_none()); + assert!(config.acronyms.is_none()); - dbg!(config); Ok(()) } -} \ No newline at end of file +} diff --git a/crates/weaver_forge/src/extensions/code.rs b/crates/weaver_forge/src/extensions/code.rs index 007344a4..f991ba11 100644 --- a/crates/weaver_forge/src/extensions/code.rs +++ b/crates/weaver_forge/src/extensions/code.rs @@ -9,8 +9,14 @@ use minijinja::{Environment, Value}; /// Add code-oriented filters to the environment. pub(crate) fn add_filters(env: &mut Environment<'_>, config: &WeaverConfig) { - env.add_filter("type_mapping", type_mapping(config.type_mapping.clone().unwrap_or_default())); - env.add_filter("map_text", map_text(config.text_maps.clone().unwrap_or_default())); + env.add_filter( + "type_mapping", + type_mapping(config.type_mapping.clone().unwrap_or_default()), + ); + env.add_filter( + "map_text", + map_text(config.text_maps.clone().unwrap_or_default()), + ); env.add_filter("comment_with_prefix", comment_with_prefix); env.add_filter("markdown_to_html", markdown_to_html); } diff --git a/crates/weaver_forge/src/extensions/util.rs b/crates/weaver_forge/src/extensions/util.rs index d9444e38..b1d2d426 100644 --- a/crates/weaver_forge/src/extensions/util.rs +++ b/crates/weaver_forge/src/extensions/util.rs @@ -10,7 +10,10 @@ use std::sync::OnceLock; /// Add utility filters and tests to the environment. pub(crate) fn add_filters(env: &mut Environment<'_>, target_config: &WeaverConfig) { - env.add_filter("acronym", acronym(target_config.acronyms.clone().unwrap_or_default())); + env.add_filter( + "acronym", + acronym(target_config.acronyms.clone().unwrap_or_default()), + ); env.add_filter("flatten", flatten); env.add_filter("split_id", split_id); } diff --git a/crates/weaver_forge/src/file_loader.rs b/crates/weaver_forge/src/file_loader.rs index b9485426..207d3d41 100644 --- a/crates/weaver_forge/src/file_loader.rs +++ b/crates/weaver_forge/src/file_loader.rs @@ -9,7 +9,6 @@ use minijinja::ErrorKind; use walkdir::WalkDir; use crate::error::Error; -use crate::error::Error::TargetNotSupported; /// An abstraction for loading files from a file system, embedded directory, etc. pub trait FileLoader { @@ -21,7 +20,28 @@ pub trait FileLoader { fn all_files(&self) -> Vec; /// Returns the content of a file from a given name. - fn load_file(&self, file: &str) -> Result, Error>; + fn load_file(&self, file: &str) -> Result, Error>; +} + +/// A struct that represents the content of a file. +#[derive(Debug)] +pub struct FileContent { + /// The path from which the file was loaded. + pub path: PathBuf, + /// The content of the file. + pub content: String, +} + +impl FileContent { + /// Creates a new file content from a path or returns an error if the path is invalid. + pub fn try_from_path>(path: P) -> Result { + let path = path.as_ref().to_path_buf(); + let content = fs::read_to_string(path.clone()).map_err(|e| Error::FileLoaderError { + file: path.clone(), + error: e.to_string(), + })?; + Ok(Self { path, content }) + } } /// A loader that loads files from the embedded directory in the binary of Weaver or @@ -30,7 +50,6 @@ pub trait FileLoader { /// This is useful for loading templates and other files that are embedded in the binary but /// can be overridden by the user. pub struct EmbeddedFileLoader { - target: String, embedded_dir: &'static include_dir::Dir<'static>, fs_loader: Option, } @@ -38,32 +57,28 @@ pub struct EmbeddedFileLoader { impl EmbeddedFileLoader { /// Create a new embedded file loader. /// - /// If the `local_dir/target` directory exists, the loader will use the file system loader. + /// If the `local_dir` directory exists, the loader will use the file system loader. /// Otherwise, it will use the embedded directory. pub fn try_new( - embedded_dir: &'static include_dir::Dir<'static>, + root_embedded_dir: &'static include_dir::Dir<'static>, + sub_embedded_dir: &str, local_dir: PathBuf, - target: &str, ) -> Result { - let target_embedded_dir = embedded_dir.get_dir(target); - let target_local_dir = local_dir.join(target); - if let Some(dir) = target_embedded_dir { - Ok(Self { - target: target.to_owned(), - embedded_dir: dir, - fs_loader: if target_local_dir.exists() { - Some(FileSystemFileLoader::try_new(local_dir, target)?) - } else { - None - }, - }) - } else { - Err(TargetNotSupported { - root_path: embedded_dir.path().to_string_lossy().to_string(), - target: target.to_owned(), - error: "Target not found".to_owned(), - }) - } + let embedded_dir = + root_embedded_dir + .get_dir(sub_embedded_dir) + .ok_or_else(|| Error::FileLoaderError { + file: PathBuf::from(sub_embedded_dir), + error: "Failed to get sub embedded directory".to_owned(), + })?; + Ok(Self { + embedded_dir, + fs_loader: if local_dir.exists() { + Some(FileSystemFileLoader::try_new(local_dir)?) + } else { + None + }, + }) } } @@ -101,21 +116,23 @@ impl FileLoader for EmbeddedFileLoader { } /// Returns the content of a file from a given name. - fn load_file(&self, file: &str) -> Result, Error> { + fn load_file(&self, file: &str) -> Result, Error> { if let Some(fs_loader) = &self.fs_loader { return fs_loader.load_file(file); } - let name = format!("{}/{}", self.target, file); - match self.embedded_dir.get_file(name) { - Some(file) => Ok(Some( - file.contents_utf8() + let file = &format!("{}/{}", self.embedded_dir.path().to_string_lossy(), file); + match self.embedded_dir.get_file(file) { + Some(file) => Ok(Some(FileContent { + content: file + .contents_utf8() .ok_or_else(|| Error::FileLoaderError { file: file.path().to_owned(), error: "Failed to read file contents".to_owned(), })? .to_owned(), - )), + path: file.path().to_path_buf(), + })), None => Ok(None), } } @@ -128,12 +145,13 @@ pub struct FileSystemFileLoader { impl FileSystemFileLoader { /// Create a new file system loader - pub fn try_new(dir: PathBuf, target: &str) -> Result { - let dir = safe_join(&dir, target).map_err(|e| TargetNotSupported { - root_path: dir.to_string_lossy().to_string(), - target: target.to_owned(), - error: e.to_string(), - })?; + pub fn try_new(dir: PathBuf) -> Result { + if !dir.exists() { + return Err(Error::FileLoaderError { + file: dir.clone(), + error: "Directory does not exist".to_owned(), + }); + } Ok(Self { dir }) } } @@ -167,14 +185,17 @@ impl FileLoader for FileSystemFileLoader { /// Returns a function that loads a file from a given name /// Based on MiniJinja loader semantics, the function should return `Ok(None)` if the template /// does not exist. - fn load_file(&self, file: &str) -> Result, Error> { + fn load_file(&self, file: &str) -> Result, Error> { let path = if let Ok(path) = safe_join(&self.dir, file) { path } else { return Ok(None); }; match fs::read_to_string(path.clone()) { - Ok(result) => Ok(Some(result)), + Ok(result) => Ok(Some(FileContent { + content: result, + path, + })), Err(err) if err.kind() == io::ErrorKind::NotFound => Ok(None), Err(err) => Err(Error::FileLoaderError { file: path, @@ -233,36 +254,40 @@ mod tests { fn test_template_loader() { let embedded_loader = EmbeddedFileLoader::try_new( &EMBEDDED_TEMPLATES, - PathBuf::from("./does-not-exist"), "test", + PathBuf::from("./does-not-exist/test"), ) .unwrap(); let embedded_content = embedded_loader.load_file("group.md"); assert!(embedded_content.is_ok()); let embedded_content = embedded_content.unwrap().unwrap(); - assert!(embedded_content.contains("# Group `{{ ctx.id }}` ({{ ctx.type }})")); + assert!(embedded_content + .content + .contains("# Group `{{ ctx.id }}` ({{ ctx.type }})")); let overloaded_embedded_loader = EmbeddedFileLoader::try_new( &EMBEDDED_TEMPLATES, - PathBuf::from("./overloaded-templates"), "test", + PathBuf::from("./overloaded-templates/test"), ) .unwrap(); let overloaded_embedded_content = overloaded_embedded_loader.load_file("group.md"); assert!(overloaded_embedded_content.is_ok()); let overloaded_embedded_content = overloaded_embedded_content.unwrap().unwrap(); assert!(overloaded_embedded_content + .content .contains("# Overloaded Group `{{ ctx.id }}` ({{ ctx.type }})")); - let fs_loader = - FileSystemFileLoader::try_new(PathBuf::from("./templates"), "test").unwrap(); + let fs_loader = FileSystemFileLoader::try_new(PathBuf::from("./templates/test")).unwrap(); let fs_content = fs_loader.load_file("group.md"); assert!(fs_content.is_ok()); let fs_content = fs_content.unwrap().unwrap(); - assert!(fs_content.contains("# Group `{{ ctx.id }}` ({{ ctx.type }})")); + assert!(fs_content + .content + .contains("# Group `{{ ctx.id }}` ({{ ctx.type }})")); // Test content equality between embedded and file system loaders - assert_eq!(embedded_content, fs_content); + assert_eq!(embedded_content.content, fs_content.content); // Test root path assert_eq!( @@ -326,8 +351,8 @@ mod tests { fn test_embedded_loader_error() { let embedded_loader = EmbeddedFileLoader::try_new( &EMBEDDED_TEMPLATES, - PathBuf::from("./does-not-exist"), "doesn't-exist", + PathBuf::from("./does-not-exist/doesn't-exist"), ); assert!(embedded_loader.is_err()); @@ -335,8 +360,7 @@ mod tests { #[test] fn test_file_system_loader_error() { - let fs_loader = - FileSystemFileLoader::try_new(PathBuf::from("./templates"), "doesn't-exist"); + let fs_loader = FileSystemFileLoader::try_new(PathBuf::from("./templates/doesn't-exist")); assert!(fs_loader.is_err()); } diff --git a/crates/weaver_forge/src/lib.rs b/crates/weaver_forge/src/lib.rs index bf649ed2..8d5df699 100644 --- a/crates/weaver_forge/src/lib.rs +++ b/crates/weaver_forge/src/lib.rs @@ -11,9 +11,9 @@ use std::path::{Path, PathBuf}; use std::sync::{Arc, Mutex}; use jaq_interpret::Val; -use minijinja::{Environment, ErrorKind, State, Value}; use minijinja::syntax::SyntaxConfig; use minijinja::value::{from_args, Object}; +use minijinja::{Environment, ErrorKind, State, Value}; use rayon::iter::IntoParallelIterator; use rayon::iter::ParallelIterator; use serde::Serialize; @@ -77,7 +77,7 @@ impl Object for TemplateObject { args: &[Value], ) -> Result { if name == "set_file_name" { - let (file_name, ): (&str,) = from_args(args)?; + let (file_name,): (&str,) = from_args(args)?; file_name.clone_into(&mut self.file_name.lock().expect("Lock poisoned")); Ok(Value::from("")) } else { @@ -166,12 +166,18 @@ impl TemplateEngine { loader: impl FileLoader + Send + Sync + 'static, params: Params, ) -> Result { - let mut target_config = WeaverConfig::try_new(&loader)?; + let config = loader.load_file(WEAVER_YAML)?; + let mut target_config = if let Some(config) = config { + WeaverConfig::resolve_from(&[config])? + } else { + WeaverConfig::default() + }; // Override the params defined in the `weaver.yaml` file with the params provided // in the command line. for (name, value) in params.params { - _ = target_config.params + _ = target_config + .params .get_or_insert_with(HashMap::new) .insert(name, value); } @@ -240,11 +246,8 @@ impl TemplateEngine { let mut errors = Vec::new(); // Build JQ context from the params. - let (jq_vars, jq_ctx): (Vec, Vec) = self - .target_config - .params - .as_ref() - .map_or_else( + let (jq_vars, jq_ctx): (Vec, Vec) = + self.target_config.params.as_ref().map_or_else( || (Vec::new(), Vec::new()), // If self.target_config.params is None, return empty vectors |params| { params @@ -299,7 +302,7 @@ impl TemplateEngine { ApplicationMode::Single => { if filtered_result.is_null() || (filtered_result.is_array() - && filtered_result.as_array().expect("is_array").is_empty()) + && filtered_result.as_array().expect("is_array").is_empty()) { // Skip the template evaluation if the filtered result is null or an empty array continue; @@ -309,8 +312,8 @@ impl TemplateEngine { NewContext { ctx: &filtered_result, } - .try_into() - .ok()?, + .try_into() + .ok()?, relative_path.as_path(), output_directive, output_dir, @@ -346,8 +349,8 @@ impl TemplateEngine { NewContext { ctx: &filtered_result, } - .try_into() - .ok()?, + .try_into() + .ok()?, relative_path.as_path(), output_directive, output_dir, @@ -394,7 +397,9 @@ impl TemplateEngine { engine.add_global("template", Value::from_object(template_object.clone())); engine.add_global( "params", - Value::from_object(ParamsObject::new(self.target_config.params.clone().unwrap_or_default())), + Value::from_object(ParamsObject::new( + self.target_config.params.clone().unwrap_or_default(), + )), ); let template = engine.get_template(template_file).map_err(|e| { @@ -439,16 +444,36 @@ impl TemplateEngine { let syntax = SyntaxConfig::builder() .block_delimiters( - Cow::Owned(template_syntax.block_start.unwrap_or_else(|| "{%".to_owned())), + Cow::Owned( + template_syntax + .block_start + .unwrap_or_else(|| "{%".to_owned()), + ), Cow::Owned(template_syntax.block_end.unwrap_or_else(|| "%}".to_owned())), ) .variable_delimiters( - Cow::Owned(template_syntax.variable_start.unwrap_or_else(|| "{{".to_owned())), - Cow::Owned(template_syntax.variable_end.unwrap_or_else(|| "}}".to_owned())), + Cow::Owned( + template_syntax + .variable_start + .unwrap_or_else(|| "{{".to_owned()), + ), + Cow::Owned( + template_syntax + .variable_end + .unwrap_or_else(|| "}}".to_owned()), + ), ) .comment_delimiters( - Cow::Owned(template_syntax.comment_start.unwrap_or_else(|| "{#".to_owned())), - Cow::Owned(template_syntax.comment_end.unwrap_or_else(|| "#}".to_owned())), + Cow::Owned( + template_syntax + .comment_start + .unwrap_or_else(|| "{#".to_owned()), + ), + Cow::Owned( + template_syntax + .comment_end + .unwrap_or_else(|| "#}".to_owned()), + ), ) .build() .map_err(|e| InvalidConfigFile { @@ -462,6 +487,7 @@ impl TemplateEngine { file_loader .load_file(name) .map_err(|e| minijinja::Error::new(ErrorKind::InvalidOperation, e.to_string())) + .map(|opt_file_content| opt_file_content.map(|file_content| file_content.content)) }); env.set_syntax(syntax); @@ -525,8 +551,8 @@ mod tests { use crate::debug::print_dedup_errors; use crate::extensions::case::case_converter; use crate::file_loader::FileSystemFileLoader; - use crate::OutputDirective; use crate::registry::ResolvedRegistry; + use crate::OutputDirective; #[test] fn test_case_converter() { @@ -653,7 +679,7 @@ mod tests { #[test] fn test() { let logger = TestLogger::default(); - let loader = FileSystemFileLoader::try_new("templates".into(), "test") + let loader = FileSystemFileLoader::try_new("templates/test".into()) .expect("Failed to create file system loader"); let mut engine = super::TemplateEngine::try_new(loader, Params::default()) .expect("Failed to create template engine"); @@ -677,12 +703,12 @@ mod tests { schema.registry(registry_id).expect("registry not found"), schema.catalog(), ) - .unwrap_or_else(|e| { - panic!( - "Failed to create the context for the template evaluation: {:?}", - e - ) - }); + .unwrap_or_else(|e| { + panic!( + "Failed to create the context for the template evaluation: {:?}", + e + ) + }); engine .generate( @@ -702,7 +728,7 @@ mod tests { #[test] fn test_whitespace_control() { let logger = TestLogger::default(); - let loader = FileSystemFileLoader::try_new("whitespace_control_templates".into(), "test") + let loader = FileSystemFileLoader::try_new("whitespace_control_templates/test".into()) .expect("Failed to create file system loader"); let engine = super::TemplateEngine::try_new(loader, Params::default()) .expect("Failed to create template engine"); @@ -717,12 +743,12 @@ mod tests { schema.registry(registry_id).expect("registry not found"), schema.catalog(), ) - .unwrap_or_else(|e| { - panic!( - "Failed to create the context for the template evaluation: {:?}", - e - ) - }); + .unwrap_or_else(|e| { + panic!( + "Failed to create the context for the template evaluation: {:?}", + e + ) + }); engine .generate( @@ -740,6 +766,6 @@ mod tests { "whitespace_control_templates/test/expected_output", "whitespace_control_templates/test/observed_output", ) - .unwrap()); + .unwrap()); } } diff --git a/crates/weaver_forge/templates/registry/test/weaver.yaml b/crates/weaver_forge/templates/registry/test/weaver.yaml deleted file mode 100644 index e69de29b..00000000 diff --git a/crates/weaver_forge/templates/registry/weaver.yaml b/crates/weaver_forge/templates/registry/weaver.yaml index e69de29b..e212f683 100644 --- a/crates/weaver_forge/templates/registry/weaver.yaml +++ b/crates/weaver_forge/templates/registry/weaver.yaml @@ -0,0 +1,7 @@ +template_syntax: + block_start: ">" + block_end: "<" + +whitespace_control: + trim_blocks: true + lstrip_blocks: true diff --git a/crates/weaver_forge/templates/registry/xyz/weaver.yaml b/crates/weaver_forge/templates/registry/xyz/weaver.yaml new file mode 100644 index 00000000..65f6f188 --- /dev/null +++ b/crates/weaver_forge/templates/registry/xyz/weaver.yaml @@ -0,0 +1,8 @@ +template_syntax: + block_start: ">" + block_end: "<<" + +whitespace_control: + trim_blocks: true + lstrip_blocks: false + keep_trailing_newline: true diff --git a/crates/weaver_semconv_gen/src/lib.rs b/crates/weaver_semconv_gen/src/lib.rs index 551c09f9..b668efa5 100644 --- a/crates/weaver_semconv_gen/src/lib.rs +++ b/crates/weaver_semconv_gen/src/lib.rs @@ -439,7 +439,7 @@ mod tests { #[test] fn test_template_engine() -> Result<(), Error> { - let loader = FileSystemFileLoader::try_new("templates/registry".into(), "markdown")?; + let loader = FileSystemFileLoader::try_new("templates/registry/markdown".into())?; let template = TemplateEngine::try_new(loader, Params::default())?; let generator = SnippetGenerator::try_from_path("data", Some(template))?; let attribute_registry_url = "/docs/attributes-registry"; diff --git a/src/main.rs b/src/main.rs index 11e0ea11..b3bcfac3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -133,8 +133,13 @@ fn process_diagnostics( if let Err(diagnostic_messages) = cmd_result.command_result { let loader = EmbeddedFileLoader::try_new( &DEFAULT_DIAGNOSTIC_TEMPLATES, - diagnostic_args.diagnostic_template, &diagnostic_args.diagnostic_format, + format!( + "{}/{}", + diagnostic_args.diagnostic_template.to_string_lossy(), + &diagnostic_args.diagnostic_format + ) + .into(), ) .expect("Failed to create the embedded file loader for the diagnostic templates"); match TemplateEngine::try_new(loader, Params::default()) { diff --git a/src/registry/generate.rs b/src/registry/generate.rs index 0413cac2..1d4ff563 100644 --- a/src/registry/generate.rs +++ b/src/registry/generate.rs @@ -26,9 +26,6 @@ use crate::{DiagnosticArgs, ExitDirectives}; /// Parameters for the `registry generate` sub-command #[derive(Debug, Args)] pub struct RegistryGenerateArgs { - /// Target to generate the artifacts for. - pub target: String, - /// Path to the directory where the generated artifacts will be saved. /// Default is the `output` directory. #[arg(default_value = "output")] @@ -108,7 +105,7 @@ pub(crate) fn command( let mut registry = SemConvRegistry::from_semconv_specs(registry_id, semconv_specs); let schema = resolve_semconv_specs(&mut registry, logger.clone())?; - let loader = FileSystemFileLoader::try_new(args.templates.join("registry"), &args.target)?; + let loader = FileSystemFileLoader::try_new(args.templates.clone())?; let engine = TemplateEngine::try_new(loader, params)?; let template_registry = ResolvedRegistry::try_from_resolved_registry( @@ -185,9 +182,8 @@ mod tests { quiet: false, command: Some(Commands::Registry(RegistryCommand { command: RegistrySubCommand::Generate(RegistryGenerateArgs { - target: "rust".to_owned(), output: temp_output.clone(), - templates: PathBuf::from("crates/weaver_codegen_test/templates/"), + templates: PathBuf::from("crates/weaver_codegen_test/templates/registry/rust"), param: None, params: None, registry: RegistryArgs { @@ -254,9 +250,8 @@ mod tests { quiet: false, command: Some(Commands::Registry(RegistryCommand { command: RegistrySubCommand::Generate(RegistryGenerateArgs { - target: "rust".to_owned(), output: temp_output.clone(), - templates: PathBuf::from("crates/weaver_codegen_test/templates/"), + templates: PathBuf::from("crates/weaver_codegen_test/templates/registry/rust"), param: None, params: None, registry: RegistryArgs { diff --git a/src/registry/update_markdown.rs b/src/registry/update_markdown.rs index c556782c..0f4bba30 100644 --- a/src/registry/update_markdown.rs +++ b/src/registry/update_markdown.rs @@ -68,8 +68,7 @@ pub(crate) fn command( None => None, Some(target) => { let loader = FileSystemFileLoader::try_new( - format!("{}/registry", args.templates).into(), - target, + format!("{}/registry/{}", args.templates, target).into(), )?; Some(TemplateEngine::try_new(loader, Params::default())?) } diff --git a/tests/registry_check.rs b/tests/registry_check.rs index fa95c6a9..a67aa914 100644 --- a/tests/registry_check.rs +++ b/tests/registry_check.rs @@ -19,7 +19,6 @@ fn test_cli_interface() { .output() .expect("failed to execute process"); - dbg!(&output); assert!(output.status.success()); // Test a local semantic convention registry. diff --git a/tests/registry_generate.rs b/tests/registry_generate.rs index e8d32832..40571392 100644 --- a/tests/registry_generate.rs +++ b/tests/registry_generate.rs @@ -30,10 +30,9 @@ fn test_cli_interface() { .arg("-r") .arg("crates/weaver_codegen_test/semconv_registry/") .arg("-t") - .arg("crates/weaver_codegen_test/templates/") + .arg("crates/weaver_codegen_test/templates/rust") .arg("--diagnostic-format") .arg("json") - .arg("rust") .arg("output/") .timeout(std::time::Duration::from_secs(60)) .output() From b6bb5ef675bef6d48a99899ad743826eb61f3157 Mon Sep 17 00:00:00 2001 From: Laurent Querel Date: Tue, 9 Jul 2024 21:09:17 -0700 Subject: [PATCH 04/29] chore(forge): Fix a unit test. --- crates/weaver_forge/src/lib.rs | 8 +-- .../weaver_forge/templates/test/weaver.yaml | 49 ++++++++++++++++++- defaults/weaver_config/weaver.yaml | 22 --------- justfile | 1 + src/registry/generate.rs | 7 +++ 5 files changed, 61 insertions(+), 26 deletions(-) delete mode 100644 defaults/weaver_config/weaver.yaml diff --git a/crates/weaver_forge/src/lib.rs b/crates/weaver_forge/src/lib.rs index 8d5df699..c0b53432 100644 --- a/crates/weaver_forge/src/lib.rs +++ b/crates/weaver_forge/src/lib.rs @@ -677,7 +677,7 @@ mod tests { } #[test] - fn test() { + fn test_template_engine() { let logger = TestLogger::default(); let loader = FileSystemFileLoader::try_new("templates/test".into()) .expect("Failed to create file system loader"); @@ -687,11 +687,13 @@ mod tests { // Add a template configuration for converter.md on top // of the default template configuration. This is useful // for test coverage purposes. - engine.target_config.templates = Some(vec![TemplateConfig { + let mut templates = engine.target_config.templates.unwrap_or_default(); + templates.push(TemplateConfig { pattern: Glob::new("converter.md").unwrap(), filter: ".".to_owned(), application_mode: ApplicationMode::Single, - }]); + }); + engine.target_config.templates = Some(templates); let registry_id = "default"; let mut registry = SemConvRegistry::try_from_path_pattern(registry_id, "data/*.yaml") diff --git a/crates/weaver_forge/templates/test/weaver.yaml b/crates/weaver_forge/templates/test/weaver.yaml index 3a7ad593..e100857c 100644 --- a/crates/weaver_forge/templates/test/weaver.yaml +++ b/crates/weaver_forge/templates/test/weaver.yaml @@ -14,4 +14,51 @@ type_mapping: "boolean[]": "[]bool" "string[]": "[]string" -acronyms: ["iOS", "API", "URL"] \ No newline at end of file +acronyms: ["iOS", "API", "URL"] + +templates: + - pattern: "registry.md" + filter: "." + application_mode: single + - pattern: "**/attribute_group.md" + filter: ".groups[] | select(.type == \"attribute_group\")" + application_mode: each + - pattern: "**/attribute_groups.md" + filter: ".groups[] | select(.type == \"attribute_group\")" + application_mode: single + - pattern: "**/event.md" + filter: ".groups[] | select(.type == \"event\")" + application_mode: each + - pattern: "**/events.md" + filter: ".groups[] | select(.type == \"event\")" + application_mode: single + - pattern: "**/group.md" + filter: ".groups" + application_mode: each + - pattern: "**/groups.md" + filter: ".groups" + application_mode: single + - pattern: "**/metric.md" + filter: ".groups[] | select(.type == \"metric\")" + application_mode: each + - pattern: "**/metrics.md" + filter: ".groups[] | select(.type == \"metric\")" + application_mode: single + - pattern: "**/resource.md" + filter: ".groups[] | select(.type == \"resource\")" + application_mode: each + - pattern: "**/resources.md" + filter: ".groups[] | select(.type == \"resource\")" + application_mode: single + - pattern: "**/scope.md" + filter: ".groups[] | select(.type == \"scope\")" + application_mode: each + - pattern: "**/scopes.md" + filter: ".groups[] | select(.type == \"scope\")" + application_mode: single + - pattern: "**/span.md" + filter: ".groups[] | select(.type == \"span\")" + application_mode: each + - pattern: "**/spans.md" + filter: ".groups[] | select(.type == \"span\")" + application_mode: single \ No newline at end of file diff --git a/defaults/weaver_config/weaver.yaml b/defaults/weaver_config/weaver.yaml deleted file mode 100644 index 05fae55e..00000000 --- a/defaults/weaver_config/weaver.yaml +++ /dev/null @@ -1,22 +0,0 @@ -# This file contains the default configuration used by Weaver. -# -# Weaver allows local configuration for a particular target as well as global -# configuration. It looks for configuration files in the target directory, the -# parent directory (i.e., the directory containing all the targets), the -# `$HOME/.weaver/weaver.yaml` directory, and finally in the -# `defaults/weaver_config` directory (embedded in the Weaver binary). A local -# definition overrides the corresponding definition that may be present in the -# parent directory, which itself may redefine the corresponding entry in the -# home directory (i.e., defined per user), and finally in the Weaver application -# binary (i.e., defined by Weaver authors). With this structure, we can specify -# configuration per target, for all targets, and even reuse a configuration -# defined in the binary of the Weaver application. - -# Default template syntax. -template_syntax: - block_start: "{%" - block_end: "%}" - variable_start: "{{" - variable_end: "}}" - comment_start: "{#" - comment_end: "#}" diff --git a/justfile b/justfile index ffdd6cf6..73ef51ed 100644 --- a/justfile +++ b/justfile @@ -19,6 +19,7 @@ pre-push-check: # [ToDo LQ] Re-enable --all-features once the issue is resolved # cargo clippy --workspace --all-features --all-targets -- -D warnings --allow deprecated cargo clippy --workspace --all-targets -- -D warnings --allow deprecated + rm -rf crates/weaver_forge/observed_output/* cargo test --all # [workaround] removed --all-features due to an issue in one of the dependency in Tantity (zstd-safe) # [ToDo LQ] Re-enable --all-features once the issue is resolved diff --git a/src/registry/generate.rs b/src/registry/generate.rs index 1d4ff563..464c333b 100644 --- a/src/registry/generate.rs +++ b/src/registry/generate.rs @@ -36,6 +36,11 @@ pub struct RegistryGenerateArgs { #[arg(short = 't', long, default_value = "templates")] pub templates: PathBuf, + /// List of `weaver.yaml` configuration files to use. When there is a conflict, the last one + /// will override the previous ones for the keys that are defined in both. + #[arg(short = 'c', long)] + pub config: Option>, + /// Parameters key=value, defined in the command line, to pass to the templates. /// The value must be a valid YAML value. #[arg(short= 'D', long, value_parser = parse_key_val)] @@ -184,6 +189,7 @@ mod tests { command: RegistrySubCommand::Generate(RegistryGenerateArgs { output: temp_output.clone(), templates: PathBuf::from("crates/weaver_codegen_test/templates/registry/rust"), + config: None, param: None, params: None, registry: RegistryArgs { @@ -252,6 +258,7 @@ mod tests { command: RegistrySubCommand::Generate(RegistryGenerateArgs { output: temp_output.clone(), templates: PathBuf::from("crates/weaver_codegen_test/templates/registry/rust"), + config: None, param: None, params: None, registry: RegistryArgs { From e81843574113adb65d01ccbfee43858cec8e2d17 Mon Sep 17 00:00:00 2001 From: Laurent Querel Date: Thu, 11 Jul 2024 09:37:02 -0700 Subject: [PATCH 05/29] feat(forge): Support multiple paths to init a WeaverConfig with overriding support. --- Cargo.lock | 1 + crates/weaver_forge/Cargo.toml | 1 + crates/weaver_forge/src/config.rs | 93 ++++++++++++++++++++++++------- 3 files changed, 75 insertions(+), 20 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index dab5aebf..2b2ee092 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3893,6 +3893,7 @@ name = "weaver_forge" version = "0.5.0" dependencies = [ "convert_case", + "dirs", "globset", "include_dir", "indexmap", diff --git a/crates/weaver_forge/Cargo.toml b/crates/weaver_forge/Cargo.toml index 1a852d69..57f05a28 100644 --- a/crates/weaver_forge/Cargo.toml +++ b/crates/weaver_forge/Cargo.toml @@ -39,6 +39,7 @@ globset.workspace = true miette.workspace = true include_dir.workspace = true schemars.workspace = true +dirs.workspace = true [dev-dependencies] opentelemetry = { version = "0.22.0", features = ["trace", "metrics", "logs", "otel_unstable"] } diff --git a/crates/weaver_forge/src/config.rs b/crates/weaver_forge/src/config.rs index 36042df5..16d873ed 100644 --- a/crates/weaver_forge/src/config.rs +++ b/crates/weaver_forge/src/config.rs @@ -6,8 +6,9 @@ use std::collections::HashMap; use std::path::Path; use std::sync::OnceLock; -use convert_case::Boundary::{DigitLower, DigitUpper, Hyphen, LowerDigit, Space, UpperDigit}; use convert_case::{Case, Casing, Converter, Pattern}; +use convert_case::Boundary::{DigitLower, DigitUpper, Hyphen, LowerDigit, Space, UpperDigit}; +use dirs::home_dir; use globset::{Glob, GlobSet, GlobSetBuilder}; use serde::Deserialize; use serde_yaml::Value; @@ -333,13 +334,65 @@ impl Default for WeaverConfig { } impl WeaverConfig { + /// Builds the Weaver configuration from a path pointing to a configuration file. + /// The returned configuration is the result of the resolution of all the configurations found + /// in: + /// - the $HOME/.weaver/weaver.yaml file, + /// - the /weaver.yaml and its weaver.yaml. + /// + /// The resolution process is done in the order of the enumeration above. + /// When a configuration is not found, it is skipped. + pub fn from_path>(path: P) -> Result { + let mut configs = Vec::new(); + + // Detect all the weaver.yaml files in the path and parent folder. + let mut current_path = path.as_ref(); + loop { + configs.push(current_path.join("weaver.yaml")); + + if let Some(parent) = current_path.parent() { + current_path = parent; + } else { + break; + } + } + + // Add the configuration from the home directory. + if let Some(home_dir) = home_dir() { + configs.push(home_dir.join(".weaver/weaver.yaml")); + } + + configs.reverse(); + Self::from_paths(configs) + } + + /// Builds the Weaver configuration from a collection of paths pointing to configuration files. + /// If a configuration file is not found, it is skipped. + /// The order of the paths is important as the first configuration in the slice is loaded, then + /// if present, the second configuration overrides the first one, and so on. + pub fn from_paths>(paths: Vec

) -> Result { + let mut configs : Vec = Vec::new(); + + for path in paths { + if path.as_ref().exists() { + configs.push(FileContent::try_from_path(path.as_ref().clone()) + .map_err(|e| InvalidConfigFile { + config_file: path.as_ref().to_path_buf(), + error: e.to_string(), + })?); + } + } + + Self::resolve_from(&configs) + } + /// Builds the Weaver configuration from a collection of configurations passed in parameter. /// The first configuration in the slice is loaded, then if present, the second configuration /// overrides the first one, and so on. This process is named "configuration resolution". /// /// This method can fail if any of the configuration content is not a valid YAML file or if the /// configuration content can't be deserialized into a `WeaverConfig` struct. - pub(crate) fn resolve_from(configs: &[FileContent]) -> Result { + pub fn resolve_from(configs: &[FileContent]) -> Result { // The default configuration is used as a base for the resolution. let mut config = WeaverConfig::default(); if configs.is_empty() { @@ -451,9 +504,9 @@ mod tests { ("a".to_owned(), "b".to_owned()), ("c".to_owned(), "d".to_owned()) ] - .iter() - .cloned() - .collect() + .iter() + .cloned() + .collect() ) ); } @@ -472,9 +525,9 @@ mod tests { "a".to_owned(), [("b".to_owned(), "g".to_owned())].iter().cloned().collect() )] - .iter() - .cloned() - .collect() + .iter() + .cloned() + .collect() ) ); let mut parent: WeaverConfig = WeaverConfig::default(); @@ -487,9 +540,9 @@ mod tests { "a".to_owned(), [("b".to_owned(), "g".to_owned())].iter().cloned().collect() )] - .iter() - .cloned() - .collect() + .iter() + .cloned() + .collect() ) ); let mut parent: WeaverConfig = @@ -509,9 +562,9 @@ mod tests { [("e".to_owned(), "f".to_owned())].iter().cloned().collect() ) ] - .iter() - .cloned() - .collect() + .iter() + .cloned() + .collect() ) ); } @@ -522,7 +575,7 @@ mod tests { let mut parent: WeaverConfig = serde_yaml::from_str( "template_syntax: {block_start: \"{{\", block_end: \"}}\", variable_start: \"#\"}", ) - .unwrap(); + .unwrap(); let local: WeaverConfig = serde_yaml::from_str("template_syntax: {block_start: \"[[\", block_end: \"]]\"}") .unwrap(); @@ -609,11 +662,11 @@ mod tests { let mut parent: WeaverConfig = serde_yaml::from_str( "templates: [{pattern: \"**/parent.md\", filter: \".\", application_mode: \"single\"}]", ) - .unwrap(); + .unwrap(); let local: WeaverConfig = serde_yaml::from_str( "templates: [{pattern: \"**/local.md\", filter: \".\", application_mode: \"each\"}]", ) - .unwrap(); + .unwrap(); parent.override_with(local); assert!(parent.templates.is_some()); let templates = parent.templates.unwrap(); @@ -625,7 +678,7 @@ mod tests { let local: WeaverConfig = serde_yaml::from_str( "templates: [{pattern: \"**/local.md\", filter: \".\", application_mode: \"each\"}]", ) - .unwrap(); + .unwrap(); parent.override_with(local); assert!(parent.templates.is_some()); let templates = parent.templates.unwrap(); @@ -636,7 +689,7 @@ mod tests { let mut parent: WeaverConfig = serde_yaml::from_str( "templates: [{pattern: \"**/parent.md\", filter: \".\", application_mode: \"single\"}]", ) - .unwrap(); + .unwrap(); let local = WeaverConfig::default(); parent.override_with(local); assert!(parent.templates.is_some()); @@ -648,7 +701,7 @@ mod tests { let mut parent: WeaverConfig = serde_yaml::from_str( "templates: [{pattern: \"**/parent.md\", filter: \".\", application_mode: \"single\"}]", ) - .unwrap(); + .unwrap(); let local: WeaverConfig = serde_yaml::from_str("templates: []").unwrap(); parent.override_with(local); assert!(parent.templates.is_some()); From fdd51cc903027dc5bc2af3628a847372594992a6 Mon Sep 17 00:00:00 2001 From: Laurent Querel Date: Thu, 11 Jul 2024 10:20:09 -0700 Subject: [PATCH 06/29] feat(cli): Reintroduce target concept --- crates/weaver_codegen_test/build.rs | 5 +- crates/weaver_forge/src/config.rs | 2 +- crates/weaver_forge/src/file_loader.rs | 71 ++++++++++++++------------ crates/weaver_forge/src/lib.rs | 4 +- crates/weaver_semconv_gen/src/lib.rs | 2 +- src/main.rs | 7 +-- src/registry/generate.rs | 11 ++-- src/registry/update_markdown.rs | 3 +- tests/registry_generate.rs | 3 +- 9 files changed, 59 insertions(+), 49 deletions(-) diff --git a/crates/weaver_codegen_test/build.rs b/crates/weaver_codegen_test/build.rs index edd4de35..9f9dbf11 100644 --- a/crates/weaver_codegen_test/build.rs +++ b/crates/weaver_codegen_test/build.rs @@ -22,8 +22,9 @@ use weaver_semconv::path::RegistryPath; use weaver_semconv::registry::SemConvRegistry; const SEMCONV_REGISTRY_PATH: &str = "./semconv_registry/"; -const TEMPLATES_PATH: &str = "./templates/registry/rust"; +const TEMPLATES_PATH: &str = "./templates/registry/"; const REGISTRY_ID: &str = "test"; +const TARGET: &str = "rust"; fn main() { // Tell Cargo when to rerun this build script @@ -48,7 +49,7 @@ fn main() { let schema = SchemaResolver::resolve_semantic_convention_registry(&mut registry) .unwrap_or_else(|e| process_error(&logger, e)); - let loader = FileSystemFileLoader::try_new(TEMPLATES_PATH.into()) + let loader = FileSystemFileLoader::try_new(TEMPLATES_PATH.into(), TARGET) .unwrap_or_else(|e| process_error(&logger, e)); let engine = TemplateEngine::try_new(loader, Params::default()) .unwrap_or_else(|e| process_error(&logger, e)); diff --git a/crates/weaver_forge/src/config.rs b/crates/weaver_forge/src/config.rs index 16d873ed..bf56be67 100644 --- a/crates/weaver_forge/src/config.rs +++ b/crates/weaver_forge/src/config.rs @@ -375,7 +375,7 @@ impl WeaverConfig { for path in paths { if path.as_ref().exists() { - configs.push(FileContent::try_from_path(path.as_ref().clone()) + configs.push(FileContent::try_from_path(path.as_ref()) .map_err(|e| InvalidConfigFile { config_file: path.as_ref().to_path_buf(), error: e.to_string(), diff --git a/crates/weaver_forge/src/file_loader.rs b/crates/weaver_forge/src/file_loader.rs index 207d3d41..57de59cd 100644 --- a/crates/weaver_forge/src/file_loader.rs +++ b/crates/weaver_forge/src/file_loader.rs @@ -9,6 +9,7 @@ use minijinja::ErrorKind; use walkdir::WalkDir; use crate::error::Error; +use crate::error::Error::TargetNotSupported; /// An abstraction for loading files from a file system, embedded directory, etc. pub trait FileLoader { @@ -50,6 +51,7 @@ impl FileContent { /// This is useful for loading templates and other files that are embedded in the binary but /// can be overridden by the user. pub struct EmbeddedFileLoader { + target: String, embedded_dir: &'static include_dir::Dir<'static>, fs_loader: Option, } @@ -57,28 +59,32 @@ pub struct EmbeddedFileLoader { impl EmbeddedFileLoader { /// Create a new embedded file loader. /// - /// If the `local_dir` directory exists, the loader will use the file system loader. + /// If the `local_dir/target` directory exists, the loader will use the file system loader. /// Otherwise, it will use the embedded directory. pub fn try_new( - root_embedded_dir: &'static include_dir::Dir<'static>, - sub_embedded_dir: &str, + embedded_dir: &'static include_dir::Dir<'static>, local_dir: PathBuf, + target: &str, ) -> Result { - let embedded_dir = - root_embedded_dir - .get_dir(sub_embedded_dir) - .ok_or_else(|| Error::FileLoaderError { - file: PathBuf::from(sub_embedded_dir), - error: "Failed to get sub embedded directory".to_owned(), - })?; - Ok(Self { - embedded_dir, - fs_loader: if local_dir.exists() { - Some(FileSystemFileLoader::try_new(local_dir)?) - } else { - None - }, - }) + let target_embedded_dir = embedded_dir.get_dir(target); + let target_local_dir = local_dir.join(target); + if let Some(dir) = target_embedded_dir { + Ok(Self { + target: target.to_owned(), + embedded_dir: dir, + fs_loader: if target_local_dir.exists() { + Some(FileSystemFileLoader::try_new(local_dir, target)?) + } else { + None + }, + }) + } else { + Err(TargetNotSupported { + root_path: embedded_dir.path().to_string_lossy().to_string(), + target: target.to_owned(), + error: "Target not found".to_owned(), + }) + } } } @@ -121,8 +127,8 @@ impl FileLoader for EmbeddedFileLoader { return fs_loader.load_file(file); } - let file = &format!("{}/{}", self.embedded_dir.path().to_string_lossy(), file); - match self.embedded_dir.get_file(file) { + let name = format!("{}/{}", self.target, file); + match self.embedded_dir.get_file(name) { Some(file) => Ok(Some(FileContent { content: file .contents_utf8() @@ -145,13 +151,12 @@ pub struct FileSystemFileLoader { impl FileSystemFileLoader { /// Create a new file system loader - pub fn try_new(dir: PathBuf) -> Result { - if !dir.exists() { - return Err(Error::FileLoaderError { - file: dir.clone(), - error: "Directory does not exist".to_owned(), - }); - } + pub fn try_new(dir: PathBuf, target: &str) -> Result { + let dir = safe_join(&dir, target).map_err(|e| TargetNotSupported { + root_path: dir.to_string_lossy().to_string(), + target: target.to_owned(), + error: e.to_string(), + })?; Ok(Self { dir }) } } @@ -254,8 +259,8 @@ mod tests { fn test_template_loader() { let embedded_loader = EmbeddedFileLoader::try_new( &EMBEDDED_TEMPLATES, + PathBuf::from("./does-not-exist"), "test", - PathBuf::from("./does-not-exist/test"), ) .unwrap(); let embedded_content = embedded_loader.load_file("group.md"); @@ -267,8 +272,8 @@ mod tests { let overloaded_embedded_loader = EmbeddedFileLoader::try_new( &EMBEDDED_TEMPLATES, + PathBuf::from("./overloaded-templates"), "test", - PathBuf::from("./overloaded-templates/test"), ) .unwrap(); let overloaded_embedded_content = overloaded_embedded_loader.load_file("group.md"); @@ -278,7 +283,8 @@ mod tests { .content .contains("# Overloaded Group `{{ ctx.id }}` ({{ ctx.type }})")); - let fs_loader = FileSystemFileLoader::try_new(PathBuf::from("./templates/test")).unwrap(); + let fs_loader = + FileSystemFileLoader::try_new(PathBuf::from("./templates"), "test").unwrap(); let fs_content = fs_loader.load_file("group.md"); assert!(fs_content.is_ok()); let fs_content = fs_content.unwrap().unwrap(); @@ -351,8 +357,8 @@ mod tests { fn test_embedded_loader_error() { let embedded_loader = EmbeddedFileLoader::try_new( &EMBEDDED_TEMPLATES, + PathBuf::from("./does-not-exist"), "doesn't-exist", - PathBuf::from("./does-not-exist/doesn't-exist"), ); assert!(embedded_loader.is_err()); @@ -360,7 +366,8 @@ mod tests { #[test] fn test_file_system_loader_error() { - let fs_loader = FileSystemFileLoader::try_new(PathBuf::from("./templates/doesn't-exist")); + let fs_loader = + FileSystemFileLoader::try_new(PathBuf::from("./templates"), "doesn't-exist"); assert!(fs_loader.is_err()); } diff --git a/crates/weaver_forge/src/lib.rs b/crates/weaver_forge/src/lib.rs index c0b53432..6311cee8 100644 --- a/crates/weaver_forge/src/lib.rs +++ b/crates/weaver_forge/src/lib.rs @@ -679,7 +679,7 @@ mod tests { #[test] fn test_template_engine() { let logger = TestLogger::default(); - let loader = FileSystemFileLoader::try_new("templates/test".into()) + let loader = FileSystemFileLoader::try_new("templates".into(), "test") .expect("Failed to create file system loader"); let mut engine = super::TemplateEngine::try_new(loader, Params::default()) .expect("Failed to create template engine"); @@ -730,7 +730,7 @@ mod tests { #[test] fn test_whitespace_control() { let logger = TestLogger::default(); - let loader = FileSystemFileLoader::try_new("whitespace_control_templates/test".into()) + let loader = FileSystemFileLoader::try_new("whitespace_control_templates".into(), "test") .expect("Failed to create file system loader"); let engine = super::TemplateEngine::try_new(loader, Params::default()) .expect("Failed to create template engine"); diff --git a/crates/weaver_semconv_gen/src/lib.rs b/crates/weaver_semconv_gen/src/lib.rs index b668efa5..551c09f9 100644 --- a/crates/weaver_semconv_gen/src/lib.rs +++ b/crates/weaver_semconv_gen/src/lib.rs @@ -439,7 +439,7 @@ mod tests { #[test] fn test_template_engine() -> Result<(), Error> { - let loader = FileSystemFileLoader::try_new("templates/registry/markdown".into())?; + let loader = FileSystemFileLoader::try_new("templates/registry".into(), "markdown")?; let template = TemplateEngine::try_new(loader, Params::default())?; let generator = SnippetGenerator::try_from_path("data", Some(template))?; let attribute_registry_url = "/docs/attributes-registry"; diff --git a/src/main.rs b/src/main.rs index b3bcfac3..11e0ea11 100644 --- a/src/main.rs +++ b/src/main.rs @@ -133,13 +133,8 @@ fn process_diagnostics( if let Err(diagnostic_messages) = cmd_result.command_result { let loader = EmbeddedFileLoader::try_new( &DEFAULT_DIAGNOSTIC_TEMPLATES, + diagnostic_args.diagnostic_template, &diagnostic_args.diagnostic_format, - format!( - "{}/{}", - diagnostic_args.diagnostic_template.to_string_lossy(), - &diagnostic_args.diagnostic_format - ) - .into(), ) .expect("Failed to create the embedded file loader for the diagnostic templates"); match TemplateEngine::try_new(loader, Params::default()) { diff --git a/src/registry/generate.rs b/src/registry/generate.rs index 464c333b..3ddb8e5c 100644 --- a/src/registry/generate.rs +++ b/src/registry/generate.rs @@ -26,6 +26,9 @@ use crate::{DiagnosticArgs, ExitDirectives}; /// Parameters for the `registry generate` sub-command #[derive(Debug, Args)] pub struct RegistryGenerateArgs { + /// Target to generate the artifacts for. + pub target: String, + /// Path to the directory where the generated artifacts will be saved. /// Default is the `output` directory. #[arg(default_value = "output")] @@ -110,7 +113,7 @@ pub(crate) fn command( let mut registry = SemConvRegistry::from_semconv_specs(registry_id, semconv_specs); let schema = resolve_semconv_specs(&mut registry, logger.clone())?; - let loader = FileSystemFileLoader::try_new(args.templates.clone())?; + let loader = FileSystemFileLoader::try_new(args.templates.join("registry"), &args.target)?; let engine = TemplateEngine::try_new(loader, params)?; let template_registry = ResolvedRegistry::try_from_resolved_registry( @@ -187,8 +190,9 @@ mod tests { quiet: false, command: Some(Commands::Registry(RegistryCommand { command: RegistrySubCommand::Generate(RegistryGenerateArgs { + target: "rust".to_owned(), output: temp_output.clone(), - templates: PathBuf::from("crates/weaver_codegen_test/templates/registry/rust"), + templates: PathBuf::from("crates/weaver_codegen_test/templates/"), config: None, param: None, params: None, @@ -256,8 +260,9 @@ mod tests { quiet: false, command: Some(Commands::Registry(RegistryCommand { command: RegistrySubCommand::Generate(RegistryGenerateArgs { + target: "rust".to_owned(), output: temp_output.clone(), - templates: PathBuf::from("crates/weaver_codegen_test/templates/registry/rust"), + templates: PathBuf::from("crates/weaver_codegen_test/templates/"), config: None, param: None, params: None, diff --git a/src/registry/update_markdown.rs b/src/registry/update_markdown.rs index 0f4bba30..c556782c 100644 --- a/src/registry/update_markdown.rs +++ b/src/registry/update_markdown.rs @@ -68,7 +68,8 @@ pub(crate) fn command( None => None, Some(target) => { let loader = FileSystemFileLoader::try_new( - format!("{}/registry/{}", args.templates, target).into(), + format!("{}/registry", args.templates).into(), + target, )?; Some(TemplateEngine::try_new(loader, Params::default())?) } diff --git a/tests/registry_generate.rs b/tests/registry_generate.rs index 40571392..e8d32832 100644 --- a/tests/registry_generate.rs +++ b/tests/registry_generate.rs @@ -30,9 +30,10 @@ fn test_cli_interface() { .arg("-r") .arg("crates/weaver_codegen_test/semconv_registry/") .arg("-t") - .arg("crates/weaver_codegen_test/templates/rust") + .arg("crates/weaver_codegen_test/templates/") .arg("--diagnostic-format") .arg("json") + .arg("rust") .arg("output/") .timeout(std::time::Duration::from_secs(60)) .output() From ef59887068b503e3ffa8d10bdba9b505d0304336 Mon Sep 17 00:00:00 2001 From: Laurent Querel Date: Thu, 11 Jul 2024 14:36:59 -0700 Subject: [PATCH 07/29] feat(cli): Introduce --config parameter in weaver registry generate --- crates/weaver_codegen_test/build.rs | 5 +- .../templates/registry/alt_weaver.yaml | 5 + .../registry/rust/attributes/attributes.rs.j2 | 4 +- .../rust/metrics/instruments/counter.j2 | 4 +- .../rust/metrics/instruments/gauge.j2 | 4 +- .../rust/metrics/instruments/histogram.j2 | 4 +- .../rust/metrics/instruments/updowncounter.j2 | 4 +- .../templates/registry/rust/weaver.yaml | 23 ++--- .../templates/registry/weaver.yaml | 5 + crates/weaver_forge/README.md | 1 - crates/weaver_forge/src/config.rs | 84 +++++++--------- crates/weaver_forge/src/lib.rs | 20 ++-- crates/weaver_semconv_gen/src/lib.rs | 10 +- src/main.rs | 12 ++- src/registry/generate.rs | 97 ++++++++++++++++++- src/registry/update_markdown.rs | 14 ++- 16 files changed, 194 insertions(+), 102 deletions(-) create mode 100644 crates/weaver_codegen_test/templates/registry/alt_weaver.yaml create mode 100644 crates/weaver_codegen_test/templates/registry/weaver.yaml diff --git a/crates/weaver_codegen_test/build.rs b/crates/weaver_codegen_test/build.rs index 9f9dbf11..0d7cd854 100644 --- a/crates/weaver_codegen_test/build.rs +++ b/crates/weaver_codegen_test/build.rs @@ -13,7 +13,7 @@ use std::process::exit; use weaver_cache::Cache; use weaver_common::in_memory::LogMessage; use weaver_common::{in_memory, Logger}; -use weaver_forge::config::Params; +use weaver_forge::config::{Params, WeaverConfig}; use weaver_forge::file_loader::FileSystemFileLoader; use weaver_forge::registry::ResolvedRegistry; use weaver_forge::{OutputDirective, TemplateEngine}; @@ -51,7 +51,8 @@ fn main() { let loader = FileSystemFileLoader::try_new(TEMPLATES_PATH.into(), TARGET) .unwrap_or_else(|e| process_error(&logger, e)); - let engine = TemplateEngine::try_new(loader, Params::default()) + let configs = WeaverConfig::collect_from_path("./templates/registry/rust"); + let engine = TemplateEngine::try_new(&configs, loader, Params::default()) .unwrap_or_else(|e| process_error(&logger, e)); let template_registry = ResolvedRegistry::try_from_resolved_registry( schema diff --git a/crates/weaver_codegen_test/templates/registry/alt_weaver.yaml b/crates/weaver_codegen_test/templates/registry/alt_weaver.yaml new file mode 100644 index 00000000..21edcbda --- /dev/null +++ b/crates/weaver_codegen_test/templates/registry/alt_weaver.yaml @@ -0,0 +1,5 @@ +# These parameters are inherited by all the sub-folders +params: + attributes: true + metrics: false # With this alternate configuration, the metrics are disabled + registry_prefix: "registry." diff --git a/crates/weaver_codegen_test/templates/registry/rust/attributes/attributes.rs.j2 b/crates/weaver_codegen_test/templates/registry/rust/attributes/attributes.rs.j2 index b14e3465..ee6de050 100644 --- a/crates/weaver_codegen_test/templates/registry/rust/attributes/attributes.rs.j2 +++ b/crates/weaver_codegen_test/templates/registry/rust/attributes/attributes.rs.j2 @@ -26,9 +26,9 @@ {%- if attribute.type.allow_custom_values is defined %} pub const {{ attribute.name | screaming_snake_case }}: crate::attributes::AttributeKey<{{ attribute.name | pascal_case }}> = crate::attributes::AttributeKey::new("{{ attribute.name }}"); {%- elif attribute.type == "string" %} -pub const {{ attribute.name | screaming_snake_case }}: crate::attributes::AttributeKey = crate::attributes::AttributeKey::new("{{ attribute.name }}"); +pub const {{ attribute.name | screaming_snake_case }}: crate::attributes::AttributeKey = crate::attributes::AttributeKey::new("{{ attribute.name }}"); {%- else %} -pub const {{ attribute.name | screaming_snake_case }}: crate::attributes::AttributeKey<{{ attribute.type | type_mapping }}> = crate::attributes::AttributeKey::new("{{ attribute.name }}"); +pub const {{ attribute.name | screaming_snake_case }}: crate::attributes::AttributeKey<{{ attribute.type | map_text("rust_types") }}> = crate::attributes::AttributeKey::new("{{ attribute.name }}"); {%- endif %} {%- if attribute.type.members is defined %} diff --git a/crates/weaver_codegen_test/templates/registry/rust/metrics/instruments/counter.j2 b/crates/weaver_codegen_test/templates/registry/rust/metrics/instruments/counter.j2 index 8a32cc75..aa6fc758 100644 --- a/crates/weaver_codegen_test/templates/registry/rust/metrics/instruments/counter.j2 +++ b/crates/weaver_codegen_test/templates/registry/rust/metrics/instruments/counter.j2 @@ -29,7 +29,7 @@ pub struct {{ metric.metric_name | pascal_case }}ReqAttributes { {%- if attribute.type.members is defined %} pub {{ attribute.name | snake_case }}: crate::attributes::{{ attribute.name | attribute_namespace }}::{{ attribute.name | pascal_case }}, {%- else %} - pub {{ attribute.name | snake_case }}: {{ attribute.type | type_mapping }}, + pub {{ attribute.name | snake_case }}: {{ attribute.type | map_text("rust_types") }}, {%- endif %} {%- endfor %} } @@ -44,7 +44,7 @@ pub struct {{ metric.metric_name | pascal_case }}OptAttributes { {%- if attribute.type.members is defined %} pub {{ attribute.name | snake_case }}: Option, {%- else %} - pub {{ attribute.name | snake_case }}: Option<{{ attribute.type | type_mapping }}>, + pub {{ attribute.name | snake_case }}: Option<{{ attribute.type | map_text("rust_types") }}>, {%- endif %} {%- endfor %} } diff --git a/crates/weaver_codegen_test/templates/registry/rust/metrics/instruments/gauge.j2 b/crates/weaver_codegen_test/templates/registry/rust/metrics/instruments/gauge.j2 index 930cbc6f..8a477a5f 100644 --- a/crates/weaver_codegen_test/templates/registry/rust/metrics/instruments/gauge.j2 +++ b/crates/weaver_codegen_test/templates/registry/rust/metrics/instruments/gauge.j2 @@ -29,7 +29,7 @@ pub struct {{ metric.metric_name | pascal_case }}ReqAttributes { {%- if attribute.type.members is defined %} pub {{ attribute.name | snake_case }}: crate::attributes::{{ attribute.name | attribute_namespace }}::{{ attribute.name | pascal_case }}, {%- else %} - pub {{ attribute.name | snake_case }}: {{ attribute.type | type_mapping }}, + pub {{ attribute.name | snake_case }}: {{ attribute.type | map_text("rust_types") }}, {%- endif %} {%- endfor %} } @@ -44,7 +44,7 @@ pub struct {{ metric.metric_name | pascal_case }}OptAttributes { {%- if attribute.type.members is defined %} pub {{ attribute.name | snake_case }}: Option, {%- else %} - pub {{ attribute.name | snake_case }}: Option<{{ attribute.type | type_mapping }}>, + pub {{ attribute.name | snake_case }}: Option<{{ attribute.type | map_text("rust_types") }}>, {%- endif %} {%- endfor %} } diff --git a/crates/weaver_codegen_test/templates/registry/rust/metrics/instruments/histogram.j2 b/crates/weaver_codegen_test/templates/registry/rust/metrics/instruments/histogram.j2 index ffe08a10..cd6342d9 100644 --- a/crates/weaver_codegen_test/templates/registry/rust/metrics/instruments/histogram.j2 +++ b/crates/weaver_codegen_test/templates/registry/rust/metrics/instruments/histogram.j2 @@ -29,7 +29,7 @@ pub struct {{ metric.metric_name | pascal_case }}ReqAttributes { {%- if attribute.type.members is defined %} pub {{ attribute.name | snake_case }}: crate::attributes::{{ attribute.name | attribute_namespace }}::{{ attribute.name | pascal_case }}, {%- else %} - pub {{ attribute.name | snake_case }}: {{ attribute.type | type_mapping }}, + pub {{ attribute.name | snake_case }}: {{ attribute.type | map_text("rust_types") }}, {%- endif %} {%- endfor %} } @@ -44,7 +44,7 @@ pub struct {{ metric.metric_name | pascal_case }}OptAttributes { {%- if attribute.type.members is defined %} pub {{ attribute.name | snake_case }}: Option, {%- else %} - pub {{ attribute.name | snake_case }}: Option<{{ attribute.type | type_mapping }}>, + pub {{ attribute.name | snake_case }}: Option<{{ attribute.type | map_text("rust_types") }}>, {%- endif %} {%- endfor %} } diff --git a/crates/weaver_codegen_test/templates/registry/rust/metrics/instruments/updowncounter.j2 b/crates/weaver_codegen_test/templates/registry/rust/metrics/instruments/updowncounter.j2 index 3276cb6f..f44b5bd4 100644 --- a/crates/weaver_codegen_test/templates/registry/rust/metrics/instruments/updowncounter.j2 +++ b/crates/weaver_codegen_test/templates/registry/rust/metrics/instruments/updowncounter.j2 @@ -30,7 +30,7 @@ pub struct {{ metric.metric_name | pascal_case }}ReqAttributes { {%- if attribute.type.members is defined %} pub {{ attribute.name | snake_case }}: crate::attributes::{{ attribute.name | attribute_namespace }}::{{ attribute.name | pascal_case }}, {%- else %} - pub {{ attribute.name | snake_case }}: {{ attribute.type | type_mapping }}, + pub {{ attribute.name | snake_case }}: {{ attribute.type | map_text("rust_types") }}, {%- endif %} {%- endfor %} } @@ -45,7 +45,7 @@ pub struct {{ metric.metric_name | pascal_case }}OptAttributes { {%- if attribute.type.members is defined %} pub {{ attribute.name | snake_case }}: Option, {%- else %} - pub {{ attribute.name | snake_case }}: Option<{{ attribute.type | type_mapping }}>, + pub {{ attribute.name | snake_case }}: Option<{{ attribute.type | map_text("rust_types") }}>, {%- endif %} {%- endfor %} } diff --git a/crates/weaver_codegen_test/templates/registry/rust/weaver.yaml b/crates/weaver_codegen_test/templates/registry/rust/weaver.yaml index f7428dce..47b4ad4a 100644 --- a/crates/weaver_codegen_test/templates/registry/rust/weaver.yaml +++ b/crates/weaver_codegen_test/templates/registry/rust/weaver.yaml @@ -1,17 +1,12 @@ -type_mapping: - int: i64 - double: f64 - boolean: bool - string: String - string[]: Vec - template[string]: String # Not yet properly handled in codegen - template[string[]]: Vec # Not yet properly handled in codegen - -# Default parameter values -params: - attributes: true - metrics: true - registry_prefix: "registry." +text_maps: + rust_types: + int: i64 + double: f64 + boolean: bool + string: String + string[]: Vec + template[string]: String # Not yet properly handled in codegen + template[string[]]: Vec # Not yet properly handled in codegen templates: - pattern: README.md diff --git a/crates/weaver_codegen_test/templates/registry/weaver.yaml b/crates/weaver_codegen_test/templates/registry/weaver.yaml new file mode 100644 index 00000000..1361e29d --- /dev/null +++ b/crates/weaver_codegen_test/templates/registry/weaver.yaml @@ -0,0 +1,5 @@ +# These parameters are inherited by all the sub-folders +params: + attributes: true + metrics: true + registry_prefix: "registry." diff --git a/crates/weaver_forge/README.md b/crates/weaver_forge/README.md index 74557574..f7ce0361 100644 --- a/crates/weaver_forge/README.md +++ b/crates/weaver_forge/README.md @@ -155,7 +155,6 @@ The following filters are available: - `screaming_snake_case_const`: Generates SCREAMING_SNAKE_CASE constants which follow semantic convention namespacing rules (underscores are ignored, but . is meaningful). - `acronym`: Replaces acronyms in the input string with the full name defined in the `acronyms` section of the `weaver.yaml` configuration file. - `split_id`: Splits a string by '.' creating a list of nested ids. -- `type_mapping`: Converts a semantic convention type to a target type (see weaver.yaml section `type_mapping`). - `comment_with_prefix(prefix)`: Outputs a multiline comment with the given prefix. - `flatten`: Converts a List of Lists into a single list with all elements. e.g. \[\[a,b\],\[c\]\] => \[a,b,c\] diff --git a/crates/weaver_forge/src/config.rs b/crates/weaver_forge/src/config.rs index bf56be67..a8c07d9d 100644 --- a/crates/weaver_forge/src/config.rs +++ b/crates/weaver_forge/src/config.rs @@ -6,8 +6,8 @@ use std::collections::HashMap; use std::path::Path; use std::sync::OnceLock; -use convert_case::{Case, Casing, Converter, Pattern}; use convert_case::Boundary::{DigitLower, DigitUpper, Hyphen, LowerDigit, Space, UpperDigit}; +use convert_case::{Case, Casing, Converter, Pattern}; use dirs::home_dir; use globset::{Glob, GlobSet, GlobSetBuilder}; use serde::Deserialize; @@ -52,7 +52,7 @@ pub enum CaseConvention { /// Weaver configuration. #[derive(Deserialize, Debug)] -pub(crate) struct WeaverConfig { +pub struct WeaverConfig { /// Case convention used to name a file. /// Open question: Do we keep this? It's probably easier for author's templates to use directly /// the case conversion filters than to rely on this configuration. @@ -334,21 +334,19 @@ impl Default for WeaverConfig { } impl WeaverConfig { - /// Builds the Weaver configuration from a path pointing to a configuration file. - /// The returned configuration is the result of the resolution of all the configurations found - /// in: + /// Collects all the configurations from the path passed in parameter. The configuration files + /// are collected in the order of the enumeration below: /// - the $HOME/.weaver/weaver.yaml file, /// - the /weaver.yaml and its weaver.yaml. - /// - /// The resolution process is done in the order of the enumeration above. - /// When a configuration is not found, it is skipped. - pub fn from_path>(path: P) -> Result { - let mut configs = Vec::new(); + pub fn collect_from_path>(path: P) -> Vec { + let mut file_contents = Vec::new(); // Detect all the weaver.yaml files in the path and parent folder. let mut current_path = path.as_ref(); loop { - configs.push(current_path.join("weaver.yaml")); + if let Ok(file_content) = FileContent::try_from_path(current_path.join("weaver.yaml")) { + file_contents.push(file_content); + } if let Some(parent) = current_path.parent() { current_path = parent; @@ -359,31 +357,15 @@ impl WeaverConfig { // Add the configuration from the home directory. if let Some(home_dir) = home_dir() { - configs.push(home_dir.join(".weaver/weaver.yaml")); - } - - configs.reverse(); - Self::from_paths(configs) - } - - /// Builds the Weaver configuration from a collection of paths pointing to configuration files. - /// If a configuration file is not found, it is skipped. - /// The order of the paths is important as the first configuration in the slice is loaded, then - /// if present, the second configuration overrides the first one, and so on. - pub fn from_paths>(paths: Vec

) -> Result { - let mut configs : Vec = Vec::new(); - - for path in paths { - if path.as_ref().exists() { - configs.push(FileContent::try_from_path(path.as_ref()) - .map_err(|e| InvalidConfigFile { - config_file: path.as_ref().to_path_buf(), - error: e.to_string(), - })?); + if let Ok(file_content) = + FileContent::try_from_path(home_dir.join(".weaver/weaver.yaml")) + { + file_contents.push(file_content); } } - Self::resolve_from(&configs) + file_contents.reverse(); + file_contents } /// Builds the Weaver configuration from a collection of configurations passed in parameter. @@ -504,9 +486,9 @@ mod tests { ("a".to_owned(), "b".to_owned()), ("c".to_owned(), "d".to_owned()) ] - .iter() - .cloned() - .collect() + .iter() + .cloned() + .collect() ) ); } @@ -525,9 +507,9 @@ mod tests { "a".to_owned(), [("b".to_owned(), "g".to_owned())].iter().cloned().collect() )] - .iter() - .cloned() - .collect() + .iter() + .cloned() + .collect() ) ); let mut parent: WeaverConfig = WeaverConfig::default(); @@ -540,9 +522,9 @@ mod tests { "a".to_owned(), [("b".to_owned(), "g".to_owned())].iter().cloned().collect() )] - .iter() - .cloned() - .collect() + .iter() + .cloned() + .collect() ) ); let mut parent: WeaverConfig = @@ -562,9 +544,9 @@ mod tests { [("e".to_owned(), "f".to_owned())].iter().cloned().collect() ) ] - .iter() - .cloned() - .collect() + .iter() + .cloned() + .collect() ) ); } @@ -575,7 +557,7 @@ mod tests { let mut parent: WeaverConfig = serde_yaml::from_str( "template_syntax: {block_start: \"{{\", block_end: \"}}\", variable_start: \"#\"}", ) - .unwrap(); + .unwrap(); let local: WeaverConfig = serde_yaml::from_str("template_syntax: {block_start: \"[[\", block_end: \"]]\"}") .unwrap(); @@ -662,11 +644,11 @@ mod tests { let mut parent: WeaverConfig = serde_yaml::from_str( "templates: [{pattern: \"**/parent.md\", filter: \".\", application_mode: \"single\"}]", ) - .unwrap(); + .unwrap(); let local: WeaverConfig = serde_yaml::from_str( "templates: [{pattern: \"**/local.md\", filter: \".\", application_mode: \"each\"}]", ) - .unwrap(); + .unwrap(); parent.override_with(local); assert!(parent.templates.is_some()); let templates = parent.templates.unwrap(); @@ -678,7 +660,7 @@ mod tests { let local: WeaverConfig = serde_yaml::from_str( "templates: [{pattern: \"**/local.md\", filter: \".\", application_mode: \"each\"}]", ) - .unwrap(); + .unwrap(); parent.override_with(local); assert!(parent.templates.is_some()); let templates = parent.templates.unwrap(); @@ -689,7 +671,7 @@ mod tests { let mut parent: WeaverConfig = serde_yaml::from_str( "templates: [{pattern: \"**/parent.md\", filter: \".\", application_mode: \"single\"}]", ) - .unwrap(); + .unwrap(); let local = WeaverConfig::default(); parent.override_with(local); assert!(parent.templates.is_some()); @@ -701,7 +683,7 @@ mod tests { let mut parent: WeaverConfig = serde_yaml::from_str( "templates: [{pattern: \"**/parent.md\", filter: \".\", application_mode: \"single\"}]", ) - .unwrap(); + .unwrap(); let local: WeaverConfig = serde_yaml::from_str("templates: []").unwrap(); parent.override_with(local); assert!(parent.templates.is_some()); diff --git a/crates/weaver_forge/src/lib.rs b/crates/weaver_forge/src/lib.rs index 6311cee8..c66598c4 100644 --- a/crates/weaver_forge/src/lib.rs +++ b/crates/weaver_forge/src/lib.rs @@ -30,7 +30,7 @@ use crate::config::{ApplicationMode, Params, WeaverConfig}; use crate::debug::error_summary; use crate::error::Error::InvalidConfigFile; use crate::extensions::{ansi, case, code, otel, util}; -use crate::file_loader::FileLoader; +use crate::file_loader::{FileContent, FileLoader}; use crate::filter::Filter; use crate::registry::{ResolvedGroup, ResolvedRegistry}; @@ -163,15 +163,11 @@ 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( + configs: &[FileContent], loader: impl FileLoader + Send + Sync + 'static, params: Params, ) -> Result { - let config = loader.load_file(WEAVER_YAML)?; - let mut target_config = if let Some(config) = config { - WeaverConfig::resolve_from(&[config])? - } else { - WeaverConfig::default() - }; + let mut target_config = WeaverConfig::resolve_from(configs)?; // Override the params defined in the `weaver.yaml` file with the params provided // in the command line. @@ -550,9 +546,9 @@ mod tests { use crate::config::{ApplicationMode, CaseConvention, Params, TemplateConfig}; use crate::debug::print_dedup_errors; use crate::extensions::case::case_converter; - use crate::file_loader::FileSystemFileLoader; + use crate::file_loader::{FileLoader, FileSystemFileLoader}; use crate::registry::ResolvedRegistry; - use crate::OutputDirective; + use crate::{OutputDirective, WEAVER_YAML}; #[test] fn test_case_converter() { @@ -681,7 +677,8 @@ mod tests { let logger = TestLogger::default(); let loader = FileSystemFileLoader::try_new("templates".into(), "test") .expect("Failed to create file system loader"); - let mut engine = super::TemplateEngine::try_new(loader, Params::default()) + let config = loader.load_file(WEAVER_YAML).unwrap().unwrap(); + let mut engine = super::TemplateEngine::try_new(&[config], loader, Params::default()) .expect("Failed to create template engine"); // Add a template configuration for converter.md on top @@ -732,7 +729,8 @@ mod tests { let logger = TestLogger::default(); let loader = FileSystemFileLoader::try_new("whitespace_control_templates".into(), "test") .expect("Failed to create file system loader"); - let engine = super::TemplateEngine::try_new(loader, Params::default()) + let config = loader.load_file(WEAVER_YAML).unwrap().unwrap(); + let engine = super::TemplateEngine::try_new(&[config], loader, Params::default()) .expect("Failed to create template engine"); let registry_id = "default"; diff --git a/crates/weaver_semconv_gen/src/lib.rs b/crates/weaver_semconv_gen/src/lib.rs index 551c09f9..7f10629a 100644 --- a/crates/weaver_semconv_gen/src/lib.rs +++ b/crates/weaver_semconv_gen/src/lib.rs @@ -425,8 +425,8 @@ mod tests { use std::path::PathBuf; use weaver_forge::config::Params; - use weaver_forge::file_loader::FileSystemFileLoader; - use weaver_forge::TemplateEngine; + use weaver_forge::file_loader::{FileLoader, FileSystemFileLoader}; + use weaver_forge::{TemplateEngine, WEAVER_YAML}; use crate::{update_markdown, Error, SnippetGenerator}; @@ -440,7 +440,11 @@ mod tests { #[test] fn test_template_engine() -> Result<(), Error> { let loader = FileSystemFileLoader::try_new("templates/registry".into(), "markdown")?; - let template = TemplateEngine::try_new(loader, Params::default())?; + let configs = loader + .load_file(WEAVER_YAML)? + .into_iter() + .collect::>(); + let template = TemplateEngine::try_new(&configs, loader, Params::default())?; let generator = SnippetGenerator::try_from_path("data", Some(template))?; let attribute_registry_url = "/docs/attributes-registry"; // Now we should check a snippet. diff --git a/src/main.rs b/src/main.rs index 11e0ea11..913dacf1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -11,8 +11,8 @@ use weaver_common::diagnostic::DiagnosticMessages; use weaver_common::quiet::QuietLogger; use weaver_common::{ConsoleLogger, Logger}; use weaver_forge::config::Params; -use weaver_forge::file_loader::EmbeddedFileLoader; -use weaver_forge::{OutputDirective, TemplateEngine}; +use weaver_forge::file_loader::{EmbeddedFileLoader, FileLoader}; +use weaver_forge::{OutputDirective, TemplateEngine, WEAVER_YAML}; use crate::cli::{Cli, Commands}; use crate::diagnostic::DEFAULT_DIAGNOSTIC_TEMPLATES; @@ -137,7 +137,13 @@ fn process_diagnostics( &diagnostic_args.diagnostic_format, ) .expect("Failed to create the embedded file loader for the diagnostic templates"); - match TemplateEngine::try_new(loader, Params::default()) { + let config = loader + .load_file(WEAVER_YAML) + .expect( + "Invalid Weaver configuration file: `defaults/diagnostic_templates/weaver.yaml`", + ) + .expect("Failed to load `defaults/diagnostic_templates/weaver.yaml`"); + match TemplateEngine::try_new(&[config], loader, Params::default()) { Ok(engine) => { match engine.generate( logger.clone(), diff --git a/src/registry/generate.rs b/src/registry/generate.rs index 3ddb8e5c..aed74d2b 100644 --- a/src/registry/generate.rs +++ b/src/registry/generate.rs @@ -10,8 +10,8 @@ use serde_yaml::Value; use weaver_cache::Cache; use weaver_common::diagnostic::DiagnosticMessages; use weaver_common::Logger; -use weaver_forge::config::Params; -use weaver_forge::file_loader::FileSystemFileLoader; +use weaver_forge::config::{Params, WeaverConfig}; +use weaver_forge::file_loader::{FileContent, FileLoader, FileSystemFileLoader}; use weaver_forge::registry::ResolvedRegistry; use weaver_forge::{OutputDirective, TemplateEngine}; use weaver_semconv::registry::SemConvRegistry; @@ -46,7 +46,7 @@ pub struct RegistryGenerateArgs { /// Parameters key=value, defined in the command line, to pass to the templates. /// The value must be a valid YAML value. - #[arg(short= 'D', long, value_parser = parse_key_val)] + #[arg(short = 'D', long, value_parser = parse_key_val)] pub param: Option>, /// Parameters, defined in a YAML file, to pass to the templates. @@ -114,7 +114,16 @@ pub(crate) fn command( let mut registry = SemConvRegistry::from_semconv_specs(registry_id, semconv_specs); let schema = resolve_semconv_specs(&mut registry, logger.clone())?; let loader = FileSystemFileLoader::try_new(args.templates.join("registry"), &args.target)?; - let engine = TemplateEngine::try_new(loader, params)?; + let mut configs = Vec::new(); + + if let Some(paths) = &args.config { + for path in paths { + configs.push(FileContent::try_from_path(path)?); + } + } else { + configs.extend(WeaverConfig::collect_from_path(loader.root())); + }; + let engine = TemplateEngine::try_new(&configs, loader, params)?; let template_registry = ResolvedRegistry::try_from_resolved_registry( schema @@ -283,4 +292,84 @@ mod tests { // The command should exit with an error code. assert_eq!(exit_directive.exit_code, 1); } + + #[test] + fn test_registry_generate_with_config() { + let logger = TestLogger::new(); + let temp_output = TempDir::new("output") + .expect("Failed to create temporary directory") + .into_path(); + let cli = Cli { + debug: 0, + quiet: false, + command: Some(Commands::Registry(RegistryCommand { + command: RegistrySubCommand::Generate(RegistryGenerateArgs { + target: "rust".to_owned(), + output: temp_output.clone(), + templates: PathBuf::from("crates/weaver_codegen_test/templates/"), + config: Some(vec![ + PathBuf::from( + "crates/weaver_codegen_test/templates/registry/alt_weaver.yaml", + ), + PathBuf::from( + "crates/weaver_codegen_test/templates/registry/rust/weaver.yaml", + ), + ]), + param: None, + params: None, + registry: RegistryArgs { + registry: RegistryPath::Local( + "crates/weaver_codegen_test/semconv_registry/".to_owned(), + ), + registry_git_sub_dir: None, + }, + policies: vec![], + skip_policies: true, + diagnostic: Default::default(), + }), + })), + }; + + let exit_directive = run_command(&cli, logger.clone()); + // The command should succeed. + assert_eq!(exit_directive.exit_code, 0); + + // Hashset containing recursively all the relative paths of rust files in the + // output directory. + let rust_files: std::collections::HashSet<_> = walkdir::WalkDir::new(&temp_output) + .into_iter() + .filter_map(|e| e.ok()) + .filter(|e| e.path().extension().map_or(false, |ext| ext == "rs")) + .map(|e| { + e.path() + .strip_prefix(&temp_output) + .unwrap() + .to_string_lossy() + .to_string() + }) + .collect(); + + let expected_rust_files = vec![ + "attributes/client.rs", + "attributes/mod.rs", + "attributes/exception.rs", + "attributes/server.rs", + "attributes/network.rs", + "attributes/url.rs", + "attributes/http.rs", + "attributes/system.rs", + "attributes/error.rs", + ] + .into_iter() + .map(|s| { + // Split the string by `/` and join the parts with the OS specific separator. + s.split('/') + .collect::() + .to_string_lossy() + .to_string() + }) + .collect::>(); + + assert_eq!(rust_files, expected_rust_files); + } } diff --git a/src/registry/update_markdown.rs b/src/registry/update_markdown.rs index c556782c..24771943 100644 --- a/src/registry/update_markdown.rs +++ b/src/registry/update_markdown.rs @@ -11,8 +11,8 @@ use weaver_cache::Cache; use weaver_common::diagnostic::DiagnosticMessages; use weaver_common::Logger; use weaver_forge::config::Params; -use weaver_forge::file_loader::FileSystemFileLoader; -use weaver_forge::TemplateEngine; +use weaver_forge::file_loader::{FileLoader, FileSystemFileLoader}; +use weaver_forge::{TemplateEngine, WEAVER_YAML}; use weaver_semconv_gen::{update_markdown, SnippetGenerator}; /// Parameters for the `registry update-markdown` sub-command @@ -71,7 +71,15 @@ pub(crate) fn command( format!("{}/registry", args.templates).into(), target, )?; - Some(TemplateEngine::try_new(loader, Params::default())?) + let configs = loader + .load_file(WEAVER_YAML)? + .into_iter() + .collect::>(); + Some(TemplateEngine::try_new( + &configs, + loader, + Params::default(), + )?) } }; From f9bf773e2f9902d12ac4a1a8ec660849cdf216de Mon Sep 17 00:00:00 2001 From: Laurent Querel Date: Thu, 11 Jul 2024 15:12:10 -0700 Subject: [PATCH 08/29] doc(forge): Document the organization and resolution of config files --- crates/weaver_forge/README.md | 28 ++++++++++--- docs/weaver-config.md | 77 +++++++++++++++++++++++++++-------- 2 files changed, 82 insertions(+), 23 deletions(-) diff --git a/crates/weaver_forge/README.md b/crates/weaver_forge/README.md index 630fbae4..85b80e93 100644 --- a/crates/weaver_forge/README.md +++ b/crates/weaver_forge/README.md @@ -23,12 +23,13 @@ using the OTel Weaver tool: ## Template Directory Structure and Naming Conventions -By default, the OTel Weaver tool expects to find a templates directory in the -current directory. +By default, Weaver expects to find the `templates/` directory in the current directory +with the following structure. The location of this directory can be redefined using +the `-t` or `--templates` CLI parameter. ```plaintext templates/ - registry/ + registry/ <-- All templates related to the semantic convention registries go/ <-- Templates to generate the semantic conventions in Go ... html/ <-- Templates to generate the semantic conventions in HTML @@ -70,8 +71,25 @@ its choice. ## Configuration File - `weaver.yaml` -The configuration file `weaver.yaml` is optional. See the [Weaver Configuration File](/docs/weaver-config.md) -documentation for more details. +In the simplest case, a configuration file named `weaver.yaml` is searched for by +the tool within the folder containing the templates. The syntax of this configuration +file is described here [Weaver Configuration File](/docs/weaver-config.md). + +It is possible to utilize the hierarchy of folders containing the targets to share +segments of the configuration common to all targets. Similarly, you can define +Weaver configuration segments in your home directory, i.e., $HOME/.weaver/weaver.yaml. + +By default, the `weaver.yaml` files are loaded in the following order: + +- $HOME/.weaver/weaver.yaml +- /weaver.yaml, all intermediate directories containing a `weaver.yaml` file up to the +`templates/registry/` directory. +- `templates/registry//weaver.yaml` + +The last configuration file loaded will override the previous ones. + +For the most complex cases, it is possible to define explicitly the list configuration +files to load using the `--config` CLI n-ary parameter. ## Global Variables diff --git a/docs/weaver-config.md b/docs/weaver-config.md index 91626ba9..56b8678e 100644 --- a/docs/weaver-config.md +++ b/docs/weaver-config.md @@ -1,7 +1,8 @@ # Weaver Configuration File - `weaver.yaml` -The configuration file `weaver.yaml` is optional. It allows configuring the -following options: +## Structure + +The following options can be configured in the `weaver.yaml` file: ```yaml # Uncomment this section to specify the configuration of the `text_map` filter. @@ -17,22 +18,6 @@ following options: # boolean: booleanKey # string: stringKey -# Deprecated, please use text_maps instead -# 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" -# ... - # Uncomment this section to specify the configuration of the Jinja template syntax # and control whitespace behavior. # Note: The default syntax is strongly recommended. @@ -83,3 +68,59 @@ following options: # filter: ".groups[] | select(.type == \"attribute_group\")" # application_mode: single ``` + +# Configuration File Loading Order and Overriding Rules + +In the simplest case, a configuration file named `weaver.yaml` is searched for by +the tool within the folder containing the templates. + +It is possible to utilize the hierarchy of folders containing the targets to share +segments of the configuration common to all targets. Similarly, you can define +Weaver configuration segments in your home directory, i.e., $HOME/.weaver/weaver.yaml. + +By default, the `weaver.yaml` files are loaded in the following order: + +- $HOME/.weaver/weaver.yaml +- /weaver.yaml, all intermediate directories containing a `weaver.yaml` file up to the + `templates/registry/` directory. +- `templates/registry//weaver.yaml` + +The last configuration file loaded will override the previous ones. + +For the most complex cases, it is possible to define explicitly the list configuration +files to load using the `--config` CLI n-ary parameter. + +## Example + +Imagine we have two slightly different variants for generating the semconv Python code. + +``` +templates +├── registry +│ ├── python +│ │ ├── weaver.yaml +│ │ ├── attribute_group.md.j2 +│ │ └── ... +│ └── python-incubation +│ │ ├── weaver.yaml +│ │ ├── attribute_group.md.j2 +│ │ └── ... +│ └── weaver.yaml +``` + +The file located in `templates/registry/weaver.yaml` will be loaded first, followed by +`templates/registry/python/weaver.yaml` if the target is `python`. + +Similarly, the file located in `templates/registry/weaver.yaml` will be loaded first, +followed by `templates/registry/python-incubation/weaver.yaml` if the target is +`python-incubation`. + +To share a list of acronyms between the two variants, you can define the list in +`templates/registry/weaver.yaml`. + +```yaml +acronyms: ["iOS", "HTTP", "API", "SDK", "CLI", "URL", "JSON", "XML", "HTML"] +``` + +This list will be automatically inherited by both variants except if the list +is redefined in the variant's `weaver.yaml` file. \ No newline at end of file From d42a61ac22a5753dab7f6ebb4407425027ef4882 Mon Sep 17 00:00:00 2001 From: Laurent Querel Date: Thu, 11 Jul 2024 15:13:26 -0700 Subject: [PATCH 09/29] doc(forge): Document the organization and resolution of config files --- crates/weaver_forge/src/config.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/crates/weaver_forge/src/config.rs b/crates/weaver_forge/src/config.rs index a8c07d9d..62d770ac 100644 --- a/crates/weaver_forge/src/config.rs +++ b/crates/weaver_forge/src/config.rs @@ -2,6 +2,8 @@ //! Weaver Configuration Definition. +#![allow(rustdoc::invalid_html_tags)] + use std::collections::HashMap; use std::path::Path; use std::sync::OnceLock; From add9388de8f167e777ac9a07fc6010ec3d7850b0 Mon Sep 17 00:00:00 2001 From: Laurent Querel Date: Mon, 15 Jul 2024 16:16:26 -0700 Subject: [PATCH 10/29] feat(forge): Improve WeaverConfig and TemplateEngine public APIs --- Cargo.lock | 31 +++++----- crates/weaver_codegen_test/Cargo.toml | 1 + crates/weaver_codegen_test/build.rs | 4 +- crates/weaver_forge/src/config.rs | 84 +++++++++++++++++---------- crates/weaver_forge/src/lib.rs | 38 ++++++------ crates/weaver_semconv_gen/src/lib.rs | 16 ++--- src/main.rs | 44 +++++--------- src/registry/generate.rs | 12 ++-- src/registry/update_markdown.rs | 17 ++---- 9 files changed, 122 insertions(+), 125 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2b2ee092..1b9359e5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -272,9 +272,9 @@ checksum = "5ce89b21cab1437276d2650d57e971f9d548a2d9037cc231abdc0562b97498ce" [[package]] name = "bytes" -version = "1.6.0" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" +checksum = "a12916984aab3fa6e39d655a33e09c0071eb36d6ab3aea5c2d78551f1df6d952" [[package]] name = "bytesize" @@ -284,9 +284,9 @@ checksum = "a3e368af43e418a04d52505cf3dbc23dda4e3407ae2fa99fd0e4f308ce546acc" [[package]] name = "cc" -version = "1.1.0" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eaff6f8ce506b9773fa786672d63fc7a191ffea1be33f72bbd4aeacefca9ffc8" +checksum = "324c74f2155653c90b04f25b2a47a8a631360cb908f92a772695f430c7e31052" [[package]] name = "cfg-if" @@ -1668,9 +1668,9 @@ dependencies = [ [[package]] name = "http-body" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cac85db508abc24a2e48553ba12a996e87244a0395ce011e62b37158745d643" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" dependencies = [ "bytes", "http", @@ -2427,7 +2427,7 @@ checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.5.2", + "redox_syscall 0.5.3", "smallvec", "windows-targets 0.52.6", ] @@ -2750,9 +2750,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.2" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c82cf8cff14456045f55ec4241383baeff27af886adb72ffb2162f99911de0fd" +checksum = "2a908a6e00f1fdd0dfd9c0eb08ce85126f6d8bbda50017e74bc4a4b7d4a926a4" dependencies = [ "bitflags 2.6.0", ] @@ -3258,9 +3258,9 @@ checksum = "b7401a30af6cb5818bb64852270bb722533397edcfc7344954a38f420819ece2" [[package]] name = "syn" -version = "2.0.70" +version = "2.0.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f0209b68b3613b093e0ec905354eccaedcfe83b8cb37cbdeae64026c3064c16" +checksum = "b146dcf730474b4bcd16c311627b31ede9ab149045db4d6088b3becaea046462" dependencies = [ "proc-macro2", "quote", @@ -3345,18 +3345,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.61" +version = "1.0.62" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709" +checksum = "f2675633b1499176c2dff06b0856a27976a8f9d436737b4cf4f312d4d91d8bbb" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.61" +version = "1.0.62" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" +checksum = "d20468752b09f49e909e55a5d338caa8bedf615594e9d80bc4c565d30faf798c" dependencies = [ "proc-macro2", "quote", @@ -3860,6 +3860,7 @@ dependencies = [ name = "weaver_codegen_test" version = "0.5.0" dependencies = [ + "dirs", "opentelemetry 0.23.0", "walkdir", "weaver_cache", diff --git a/crates/weaver_codegen_test/Cargo.toml b/crates/weaver_codegen_test/Cargo.toml index fe75f686..5ce1a550 100644 --- a/crates/weaver_codegen_test/Cargo.toml +++ b/crates/weaver_codegen_test/Cargo.toml @@ -18,6 +18,7 @@ weaver_forge = { path = "../weaver_forge" } weaver_resolver = { path = "../weaver_resolver" } weaver_semconv = { path = "../weaver_semconv" } walkdir.workspace = true +dirs.workspace = true [dependencies] opentelemetry = { version = "0.23.0", features = ["trace", "metrics", "logs", "otel_unstable"] } \ No newline at end of file diff --git a/crates/weaver_codegen_test/build.rs b/crates/weaver_codegen_test/build.rs index 0d7cd854..0a958927 100644 --- a/crates/weaver_codegen_test/build.rs +++ b/crates/weaver_codegen_test/build.rs @@ -51,9 +51,9 @@ fn main() { let loader = FileSystemFileLoader::try_new(TEMPLATES_PATH.into(), TARGET) .unwrap_or_else(|e| process_error(&logger, e)); - let configs = WeaverConfig::collect_from_path("./templates/registry/rust"); - let engine = TemplateEngine::try_new(&configs, loader, Params::default()) + let config = WeaverConfig::try_from_path("./templates/registry/rust") .unwrap_or_else(|e| process_error(&logger, e)); + let engine = TemplateEngine::new(config, loader, Params::default()); let template_registry = ResolvedRegistry::try_from_resolved_registry( schema .registry(REGISTRY_ID) diff --git a/crates/weaver_forge/src/config.rs b/crates/weaver_forge/src/config.rs index 62d770ac..ac349e0f 100644 --- a/crates/weaver_forge/src/config.rs +++ b/crates/weaver_forge/src/config.rs @@ -17,7 +17,8 @@ use serde_yaml::Value; use crate::error::Error; use crate::error::Error::InvalidConfigFile; -use crate::file_loader::FileContent; +use crate::file_loader::{FileContent, FileLoader}; +use crate::WEAVER_YAML; /// Case convention for naming of functions and structs. #[derive(Deserialize, Clone, Debug)] @@ -336,38 +337,28 @@ impl Default for WeaverConfig { } impl WeaverConfig { - /// Collects all the configurations from the path passed in parameter. The configuration files - /// are collected in the order of the enumeration below: - /// - the $HOME/.weaver/weaver.yaml file, - /// - the /weaver.yaml and its weaver.yaml. - pub fn collect_from_path>(path: P) -> Vec { - let mut file_contents = Vec::new(); - - // Detect all the weaver.yaml files in the path and parent folder. - let mut current_path = path.as_ref(); - loop { - if let Ok(file_content) = FileContent::try_from_path(current_path.join("weaver.yaml")) { - file_contents.push(file_content); - } - - if let Some(parent) = current_path.parent() { - current_path = parent; - } else { - break; - } - } + /// Attempts to load and build a `WeaverConfig` from configuration files found in the specified + /// path. Configuration files are loaded in the following order of precedence: + /// + /// 1. The `/weaver.yaml` file. + /// 2. Any `weaver.yaml` files found in parent directories of the specified path, up to the root + /// directory. + /// 3. The `$HOME/.weaver/weaver.yaml` file. + pub fn try_from_path>(path: P) -> Result { + let configs = Self::collect_from_path(path); + Self::resolve_from(&configs) + } - // Add the configuration from the home directory. - if let Some(home_dir) = home_dir() { - if let Ok(file_content) = - FileContent::try_from_path(home_dir.join(".weaver/weaver.yaml")) - { - file_contents.push(file_content); - } + /// Attempts to load and build a `weaver.yaml` file from the specified file loader. This + /// constructor is only initializing the configuration from a single weaver.yaml file found + /// in the loader. If no file is found, the default configuration is returned. + pub fn try_from_loader( + loader: &(impl FileLoader + Send + Sync + 'static), + ) -> Result { + match loader.load_file(WEAVER_YAML)? { + Some(config) => Self::resolve_from(&[config]), + None => Ok(WeaverConfig::default()), } - - file_contents.reverse(); - file_contents } /// Builds the Weaver configuration from a collection of configurations passed in parameter. @@ -396,6 +387,37 @@ impl WeaverConfig { Ok(config) } + + fn collect_from_path>(path: P) -> Vec { + let mut file_contents = Vec::new(); + + // Detect all the weaver.yaml files in the path and parent folder. + let mut current_path = path.as_ref(); + loop { + if let Ok(file_content) = FileContent::try_from_path(current_path.join("weaver.yaml")) { + file_contents.push(file_content); + } + + if let Some(parent) = current_path.parent() { + current_path = parent; + } else { + break; + } + } + + // Add the configuration from the home directory. + if let Some(home_dir) = home_dir() { + if let Ok(file_content) = + FileContent::try_from_path(home_dir.join(".weaver/weaver.yaml")) + { + file_contents.push(file_content); + } + } + + file_contents.reverse(); + file_contents + } + /// Return a template matcher for the target configuration. pub fn template_matcher(&self) -> Result, Error> { if let Some(templates) = &self.templates { diff --git a/crates/weaver_forge/src/lib.rs b/crates/weaver_forge/src/lib.rs index c66598c4..cb5c4a81 100644 --- a/crates/weaver_forge/src/lib.rs +++ b/crates/weaver_forge/src/lib.rs @@ -30,7 +30,7 @@ use crate::config::{ApplicationMode, Params, WeaverConfig}; use crate::debug::error_summary; use crate::error::Error::InvalidConfigFile; use crate::extensions::{ansi, case, code, otel, util}; -use crate::file_loader::{FileContent, FileLoader}; +use crate::file_loader::FileLoader; use crate::filter::Filter; use crate::registry::{ResolvedGroup, ResolvedRegistry}; @@ -160,28 +160,25 @@ impl TryInto for NewContext<'_> { } 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( - configs: &[FileContent], + /// Create a new template engine for the given Weaver config. + pub fn new( + mut config: WeaverConfig, loader: impl FileLoader + Send + Sync + 'static, params: Params, - ) -> Result { - let mut target_config = WeaverConfig::resolve_from(configs)?; - + ) -> Self { // Override the params defined in the `weaver.yaml` file with the params provided // in the command line. for (name, value) in params.params { - _ = target_config + _ = config .params .get_or_insert_with(HashMap::new) .insert(name, value); } - Ok(Self { + Self { file_loader: Arc::new(loader), - target_config, - }) + target_config: config, + } } /// Generate a template snippet from serializable context and a snippet identifier. @@ -543,12 +540,12 @@ mod tests { use weaver_resolver::SchemaResolver; use weaver_semconv::registry::SemConvRegistry; - use crate::config::{ApplicationMode, CaseConvention, Params, TemplateConfig}; + use crate::config::{ApplicationMode, CaseConvention, Params, TemplateConfig, WeaverConfig}; use crate::debug::print_dedup_errors; use crate::extensions::case::case_converter; - use crate::file_loader::{FileLoader, FileSystemFileLoader}; + use crate::file_loader::FileSystemFileLoader; use crate::registry::ResolvedRegistry; - use crate::{OutputDirective, WEAVER_YAML}; + use crate::OutputDirective; #[test] fn test_case_converter() { @@ -677,9 +674,9 @@ mod tests { let logger = TestLogger::default(); let loader = FileSystemFileLoader::try_new("templates".into(), "test") .expect("Failed to create file system loader"); - let config = loader.load_file(WEAVER_YAML).unwrap().unwrap(); - let mut engine = super::TemplateEngine::try_new(&[config], loader, Params::default()) - .expect("Failed to create template engine"); + let config = + WeaverConfig::try_from_loader(&loader).expect("Failed to load `templates/weaver.yaml`"); + let mut engine = super::TemplateEngine::new(config, loader, Params::default()); // Add a template configuration for converter.md on top // of the default template configuration. This is useful @@ -729,9 +726,8 @@ mod tests { let logger = TestLogger::default(); let loader = FileSystemFileLoader::try_new("whitespace_control_templates".into(), "test") .expect("Failed to create file system loader"); - let config = loader.load_file(WEAVER_YAML).unwrap().unwrap(); - let engine = super::TemplateEngine::try_new(&[config], loader, Params::default()) - .expect("Failed to create template engine"); + let config = WeaverConfig::try_from_loader(&loader).unwrap(); + let engine = super::TemplateEngine::new(config, loader, Params::default()); let registry_id = "default"; let mut registry = SemConvRegistry::try_from_path_pattern(registry_id, "data/*.yaml") diff --git a/crates/weaver_semconv_gen/src/lib.rs b/crates/weaver_semconv_gen/src/lib.rs index 7f10629a..51ee9936 100644 --- a/crates/weaver_semconv_gen/src/lib.rs +++ b/crates/weaver_semconv_gen/src/lib.rs @@ -422,11 +422,10 @@ impl ResolvedSemconvRegistry { #[cfg(test)] mod tests { use std::fs; - use std::path::PathBuf; - use weaver_forge::config::Params; - use weaver_forge::file_loader::{FileLoader, FileSystemFileLoader}; - use weaver_forge::{TemplateEngine, WEAVER_YAML}; + use weaver_forge::config::{Params, WeaverConfig}; + use weaver_forge::file_loader::FileSystemFileLoader; + use weaver_forge::TemplateEngine; use crate::{update_markdown, Error, SnippetGenerator}; @@ -440,11 +439,8 @@ mod tests { #[test] fn test_template_engine() -> Result<(), Error> { let loader = FileSystemFileLoader::try_new("templates/registry".into(), "markdown")?; - let configs = loader - .load_file(WEAVER_YAML)? - .into_iter() - .collect::>(); - let template = TemplateEngine::try_new(&configs, loader, Params::default())?; + let config = WeaverConfig::try_from_loader(&loader)?; + let template = TemplateEngine::new(config, loader, Params::default()); let generator = SnippetGenerator::try_from_path("data", Some(template))?; let attribute_registry_url = "/docs/attributes-registry"; // Now we should check a snippet. @@ -495,7 +491,7 @@ mod tests { } } - fn run_legacy_test(path: PathBuf) -> Result<(), Error> { + fn run_legacy_test(path: std::path::PathBuf) -> Result<(), Error> { let semconv_path = format!("{}", path.display()); let lookup = SnippetGenerator::try_from_path(&semconv_path, None)?; let test_path = path.join("test.md").display().to_string(); diff --git a/src/main.rs b/src/main.rs index 913dacf1..0583d8d0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -10,9 +10,9 @@ use registry::semconv_registry; use weaver_common::diagnostic::DiagnosticMessages; use weaver_common::quiet::QuietLogger; use weaver_common::{ConsoleLogger, Logger}; -use weaver_forge::config::Params; -use weaver_forge::file_loader::{EmbeddedFileLoader, FileLoader}; -use weaver_forge::{OutputDirective, TemplateEngine, WEAVER_YAML}; +use weaver_forge::config::{Params, WeaverConfig}; +use weaver_forge::file_loader::EmbeddedFileLoader; +use weaver_forge::{OutputDirective, TemplateEngine}; use crate::cli::{Cli, Commands}; use crate::diagnostic::DEFAULT_DIAGNOSTIC_TEMPLATES; @@ -137,33 +137,21 @@ fn process_diagnostics( &diagnostic_args.diagnostic_format, ) .expect("Failed to create the embedded file loader for the diagnostic templates"); - let config = loader - .load_file(WEAVER_YAML) - .expect( - "Invalid Weaver configuration file: `defaults/diagnostic_templates/weaver.yaml`", - ) + let config = WeaverConfig::try_from_loader(&loader) .expect("Failed to load `defaults/diagnostic_templates/weaver.yaml`"); - match TemplateEngine::try_new(&[config], loader, Params::default()) { - Ok(engine) => { - match engine.generate( - logger.clone(), - &diagnostic_messages, - PathBuf::new().as_path(), - &OutputDirective::Stdout, - ) { - Ok(_) => {} - Err(e) => { - logger.error(&format!( - "Failed to render the diagnostic messages. Error: {}", - e - )); - exit_directives.exit_code = 1; - return exit_directives; - } - } - } + let engine = TemplateEngine::new(config, loader, Params::default()); + match engine.generate( + logger.clone(), + &diagnostic_messages, + PathBuf::new().as_path(), + &OutputDirective::Stdout, + ) { + Ok(_) => {} Err(e) => { - logger.error(&format!("Failed to create the template engine to render the diagnostic messages. Error: {}", e)); + logger.error(&format!( + "Failed to render the diagnostic messages. Error: {}", + e + )); exit_directives.exit_code = 1; return exit_directives; } diff --git a/src/registry/generate.rs b/src/registry/generate.rs index aed74d2b..5d658590 100644 --- a/src/registry/generate.rs +++ b/src/registry/generate.rs @@ -114,16 +114,16 @@ pub(crate) fn command( let mut registry = SemConvRegistry::from_semconv_specs(registry_id, semconv_specs); let schema = resolve_semconv_specs(&mut registry, logger.clone())?; let loader = FileSystemFileLoader::try_new(args.templates.join("registry"), &args.target)?; - let mut configs = Vec::new(); - - if let Some(paths) = &args.config { + let config = if let Some(paths) = &args.config { + let mut configs = Vec::new(); for path in paths { configs.push(FileContent::try_from_path(path)?); } + WeaverConfig::resolve_from(&configs) } else { - configs.extend(WeaverConfig::collect_from_path(loader.root())); - }; - let engine = TemplateEngine::try_new(&configs, loader, params)?; + WeaverConfig::try_from_path(loader.root()) + }?; + let engine = TemplateEngine::new(config, loader, params); let template_registry = ResolvedRegistry::try_from_resolved_registry( schema diff --git a/src/registry/update_markdown.rs b/src/registry/update_markdown.rs index 24771943..abfafc9b 100644 --- a/src/registry/update_markdown.rs +++ b/src/registry/update_markdown.rs @@ -10,9 +10,9 @@ use clap::Args; use weaver_cache::Cache; use weaver_common::diagnostic::DiagnosticMessages; use weaver_common::Logger; -use weaver_forge::config::Params; -use weaver_forge::file_loader::{FileLoader, FileSystemFileLoader}; -use weaver_forge::{TemplateEngine, WEAVER_YAML}; +use weaver_forge::config::{Params, WeaverConfig}; +use weaver_forge::file_loader::FileSystemFileLoader; +use weaver_forge::TemplateEngine; use weaver_semconv_gen::{update_markdown, SnippetGenerator}; /// Parameters for the `registry update-markdown` sub-command @@ -71,15 +71,8 @@ pub(crate) fn command( format!("{}/registry", args.templates).into(), target, )?; - let configs = loader - .load_file(WEAVER_YAML)? - .into_iter() - .collect::>(); - Some(TemplateEngine::try_new( - &configs, - loader, - Params::default(), - )?) + let config = WeaverConfig::try_from_loader(&loader)?; + Some(TemplateEngine::new(config, loader, Params::default())) } }; From 582516bf868d62e5c58c315eae33f283f00d46ee Mon Sep 17 00:00:00 2001 From: Laurent Querel Date: Mon, 15 Jul 2024 16:27:21 -0700 Subject: [PATCH 11/29] feat(forge): Remove FileContent from the public API --- crates/weaver_forge/src/config.rs | 16 ++++++++++++++-- src/registry/generate.rs | 8 ++------ 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/crates/weaver_forge/src/config.rs b/crates/weaver_forge/src/config.rs index ac349e0f..a5030dc5 100644 --- a/crates/weaver_forge/src/config.rs +++ b/crates/weaver_forge/src/config.rs @@ -349,6 +349,19 @@ impl WeaverConfig { Self::resolve_from(&configs) } + /// Attempts to load all the configuration files and build a unique `WeaverConfig` from the + /// specified configuration files. The last files in the list will override the first ones. + /// + /// This method can fail if any of the configuration content is not a valid YAML file or if the + /// configuration content can't be deserialized into a `WeaverConfig` struct. + pub fn try_from_config_files>(config_files: &[P]) -> Result { + let mut configs = Vec::new(); + for config in config_files { + configs.push(FileContent::try_from_path(config)?); + } + WeaverConfig::resolve_from(&configs) + } + /// Attempts to load and build a `weaver.yaml` file from the specified file loader. This /// constructor is only initializing the configuration from a single weaver.yaml file found /// in the loader. If no file is found, the default configuration is returned. @@ -367,7 +380,7 @@ impl WeaverConfig { /// /// This method can fail if any of the configuration content is not a valid YAML file or if the /// configuration content can't be deserialized into a `WeaverConfig` struct. - pub fn resolve_from(configs: &[FileContent]) -> Result { + fn resolve_from(configs: &[FileContent]) -> Result { // The default configuration is used as a base for the resolution. let mut config = WeaverConfig::default(); if configs.is_empty() { @@ -387,7 +400,6 @@ impl WeaverConfig { Ok(config) } - fn collect_from_path>(path: P) -> Vec { let mut file_contents = Vec::new(); diff --git a/src/registry/generate.rs b/src/registry/generate.rs index 5d658590..2a44fdc2 100644 --- a/src/registry/generate.rs +++ b/src/registry/generate.rs @@ -11,7 +11,7 @@ use weaver_cache::Cache; use weaver_common::diagnostic::DiagnosticMessages; use weaver_common::Logger; use weaver_forge::config::{Params, WeaverConfig}; -use weaver_forge::file_loader::{FileContent, FileLoader, FileSystemFileLoader}; +use weaver_forge::file_loader::{FileLoader, FileSystemFileLoader}; use weaver_forge::registry::ResolvedRegistry; use weaver_forge::{OutputDirective, TemplateEngine}; use weaver_semconv::registry::SemConvRegistry; @@ -115,11 +115,7 @@ pub(crate) fn command( let schema = resolve_semconv_specs(&mut registry, logger.clone())?; let loader = FileSystemFileLoader::try_new(args.templates.join("registry"), &args.target)?; let config = if let Some(paths) = &args.config { - let mut configs = Vec::new(); - for path in paths { - configs.push(FileContent::try_from_path(path)?); - } - WeaverConfig::resolve_from(&configs) + WeaverConfig::try_from_config_files(paths) } else { WeaverConfig::try_from_path(loader.root()) }?; From 78d4f40d3ab653a85cc557ffa41876aff0866c73 Mon Sep 17 00:00:00 2001 From: Laurent Querel Date: Mon, 15 Jul 2024 16:34:49 -0700 Subject: [PATCH 12/29] feat(forge): Create constants for Jinja syntax delimiters --- crates/weaver_forge/src/lib.rs | 36 ++++++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/crates/weaver_forge/src/lib.rs b/crates/weaver_forge/src/lib.rs index cb5c4a81..31474a60 100644 --- a/crates/weaver_forge/src/lib.rs +++ b/crates/weaver_forge/src/lib.rs @@ -45,6 +45,26 @@ pub mod registry; /// Name of the Weaver configuration file. pub const WEAVER_YAML: &str = "weaver.yaml"; +// Jinja syntax delimiters + +/// Constant defining the start of a Jinja block. +pub const BLOCK_START: &str = "{%"; + +/// Constant defining the end of a Jinja block. +pub const BLOCK_END: &str = "%}"; + +/// Constant defining the start of a Jinja variable. +pub const VARIABLE_START: &str = "{{"; + +/// Constant defining the end of a Jinja variable. +pub const VARIABLE_END: &str = "}}"; + +/// Constant defining the start of a Jinja comment. +pub const COMMENT_START: &str = "{#"; + +/// Constant defining the end of a Jinja comment. +pub const COMMEND_END: &str = "#}"; + /// Enumeration defining where the output of program execution should be directed. #[derive(Debug, Clone)] pub enum OutputDirective { @@ -440,32 +460,36 @@ impl TemplateEngine { Cow::Owned( template_syntax .block_start - .unwrap_or_else(|| "{%".to_owned()), + .unwrap_or_else(|| BLOCK_START.to_owned()), + ), + Cow::Owned( + template_syntax + .block_end + .unwrap_or_else(|| BLOCK_END.to_owned()), ), - Cow::Owned(template_syntax.block_end.unwrap_or_else(|| "%}".to_owned())), ) .variable_delimiters( Cow::Owned( template_syntax .variable_start - .unwrap_or_else(|| "{{".to_owned()), + .unwrap_or_else(|| VARIABLE_START.to_owned()), ), Cow::Owned( template_syntax .variable_end - .unwrap_or_else(|| "}}".to_owned()), + .unwrap_or_else(|| VARIABLE_END.to_owned()), ), ) .comment_delimiters( Cow::Owned( template_syntax .comment_start - .unwrap_or_else(|| "{#".to_owned()), + .unwrap_or_else(|| COMMENT_START.to_owned()), ), Cow::Owned( template_syntax .comment_end - .unwrap_or_else(|| "#}".to_owned()), + .unwrap_or_else(|| COMMEND_END.to_owned()), ), ) .build() From 0f2d7c75606a90921031737a2a2745bba7d122d6 Mon Sep 17 00:00:00 2001 From: querel Date: Tue, 16 Jul 2024 07:55:16 -0700 Subject: [PATCH 13/29] chore(forge): Remove unused filters function_name, struct_name, ... --- crates/weaver_forge/README.md | 2 +- .../overloaded-templates/test/group.md | 2 +- .../weaver_forge/templates/test/attribute_group.md | 2 +- crates/weaver_forge/templates/test/event.md | 2 +- crates/weaver_forge/templates/test/group.md | 2 +- crates/weaver_forge/templates/test/metric.md | 2 +- crates/weaver_forge/templates/test/registry.md | 14 +++++++------- crates/weaver_forge/templates/test/resource.md | 2 +- crates/weaver_forge/templates/test/span.md | 2 +- .../whitespace_control_templates/test/registry.md | 14 +++++++------- 10 files changed, 22 insertions(+), 22 deletions(-) diff --git a/crates/weaver_forge/README.md b/crates/weaver_forge/README.md index 85b80e93..b91d79ee 100644 --- a/crates/weaver_forge/README.md +++ b/crates/weaver_forge/README.md @@ -61,7 +61,7 @@ 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 -%} +{%- set file_name = group.id | snake_case -%} {{- template.set_file_name("span/" ~ file_name ~ ".md") -}} ``` diff --git a/crates/weaver_forge/overloaded-templates/test/group.md b/crates/weaver_forge/overloaded-templates/test/group.md index a817d676..32e0b553 100644 --- a/crates/weaver_forge/overloaded-templates/test/group.md +++ b/crates/weaver_forge/overloaded-templates/test/group.md @@ -1,4 +1,4 @@ -{%- set file_name = ctx.id | file_name -%} +{%- set file_name = ctx.id | snake_case -%} {{- template.set_file_name("group/" ~ file_name ~ ".md") -}} # Overloaded Group `{{ ctx.id }}` ({{ ctx.type }}) diff --git a/crates/weaver_forge/templates/test/attribute_group.md b/crates/weaver_forge/templates/test/attribute_group.md index 80fb05f0..fd90cae0 100644 --- a/crates/weaver_forge/templates/test/attribute_group.md +++ b/crates/weaver_forge/templates/test/attribute_group.md @@ -1,4 +1,4 @@ -{%- set file_name = ctx.id | file_name -%} +{%- set file_name = ctx.id | snake_case -%} {{- template.set_file_name("attribute_group/" ~ file_name ~ ".md") -}} ## Group `{{ ctx.id | split_id | list | join("_") }}` ({{ ctx.type }}) diff --git a/crates/weaver_forge/templates/test/event.md b/crates/weaver_forge/templates/test/event.md index 43736aa7..ecdeac3d 100644 --- a/crates/weaver_forge/templates/test/event.md +++ b/crates/weaver_forge/templates/test/event.md @@ -1,4 +1,4 @@ -{%- set file_name = ctx.id | file_name -%} +{%- set file_name = ctx.id | snake_case -%} {{- template.set_file_name("event/" ~ file_name ~ ".md") -}} # Group `{{ ctx.id }}` ({{ ctx.type }}) diff --git a/crates/weaver_forge/templates/test/group.md b/crates/weaver_forge/templates/test/group.md index 1d14bc87..6c00c430 100644 --- a/crates/weaver_forge/templates/test/group.md +++ b/crates/weaver_forge/templates/test/group.md @@ -1,4 +1,4 @@ -{%- set file_name = ctx.id | file_name -%} +{%- set file_name = ctx.id | snake_case -%} {{- template.set_file_name("group/" ~ file_name ~ ".md") -}} # Group `{{ ctx.id }}` ({{ ctx.type }}) diff --git a/crates/weaver_forge/templates/test/metric.md b/crates/weaver_forge/templates/test/metric.md index d45df277..ea30d22a 100644 --- a/crates/weaver_forge/templates/test/metric.md +++ b/crates/weaver_forge/templates/test/metric.md @@ -1,4 +1,4 @@ -{%- set file_name = ctx.id | file_name -%} +{%- set file_name = ctx.id | snake_case -%} {{- template.set_file_name("metric/" ~ file_name ~ ".md") -}} ## Group `{{ ctx.id }}` ({{ ctx.type }}) diff --git a/crates/weaver_forge/templates/test/registry.md b/crates/weaver_forge/templates/test/registry.md index 3bd4b2c5..dceb0e89 100644 --- a/crates/weaver_forge/templates/test/registry.md +++ b/crates/weaver_forge/templates/test/registry.md @@ -5,48 +5,48 @@ Url: {{ registry_url }} # Attribute Groups {% for group in ctx.groups -%} {%- if group.type == "attribute_group" %} -- [{{ group.id }}](attribute_group/{{ group.id | file_name }}.md) +- [{{ group.id }}](attribute_group/{{ group.id | snake_case }}.md) {%- endif %} {%- endfor %} # Events {% for group in ctx.groups -%} {%- if group.type == "event" %} -- [{{ group.id }}](event/{{ group.id | file_name }}.md) +- [{{ group.id }}](event/{{ group.id | snake_case }}.md) {%- endif %} {%- endfor %} # Metrics {% for group in ctx.groups -%} {%- if group.type == "metric" %} -- [{{ group.id }}](metric/{{ group.id | file_name }}.md) +- [{{ group.id }}](metric/{{ group.id | snake_case }}.md) {%- endif %} {%- endfor %} # Metric Groups {% for group in ctx.groups -%} {%- if group.type == "metric_group" %} -- [{{ group.id }}](metric_group/{{ group.id | file_name }}.md) +- [{{ group.id }}](metric_group/{{ group.id | snake_case }}.md) {%- endif %} {%- endfor %} # Resource {% for group in ctx.groups -%} {%- if group.type == "resource" %} -- [{{ group.id }}](resource/{{ group.id | file_name }}.md) +- [{{ group.id }}](resource/{{ group.id | snake_case }}.md) {%- endif %} {%- endfor %} # Scope {% for group in ctx.groups -%} {%- if group.type == "scope" %} -- [{{ group.id }}](scope/{{ group.id | file_name }}.md) +- [{{ group.id }}](scope/{{ group.id | snake_case }}.md) {%- endif %} {%- endfor %} # Span {% for group in ctx.groups -%} {%- if group.type == "span" %} -- [{{ group.id }}](span/{{ group.id | file_name }}.md) +- [{{ group.id }}](span/{{ group.id | snake_case }}.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 5fb7efa6..b4ab50a9 100644 --- a/crates/weaver_forge/templates/test/resource.md +++ b/crates/weaver_forge/templates/test/resource.md @@ -1,4 +1,4 @@ -{%- set file_name = ctx.id | file_name -%} +{%- set file_name = ctx.id | snake_case -%} {{- template.set_file_name("resource/" ~ file_name ~ ".md") -}} ## Group `{{ ctx.id }}` ({{ ctx.type }}) diff --git a/crates/weaver_forge/templates/test/span.md b/crates/weaver_forge/templates/test/span.md index 02b58a3f..6f00ffc3 100644 --- a/crates/weaver_forge/templates/test/span.md +++ b/crates/weaver_forge/templates/test/span.md @@ -1,4 +1,4 @@ -{%- set file_name = ctx.id | file_name -%} +{%- set file_name = ctx.id | snake_case -%} {{- template.set_file_name("span/" ~ file_name ~ ".md") -}} ## Group `{{ ctx.id }}` ({{ ctx.type }}) diff --git a/crates/weaver_forge/whitespace_control_templates/test/registry.md b/crates/weaver_forge/whitespace_control_templates/test/registry.md index 73f1c62c..49df936f 100644 --- a/crates/weaver_forge/whitespace_control_templates/test/registry.md +++ b/crates/weaver_forge/whitespace_control_templates/test/registry.md @@ -6,7 +6,7 @@ Url:{{ registry_url }} {% for group in ctx.groups %} {% if group.type == "attribute_group" %} -- [{{ group.id }}](attribute_group/{{ group.id | file_name }}.md) +- [{{ group.id }}](attribute_group/{{ group.id | snake_case }}.md) {% endif %} {% endfor %} @@ -14,7 +14,7 @@ Url:{{ registry_url }} {% for group in ctx.groups %} {% if group.type == "event" %} -- [{{ group.id }}](event/{{ group.id | file_name }}.md) +- [{{ group.id }}](event/{{ group.id | snake_case }}.md) {% endif %} {% endfor %} @@ -22,14 +22,14 @@ Url:{{ registry_url }} {% for group in ctx.groups %} {% if group.type == "metric" %} -- [{{ group.id }}](metric/{{ group.id | file_name }}.md) +- [{{ group.id }}](metric/{{ group.id | snake_case }}.md) {% endif %} {% endfor %} ## Metric Groups {% for group in ctx.groups %} {% if group.type == "metric_group" %} -- [{{ group.id }}](metric_group/{{ group.id | file_name }}.md) +- [{{ group.id }}](metric_group/{{ group.id | snake_case }}.md) {% endif %} {% endfor %} @@ -37,14 +37,14 @@ Url:{{ registry_url }} {% for group in ctx.groups %} {% if group.type == "resource" %} -- [{{ group.id }}](resource/{{ group.id | file_name }}.md) +- [{{ group.id }}](resource/{{ group.id | snake_case }}.md) {% endif %} {% endfor %} ## Scope {% for group in ctx.groups %} {% if group.type == "scope" %} -- [{{ group.id }}](scope/{{ group.id | file_name }}.md) +- [{{ group.id }}](scope/{{ group.id | snake_case }}.md) {% endif %} {% endfor %} @@ -52,6 +52,6 @@ Url:{{ registry_url }} {% for group in ctx.groups %} {% if group.type == "span" %} -- [{{ group.id }}](span/{{ group.id | file_name }}.md) +- [{{ group.id }}](span/{{ group.id | snake_case }}.md) {% endif %} {% endfor %} From d93a9c88185d218be2259be55ed35c37306d17f4 Mon Sep 17 00:00:00 2001 From: querel Date: Tue, 16 Jul 2024 09:12:34 -0700 Subject: [PATCH 14/29] chore(build): Merge with main and bump weaver version --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index fb67d67d..a2a5a281 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "weaver" -version = "0.5.0" +version = "0.6.0" authors = ["OpenTelemetry"] edition = "2021" repository = "https://github.com/open-telemetry/weaver" From 088cf19133eb6e501d608d8ac56e4f4cfb659ebb Mon Sep 17 00:00:00 2001 From: Laurent Querel Date: Wed, 17 Jul 2024 00:09:31 -0700 Subject: [PATCH 15/29] feat(forge): Add predefined semconv JQ functions --- .../templates/registry/rust/weaver.yaml | 43 +++++-------------- crates/weaver_forge/src/filter.rs | 17 ++++++++ .../weaver_forge/templates/test/weaver.yaml | 24 +++++------ defaults/jq/semconv.jq | 36 ++++++++++++++++ 4 files changed, 75 insertions(+), 45 deletions(-) create mode 100644 defaults/jq/semconv.jq diff --git a/crates/weaver_codegen_test/templates/registry/rust/weaver.yaml b/crates/weaver_codegen_test/templates/registry/rust/weaver.yaml index 47b4ad4a..08a6acbb 100644 --- a/crates/weaver_codegen_test/templates/registry/rust/weaver.yaml +++ b/crates/weaver_codegen_test/templates/registry/rust/weaver.yaml @@ -25,16 +25,9 @@ templates: # - groups are sorted by namespace. filter: > if $attributes then - .groups - | map(select(.id | startswith($registry_prefix))) - | map(select(.type == "attribute_group") - | { - id, - type, - brief, - prefix}) - | unique_by(.id | split(".") | .[1]) - | sort_by(.id | split(".") | .[1]) + semconv_attributes + | unique_by(.group_id) + | sort_by(.group_id) else empty end @@ -47,16 +40,8 @@ templates: # - groups are sorted by namespace. filter: > if $attributes then - .groups - | map(select(.id | startswith($registry_prefix))) - | map(select(.type == "attribute_group") - | { - id, - type, - brief, - prefix, - attributes}) - | group_by(.id | split(".") | .[1]) + semconv_attributes + | group_by(.group_id) | map({ id: (map(select(.id | endswith(".deprecated") | not)) | first).id, type: (map(select(.id | endswith(".deprecated") | not)) | first).type, @@ -79,16 +64,9 @@ templates: # - groups are sorted by prefix. filter: > if $metrics then - .groups - | map(select(.id | startswith("metric."))) - | map(select(.type == "metric") - | { - id, - type, - brief, - prefix}) - | unique_by(.id | split(".") | .[1]) - | sort_by(.id | split(".") | .[1]) + semconv_metrics + | unique_by(.group_id) + | sort_by(.group_id) else empty end @@ -101,9 +79,8 @@ templates: # - groups are sorted by namespace. filter: > if $metrics then - .groups - | map(select(.id | startswith("metric."))) - | group_by(.id | split(".") | .[1]) + semconv_metrics + | group_by(.group_id) | map({ prefix: .[0].id | split(".") | .[1], groups: . diff --git a/crates/weaver_forge/src/filter.rs b/crates/weaver_forge/src/filter.rs index 66219927..803c82a4 100644 --- a/crates/weaver_forge/src/filter.rs +++ b/crates/weaver_forge/src/filter.rs @@ -7,6 +7,8 @@ use core::fmt; use jaq_interpret::{Ctx, FilterT, RcIter, Val}; use std::fmt::Debug; +const SEMCONV_JQ: &str = include_str!("../../../defaults/jq/semconv.jq"); + /// A filter that can be applied to a JSON value. pub struct Filter { filter_expr: String, @@ -22,6 +24,21 @@ impl Filter { let mut ctx = jaq_interpret::ParseCtx::new(vars); ctx.insert_natives(jaq_core::core()); ctx.insert_defs(jaq_std::std()); + // ToDO LQ Move this as a parameter + let (defs, errs) = jaq_parse::parse(SEMCONV_JQ, jaq_parse::defs()); + if !errs.is_empty() { + return Err(Error::CompoundError( + errs.into_iter() + .map(|e| Error::FilterError { + filter: filter_expr.to_owned(), + error: e.to_string(), + }) + .collect(), + )); + } + if let Some(defs) = defs { + ctx.insert_defs(defs); + } let (parsed_expr, errs) = jaq_parse::parse(filter_expr, jaq_parse::main()); diff --git a/crates/weaver_forge/templates/test/weaver.yaml b/crates/weaver_forge/templates/test/weaver.yaml index e100857c..e0bde633 100644 --- a/crates/weaver_forge/templates/test/weaver.yaml +++ b/crates/weaver_forge/templates/test/weaver.yaml @@ -21,16 +21,16 @@ templates: filter: "." application_mode: single - pattern: "**/attribute_group.md" - filter: ".groups[] | select(.type == \"attribute_group\")" + filter: semconv_attributes application_mode: each - pattern: "**/attribute_groups.md" - filter: ".groups[] | select(.type == \"attribute_group\")" + filter: semconv_attributes application_mode: single - pattern: "**/event.md" - filter: ".groups[] | select(.type == \"event\")" + filter: semconv_events application_mode: each - pattern: "**/events.md" - filter: ".groups[] | select(.type == \"event\")" + filter: semconv_events application_mode: single - pattern: "**/group.md" filter: ".groups" @@ -39,26 +39,26 @@ templates: filter: ".groups" application_mode: single - pattern: "**/metric.md" - filter: ".groups[] | select(.type == \"metric\")" + filter: semconv_metrics application_mode: each - pattern: "**/metrics.md" - filter: ".groups[] | select(.type == \"metric\")" + filter: semconv_metrics application_mode: single - pattern: "**/resource.md" - filter: ".groups[] | select(.type == \"resource\")" + filter: semconv_resources application_mode: each - pattern: "**/resources.md" - filter: ".groups[] | select(.type == \"resource\")" + filter: semconv_resources application_mode: single - pattern: "**/scope.md" - filter: ".groups[] | select(.type == \"scope\")" + filter: semconv_scopes application_mode: each - pattern: "**/scopes.md" - filter: ".groups[] | select(.type == \"scope\")" + filter: semconv_scopes application_mode: single - pattern: "**/span.md" - filter: ".groups[] | select(.type == \"span\")" + filter: semconv_spans application_mode: each - pattern: "**/spans.md" - filter: ".groups[] | select(.type == \"span\")" + filter: semconv_spans application_mode: single \ No newline at end of file diff --git a/defaults/jq/semconv.jq b/defaults/jq/semconv.jq new file mode 100644 index 00000000..76adaa9a --- /dev/null +++ b/defaults/jq/semconv.jq @@ -0,0 +1,36 @@ +def semconv_attributes: + .groups[] + | map(select(.id | startswith("registry."))) + | map(select(.type == "attribute_group")) + | map(. + {group_id: .id | split(".") | .[1]}); + +def semconv_metrics: + .groups[] + | map(select(.type == "metric")) + | map(. + {group_id: .id | split(".") | .[1]}); + +def semconv_resources: + .groups[] + | map(select(.type == "resource")) + | map(. + {group_id: .id | split(".") | .[1]}); + +def semconv_scopes: + .groups[] + | map(select(.type == "scope")) + | map(. + {group_id: .id | split(".") | .[1]}); + +def semconv_spans: + .groups[] + | map(select(.type == "span")) + | map(. + {group_id: .id | split(".") | .[1]}); + +def semconv_events: + .groups[] + | map(select(.type == "event")) + | map(. + {group_id: .id | split(".") | .[1]}); + +def semconv_group_by_namespace: + sort_by(.group_id) + | group_by(.group_id); + + From cd08316255035f98cf7857b9c0360c1058af3c26 Mon Sep 17 00:00:00 2001 From: Laurent Querel Date: Wed, 17 Jul 2024 06:42:08 -0700 Subject: [PATCH 16/29] feat(forge): Add more predefined semconv JQ functions --- defaults/jq/semconv.jq | 64 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 56 insertions(+), 8 deletions(-) diff --git a/defaults/jq/semconv.jq b/defaults/jq/semconv.jq index 76adaa9a..0cfb9399 100644 --- a/defaults/jq/semconv.jq +++ b/defaults/jq/semconv.jq @@ -2,35 +2,83 @@ def semconv_attributes: .groups[] | map(select(.id | startswith("registry."))) | map(select(.type == "attribute_group")) - | map(. + {group_id: .id | split(".") | .[1]}); + | map(. + {group_id: .id | split(".") | .[1]}) + | sort_by(.group_id); + +def semconv_grouped_attributes: + .groups[] + | map(select(.id | startswith("registry."))) + | map(select(.type == "attribute_group")) + | map(. + {group_id: .id | split(".") | .[1]}) + | sort_by(.group_id) + | group_by(.group_id); def semconv_metrics: .groups[] | map(select(.type == "metric")) - | map(. + {group_id: .id | split(".") | .[1]}); + | map(. + {group_id: .id | split(".") | .[1]}) + | sort_by(.group_id); + +def semconv_grouped_metrics: + .groups[] + | map(select(.type == "metric")) + | map(. + {group_id: .id | split(".") | .[1]}) + | sort_by(.group_id) + | group_by(.group_id); def semconv_resources: .groups[] | map(select(.type == "resource")) - | map(. + {group_id: .id | split(".") | .[1]}); + | map(. + {group_id: .id | split(".") | .[1]}) + | sort_by(.group_id); + +def semconv_grouped_resources: + .groups[] + | map(select(.type == "resource")) + | map(. + {group_id: .id | split(".") | .[1]}) + | sort_by(.group_id) + | group_by(.group_id); def semconv_scopes: .groups[] | map(select(.type == "scope")) - | map(. + {group_id: .id | split(".") | .[1]}); + | map(. + {group_id: .id | split(".") | .[1]}) + | sort_by(.group_id); + +def semconv_grouped_scopes: + .groups[] + | map(select(.type == "scope")) + | map(. + {group_id: .id | split(".") | .[1]}) + | sort_by(.group_id) + | group_by(.group_id); def semconv_spans: .groups[] | map(select(.type == "span")) - | map(. + {group_id: .id | split(".") | .[1]}); + | map(. + {group_id: .id | split(".") | .[1]}) + | sort_by(.group_id); + +def semconv_grouped_spans: + .groups[] + | map(select(.type == "span")) + | map(. + {group_id: .id | split(".") | .[1]}) + | sort_by(.group_id) + | group_by(.group_id); def semconv_events: .groups[] | map(select(.type == "event")) - | map(. + {group_id: .id | split(".") | .[1]}); + | map(. + {group_id: .id | split(".") | .[1]}) + | sort_by(.group_id); -def semconv_group_by_namespace: - sort_by(.group_id) +def semconv_grouped_events: + .groups[] + | map(select(.type == "event")) + | map(. + {group_id: .id | split(".") | .[1]}) + | sort_by(.group_id) | group_by(.group_id); +def semconv_group_by_namespace: + group_by(.group_id); + From 73d464bd9c1cfac4a464583dea5f8ba38ab89243 Mon Sep 17 00:00:00 2001 From: Laurent Querel Date: Wed, 17 Jul 2024 06:54:07 -0700 Subject: [PATCH 17/29] feat(forge): Use new JQ function in rust codegen example --- .../templates/registry/rust/metrics/metrics.rs.j2 | 2 +- .../templates/registry/rust/weaver.yaml | 13 ++----------- 2 files changed, 3 insertions(+), 12 deletions(-) diff --git a/crates/weaver_codegen_test/templates/registry/rust/metrics/metrics.rs.j2 b/crates/weaver_codegen_test/templates/registry/rust/metrics/metrics.rs.j2 index 0b23820a..b407e6d5 100644 --- a/crates/weaver_codegen_test/templates/registry/rust/metrics/metrics.rs.j2 +++ b/crates/weaver_codegen_test/templates/registry/rust/metrics/metrics.rs.j2 @@ -1,4 +1,4 @@ -{%- set file_name = ctx.prefix | snake_case -%} +{%- set file_name = ctx.group_id | snake_case -%} {{- template.set_file_name("metrics/" ~ file_name ~ ".rs") -}} /* diff --git a/crates/weaver_codegen_test/templates/registry/rust/weaver.yaml b/crates/weaver_codegen_test/templates/registry/rust/weaver.yaml index 08a6acbb..46846fe2 100644 --- a/crates/weaver_codegen_test/templates/registry/rust/weaver.yaml +++ b/crates/weaver_codegen_test/templates/registry/rust/weaver.yaml @@ -27,7 +27,6 @@ templates: if $attributes then semconv_attributes | unique_by(.group_id) - | sort_by(.group_id) else empty end @@ -40,8 +39,7 @@ templates: # - groups are sorted by namespace. filter: > if $attributes then - semconv_attributes - | group_by(.group_id) + semconv_grouped_attributes | map({ id: (map(select(.id | endswith(".deprecated") | not)) | first).id, type: (map(select(.id | endswith(".deprecated") | not)) | first).type, @@ -49,7 +47,6 @@ templates: prefix: (map(select(.id | endswith(".deprecated") | not)) | first).prefix, attributes: map(.attributes) | add }) - | sort_by(.id | split(".") | .[1]) else empty end @@ -66,7 +63,6 @@ templates: if $metrics then semconv_metrics | unique_by(.group_id) - | sort_by(.group_id) else empty end @@ -79,12 +75,7 @@ templates: # - groups are sorted by namespace. filter: > if $metrics then - semconv_metrics - | group_by(.group_id) - | map({ - prefix: .[0].id | split(".") | .[1], - groups: . - }) + semconv_grouped_metrics else empty end From 4001a24147ae9cb63bee888f0bbfd4685daad56e Mon Sep 17 00:00:00 2001 From: Laurent Querel Date: Wed, 17 Jul 2024 23:43:26 -0700 Subject: [PATCH 18/29] feat(forge): Define semconv functions --- .../semconv_jq_fn/semconv_attributes.json | 1 + .../semconv_grouped_attributes.json | 1 + ...ouped_attributes_without_experimental.json | 1 + .../semconv_jq_fn/semconv_metrics.json | 1 + crates/weaver_forge/src/lib.rs | 45 +++++ .../semconv_jq_fn/semconv_attributes.json | 1 + .../semconv_grouped_attributes.json | 1 + ...ouped_attributes_without_experimental.json | 1 + .../semconv_jq_fn/semconv_metrics.json | 1 + .../templates/semconv_jq_fn/weaver.yaml | 22 +++ defaults/jq/semconv.jq | 172 +++++++++--------- 11 files changed, 165 insertions(+), 82 deletions(-) create mode 100644 crates/weaver_forge/expected_output/semconv_jq_fn/semconv_attributes.json create mode 100644 crates/weaver_forge/expected_output/semconv_jq_fn/semconv_grouped_attributes.json create mode 100644 crates/weaver_forge/expected_output/semconv_jq_fn/semconv_grouped_attributes_without_experimental.json create mode 100644 crates/weaver_forge/expected_output/semconv_jq_fn/semconv_metrics.json create mode 100644 crates/weaver_forge/templates/semconv_jq_fn/semconv_attributes.json create mode 100644 crates/weaver_forge/templates/semconv_jq_fn/semconv_grouped_attributes.json create mode 100644 crates/weaver_forge/templates/semconv_jq_fn/semconv_grouped_attributes_without_experimental.json create mode 100644 crates/weaver_forge/templates/semconv_jq_fn/semconv_metrics.json create mode 100644 crates/weaver_forge/templates/semconv_jq_fn/weaver.yaml diff --git a/crates/weaver_forge/expected_output/semconv_jq_fn/semconv_attributes.json b/crates/weaver_forge/expected_output/semconv_jq_fn/semconv_attributes.json new file mode 100644 index 00000000..1baced83 --- /dev/null +++ b/crates/weaver_forge/expected_output/semconv_jq_fn/semconv_attributes.json @@ -0,0 +1 @@ +[{"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","name":"db.cassandra.consistency_level","namespace":"db","requirement_level":"recommended","tag":"tech-specific-cassandra","type":{"allow_custom_values":true,"members":[{"brief":null,"deprecated":null,"id":"all","note":null,"stability":null,"value":"all"},{"brief":null,"deprecated":null,"id":"each_quorum","note":null,"stability":null,"value":"each_quorum"},{"brief":null,"deprecated":null,"id":"quorum","note":null,"stability":null,"value":"quorum"},{"brief":null,"deprecated":null,"id":"local_quorum","note":null,"stability":null,"value":"local_quorum"},{"brief":null,"deprecated":null,"id":"one","note":null,"stability":null,"value":"one"},{"brief":null,"deprecated":null,"id":"two","note":null,"stability":null,"value":"two"},{"brief":null,"deprecated":null,"id":"three","note":null,"stability":null,"value":"three"},{"brief":null,"deprecated":null,"id":"local_one","note":null,"stability":null,"value":"local_one"},{"brief":null,"deprecated":null,"id":"any","note":null,"stability":null,"value":"any"},{"brief":null,"deprecated":null,"id":"serial","note":null,"stability":null,"value":"serial"},{"brief":null,"deprecated":null,"id":"local_serial","note":null,"stability":null,"value":"local_serial"}]}},{"brief":"The data center of the coordinating node for a query.\n","examples":"us-west-2","name":"db.cassandra.coordinator.dc","namespace":"db","requirement_level":"recommended","tag":"tech-specific-cassandra","type":"string"},{"brief":"The ID of the coordinating node for a query.\n","examples":"be13faa2-8574-4d71-926d-27f16cf8a7af","name":"db.cassandra.coordinator.id","namespace":"db","requirement_level":"recommended","tag":"tech-specific-cassandra","type":"string"},{"brief":"Whether or not the query is idempotent.\n","name":"db.cassandra.idempotence","namespace":"db","requirement_level":"recommended","tag":"tech-specific-cassandra","type":"boolean"},{"brief":"The fetch size used for paging, i.e. how many rows will be returned at once.\n","examples":[5000],"name":"db.cassandra.page_size","namespace":"db","requirement_level":"recommended","tag":"tech-specific-cassandra","type":"int"},{"brief":"The number of times a query was speculatively executed. Not set or `0` if the query was not executed speculatively.\n","examples":[0,2],"name":"db.cassandra.speculative_execution_count","namespace":"db","requirement_level":"recommended","tag":"tech-specific-cassandra","type":"int"},{"brief":"The name of the primary Cassandra table that the operation is acting upon, including the keyspace name (if applicable).","examples":"mytable","name":"db.cassandra.table","namespace":"db","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","requirement_level":"recommended","tag":"tech-specific-cassandra","type":"string"},{"brief":"The connection string used to connect to the database. It is recommended to remove embedded credentials.\n","examples":"Server=(localdb)\\v11.0;Integrated Security=true;","name":"db.connection_string","namespace":"db","requirement_level":"recommended","tag":"db-generic","type":"string"},{"brief":"Unique Cosmos client instance id.","examples":"3ba4827d-4422-483f-b59f-85b74211c11d","name":"db.cosmosdb.client_id","namespace":"db","requirement_level":"recommended","tag":"tech-specific-cosmosdb","type":"string"},{"brief":"Cosmos client connection mode.","name":"db.cosmosdb.connection_mode","namespace":"db","requirement_level":"recommended","tag":"tech-specific-cosmosdb","type":{"allow_custom_values":false,"members":[{"brief":"Gateway (HTTP) connections mode","deprecated":null,"id":"gateway","note":null,"stability":null,"value":"gateway"},{"brief":"Direct connection.","deprecated":null,"id":"direct","note":null,"stability":null,"value":"direct"}]}},{"brief":"Cosmos DB container name.","examples":"anystring","name":"db.cosmosdb.container","namespace":"db","requirement_level":"recommended","tag":"tech-specific-cosmosdb","type":"string"},{"brief":"CosmosDB Operation Type.","name":"db.cosmosdb.operation_type","namespace":"db","requirement_level":"recommended","tag":"tech-specific-cosmosdb","type":{"allow_custom_values":true,"members":[{"brief":null,"deprecated":null,"id":"invalid","note":null,"stability":null,"value":"Invalid"},{"brief":null,"deprecated":null,"id":"create","note":null,"stability":null,"value":"Create"},{"brief":null,"deprecated":null,"id":"patch","note":null,"stability":null,"value":"Patch"},{"brief":null,"deprecated":null,"id":"read","note":null,"stability":null,"value":"Read"},{"brief":null,"deprecated":null,"id":"read_feed","note":null,"stability":null,"value":"ReadFeed"},{"brief":null,"deprecated":null,"id":"delete","note":null,"stability":null,"value":"Delete"},{"brief":null,"deprecated":null,"id":"replace","note":null,"stability":null,"value":"Replace"},{"brief":null,"deprecated":null,"id":"execute","note":null,"stability":null,"value":"Execute"},{"brief":null,"deprecated":null,"id":"query","note":null,"stability":null,"value":"Query"},{"brief":null,"deprecated":null,"id":"head","note":null,"stability":null,"value":"Head"},{"brief":null,"deprecated":null,"id":"head_feed","note":null,"stability":null,"value":"HeadFeed"},{"brief":null,"deprecated":null,"id":"upsert","note":null,"stability":null,"value":"Upsert"},{"brief":null,"deprecated":null,"id":"batch","note":null,"stability":null,"value":"Batch"},{"brief":null,"deprecated":null,"id":"query_plan","note":null,"stability":null,"value":"QueryPlan"},{"brief":null,"deprecated":null,"id":"execute_javascript","note":null,"stability":null,"value":"ExecuteJavaScript"}]}},{"brief":"RU consumed for that operation","examples":[46.18,1.0],"name":"db.cosmosdb.request_charge","namespace":"db","requirement_level":"recommended","tag":"tech-specific-cosmosdb","type":"double"},{"brief":"Request payload size in bytes","name":"db.cosmosdb.request_content_length","namespace":"db","requirement_level":"recommended","tag":"tech-specific-cosmosdb","type":"int"},{"brief":"Cosmos DB status code.","examples":[200,201],"name":"db.cosmosdb.status_code","namespace":"db","requirement_level":"recommended","tag":"tech-specific-cosmosdb","type":"int"},{"brief":"Cosmos DB sub status code.","examples":[1000,1002],"name":"db.cosmosdb.sub_status_code","namespace":"db","requirement_level":"recommended","tag":"tech-specific-cosmosdb","type":"int"},{"brief":"Represents the identifier of an Elasticsearch cluster.\n","examples":["e9106fc68e3044f0b1475b04bf4ffd5f"],"name":"db.elasticsearch.cluster.name","namespace":"db","requirement_level":"recommended","tag":"tech-specific-elasticsearch","type":"string"},{"brief":"Represents the human-readable identifier of the node/instance to which a request was routed.\n","examples":["instance-0000000001"],"name":"db.elasticsearch.node.name","namespace":"db","requirement_level":"recommended","tag":"tech-specific-elasticsearch","type":"string"},{"brief":"A dynamic value in the url path.\n","examples":["db.elasticsearch.path_parts.index=test-index","db.elasticsearch.path_parts.doc_id=123"],"name":"db.elasticsearch.path_parts","namespace":"db","note":"Many Elasticsearch url paths allow dynamic values. These SHOULD be recorded in span attributes in the format `db.elasticsearch.path_parts.\u003ckey\u003e`, where `\u003ckey\u003e` 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","requirement_level":"recommended","tag":"tech-specific-elasticsearch","type":"template[string]"},{"brief":"An identifier (address, unique name, or any other identifier) of the database instance that is executing queries or mutations on the current connection. This is useful in cases where the database is running in a clustered environment and the instrumentation is able to record the node executing the query. The client may obtain this value in databases like MySQL using queries like `select @@hostname`.\n","examples":"mysql-e26b99z.example.com","name":"db.instance.id","namespace":"db","requirement_level":"recommended","tag":"db-generic","type":"string"},{"brief":"The fully-qualified class name of the [Java Database Connectivity (JDBC)](https://docs.oracle.com/javase/8/docs/technotes/guides/jdbc/) driver used to connect.\n","examples":["org.postgresql.Driver","com.microsoft.sqlserver.jdbc.SQLServerDriver"],"name":"db.jdbc.driver_classname","namespace":"db","requirement_level":"recommended","tag":"tech-specific-jdbc","type":"string"},{"brief":"The MongoDB collection being accessed within the database stated in `db.name`.\n","examples":["customers","products"],"name":"db.mongodb.collection","namespace":"db","requirement_level":"recommended","tag":"tech-specific-mongodb","type":"string"},{"brief":"The Microsoft SQL Server [instance name](https://docs.microsoft.com/sql/connect/jdbc/building-the-connection-url?view=sql-server-ver15) connecting to. This name is used to determine the port of a named instance.\n","examples":"MSSQLSERVER","name":"db.mssql.instance_name","namespace":"db","note":"If setting a `db.mssql.instance_name`, `server.port` is no longer required (but still recommended if non-standard).\n","requirement_level":"recommended","tag":"tech-specific-mssql","type":"string"},{"brief":"This attribute is used to report the name of the database being accessed. For commands that switch the database, this should be set to the target database (even if the command fails).\n","examples":["customers","main"],"name":"db.name","namespace":"db","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","requirement_level":"recommended","tag":"db-generic","type":"string"},{"brief":"The name of the operation being executed, e.g. the [MongoDB command name](https://docs.mongodb.com/manual/reference/command/#database-operations) such as `findAndModify`, or the SQL keyword.\n","examples":["findAndModify","HMSET","SELECT"],"name":"db.operation","namespace":"db","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","requirement_level":"recommended","tag":"db-generic","type":"string"},{"brief":"The index of the database being accessed as used in the [`SELECT` command](https://redis.io/commands/select), provided as an integer. To be used instead of the generic `db.name` attribute.\n","examples":[0,1,15],"name":"db.redis.database_index","namespace":"db","requirement_level":"recommended","tag":"tech-specific-redis","type":"int"},{"brief":"The name of the primary table that the operation is acting upon, including the database name (if applicable).","examples":["public.users","customers"],"name":"db.sql.table","namespace":"db","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","requirement_level":"recommended","tag":"tech-specific-sql","type":"string"},{"brief":"The database statement being executed.\n","examples":["SELECT * FROM wuser_table","SET mykey \"WuValue\""],"name":"db.statement","namespace":"db","requirement_level":"recommended","tag":"db-generic","type":"string"},{"brief":"An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers.","name":"db.system","namespace":"db","requirement_level":"recommended","tag":"db-generic","type":{"allow_custom_values":true,"members":[{"brief":"Some other SQL database. Fallback only. See notes.","deprecated":null,"id":"other_sql","note":null,"stability":null,"value":"other_sql"},{"brief":"Microsoft SQL Server","deprecated":null,"id":"mssql","note":null,"stability":null,"value":"mssql"},{"brief":"Microsoft SQL Server Compact","deprecated":null,"id":"mssqlcompact","note":null,"stability":null,"value":"mssqlcompact"},{"brief":"MySQL","deprecated":null,"id":"mysql","note":null,"stability":null,"value":"mysql"},{"brief":"Oracle Database","deprecated":null,"id":"oracle","note":null,"stability":null,"value":"oracle"},{"brief":"IBM Db2","deprecated":null,"id":"db2","note":null,"stability":null,"value":"db2"},{"brief":"PostgreSQL","deprecated":null,"id":"postgresql","note":null,"stability":null,"value":"postgresql"},{"brief":"Amazon Redshift","deprecated":null,"id":"redshift","note":null,"stability":null,"value":"redshift"},{"brief":"Apache Hive","deprecated":null,"id":"hive","note":null,"stability":null,"value":"hive"},{"brief":"Cloudscape","deprecated":null,"id":"cloudscape","note":null,"stability":null,"value":"cloudscape"},{"brief":"HyperSQL DataBase","deprecated":null,"id":"hsqldb","note":null,"stability":null,"value":"hsqldb"},{"brief":"Progress Database","deprecated":null,"id":"progress","note":null,"stability":null,"value":"progress"},{"brief":"SAP MaxDB","deprecated":null,"id":"maxdb","note":null,"stability":null,"value":"maxdb"},{"brief":"SAP HANA","deprecated":null,"id":"hanadb","note":null,"stability":null,"value":"hanadb"},{"brief":"Ingres","deprecated":null,"id":"ingres","note":null,"stability":null,"value":"ingres"},{"brief":"FirstSQL","deprecated":null,"id":"firstsql","note":null,"stability":null,"value":"firstsql"},{"brief":"EnterpriseDB","deprecated":null,"id":"edb","note":null,"stability":null,"value":"edb"},{"brief":"InterSystems Caché","deprecated":null,"id":"cache","note":null,"stability":null,"value":"cache"},{"brief":"Adabas (Adaptable Database System)","deprecated":null,"id":"adabas","note":null,"stability":null,"value":"adabas"},{"brief":"Firebird","deprecated":null,"id":"firebird","note":null,"stability":null,"value":"firebird"},{"brief":"Apache Derby","deprecated":null,"id":"derby","note":null,"stability":null,"value":"derby"},{"brief":"FileMaker","deprecated":null,"id":"filemaker","note":null,"stability":null,"value":"filemaker"},{"brief":"Informix","deprecated":null,"id":"informix","note":null,"stability":null,"value":"informix"},{"brief":"InstantDB","deprecated":null,"id":"instantdb","note":null,"stability":null,"value":"instantdb"},{"brief":"InterBase","deprecated":null,"id":"interbase","note":null,"stability":null,"value":"interbase"},{"brief":"MariaDB","deprecated":null,"id":"mariadb","note":null,"stability":null,"value":"mariadb"},{"brief":"Netezza","deprecated":null,"id":"netezza","note":null,"stability":null,"value":"netezza"},{"brief":"Pervasive PSQL","deprecated":null,"id":"pervasive","note":null,"stability":null,"value":"pervasive"},{"brief":"PointBase","deprecated":null,"id":"pointbase","note":null,"stability":null,"value":"pointbase"},{"brief":"SQLite","deprecated":null,"id":"sqlite","note":null,"stability":null,"value":"sqlite"},{"brief":"Sybase","deprecated":null,"id":"sybase","note":null,"stability":null,"value":"sybase"},{"brief":"Teradata","deprecated":null,"id":"teradata","note":null,"stability":null,"value":"teradata"},{"brief":"Vertica","deprecated":null,"id":"vertica","note":null,"stability":null,"value":"vertica"},{"brief":"H2","deprecated":null,"id":"h2","note":null,"stability":null,"value":"h2"},{"brief":"ColdFusion IMQ","deprecated":null,"id":"coldfusion","note":null,"stability":null,"value":"coldfusion"},{"brief":"Apache Cassandra","deprecated":null,"id":"cassandra","note":null,"stability":null,"value":"cassandra"},{"brief":"Apache HBase","deprecated":null,"id":"hbase","note":null,"stability":null,"value":"hbase"},{"brief":"MongoDB","deprecated":null,"id":"mongodb","note":null,"stability":null,"value":"mongodb"},{"brief":"Redis","deprecated":null,"id":"redis","note":null,"stability":null,"value":"redis"},{"brief":"Couchbase","deprecated":null,"id":"couchbase","note":null,"stability":null,"value":"couchbase"},{"brief":"CouchDB","deprecated":null,"id":"couchdb","note":null,"stability":null,"value":"couchdb"},{"brief":"Microsoft Azure Cosmos DB","deprecated":null,"id":"cosmosdb","note":null,"stability":null,"value":"cosmosdb"},{"brief":"Amazon DynamoDB","deprecated":null,"id":"dynamodb","note":null,"stability":null,"value":"dynamodb"},{"brief":"Neo4j","deprecated":null,"id":"neo4j","note":null,"stability":null,"value":"neo4j"},{"brief":"Apache Geode","deprecated":null,"id":"geode","note":null,"stability":null,"value":"geode"},{"brief":"Elasticsearch","deprecated":null,"id":"elasticsearch","note":null,"stability":null,"value":"elasticsearch"},{"brief":"Memcached","deprecated":null,"id":"memcached","note":null,"stability":null,"value":"memcached"},{"brief":"CockroachDB","deprecated":null,"id":"cockroachdb","note":null,"stability":null,"value":"cockroachdb"},{"brief":"OpenSearch","deprecated":null,"id":"opensearch","note":null,"stability":null,"value":"opensearch"},{"brief":"ClickHouse","deprecated":null,"id":"clickhouse","note":null,"stability":null,"value":"clickhouse"},{"brief":"Cloud Spanner","deprecated":null,"id":"spanner","note":null,"stability":null,"value":"spanner"},{"brief":"Trino","deprecated":null,"id":"trino","note":null,"stability":null,"value":"trino"}]}},{"brief":"Username for accessing the database.\n","examples":["readonly_user","reporting_user"],"name":"db.user","namespace":"db","requirement_level":"recommended","tag":"db-generic","type":"string"},{"brief":"The size of the request payload body in bytes. This is the number of bytes transferred excluding headers and is often, but not always, present as the [Content-Length](https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length) header. For requests using transport encoding, this should be the compressed size.\n","examples":3495,"name":"http.request.body.size","namespace":"http","requirement_level":"recommended","stability":"experimental","type":"int"},{"brief":"HTTP request headers, `\u003ckey\u003e` being the normalized HTTP Header name (lowercase), the value being the header values.\n","examples":["http.request.header.content-type=[\"application/json\"]","http.request.header.x-forwarded-for=[\"1.2.3.4\", \"1.2.3.5\"]"],"name":"http.request.header","namespace":"http","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","requirement_level":"recommended","stability":"stable","type":"template[string[]]"},{"brief":"HTTP request method.","examples":["GET","POST","HEAD"],"name":"http.request.method","namespace":"http","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","requirement_level":"recommended","stability":"stable","type":{"allow_custom_values":true,"members":[{"brief":"CONNECT method.","deprecated":null,"id":"connect","note":null,"stability":null,"value":"CONNECT"},{"brief":"DELETE method.","deprecated":null,"id":"delete","note":null,"stability":null,"value":"DELETE"},{"brief":"GET method.","deprecated":null,"id":"get","note":null,"stability":null,"value":"GET"},{"brief":"HEAD method.","deprecated":null,"id":"head","note":null,"stability":null,"value":"HEAD"},{"brief":"OPTIONS method.","deprecated":null,"id":"options","note":null,"stability":null,"value":"OPTIONS"},{"brief":"PATCH method.","deprecated":null,"id":"patch","note":null,"stability":null,"value":"PATCH"},{"brief":"POST method.","deprecated":null,"id":"post","note":null,"stability":null,"value":"POST"},{"brief":"PUT method.","deprecated":null,"id":"put","note":null,"stability":null,"value":"PUT"},{"brief":"TRACE method.","deprecated":null,"id":"trace","note":null,"stability":null,"value":"TRACE"},{"brief":"Any HTTP method that the instrumentation has no prior knowledge of.","deprecated":null,"id":"other","note":null,"stability":null,"value":"_OTHER"}]}},{"brief":"Original HTTP method sent by the client in the request line.","examples":["GeT","ACL","foo"],"name":"http.request.method_original","namespace":"http","requirement_level":"recommended","stability":"stable","type":"string"},{"brief":"The ordinal number of request resending attempt (for any reason, including redirects).\n","examples":3,"name":"http.request.resend_count","namespace":"http","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","requirement_level":"recommended","stability":"stable","type":"int"},{"brief":"The size of the response payload body in bytes. This is the number of bytes transferred excluding headers and is often, but not always, present as the [Content-Length](https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length) header. For requests using transport encoding, this should be the compressed size.\n","examples":3495,"name":"http.response.body.size","namespace":"http","requirement_level":"recommended","stability":"experimental","type":"int"},{"brief":"HTTP response headers, `\u003ckey\u003e` being the normalized HTTP Header name (lowercase), the value being the header values.\n","examples":["http.response.header.content-type=[\"application/json\"]","http.response.header.my-custom-header=[\"abc\", \"def\"]"],"name":"http.response.header","namespace":"http","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","requirement_level":"recommended","stability":"stable","type":"template[string[]]"},{"brief":"[HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6).","examples":[200],"name":"http.response.status_code","namespace":"http","requirement_level":"recommended","stability":"stable","type":"int"},{"brief":"The matched route, that is, the path template in the format used by the respective server framework.\n","examples":["/users/:userID?","{controller}/{action}/{id?}"],"name":"http.route","namespace":"http","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.","requirement_level":"recommended","stability":"stable","type":"string"},{"brief":"The ISO 3166-1 alpha-2 2-character country code associated with the mobile carrier network.","examples":"DE","name":"network.carrier.icc","namespace":"network","requirement_level":"recommended","type":"string"},{"brief":"The mobile carrier country code.","examples":"310","name":"network.carrier.mcc","namespace":"network","requirement_level":"recommended","type":"string"},{"brief":"The mobile carrier network code.","examples":"001","name":"network.carrier.mnc","namespace":"network","requirement_level":"recommended","type":"string"},{"brief":"The name of the mobile carrier.","examples":"sprint","name":"network.carrier.name","namespace":"network","requirement_level":"recommended","type":"string"},{"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","name":"network.connection.subtype","namespace":"network","requirement_level":"recommended","type":{"allow_custom_values":true,"members":[{"brief":"GPRS","deprecated":null,"id":"gprs","note":null,"stability":null,"value":"gprs"},{"brief":"EDGE","deprecated":null,"id":"edge","note":null,"stability":null,"value":"edge"},{"brief":"UMTS","deprecated":null,"id":"umts","note":null,"stability":null,"value":"umts"},{"brief":"CDMA","deprecated":null,"id":"cdma","note":null,"stability":null,"value":"cdma"},{"brief":"EVDO Rel. 0","deprecated":null,"id":"evdo_0","note":null,"stability":null,"value":"evdo_0"},{"brief":"EVDO Rev. A","deprecated":null,"id":"evdo_a","note":null,"stability":null,"value":"evdo_a"},{"brief":"CDMA2000 1XRTT","deprecated":null,"id":"cdma2000_1xrtt","note":null,"stability":null,"value":"cdma2000_1xrtt"},{"brief":"HSDPA","deprecated":null,"id":"hsdpa","note":null,"stability":null,"value":"hsdpa"},{"brief":"HSUPA","deprecated":null,"id":"hsupa","note":null,"stability":null,"value":"hsupa"},{"brief":"HSPA","deprecated":null,"id":"hspa","note":null,"stability":null,"value":"hspa"},{"brief":"IDEN","deprecated":null,"id":"iden","note":null,"stability":null,"value":"iden"},{"brief":"EVDO Rev. B","deprecated":null,"id":"evdo_b","note":null,"stability":null,"value":"evdo_b"},{"brief":"LTE","deprecated":null,"id":"lte","note":null,"stability":null,"value":"lte"},{"brief":"EHRPD","deprecated":null,"id":"ehrpd","note":null,"stability":null,"value":"ehrpd"},{"brief":"HSPAP","deprecated":null,"id":"hspap","note":null,"stability":null,"value":"hspap"},{"brief":"GSM","deprecated":null,"id":"gsm","note":null,"stability":null,"value":"gsm"},{"brief":"TD-SCDMA","deprecated":null,"id":"td_scdma","note":null,"stability":null,"value":"td_scdma"},{"brief":"IWLAN","deprecated":null,"id":"iwlan","note":null,"stability":null,"value":"iwlan"},{"brief":"5G NR (New Radio)","deprecated":null,"id":"nr","note":null,"stability":null,"value":"nr"},{"brief":"5G NRNSA (New Radio Non-Standalone)","deprecated":null,"id":"nrnsa","note":null,"stability":null,"value":"nrnsa"},{"brief":"LTE CA","deprecated":null,"id":"lte_ca","note":null,"stability":null,"value":"lte_ca"}]}},{"brief":"The internet connection type.","examples":"wifi","name":"network.connection.type","namespace":"network","requirement_level":"recommended","type":{"allow_custom_values":true,"members":[{"brief":null,"deprecated":null,"id":"wifi","note":null,"stability":null,"value":"wifi"},{"brief":null,"deprecated":null,"id":"wired","note":null,"stability":null,"value":"wired"},{"brief":null,"deprecated":null,"id":"cell","note":null,"stability":null,"value":"cell"},{"brief":null,"deprecated":null,"id":"unavailable","note":null,"stability":null,"value":"unavailable"},{"brief":null,"deprecated":null,"id":"unknown","note":null,"stability":null,"value":"unknown"}]}},{"brief":"The network IO operation direction.","examples":["transmit"],"name":"network.io.direction","namespace":"network","requirement_level":"recommended","type":{"allow_custom_values":false,"members":[{"brief":null,"deprecated":null,"id":"transmit","note":null,"stability":null,"value":"transmit"},{"brief":null,"deprecated":null,"id":"receive","note":null,"stability":null,"value":"receive"}]}},{"brief":"Local address of the network connection - IP address or Unix domain socket name.","examples":["10.1.2.80","/tmp/my.sock"],"name":"network.local.address","namespace":"network","requirement_level":"recommended","stability":"stable","type":"string"},{"brief":"Local port number of the network connection.","examples":[65123],"name":"network.local.port","namespace":"network","requirement_level":"recommended","stability":"stable","type":"int"},{"brief":"Peer address of the network connection - IP address or Unix domain socket name.","examples":["10.1.2.80","/tmp/my.sock"],"name":"network.peer.address","namespace":"network","requirement_level":"recommended","stability":"stable","type":"string"},{"brief":"Peer port number of the network connection.","examples":[65123],"name":"network.peer.port","namespace":"network","requirement_level":"recommended","stability":"stable","type":"int"},{"brief":"[OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent.","examples":["amqp","http","mqtt"],"name":"network.protocol.name","namespace":"network","note":"The value SHOULD be normalized to lowercase.","requirement_level":"recommended","stability":"stable","type":"string"},{"brief":"Version of the protocol specified in `network.protocol.name`.","examples":"3.1.1","name":"network.protocol.version","namespace":"network","note":"`network.protocol.version` refers to the version of the protocol used and might be different from the protocol client\u0027s 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","requirement_level":"recommended","stability":"stable","type":"string"},{"brief":"[OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication).\n","examples":["tcp","udp"],"name":"network.transport","namespace":"network","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","requirement_level":"recommended","stability":"stable","type":{"allow_custom_values":true,"members":[{"brief":"TCP","deprecated":null,"id":"tcp","note":null,"stability":null,"value":"tcp"},{"brief":"UDP","deprecated":null,"id":"udp","note":null,"stability":null,"value":"udp"},{"brief":"Named or anonymous pipe.","deprecated":null,"id":"pipe","note":null,"stability":null,"value":"pipe"},{"brief":"Unix domain socket","deprecated":null,"id":"unix","note":null,"stability":null,"value":"unix"}]}},{"brief":"[OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent.","examples":["ipv4","ipv6"],"name":"network.type","namespace":"network","note":"The value SHOULD be normalized to lowercase.","requirement_level":"recommended","stability":"stable","type":{"allow_custom_values":true,"members":[{"brief":"IPv4","deprecated":null,"id":"ipv4","note":null,"stability":null,"value":"ipv4"},{"brief":"IPv6","deprecated":null,"id":"ipv6","note":null,"stability":null,"value":"ipv6"}]}},{"brief":"The [URI fragment](https://www.rfc-editor.org/rfc/rfc3986#section-3.5) component","examples":["SemConv"],"name":"url.fragment","namespace":"url","requirement_level":"recommended","stability":"stable","type":"string"},{"brief":"Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986)","examples":["https://www.foo.bar/search?q=OpenTelemetry#SemConv","//localhost"],"name":"url.full","namespace":"url","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\u0027s 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","requirement_level":"recommended","stability":"stable","type":"string"},{"brief":"The [URI path](https://www.rfc-editor.org/rfc/rfc3986#section-3.3) component","examples":["/search"],"name":"url.path","namespace":"url","requirement_level":"recommended","stability":"stable","type":"string"},{"brief":"The [URI query](https://www.rfc-editor.org/rfc/rfc3986#section-3.4) component","examples":["q=OpenTelemetry"],"name":"url.query","namespace":"url","note":"Sensitive content provided in query string SHOULD be scrubbed when instrumentations can identify it.","requirement_level":"recommended","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"],"name":"url.scheme","namespace":"url","requirement_level":"recommended","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.\n","examples":["CERN-LineMode/2.15 libwww/2.17b3","Mozilla/5.0 (iPhone; CPU iPhone OS 14_7_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.2 Mobile/15E148 Safari/604.1"],"name":"user_agent.original","namespace":"user_agent","requirement_level":"recommended","stability":"stable","type":"string"}] \ No newline at end of file diff --git a/crates/weaver_forge/expected_output/semconv_jq_fn/semconv_grouped_attributes.json b/crates/weaver_forge/expected_output/semconv_jq_fn/semconv_grouped_attributes.json new file mode 100644 index 00000000..b9065fa7 --- /dev/null +++ b/crates/weaver_forge/expected_output/semconv_jq_fn/semconv_grouped_attributes.json @@ -0,0 +1 @@ +[{"attributes":[{"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","name":"db.cassandra.consistency_level","namespace":"db","requirement_level":"recommended","tag":"tech-specific-cassandra","type":{"allow_custom_values":true,"members":[{"brief":null,"deprecated":null,"id":"all","note":null,"stability":null,"value":"all"},{"brief":null,"deprecated":null,"id":"each_quorum","note":null,"stability":null,"value":"each_quorum"},{"brief":null,"deprecated":null,"id":"quorum","note":null,"stability":null,"value":"quorum"},{"brief":null,"deprecated":null,"id":"local_quorum","note":null,"stability":null,"value":"local_quorum"},{"brief":null,"deprecated":null,"id":"one","note":null,"stability":null,"value":"one"},{"brief":null,"deprecated":null,"id":"two","note":null,"stability":null,"value":"two"},{"brief":null,"deprecated":null,"id":"three","note":null,"stability":null,"value":"three"},{"brief":null,"deprecated":null,"id":"local_one","note":null,"stability":null,"value":"local_one"},{"brief":null,"deprecated":null,"id":"any","note":null,"stability":null,"value":"any"},{"brief":null,"deprecated":null,"id":"serial","note":null,"stability":null,"value":"serial"},{"brief":null,"deprecated":null,"id":"local_serial","note":null,"stability":null,"value":"local_serial"}]}},{"brief":"The data center of the coordinating node for a query.\n","examples":"us-west-2","name":"db.cassandra.coordinator.dc","namespace":"db","requirement_level":"recommended","tag":"tech-specific-cassandra","type":"string"},{"brief":"The ID of the coordinating node for a query.\n","examples":"be13faa2-8574-4d71-926d-27f16cf8a7af","name":"db.cassandra.coordinator.id","namespace":"db","requirement_level":"recommended","tag":"tech-specific-cassandra","type":"string"},{"brief":"Whether or not the query is idempotent.\n","name":"db.cassandra.idempotence","namespace":"db","requirement_level":"recommended","tag":"tech-specific-cassandra","type":"boolean"},{"brief":"The fetch size used for paging, i.e. how many rows will be returned at once.\n","examples":[5000],"name":"db.cassandra.page_size","namespace":"db","requirement_level":"recommended","tag":"tech-specific-cassandra","type":"int"},{"brief":"The number of times a query was speculatively executed. Not set or `0` if the query was not executed speculatively.\n","examples":[0,2],"name":"db.cassandra.speculative_execution_count","namespace":"db","requirement_level":"recommended","tag":"tech-specific-cassandra","type":"int"},{"brief":"The name of the primary Cassandra table that the operation is acting upon, including the keyspace name (if applicable).","examples":"mytable","name":"db.cassandra.table","namespace":"db","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","requirement_level":"recommended","tag":"tech-specific-cassandra","type":"string"},{"brief":"The connection string used to connect to the database. It is recommended to remove embedded credentials.\n","examples":"Server=(localdb)\\v11.0;Integrated Security=true;","name":"db.connection_string","namespace":"db","requirement_level":"recommended","tag":"db-generic","type":"string"},{"brief":"Unique Cosmos client instance id.","examples":"3ba4827d-4422-483f-b59f-85b74211c11d","name":"db.cosmosdb.client_id","namespace":"db","requirement_level":"recommended","tag":"tech-specific-cosmosdb","type":"string"},{"brief":"Cosmos client connection mode.","name":"db.cosmosdb.connection_mode","namespace":"db","requirement_level":"recommended","tag":"tech-specific-cosmosdb","type":{"allow_custom_values":false,"members":[{"brief":"Gateway (HTTP) connections mode","deprecated":null,"id":"gateway","note":null,"stability":null,"value":"gateway"},{"brief":"Direct connection.","deprecated":null,"id":"direct","note":null,"stability":null,"value":"direct"}]}},{"brief":"Cosmos DB container name.","examples":"anystring","name":"db.cosmosdb.container","namespace":"db","requirement_level":"recommended","tag":"tech-specific-cosmosdb","type":"string"},{"brief":"CosmosDB Operation Type.","name":"db.cosmosdb.operation_type","namespace":"db","requirement_level":"recommended","tag":"tech-specific-cosmosdb","type":{"allow_custom_values":true,"members":[{"brief":null,"deprecated":null,"id":"invalid","note":null,"stability":null,"value":"Invalid"},{"brief":null,"deprecated":null,"id":"create","note":null,"stability":null,"value":"Create"},{"brief":null,"deprecated":null,"id":"patch","note":null,"stability":null,"value":"Patch"},{"brief":null,"deprecated":null,"id":"read","note":null,"stability":null,"value":"Read"},{"brief":null,"deprecated":null,"id":"read_feed","note":null,"stability":null,"value":"ReadFeed"},{"brief":null,"deprecated":null,"id":"delete","note":null,"stability":null,"value":"Delete"},{"brief":null,"deprecated":null,"id":"replace","note":null,"stability":null,"value":"Replace"},{"brief":null,"deprecated":null,"id":"execute","note":null,"stability":null,"value":"Execute"},{"brief":null,"deprecated":null,"id":"query","note":null,"stability":null,"value":"Query"},{"brief":null,"deprecated":null,"id":"head","note":null,"stability":null,"value":"Head"},{"brief":null,"deprecated":null,"id":"head_feed","note":null,"stability":null,"value":"HeadFeed"},{"brief":null,"deprecated":null,"id":"upsert","note":null,"stability":null,"value":"Upsert"},{"brief":null,"deprecated":null,"id":"batch","note":null,"stability":null,"value":"Batch"},{"brief":null,"deprecated":null,"id":"query_plan","note":null,"stability":null,"value":"QueryPlan"},{"brief":null,"deprecated":null,"id":"execute_javascript","note":null,"stability":null,"value":"ExecuteJavaScript"}]}},{"brief":"RU consumed for that operation","examples":[46.18,1.0],"name":"db.cosmosdb.request_charge","namespace":"db","requirement_level":"recommended","tag":"tech-specific-cosmosdb","type":"double"},{"brief":"Request payload size in bytes","name":"db.cosmosdb.request_content_length","namespace":"db","requirement_level":"recommended","tag":"tech-specific-cosmosdb","type":"int"},{"brief":"Cosmos DB status code.","examples":[200,201],"name":"db.cosmosdb.status_code","namespace":"db","requirement_level":"recommended","tag":"tech-specific-cosmosdb","type":"int"},{"brief":"Cosmos DB sub status code.","examples":[1000,1002],"name":"db.cosmosdb.sub_status_code","namespace":"db","requirement_level":"recommended","tag":"tech-specific-cosmosdb","type":"int"},{"brief":"Represents the identifier of an Elasticsearch cluster.\n","examples":["e9106fc68e3044f0b1475b04bf4ffd5f"],"name":"db.elasticsearch.cluster.name","namespace":"db","requirement_level":"recommended","tag":"tech-specific-elasticsearch","type":"string"},{"brief":"Represents the human-readable identifier of the node/instance to which a request was routed.\n","examples":["instance-0000000001"],"name":"db.elasticsearch.node.name","namespace":"db","requirement_level":"recommended","tag":"tech-specific-elasticsearch","type":"string"},{"brief":"A dynamic value in the url path.\n","examples":["db.elasticsearch.path_parts.index=test-index","db.elasticsearch.path_parts.doc_id=123"],"name":"db.elasticsearch.path_parts","namespace":"db","note":"Many Elasticsearch url paths allow dynamic values. These SHOULD be recorded in span attributes in the format `db.elasticsearch.path_parts.\u003ckey\u003e`, where `\u003ckey\u003e` 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","requirement_level":"recommended","tag":"tech-specific-elasticsearch","type":"template[string]"},{"brief":"An identifier (address, unique name, or any other identifier) of the database instance that is executing queries or mutations on the current connection. This is useful in cases where the database is running in a clustered environment and the instrumentation is able to record the node executing the query. The client may obtain this value in databases like MySQL using queries like `select @@hostname`.\n","examples":"mysql-e26b99z.example.com","name":"db.instance.id","namespace":"db","requirement_level":"recommended","tag":"db-generic","type":"string"},{"brief":"The fully-qualified class name of the [Java Database Connectivity (JDBC)](https://docs.oracle.com/javase/8/docs/technotes/guides/jdbc/) driver used to connect.\n","examples":["org.postgresql.Driver","com.microsoft.sqlserver.jdbc.SQLServerDriver"],"name":"db.jdbc.driver_classname","namespace":"db","requirement_level":"recommended","tag":"tech-specific-jdbc","type":"string"},{"brief":"The MongoDB collection being accessed within the database stated in `db.name`.\n","examples":["customers","products"],"name":"db.mongodb.collection","namespace":"db","requirement_level":"recommended","tag":"tech-specific-mongodb","type":"string"},{"brief":"The Microsoft SQL Server [instance name](https://docs.microsoft.com/sql/connect/jdbc/building-the-connection-url?view=sql-server-ver15) connecting to. This name is used to determine the port of a named instance.\n","examples":"MSSQLSERVER","name":"db.mssql.instance_name","namespace":"db","note":"If setting a `db.mssql.instance_name`, `server.port` is no longer required (but still recommended if non-standard).\n","requirement_level":"recommended","tag":"tech-specific-mssql","type":"string"},{"brief":"This attribute is used to report the name of the database being accessed. For commands that switch the database, this should be set to the target database (even if the command fails).\n","examples":["customers","main"],"name":"db.name","namespace":"db","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","requirement_level":"recommended","tag":"db-generic","type":"string"},{"brief":"The name of the operation being executed, e.g. the [MongoDB command name](https://docs.mongodb.com/manual/reference/command/#database-operations) such as `findAndModify`, or the SQL keyword.\n","examples":["findAndModify","HMSET","SELECT"],"name":"db.operation","namespace":"db","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","requirement_level":"recommended","tag":"db-generic","type":"string"},{"brief":"The index of the database being accessed as used in the [`SELECT` command](https://redis.io/commands/select), provided as an integer. To be used instead of the generic `db.name` attribute.\n","examples":[0,1,15],"name":"db.redis.database_index","namespace":"db","requirement_level":"recommended","tag":"tech-specific-redis","type":"int"},{"brief":"The name of the primary table that the operation is acting upon, including the database name (if applicable).","examples":["public.users","customers"],"name":"db.sql.table","namespace":"db","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","requirement_level":"recommended","tag":"tech-specific-sql","type":"string"},{"brief":"The database statement being executed.\n","examples":["SELECT * FROM wuser_table","SET mykey \"WuValue\""],"name":"db.statement","namespace":"db","requirement_level":"recommended","tag":"db-generic","type":"string"},{"brief":"An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers.","name":"db.system","namespace":"db","requirement_level":"recommended","tag":"db-generic","type":{"allow_custom_values":true,"members":[{"brief":"Some other SQL database. Fallback only. See notes.","deprecated":null,"id":"other_sql","note":null,"stability":null,"value":"other_sql"},{"brief":"Microsoft SQL Server","deprecated":null,"id":"mssql","note":null,"stability":null,"value":"mssql"},{"brief":"Microsoft SQL Server Compact","deprecated":null,"id":"mssqlcompact","note":null,"stability":null,"value":"mssqlcompact"},{"brief":"MySQL","deprecated":null,"id":"mysql","note":null,"stability":null,"value":"mysql"},{"brief":"Oracle Database","deprecated":null,"id":"oracle","note":null,"stability":null,"value":"oracle"},{"brief":"IBM Db2","deprecated":null,"id":"db2","note":null,"stability":null,"value":"db2"},{"brief":"PostgreSQL","deprecated":null,"id":"postgresql","note":null,"stability":null,"value":"postgresql"},{"brief":"Amazon Redshift","deprecated":null,"id":"redshift","note":null,"stability":null,"value":"redshift"},{"brief":"Apache Hive","deprecated":null,"id":"hive","note":null,"stability":null,"value":"hive"},{"brief":"Cloudscape","deprecated":null,"id":"cloudscape","note":null,"stability":null,"value":"cloudscape"},{"brief":"HyperSQL DataBase","deprecated":null,"id":"hsqldb","note":null,"stability":null,"value":"hsqldb"},{"brief":"Progress Database","deprecated":null,"id":"progress","note":null,"stability":null,"value":"progress"},{"brief":"SAP MaxDB","deprecated":null,"id":"maxdb","note":null,"stability":null,"value":"maxdb"},{"brief":"SAP HANA","deprecated":null,"id":"hanadb","note":null,"stability":null,"value":"hanadb"},{"brief":"Ingres","deprecated":null,"id":"ingres","note":null,"stability":null,"value":"ingres"},{"brief":"FirstSQL","deprecated":null,"id":"firstsql","note":null,"stability":null,"value":"firstsql"},{"brief":"EnterpriseDB","deprecated":null,"id":"edb","note":null,"stability":null,"value":"edb"},{"brief":"InterSystems Caché","deprecated":null,"id":"cache","note":null,"stability":null,"value":"cache"},{"brief":"Adabas (Adaptable Database System)","deprecated":null,"id":"adabas","note":null,"stability":null,"value":"adabas"},{"brief":"Firebird","deprecated":null,"id":"firebird","note":null,"stability":null,"value":"firebird"},{"brief":"Apache Derby","deprecated":null,"id":"derby","note":null,"stability":null,"value":"derby"},{"brief":"FileMaker","deprecated":null,"id":"filemaker","note":null,"stability":null,"value":"filemaker"},{"brief":"Informix","deprecated":null,"id":"informix","note":null,"stability":null,"value":"informix"},{"brief":"InstantDB","deprecated":null,"id":"instantdb","note":null,"stability":null,"value":"instantdb"},{"brief":"InterBase","deprecated":null,"id":"interbase","note":null,"stability":null,"value":"interbase"},{"brief":"MariaDB","deprecated":null,"id":"mariadb","note":null,"stability":null,"value":"mariadb"},{"brief":"Netezza","deprecated":null,"id":"netezza","note":null,"stability":null,"value":"netezza"},{"brief":"Pervasive PSQL","deprecated":null,"id":"pervasive","note":null,"stability":null,"value":"pervasive"},{"brief":"PointBase","deprecated":null,"id":"pointbase","note":null,"stability":null,"value":"pointbase"},{"brief":"SQLite","deprecated":null,"id":"sqlite","note":null,"stability":null,"value":"sqlite"},{"brief":"Sybase","deprecated":null,"id":"sybase","note":null,"stability":null,"value":"sybase"},{"brief":"Teradata","deprecated":null,"id":"teradata","note":null,"stability":null,"value":"teradata"},{"brief":"Vertica","deprecated":null,"id":"vertica","note":null,"stability":null,"value":"vertica"},{"brief":"H2","deprecated":null,"id":"h2","note":null,"stability":null,"value":"h2"},{"brief":"ColdFusion IMQ","deprecated":null,"id":"coldfusion","note":null,"stability":null,"value":"coldfusion"},{"brief":"Apache Cassandra","deprecated":null,"id":"cassandra","note":null,"stability":null,"value":"cassandra"},{"brief":"Apache HBase","deprecated":null,"id":"hbase","note":null,"stability":null,"value":"hbase"},{"brief":"MongoDB","deprecated":null,"id":"mongodb","note":null,"stability":null,"value":"mongodb"},{"brief":"Redis","deprecated":null,"id":"redis","note":null,"stability":null,"value":"redis"},{"brief":"Couchbase","deprecated":null,"id":"couchbase","note":null,"stability":null,"value":"couchbase"},{"brief":"CouchDB","deprecated":null,"id":"couchdb","note":null,"stability":null,"value":"couchdb"},{"brief":"Microsoft Azure Cosmos DB","deprecated":null,"id":"cosmosdb","note":null,"stability":null,"value":"cosmosdb"},{"brief":"Amazon DynamoDB","deprecated":null,"id":"dynamodb","note":null,"stability":null,"value":"dynamodb"},{"brief":"Neo4j","deprecated":null,"id":"neo4j","note":null,"stability":null,"value":"neo4j"},{"brief":"Apache Geode","deprecated":null,"id":"geode","note":null,"stability":null,"value":"geode"},{"brief":"Elasticsearch","deprecated":null,"id":"elasticsearch","note":null,"stability":null,"value":"elasticsearch"},{"brief":"Memcached","deprecated":null,"id":"memcached","note":null,"stability":null,"value":"memcached"},{"brief":"CockroachDB","deprecated":null,"id":"cockroachdb","note":null,"stability":null,"value":"cockroachdb"},{"brief":"OpenSearch","deprecated":null,"id":"opensearch","note":null,"stability":null,"value":"opensearch"},{"brief":"ClickHouse","deprecated":null,"id":"clickhouse","note":null,"stability":null,"value":"clickhouse"},{"brief":"Cloud Spanner","deprecated":null,"id":"spanner","note":null,"stability":null,"value":"spanner"},{"brief":"Trino","deprecated":null,"id":"trino","note":null,"stability":null,"value":"trino"}]}},{"brief":"Username for accessing the database.\n","examples":["readonly_user","reporting_user"],"name":"db.user","namespace":"db","requirement_level":"recommended","tag":"db-generic","type":"string"}],"namespace":"db"},{"attributes":[{"brief":"The size of the request payload body in bytes. This is the number of bytes transferred excluding headers and is often, but not always, present as the [Content-Length](https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length) header. For requests using transport encoding, this should be the compressed size.\n","examples":3495,"name":"http.request.body.size","namespace":"http","requirement_level":"recommended","stability":"experimental","type":"int"},{"brief":"HTTP request headers, `\u003ckey\u003e` being the normalized HTTP Header name (lowercase), the value being the header values.\n","examples":["http.request.header.content-type=[\"application/json\"]","http.request.header.x-forwarded-for=[\"1.2.3.4\", \"1.2.3.5\"]"],"name":"http.request.header","namespace":"http","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","requirement_level":"recommended","stability":"stable","type":"template[string[]]"},{"brief":"HTTP request method.","examples":["GET","POST","HEAD"],"name":"http.request.method","namespace":"http","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","requirement_level":"recommended","stability":"stable","type":{"allow_custom_values":true,"members":[{"brief":"CONNECT method.","deprecated":null,"id":"connect","note":null,"stability":null,"value":"CONNECT"},{"brief":"DELETE method.","deprecated":null,"id":"delete","note":null,"stability":null,"value":"DELETE"},{"brief":"GET method.","deprecated":null,"id":"get","note":null,"stability":null,"value":"GET"},{"brief":"HEAD method.","deprecated":null,"id":"head","note":null,"stability":null,"value":"HEAD"},{"brief":"OPTIONS method.","deprecated":null,"id":"options","note":null,"stability":null,"value":"OPTIONS"},{"brief":"PATCH method.","deprecated":null,"id":"patch","note":null,"stability":null,"value":"PATCH"},{"brief":"POST method.","deprecated":null,"id":"post","note":null,"stability":null,"value":"POST"},{"brief":"PUT method.","deprecated":null,"id":"put","note":null,"stability":null,"value":"PUT"},{"brief":"TRACE method.","deprecated":null,"id":"trace","note":null,"stability":null,"value":"TRACE"},{"brief":"Any HTTP method that the instrumentation has no prior knowledge of.","deprecated":null,"id":"other","note":null,"stability":null,"value":"_OTHER"}]}},{"brief":"Original HTTP method sent by the client in the request line.","examples":["GeT","ACL","foo"],"name":"http.request.method_original","namespace":"http","requirement_level":"recommended","stability":"stable","type":"string"},{"brief":"The ordinal number of request resending attempt (for any reason, including redirects).\n","examples":3,"name":"http.request.resend_count","namespace":"http","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","requirement_level":"recommended","stability":"stable","type":"int"},{"brief":"The size of the response payload body in bytes. This is the number of bytes transferred excluding headers and is often, but not always, present as the [Content-Length](https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length) header. For requests using transport encoding, this should be the compressed size.\n","examples":3495,"name":"http.response.body.size","namespace":"http","requirement_level":"recommended","stability":"experimental","type":"int"},{"brief":"HTTP response headers, `\u003ckey\u003e` being the normalized HTTP Header name (lowercase), the value being the header values.\n","examples":["http.response.header.content-type=[\"application/json\"]","http.response.header.my-custom-header=[\"abc\", \"def\"]"],"name":"http.response.header","namespace":"http","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","requirement_level":"recommended","stability":"stable","type":"template[string[]]"},{"brief":"[HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6).","examples":[200],"name":"http.response.status_code","namespace":"http","requirement_level":"recommended","stability":"stable","type":"int"},{"brief":"The matched route, that is, the path template in the format used by the respective server framework.\n","examples":["/users/:userID?","{controller}/{action}/{id?}"],"name":"http.route","namespace":"http","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.","requirement_level":"recommended","stability":"stable","type":"string"}],"namespace":"http"},{"attributes":[{"brief":"The ISO 3166-1 alpha-2 2-character country code associated with the mobile carrier network.","examples":"DE","name":"network.carrier.icc","namespace":"network","requirement_level":"recommended","type":"string"},{"brief":"The mobile carrier country code.","examples":"310","name":"network.carrier.mcc","namespace":"network","requirement_level":"recommended","type":"string"},{"brief":"The mobile carrier network code.","examples":"001","name":"network.carrier.mnc","namespace":"network","requirement_level":"recommended","type":"string"},{"brief":"The name of the mobile carrier.","examples":"sprint","name":"network.carrier.name","namespace":"network","requirement_level":"recommended","type":"string"},{"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","name":"network.connection.subtype","namespace":"network","requirement_level":"recommended","type":{"allow_custom_values":true,"members":[{"brief":"GPRS","deprecated":null,"id":"gprs","note":null,"stability":null,"value":"gprs"},{"brief":"EDGE","deprecated":null,"id":"edge","note":null,"stability":null,"value":"edge"},{"brief":"UMTS","deprecated":null,"id":"umts","note":null,"stability":null,"value":"umts"},{"brief":"CDMA","deprecated":null,"id":"cdma","note":null,"stability":null,"value":"cdma"},{"brief":"EVDO Rel. 0","deprecated":null,"id":"evdo_0","note":null,"stability":null,"value":"evdo_0"},{"brief":"EVDO Rev. A","deprecated":null,"id":"evdo_a","note":null,"stability":null,"value":"evdo_a"},{"brief":"CDMA2000 1XRTT","deprecated":null,"id":"cdma2000_1xrtt","note":null,"stability":null,"value":"cdma2000_1xrtt"},{"brief":"HSDPA","deprecated":null,"id":"hsdpa","note":null,"stability":null,"value":"hsdpa"},{"brief":"HSUPA","deprecated":null,"id":"hsupa","note":null,"stability":null,"value":"hsupa"},{"brief":"HSPA","deprecated":null,"id":"hspa","note":null,"stability":null,"value":"hspa"},{"brief":"IDEN","deprecated":null,"id":"iden","note":null,"stability":null,"value":"iden"},{"brief":"EVDO Rev. B","deprecated":null,"id":"evdo_b","note":null,"stability":null,"value":"evdo_b"},{"brief":"LTE","deprecated":null,"id":"lte","note":null,"stability":null,"value":"lte"},{"brief":"EHRPD","deprecated":null,"id":"ehrpd","note":null,"stability":null,"value":"ehrpd"},{"brief":"HSPAP","deprecated":null,"id":"hspap","note":null,"stability":null,"value":"hspap"},{"brief":"GSM","deprecated":null,"id":"gsm","note":null,"stability":null,"value":"gsm"},{"brief":"TD-SCDMA","deprecated":null,"id":"td_scdma","note":null,"stability":null,"value":"td_scdma"},{"brief":"IWLAN","deprecated":null,"id":"iwlan","note":null,"stability":null,"value":"iwlan"},{"brief":"5G NR (New Radio)","deprecated":null,"id":"nr","note":null,"stability":null,"value":"nr"},{"brief":"5G NRNSA (New Radio Non-Standalone)","deprecated":null,"id":"nrnsa","note":null,"stability":null,"value":"nrnsa"},{"brief":"LTE CA","deprecated":null,"id":"lte_ca","note":null,"stability":null,"value":"lte_ca"}]}},{"brief":"The internet connection type.","examples":"wifi","name":"network.connection.type","namespace":"network","requirement_level":"recommended","type":{"allow_custom_values":true,"members":[{"brief":null,"deprecated":null,"id":"wifi","note":null,"stability":null,"value":"wifi"},{"brief":null,"deprecated":null,"id":"wired","note":null,"stability":null,"value":"wired"},{"brief":null,"deprecated":null,"id":"cell","note":null,"stability":null,"value":"cell"},{"brief":null,"deprecated":null,"id":"unavailable","note":null,"stability":null,"value":"unavailable"},{"brief":null,"deprecated":null,"id":"unknown","note":null,"stability":null,"value":"unknown"}]}},{"brief":"The network IO operation direction.","examples":["transmit"],"name":"network.io.direction","namespace":"network","requirement_level":"recommended","type":{"allow_custom_values":false,"members":[{"brief":null,"deprecated":null,"id":"transmit","note":null,"stability":null,"value":"transmit"},{"brief":null,"deprecated":null,"id":"receive","note":null,"stability":null,"value":"receive"}]}},{"brief":"Local address of the network connection - IP address or Unix domain socket name.","examples":["10.1.2.80","/tmp/my.sock"],"name":"network.local.address","namespace":"network","requirement_level":"recommended","stability":"stable","type":"string"},{"brief":"Local port number of the network connection.","examples":[65123],"name":"network.local.port","namespace":"network","requirement_level":"recommended","stability":"stable","type":"int"},{"brief":"Peer address of the network connection - IP address or Unix domain socket name.","examples":["10.1.2.80","/tmp/my.sock"],"name":"network.peer.address","namespace":"network","requirement_level":"recommended","stability":"stable","type":"string"},{"brief":"Peer port number of the network connection.","examples":[65123],"name":"network.peer.port","namespace":"network","requirement_level":"recommended","stability":"stable","type":"int"},{"brief":"[OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent.","examples":["amqp","http","mqtt"],"name":"network.protocol.name","namespace":"network","note":"The value SHOULD be normalized to lowercase.","requirement_level":"recommended","stability":"stable","type":"string"},{"brief":"Version of the protocol specified in `network.protocol.name`.","examples":"3.1.1","name":"network.protocol.version","namespace":"network","note":"`network.protocol.version` refers to the version of the protocol used and might be different from the protocol client\u0027s 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","requirement_level":"recommended","stability":"stable","type":"string"},{"brief":"[OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication).\n","examples":["tcp","udp"],"name":"network.transport","namespace":"network","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","requirement_level":"recommended","stability":"stable","type":{"allow_custom_values":true,"members":[{"brief":"TCP","deprecated":null,"id":"tcp","note":null,"stability":null,"value":"tcp"},{"brief":"UDP","deprecated":null,"id":"udp","note":null,"stability":null,"value":"udp"},{"brief":"Named or anonymous pipe.","deprecated":null,"id":"pipe","note":null,"stability":null,"value":"pipe"},{"brief":"Unix domain socket","deprecated":null,"id":"unix","note":null,"stability":null,"value":"unix"}]}},{"brief":"[OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent.","examples":["ipv4","ipv6"],"name":"network.type","namespace":"network","note":"The value SHOULD be normalized to lowercase.","requirement_level":"recommended","stability":"stable","type":{"allow_custom_values":true,"members":[{"brief":"IPv4","deprecated":null,"id":"ipv4","note":null,"stability":null,"value":"ipv4"},{"brief":"IPv6","deprecated":null,"id":"ipv6","note":null,"stability":null,"value":"ipv6"}]}}],"namespace":"network"},{"attributes":[{"brief":"The [URI fragment](https://www.rfc-editor.org/rfc/rfc3986#section-3.5) component","examples":["SemConv"],"name":"url.fragment","namespace":"url","requirement_level":"recommended","stability":"stable","type":"string"},{"brief":"Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986)","examples":["https://www.foo.bar/search?q=OpenTelemetry#SemConv","//localhost"],"name":"url.full","namespace":"url","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\u0027s 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","requirement_level":"recommended","stability":"stable","type":"string"},{"brief":"The [URI path](https://www.rfc-editor.org/rfc/rfc3986#section-3.3) component","examples":["/search"],"name":"url.path","namespace":"url","requirement_level":"recommended","stability":"stable","type":"string"},{"brief":"The [URI query](https://www.rfc-editor.org/rfc/rfc3986#section-3.4) component","examples":["q=OpenTelemetry"],"name":"url.query","namespace":"url","note":"Sensitive content provided in query string SHOULD be scrubbed when instrumentations can identify it.","requirement_level":"recommended","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"],"name":"url.scheme","namespace":"url","requirement_level":"recommended","stability":"stable","type":"string"}],"namespace":"url"},{"attributes":[{"brief":"Value of the [HTTP User-Agent](https://www.rfc-editor.org/rfc/rfc9110.html#field.user-agent) header sent by the client.\n","examples":["CERN-LineMode/2.15 libwww/2.17b3","Mozilla/5.0 (iPhone; CPU iPhone OS 14_7_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.2 Mobile/15E148 Safari/604.1"],"name":"user_agent.original","namespace":"user_agent","requirement_level":"recommended","stability":"stable","type":"string"}],"namespace":"user_agent"}] \ No newline at end of file diff --git a/crates/weaver_forge/expected_output/semconv_jq_fn/semconv_grouped_attributes_without_experimental.json b/crates/weaver_forge/expected_output/semconv_jq_fn/semconv_grouped_attributes_without_experimental.json new file mode 100644 index 00000000..6a25d5b6 --- /dev/null +++ b/crates/weaver_forge/expected_output/semconv_jq_fn/semconv_grouped_attributes_without_experimental.json @@ -0,0 +1 @@ +[{"attributes":[{"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","name":"db.cassandra.consistency_level","namespace":"db","requirement_level":"recommended","tag":"tech-specific-cassandra","type":{"allow_custom_values":true,"members":[{"brief":null,"deprecated":null,"id":"all","note":null,"stability":null,"value":"all"},{"brief":null,"deprecated":null,"id":"each_quorum","note":null,"stability":null,"value":"each_quorum"},{"brief":null,"deprecated":null,"id":"quorum","note":null,"stability":null,"value":"quorum"},{"brief":null,"deprecated":null,"id":"local_quorum","note":null,"stability":null,"value":"local_quorum"},{"brief":null,"deprecated":null,"id":"one","note":null,"stability":null,"value":"one"},{"brief":null,"deprecated":null,"id":"two","note":null,"stability":null,"value":"two"},{"brief":null,"deprecated":null,"id":"three","note":null,"stability":null,"value":"three"},{"brief":null,"deprecated":null,"id":"local_one","note":null,"stability":null,"value":"local_one"},{"brief":null,"deprecated":null,"id":"any","note":null,"stability":null,"value":"any"},{"brief":null,"deprecated":null,"id":"serial","note":null,"stability":null,"value":"serial"},{"brief":null,"deprecated":null,"id":"local_serial","note":null,"stability":null,"value":"local_serial"}]}},{"brief":"The data center of the coordinating node for a query.\n","examples":"us-west-2","name":"db.cassandra.coordinator.dc","namespace":"db","requirement_level":"recommended","tag":"tech-specific-cassandra","type":"string"},{"brief":"The ID of the coordinating node for a query.\n","examples":"be13faa2-8574-4d71-926d-27f16cf8a7af","name":"db.cassandra.coordinator.id","namespace":"db","requirement_level":"recommended","tag":"tech-specific-cassandra","type":"string"},{"brief":"Whether or not the query is idempotent.\n","name":"db.cassandra.idempotence","namespace":"db","requirement_level":"recommended","tag":"tech-specific-cassandra","type":"boolean"},{"brief":"The fetch size used for paging, i.e. how many rows will be returned at once.\n","examples":[5000],"name":"db.cassandra.page_size","namespace":"db","requirement_level":"recommended","tag":"tech-specific-cassandra","type":"int"},{"brief":"The number of times a query was speculatively executed. Not set or `0` if the query was not executed speculatively.\n","examples":[0,2],"name":"db.cassandra.speculative_execution_count","namespace":"db","requirement_level":"recommended","tag":"tech-specific-cassandra","type":"int"},{"brief":"The name of the primary Cassandra table that the operation is acting upon, including the keyspace name (if applicable).","examples":"mytable","name":"db.cassandra.table","namespace":"db","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","requirement_level":"recommended","tag":"tech-specific-cassandra","type":"string"},{"brief":"The connection string used to connect to the database. It is recommended to remove embedded credentials.\n","examples":"Server=(localdb)\\v11.0;Integrated Security=true;","name":"db.connection_string","namespace":"db","requirement_level":"recommended","tag":"db-generic","type":"string"},{"brief":"Unique Cosmos client instance id.","examples":"3ba4827d-4422-483f-b59f-85b74211c11d","name":"db.cosmosdb.client_id","namespace":"db","requirement_level":"recommended","tag":"tech-specific-cosmosdb","type":"string"},{"brief":"Cosmos client connection mode.","name":"db.cosmosdb.connection_mode","namespace":"db","requirement_level":"recommended","tag":"tech-specific-cosmosdb","type":{"allow_custom_values":false,"members":[{"brief":"Gateway (HTTP) connections mode","deprecated":null,"id":"gateway","note":null,"stability":null,"value":"gateway"},{"brief":"Direct connection.","deprecated":null,"id":"direct","note":null,"stability":null,"value":"direct"}]}},{"brief":"Cosmos DB container name.","examples":"anystring","name":"db.cosmosdb.container","namespace":"db","requirement_level":"recommended","tag":"tech-specific-cosmosdb","type":"string"},{"brief":"CosmosDB Operation Type.","name":"db.cosmosdb.operation_type","namespace":"db","requirement_level":"recommended","tag":"tech-specific-cosmosdb","type":{"allow_custom_values":true,"members":[{"brief":null,"deprecated":null,"id":"invalid","note":null,"stability":null,"value":"Invalid"},{"brief":null,"deprecated":null,"id":"create","note":null,"stability":null,"value":"Create"},{"brief":null,"deprecated":null,"id":"patch","note":null,"stability":null,"value":"Patch"},{"brief":null,"deprecated":null,"id":"read","note":null,"stability":null,"value":"Read"},{"brief":null,"deprecated":null,"id":"read_feed","note":null,"stability":null,"value":"ReadFeed"},{"brief":null,"deprecated":null,"id":"delete","note":null,"stability":null,"value":"Delete"},{"brief":null,"deprecated":null,"id":"replace","note":null,"stability":null,"value":"Replace"},{"brief":null,"deprecated":null,"id":"execute","note":null,"stability":null,"value":"Execute"},{"brief":null,"deprecated":null,"id":"query","note":null,"stability":null,"value":"Query"},{"brief":null,"deprecated":null,"id":"head","note":null,"stability":null,"value":"Head"},{"brief":null,"deprecated":null,"id":"head_feed","note":null,"stability":null,"value":"HeadFeed"},{"brief":null,"deprecated":null,"id":"upsert","note":null,"stability":null,"value":"Upsert"},{"brief":null,"deprecated":null,"id":"batch","note":null,"stability":null,"value":"Batch"},{"brief":null,"deprecated":null,"id":"query_plan","note":null,"stability":null,"value":"QueryPlan"},{"brief":null,"deprecated":null,"id":"execute_javascript","note":null,"stability":null,"value":"ExecuteJavaScript"}]}},{"brief":"RU consumed for that operation","examples":[46.18,1.0],"name":"db.cosmosdb.request_charge","namespace":"db","requirement_level":"recommended","tag":"tech-specific-cosmosdb","type":"double"},{"brief":"Request payload size in bytes","name":"db.cosmosdb.request_content_length","namespace":"db","requirement_level":"recommended","tag":"tech-specific-cosmosdb","type":"int"},{"brief":"Cosmos DB status code.","examples":[200,201],"name":"db.cosmosdb.status_code","namespace":"db","requirement_level":"recommended","tag":"tech-specific-cosmosdb","type":"int"},{"brief":"Cosmos DB sub status code.","examples":[1000,1002],"name":"db.cosmosdb.sub_status_code","namespace":"db","requirement_level":"recommended","tag":"tech-specific-cosmosdb","type":"int"},{"brief":"Represents the identifier of an Elasticsearch cluster.\n","examples":["e9106fc68e3044f0b1475b04bf4ffd5f"],"name":"db.elasticsearch.cluster.name","namespace":"db","requirement_level":"recommended","tag":"tech-specific-elasticsearch","type":"string"},{"brief":"Represents the human-readable identifier of the node/instance to which a request was routed.\n","examples":["instance-0000000001"],"name":"db.elasticsearch.node.name","namespace":"db","requirement_level":"recommended","tag":"tech-specific-elasticsearch","type":"string"},{"brief":"A dynamic value in the url path.\n","examples":["db.elasticsearch.path_parts.index=test-index","db.elasticsearch.path_parts.doc_id=123"],"name":"db.elasticsearch.path_parts","namespace":"db","note":"Many Elasticsearch url paths allow dynamic values. These SHOULD be recorded in span attributes in the format `db.elasticsearch.path_parts.\u003ckey\u003e`, where `\u003ckey\u003e` 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","requirement_level":"recommended","tag":"tech-specific-elasticsearch","type":"template[string]"},{"brief":"An identifier (address, unique name, or any other identifier) of the database instance that is executing queries or mutations on the current connection. This is useful in cases where the database is running in a clustered environment and the instrumentation is able to record the node executing the query. The client may obtain this value in databases like MySQL using queries like `select @@hostname`.\n","examples":"mysql-e26b99z.example.com","name":"db.instance.id","namespace":"db","requirement_level":"recommended","tag":"db-generic","type":"string"},{"brief":"The fully-qualified class name of the [Java Database Connectivity (JDBC)](https://docs.oracle.com/javase/8/docs/technotes/guides/jdbc/) driver used to connect.\n","examples":["org.postgresql.Driver","com.microsoft.sqlserver.jdbc.SQLServerDriver"],"name":"db.jdbc.driver_classname","namespace":"db","requirement_level":"recommended","tag":"tech-specific-jdbc","type":"string"},{"brief":"The MongoDB collection being accessed within the database stated in `db.name`.\n","examples":["customers","products"],"name":"db.mongodb.collection","namespace":"db","requirement_level":"recommended","tag":"tech-specific-mongodb","type":"string"},{"brief":"The Microsoft SQL Server [instance name](https://docs.microsoft.com/sql/connect/jdbc/building-the-connection-url?view=sql-server-ver15) connecting to. This name is used to determine the port of a named instance.\n","examples":"MSSQLSERVER","name":"db.mssql.instance_name","namespace":"db","note":"If setting a `db.mssql.instance_name`, `server.port` is no longer required (but still recommended if non-standard).\n","requirement_level":"recommended","tag":"tech-specific-mssql","type":"string"},{"brief":"This attribute is used to report the name of the database being accessed. For commands that switch the database, this should be set to the target database (even if the command fails).\n","examples":["customers","main"],"name":"db.name","namespace":"db","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","requirement_level":"recommended","tag":"db-generic","type":"string"},{"brief":"The name of the operation being executed, e.g. the [MongoDB command name](https://docs.mongodb.com/manual/reference/command/#database-operations) such as `findAndModify`, or the SQL keyword.\n","examples":["findAndModify","HMSET","SELECT"],"name":"db.operation","namespace":"db","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","requirement_level":"recommended","tag":"db-generic","type":"string"},{"brief":"The index of the database being accessed as used in the [`SELECT` command](https://redis.io/commands/select), provided as an integer. To be used instead of the generic `db.name` attribute.\n","examples":[0,1,15],"name":"db.redis.database_index","namespace":"db","requirement_level":"recommended","tag":"tech-specific-redis","type":"int"},{"brief":"The name of the primary table that the operation is acting upon, including the database name (if applicable).","examples":["public.users","customers"],"name":"db.sql.table","namespace":"db","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","requirement_level":"recommended","tag":"tech-specific-sql","type":"string"},{"brief":"The database statement being executed.\n","examples":["SELECT * FROM wuser_table","SET mykey \"WuValue\""],"name":"db.statement","namespace":"db","requirement_level":"recommended","tag":"db-generic","type":"string"},{"brief":"An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers.","name":"db.system","namespace":"db","requirement_level":"recommended","tag":"db-generic","type":{"allow_custom_values":true,"members":[{"brief":"Some other SQL database. Fallback only. See notes.","deprecated":null,"id":"other_sql","note":null,"stability":null,"value":"other_sql"},{"brief":"Microsoft SQL Server","deprecated":null,"id":"mssql","note":null,"stability":null,"value":"mssql"},{"brief":"Microsoft SQL Server Compact","deprecated":null,"id":"mssqlcompact","note":null,"stability":null,"value":"mssqlcompact"},{"brief":"MySQL","deprecated":null,"id":"mysql","note":null,"stability":null,"value":"mysql"},{"brief":"Oracle Database","deprecated":null,"id":"oracle","note":null,"stability":null,"value":"oracle"},{"brief":"IBM Db2","deprecated":null,"id":"db2","note":null,"stability":null,"value":"db2"},{"brief":"PostgreSQL","deprecated":null,"id":"postgresql","note":null,"stability":null,"value":"postgresql"},{"brief":"Amazon Redshift","deprecated":null,"id":"redshift","note":null,"stability":null,"value":"redshift"},{"brief":"Apache Hive","deprecated":null,"id":"hive","note":null,"stability":null,"value":"hive"},{"brief":"Cloudscape","deprecated":null,"id":"cloudscape","note":null,"stability":null,"value":"cloudscape"},{"brief":"HyperSQL DataBase","deprecated":null,"id":"hsqldb","note":null,"stability":null,"value":"hsqldb"},{"brief":"Progress Database","deprecated":null,"id":"progress","note":null,"stability":null,"value":"progress"},{"brief":"SAP MaxDB","deprecated":null,"id":"maxdb","note":null,"stability":null,"value":"maxdb"},{"brief":"SAP HANA","deprecated":null,"id":"hanadb","note":null,"stability":null,"value":"hanadb"},{"brief":"Ingres","deprecated":null,"id":"ingres","note":null,"stability":null,"value":"ingres"},{"brief":"FirstSQL","deprecated":null,"id":"firstsql","note":null,"stability":null,"value":"firstsql"},{"brief":"EnterpriseDB","deprecated":null,"id":"edb","note":null,"stability":null,"value":"edb"},{"brief":"InterSystems Caché","deprecated":null,"id":"cache","note":null,"stability":null,"value":"cache"},{"brief":"Adabas (Adaptable Database System)","deprecated":null,"id":"adabas","note":null,"stability":null,"value":"adabas"},{"brief":"Firebird","deprecated":null,"id":"firebird","note":null,"stability":null,"value":"firebird"},{"brief":"Apache Derby","deprecated":null,"id":"derby","note":null,"stability":null,"value":"derby"},{"brief":"FileMaker","deprecated":null,"id":"filemaker","note":null,"stability":null,"value":"filemaker"},{"brief":"Informix","deprecated":null,"id":"informix","note":null,"stability":null,"value":"informix"},{"brief":"InstantDB","deprecated":null,"id":"instantdb","note":null,"stability":null,"value":"instantdb"},{"brief":"InterBase","deprecated":null,"id":"interbase","note":null,"stability":null,"value":"interbase"},{"brief":"MariaDB","deprecated":null,"id":"mariadb","note":null,"stability":null,"value":"mariadb"},{"brief":"Netezza","deprecated":null,"id":"netezza","note":null,"stability":null,"value":"netezza"},{"brief":"Pervasive PSQL","deprecated":null,"id":"pervasive","note":null,"stability":null,"value":"pervasive"},{"brief":"PointBase","deprecated":null,"id":"pointbase","note":null,"stability":null,"value":"pointbase"},{"brief":"SQLite","deprecated":null,"id":"sqlite","note":null,"stability":null,"value":"sqlite"},{"brief":"Sybase","deprecated":null,"id":"sybase","note":null,"stability":null,"value":"sybase"},{"brief":"Teradata","deprecated":null,"id":"teradata","note":null,"stability":null,"value":"teradata"},{"brief":"Vertica","deprecated":null,"id":"vertica","note":null,"stability":null,"value":"vertica"},{"brief":"H2","deprecated":null,"id":"h2","note":null,"stability":null,"value":"h2"},{"brief":"ColdFusion IMQ","deprecated":null,"id":"coldfusion","note":null,"stability":null,"value":"coldfusion"},{"brief":"Apache Cassandra","deprecated":null,"id":"cassandra","note":null,"stability":null,"value":"cassandra"},{"brief":"Apache HBase","deprecated":null,"id":"hbase","note":null,"stability":null,"value":"hbase"},{"brief":"MongoDB","deprecated":null,"id":"mongodb","note":null,"stability":null,"value":"mongodb"},{"brief":"Redis","deprecated":null,"id":"redis","note":null,"stability":null,"value":"redis"},{"brief":"Couchbase","deprecated":null,"id":"couchbase","note":null,"stability":null,"value":"couchbase"},{"brief":"CouchDB","deprecated":null,"id":"couchdb","note":null,"stability":null,"value":"couchdb"},{"brief":"Microsoft Azure Cosmos DB","deprecated":null,"id":"cosmosdb","note":null,"stability":null,"value":"cosmosdb"},{"brief":"Amazon DynamoDB","deprecated":null,"id":"dynamodb","note":null,"stability":null,"value":"dynamodb"},{"brief":"Neo4j","deprecated":null,"id":"neo4j","note":null,"stability":null,"value":"neo4j"},{"brief":"Apache Geode","deprecated":null,"id":"geode","note":null,"stability":null,"value":"geode"},{"brief":"Elasticsearch","deprecated":null,"id":"elasticsearch","note":null,"stability":null,"value":"elasticsearch"},{"brief":"Memcached","deprecated":null,"id":"memcached","note":null,"stability":null,"value":"memcached"},{"brief":"CockroachDB","deprecated":null,"id":"cockroachdb","note":null,"stability":null,"value":"cockroachdb"},{"brief":"OpenSearch","deprecated":null,"id":"opensearch","note":null,"stability":null,"value":"opensearch"},{"brief":"ClickHouse","deprecated":null,"id":"clickhouse","note":null,"stability":null,"value":"clickhouse"},{"brief":"Cloud Spanner","deprecated":null,"id":"spanner","note":null,"stability":null,"value":"spanner"},{"brief":"Trino","deprecated":null,"id":"trino","note":null,"stability":null,"value":"trino"}]}},{"brief":"Username for accessing the database.\n","examples":["readonly_user","reporting_user"],"name":"db.user","namespace":"db","requirement_level":"recommended","tag":"db-generic","type":"string"}],"namespace":"db"},{"attributes":[{"brief":"HTTP request headers, `\u003ckey\u003e` being the normalized HTTP Header name (lowercase), the value being the header values.\n","examples":["http.request.header.content-type=[\"application/json\"]","http.request.header.x-forwarded-for=[\"1.2.3.4\", \"1.2.3.5\"]"],"name":"http.request.header","namespace":"http","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","requirement_level":"recommended","stability":"stable","type":"template[string[]]"},{"brief":"HTTP request method.","examples":["GET","POST","HEAD"],"name":"http.request.method","namespace":"http","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","requirement_level":"recommended","stability":"stable","type":{"allow_custom_values":true,"members":[{"brief":"CONNECT method.","deprecated":null,"id":"connect","note":null,"stability":null,"value":"CONNECT"},{"brief":"DELETE method.","deprecated":null,"id":"delete","note":null,"stability":null,"value":"DELETE"},{"brief":"GET method.","deprecated":null,"id":"get","note":null,"stability":null,"value":"GET"},{"brief":"HEAD method.","deprecated":null,"id":"head","note":null,"stability":null,"value":"HEAD"},{"brief":"OPTIONS method.","deprecated":null,"id":"options","note":null,"stability":null,"value":"OPTIONS"},{"brief":"PATCH method.","deprecated":null,"id":"patch","note":null,"stability":null,"value":"PATCH"},{"brief":"POST method.","deprecated":null,"id":"post","note":null,"stability":null,"value":"POST"},{"brief":"PUT method.","deprecated":null,"id":"put","note":null,"stability":null,"value":"PUT"},{"brief":"TRACE method.","deprecated":null,"id":"trace","note":null,"stability":null,"value":"TRACE"},{"brief":"Any HTTP method that the instrumentation has no prior knowledge of.","deprecated":null,"id":"other","note":null,"stability":null,"value":"_OTHER"}]}},{"brief":"Original HTTP method sent by the client in the request line.","examples":["GeT","ACL","foo"],"name":"http.request.method_original","namespace":"http","requirement_level":"recommended","stability":"stable","type":"string"},{"brief":"The ordinal number of request resending attempt (for any reason, including redirects).\n","examples":3,"name":"http.request.resend_count","namespace":"http","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","requirement_level":"recommended","stability":"stable","type":"int"},{"brief":"HTTP response headers, `\u003ckey\u003e` being the normalized HTTP Header name (lowercase), the value being the header values.\n","examples":["http.response.header.content-type=[\"application/json\"]","http.response.header.my-custom-header=[\"abc\", \"def\"]"],"name":"http.response.header","namespace":"http","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","requirement_level":"recommended","stability":"stable","type":"template[string[]]"},{"brief":"[HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6).","examples":[200],"name":"http.response.status_code","namespace":"http","requirement_level":"recommended","stability":"stable","type":"int"},{"brief":"The matched route, that is, the path template in the format used by the respective server framework.\n","examples":["/users/:userID?","{controller}/{action}/{id?}"],"name":"http.route","namespace":"http","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.","requirement_level":"recommended","stability":"stable","type":"string"}],"namespace":"http"},{"attributes":[{"brief":"Value of the [HTTP User-Agent](https://www.rfc-editor.org/rfc/rfc9110.html#field.user-agent) header sent by the client.\n","examples":["CERN-LineMode/2.15 libwww/2.17b3","Mozilla/5.0 (iPhone; CPU iPhone OS 14_7_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.2 Mobile/15E148 Safari/604.1"],"name":"user_agent.original","namespace":"user_agent","requirement_level":"recommended","stability":"stable","type":"string"}],"namespace":"user_agent"}] \ No newline at end of file diff --git a/crates/weaver_forge/expected_output/semconv_jq_fn/semconv_metrics.json b/crates/weaver_forge/expected_output/semconv_jq_fn/semconv_metrics.json new file mode 100644 index 00000000..db3f0f3b --- /dev/null +++ b/crates/weaver_forge/expected_output/semconv_jq_fn/semconv_metrics.json @@ -0,0 +1 @@ +[{"metrics":[{"attributes":[{"brief":"The type of memory.","examples":["heap","non_heap"],"name":"jvm.memory.type","requirement_level":"recommended","stability":"stable","type":{"allow_custom_values":false,"members":[{"brief":"Heap memory.","deprecated":null,"id":"heap","note":null,"stability":null,"value":"heap"},{"brief":"Non-heap memory","deprecated":null,"id":"non_heap","note":null,"stability":null,"value":"non_heap"}]}},{"brief":"Name of the memory pool.","examples":["G1 Old Gen","G1 Eden space","G1 Survivor Space"],"name":"jvm.memory.pool.name","note":"Pool names are generally obtained via [MemoryPoolMXBean#getName()](https://docs.oracle.com/en/java/javase/11/docs/api/java.management/java/lang/management/MemoryPoolMXBean.html#getName()).\n","requirement_level":"recommended","stability":"stable","type":"string"}],"brief":"Measure of memory used.","events":[],"id":"metric.jvm.memory.used","instrument":"updowncounter","lineage":{"attributes":{"jvm.memory.pool.name":{"inherited_fields":["brief","examples","note","requirement_level","stability"],"source_group":"attributes.jvm.memory"},"jvm.memory.type":{"inherited_fields":["brief","examples","note","requirement_level","stability"],"source_group":"attributes.jvm.memory"}},"source_file":"data/jvm-metrics.yaml"},"metric_name":"jvm.memory.used","name":null,"namespace":"jvm","span_kind":null,"stability":"stable","type":"metric","unit":"By"},{"attributes":[{"brief":"The type of memory.","examples":["heap","non_heap"],"name":"jvm.memory.type","requirement_level":"recommended","stability":"stable","type":{"allow_custom_values":false,"members":[{"brief":"Heap memory.","deprecated":null,"id":"heap","note":null,"stability":null,"value":"heap"},{"brief":"Non-heap memory","deprecated":null,"id":"non_heap","note":null,"stability":null,"value":"non_heap"}]}},{"brief":"Name of the memory pool.","examples":["G1 Old Gen","G1 Eden space","G1 Survivor Space"],"name":"jvm.memory.pool.name","note":"Pool names are generally obtained via [MemoryPoolMXBean#getName()](https://docs.oracle.com/en/java/javase/11/docs/api/java.management/java/lang/management/MemoryPoolMXBean.html#getName()).\n","requirement_level":"recommended","stability":"stable","type":"string"}],"brief":"Measure of memory committed.","events":[],"id":"metric.jvm.memory.committed","instrument":"updowncounter","lineage":{"attributes":{"jvm.memory.pool.name":{"inherited_fields":["brief","examples","note","requirement_level","stability"],"source_group":"attributes.jvm.memory"},"jvm.memory.type":{"inherited_fields":["brief","examples","note","requirement_level","stability"],"source_group":"attributes.jvm.memory"}},"source_file":"data/jvm-metrics.yaml"},"metric_name":"jvm.memory.committed","name":null,"namespace":"jvm","span_kind":null,"stability":"stable","type":"metric","unit":"By"},{"attributes":[{"brief":"The type of memory.","examples":["heap","non_heap"],"name":"jvm.memory.type","requirement_level":"recommended","stability":"stable","type":{"allow_custom_values":false,"members":[{"brief":"Heap memory.","deprecated":null,"id":"heap","note":null,"stability":null,"value":"heap"},{"brief":"Non-heap memory","deprecated":null,"id":"non_heap","note":null,"stability":null,"value":"non_heap"}]}},{"brief":"Name of the memory pool.","examples":["G1 Old Gen","G1 Eden space","G1 Survivor Space"],"name":"jvm.memory.pool.name","note":"Pool names are generally obtained via [MemoryPoolMXBean#getName()](https://docs.oracle.com/en/java/javase/11/docs/api/java.management/java/lang/management/MemoryPoolMXBean.html#getName()).\n","requirement_level":"recommended","stability":"stable","type":"string"}],"brief":"Measure of max obtainable memory.","events":[],"id":"metric.jvm.memory.limit","instrument":"updowncounter","lineage":{"attributes":{"jvm.memory.pool.name":{"inherited_fields":["brief","examples","note","requirement_level","stability"],"source_group":"attributes.jvm.memory"},"jvm.memory.type":{"inherited_fields":["brief","examples","note","requirement_level","stability"],"source_group":"attributes.jvm.memory"}},"source_file":"data/jvm-metrics.yaml"},"metric_name":"jvm.memory.limit","name":null,"namespace":"jvm","span_kind":null,"stability":"stable","type":"metric","unit":"By"},{"attributes":[{"brief":"The type of memory.","examples":["heap","non_heap"],"name":"jvm.memory.type","requirement_level":"recommended","stability":"stable","type":{"allow_custom_values":false,"members":[{"brief":"Heap memory.","deprecated":null,"id":"heap","note":null,"stability":null,"value":"heap"},{"brief":"Non-heap memory","deprecated":null,"id":"non_heap","note":null,"stability":null,"value":"non_heap"}]}},{"brief":"Name of the memory pool.","examples":["G1 Old Gen","G1 Eden space","G1 Survivor Space"],"name":"jvm.memory.pool.name","note":"Pool names are generally obtained via [MemoryPoolMXBean#getName()](https://docs.oracle.com/en/java/javase/11/docs/api/java.management/java/lang/management/MemoryPoolMXBean.html#getName()).\n","requirement_level":"recommended","stability":"stable","type":"string"}],"brief":"Measure of memory used, as measured after the most recent garbage collection event on this pool.","events":[],"id":"metric.jvm.memory.used_after_last_gc","instrument":"updowncounter","lineage":{"attributes":{"jvm.memory.pool.name":{"inherited_fields":["brief","examples","note","requirement_level","stability"],"source_group":"attributes.jvm.memory"},"jvm.memory.type":{"inherited_fields":["brief","examples","note","requirement_level","stability"],"source_group":"attributes.jvm.memory"}},"source_file":"data/jvm-metrics.yaml"},"metric_name":"jvm.memory.used_after_last_gc","name":null,"namespace":"jvm","span_kind":null,"stability":"stable","type":"metric","unit":"By"},{"attributes":[{"brief":"Name of the garbage collector.","examples":["G1 Young Generation","G1 Old Generation"],"name":"jvm.gc.name","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()).\n","requirement_level":"recommended","stability":"stable","type":"string"},{"brief":"Name of the garbage collector action.","examples":["end of minor GC","end of major GC"],"name":"jvm.gc.action","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()).\n","requirement_level":"recommended","stability":"stable","type":"string"}],"brief":"Duration of JVM garbage collection actions.","events":[],"id":"metric.jvm.gc.duration","instrument":"histogram","lineage":{"source_file":"data/jvm-metrics.yaml"},"metric_name":"jvm.gc.duration","name":null,"namespace":"jvm","prefix":"jvm.gc","span_kind":null,"stability":"stable","type":"metric","unit":"s"},{"attributes":[{"brief":"Whether the thread is daemon or not.","name":"jvm.thread.daemon","requirement_level":"recommended","stability":"stable","type":"boolean"},{"brief":"State of the thread.","examples":["runnable","blocked"],"name":"jvm.thread.state","requirement_level":"recommended","stability":"stable","type":{"allow_custom_values":false,"members":[{"brief":"A thread that has not yet started is in this state.","deprecated":null,"id":"new","note":null,"stability":null,"value":"new"},{"brief":"A thread executing in the Java virtual machine is in this state.","deprecated":null,"id":"runnable","note":null,"stability":null,"value":"runnable"},{"brief":"A thread that is blocked waiting for a monitor lock is in this state.","deprecated":null,"id":"blocked","note":null,"stability":null,"value":"blocked"},{"brief":"A thread that is waiting indefinitely for another thread to perform a particular action is in this state.","deprecated":null,"id":"waiting","note":null,"stability":null,"value":"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.","deprecated":null,"id":"timed_waiting","note":null,"stability":null,"value":"timed_waiting"},{"brief":"A thread that has exited is in this state.","deprecated":null,"id":"terminated","note":null,"stability":null,"value":"terminated"}]}}],"brief":"Number of executing platform threads.","events":[],"id":"metric.jvm.thread.count","instrument":"updowncounter","lineage":{"source_file":"data/jvm-metrics.yaml"},"metric_name":"jvm.thread.count","name":null,"namespace":"jvm","span_kind":null,"stability":"stable","type":"metric","unit":"{thread}"},{"attributes":[],"brief":"Number of classes loaded since JVM start.","events":[],"id":"metric.jvm.class.loaded","instrument":"counter","lineage":{"source_file":"data/jvm-metrics.yaml"},"metric_name":"jvm.class.loaded","name":null,"namespace":"jvm","span_kind":null,"stability":"stable","type":"metric","unit":"{class}"},{"attributes":[],"brief":"Number of classes unloaded since JVM start.","events":[],"id":"metric.jvm.class.unloaded","instrument":"counter","lineage":{"source_file":"data/jvm-metrics.yaml"},"metric_name":"jvm.class.unloaded","name":null,"namespace":"jvm","span_kind":null,"stability":"stable","type":"metric","unit":"{class}"},{"attributes":[],"brief":"Number of classes currently loaded.","events":[],"id":"metric.jvm.class.count","instrument":"updowncounter","lineage":{"source_file":"data/jvm-metrics.yaml"},"metric_name":"jvm.class.count","name":null,"namespace":"jvm","span_kind":null,"stability":"stable","type":"metric","unit":"{class}"},{"attributes":[],"brief":"Number of processors available to the Java virtual machine.","events":[],"id":"metric.jvm.cpu.count","instrument":"updowncounter","lineage":{"source_file":"data/jvm-metrics.yaml"},"metric_name":"jvm.cpu.count","name":null,"namespace":"jvm","span_kind":null,"stability":"stable","type":"metric","unit":"{cpu}"},{"attributes":[],"brief":"CPU time used by the process as reported by the JVM.","events":[],"id":"metric.jvm.cpu.time","instrument":"counter","lineage":{"source_file":"data/jvm-metrics.yaml"},"metric_name":"jvm.cpu.time","name":null,"namespace":"jvm","span_kind":null,"stability":"stable","type":"metric","unit":"s"},{"attributes":[],"brief":"Recent CPU utilization for the process as reported by the JVM.","events":[],"id":"metric.jvm.cpu.recent_utilization","instrument":"gauge","lineage":{"source_file":"data/jvm-metrics.yaml"},"metric_name":"jvm.cpu.recent_utilization","name":null,"namespace":"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()).\n","span_kind":null,"stability":"stable","type":"metric","unit":"1"}],"namespace":"jvm"}] \ No newline at end of file diff --git a/crates/weaver_forge/src/lib.rs b/crates/weaver_forge/src/lib.rs index 27695aa3..389083cd 100644 --- a/crates/weaver_forge/src/lib.rs +++ b/crates/weaver_forge/src/lib.rs @@ -560,6 +560,7 @@ impl TemplateEngine { #[cfg(test)] mod tests { + use std::fs; use std::path::Path; use globset::Glob; @@ -825,4 +826,48 @@ mod tests { assert!(diff_dir("expected_output/py_compat", "observed_output/py_compat").unwrap()); } + + #[test] + fn test_semconv_jq_functions() { + let logger = TestLogger::default(); + let loader = FileSystemFileLoader::try_new("templates".into(), "semconv_jq_fn") + .expect("Failed to create file system loader"); + let config = + WeaverConfig::try_from_loader(&loader).expect("Failed to load `templates/weaver.yaml`"); + let engine = super::TemplateEngine::new(config, loader, Params::default()); + let registry_id = "default"; + let mut registry = SemConvRegistry::try_from_path_pattern(registry_id, "data/*.yaml") + .expect("Failed to load registry"); + let schema = SchemaResolver::resolve_semantic_convention_registry(&mut registry) + .expect("Failed to resolve registry"); + + let template_registry = ResolvedRegistry::try_from_resolved_registry( + schema.registry(registry_id).expect("registry not found"), + schema.catalog(), + ) + .unwrap_or_else(|e| { + panic!( + "Failed to create the context for the template evaluation: {:?}", + e + ) + }); + + // Delete all the files in the observed_output/semconv_jq_fn directory + // before generating the new files. + fs::remove_dir_all("observed_output/semconv_jq_fn").unwrap_or_default(); + + engine + .generate( + logger.clone(), + &template_registry, + Path::new("observed_output/semconv_jq_fn"), + &OutputDirective::File, + ) + .inspect_err(|e| { + print_dedup_errors(logger.clone(), e.clone()); + }) + .expect("Failed to generate registry assets"); + + assert!(diff_dir("expected_output/semconv_jq_fn", "observed_output/semconv_jq_fn").unwrap()); + } } diff --git a/crates/weaver_forge/templates/semconv_jq_fn/semconv_attributes.json b/crates/weaver_forge/templates/semconv_jq_fn/semconv_attributes.json new file mode 100644 index 00000000..760f1e67 --- /dev/null +++ b/crates/weaver_forge/templates/semconv_jq_fn/semconv_attributes.json @@ -0,0 +1 @@ +{{ ctx | tojson }} \ No newline at end of file diff --git a/crates/weaver_forge/templates/semconv_jq_fn/semconv_grouped_attributes.json b/crates/weaver_forge/templates/semconv_jq_fn/semconv_grouped_attributes.json new file mode 100644 index 00000000..760f1e67 --- /dev/null +++ b/crates/weaver_forge/templates/semconv_jq_fn/semconv_grouped_attributes.json @@ -0,0 +1 @@ +{{ ctx | tojson }} \ No newline at end of file diff --git a/crates/weaver_forge/templates/semconv_jq_fn/semconv_grouped_attributes_without_experimental.json b/crates/weaver_forge/templates/semconv_jq_fn/semconv_grouped_attributes_without_experimental.json new file mode 100644 index 00000000..760f1e67 --- /dev/null +++ b/crates/weaver_forge/templates/semconv_jq_fn/semconv_grouped_attributes_without_experimental.json @@ -0,0 +1 @@ +{{ ctx | tojson }} \ No newline at end of file diff --git a/crates/weaver_forge/templates/semconv_jq_fn/semconv_metrics.json b/crates/weaver_forge/templates/semconv_jq_fn/semconv_metrics.json new file mode 100644 index 00000000..760f1e67 --- /dev/null +++ b/crates/weaver_forge/templates/semconv_jq_fn/semconv_metrics.json @@ -0,0 +1 @@ +{{ ctx | tojson }} \ No newline at end of file diff --git a/crates/weaver_forge/templates/semconv_jq_fn/weaver.yaml b/crates/weaver_forge/templates/semconv_jq_fn/weaver.yaml new file mode 100644 index 00000000..4de05adf --- /dev/null +++ b/crates/weaver_forge/templates/semconv_jq_fn/weaver.yaml @@ -0,0 +1,22 @@ +params: + exclude_stability: ["experimental"] + +templates: + - pattern: "**/semconv_attributes.json" + filter: semconv_attributes + application_mode: single + - pattern: "**/semconv_grouped_attributes.json" + filter: > + semconv_grouped_attributes + application_mode: single + - pattern: "**/semconv_grouped_attributes_without_experimental.json" + filter: > + semconv_grouped_attributes({ + "exclude_namespace": ["url", "network"], + "exclude_stability": ["experimental"] + }) + application_mode: single + - pattern: "**/semconv_metrics.json" + filter: > + semconv_grouped_metrics({"exclude_stability": ["experimental"]}) + application_mode: single diff --git a/defaults/jq/semconv.jq b/defaults/jq/semconv.jq index 0cfb9399..4024eb57 100644 --- a/defaults/jq/semconv.jq +++ b/defaults/jq/semconv.jq @@ -1,84 +1,92 @@ -def semconv_attributes: - .groups[] - | map(select(.id | startswith("registry."))) - | map(select(.type == "attribute_group")) - | map(. + {group_id: .id | split(".") | .[1]}) - | sort_by(.group_id); - -def semconv_grouped_attributes: - .groups[] - | map(select(.id | startswith("registry."))) - | map(select(.type == "attribute_group")) - | map(. + {group_id: .id | split(".") | .[1]}) - | sort_by(.group_id) - | group_by(.group_id); - -def semconv_metrics: - .groups[] - | map(select(.type == "metric")) - | map(. + {group_id: .id | split(".") | .[1]}) - | sort_by(.group_id); - -def semconv_grouped_metrics: - .groups[] - | map(select(.type == "metric")) - | map(. + {group_id: .id | split(".") | .[1]}) - | sort_by(.group_id) - | group_by(.group_id); - -def semconv_resources: - .groups[] - | map(select(.type == "resource")) - | map(. + {group_id: .id | split(".") | .[1]}) - | sort_by(.group_id); - -def semconv_grouped_resources: - .groups[] - | map(select(.type == "resource")) - | map(. + {group_id: .id | split(".") | .[1]}) - | sort_by(.group_id) - | group_by(.group_id); - -def semconv_scopes: - .groups[] - | map(select(.type == "scope")) - | map(. + {group_id: .id | split(".") | .[1]}) - | sort_by(.group_id); - -def semconv_grouped_scopes: - .groups[] - | map(select(.type == "scope")) - | map(. + {group_id: .id | split(".") | .[1]}) - | sort_by(.group_id) - | group_by(.group_id); - -def semconv_spans: - .groups[] - | map(select(.type == "span")) - | map(. + {group_id: .id | split(".") | .[1]}) - | sort_by(.group_id); - -def semconv_grouped_spans: - .groups[] - | map(select(.type == "span")) - | map(. + {group_id: .id | split(".") | .[1]}) - | sort_by(.group_id) - | group_by(.group_id); - -def semconv_events: - .groups[] - | map(select(.type == "event")) - | map(. + {group_id: .id | split(".") | .[1]}) - | sort_by(.group_id); - -def semconv_grouped_events: - .groups[] - | map(select(.type == "event")) - | map(. + {group_id: .id | split(".") | .[1]}) - | sort_by(.group_id) - | group_by(.group_id); - -def semconv_group_by_namespace: - group_by(.group_id); +def semconv_group_attributes_by_namespace: + group_by(.namespace) + | map({ namespace: .[0].namespace, attributes: . | sort_by(.name) }); +##################### +# Attribute functions +##################### +def semconv_attributes($options): + .groups + | map(select(.type == "attribute_group" and (.id | startswith("registry.")))) + | map(.attributes) | add + | if ($options | has("exclude_stability")) then + map(select(.stability as $st | $options.exclude_stability | index($st) | not)) + else + . + end + | map(. + {namespace: (if .name | index(".") then .name | split(".")[0] else "other" end)}) + | if ($options | has("exclude_namespace")) then + map(select(.namespace as $st | $options.exclude_namespace | index($st) | not)) + else + . + end + | sort_by(.namespace, .name); +def semconv_attributes: semconv_attributes({}); + +def semconv_grouped_attributes($options): + semconv_attributes($options) + | semconv_group_attributes_by_namespace; + +def semconv_grouped_attributes: semconv_grouped_attributes({}); + +# Generic Signal Functions +def semconv_group_signals_by_namespace($signal): + group_by(.namespace) + | map({ namespace: .[0].namespace, ($signal): . | sort_by(.name) }); + +def semconv_signal($signal; $options): + .groups + | map(select(.type == $signal)) + | if ($options | has("exclude_stability")) then + map(select(.stability as $st | $options.exclude_stability | index($st) | not)) + else + . + end + | map(. + {namespace: .id | split(".") | .[1]}) + | if ($options | has("exclude_namespace")) then + map(select(.namespace as $st | $options.exclude_namespace | index($st) | not)) + else + . + end + | sort_by(.namespace); + +# Metric Functions +def semconv_group_metrics_by_namespace: semconv_group_signals_by_namespace("metrics"); +def semconv_metrics($options): semconv_signal("metric"; $options); +def semconv_metrics: semconv_metrics({}); + +def semconv_grouped_metrics($options): semconv_metrics($options) | semconv_group_metrics_by_namespace; +def semconv_grouped_metrics: semconv_grouped_metrics({}); + +# Resource functions +def semconv_group_resources_by_namespace: semconv_group_signals_by_namespace("resources"); +def semconv_resources($options): semconv_signal("resource"; $options); +def semconv_resources: semconv_resources({}); + +def semconv_grouped_resources($options): semconv_resources($options) | semconv_group_resources_by_namespace; +def semconv_grouped_resources: semconv_grouped_resources({}); + +# Scope functions +def semconv_group_scopes_by_namespace: semconv_group_signals_by_namespace("scopes"); +def semconv_scopes($options): semconv_signal("scope"; $options); +def semconv_scopes: semconv_scopes({}); + +def semconv_grouped_scopes($options): semconv_scopes($options) | semconv_group_scopes_by_namespace; +def semconv_grouped_scopes: semconv_grouped_scopes({}); + +# Span functions +def semconv_group_spans_by_namespace: semconv_group_signals_by_namespace("spans"); +def semconv_spans($options): semconv_signal("span"; $options); +def semconv_spans: semconv_spans({}); + +def semconv_grouped_spans($options): semconv_spans($options) | semconv_group_spans_by_namespace; +def semconv_grouped_spans: semconv_grouped_spans({}); + +# Event functions +def semconv_group_events_by_namespace: semconv_group_signals_by_namespace("events"); +def semconv_events($options): semconv_signal("event"; $options); +def semconv_events: semconv_events({}); + +def semconv_grouped_events($options): semconv_events($options) | semconv_group_events_by_namespace; +def semconv_grouped_events: semconv_grouped_events({}); From 7aff7c00625fd881e8025c57fc93dcbe8d054537 Mon Sep 17 00:00:00 2001 From: Laurent Querel Date: Thu, 18 Jul 2024 09:55:39 -0700 Subject: [PATCH 19/29] feat(forge): Update documentation --- crates/weaver_forge/README.md | 184 ++++++++++++++++++++++++++++++++-- 1 file changed, 174 insertions(+), 10 deletions(-) diff --git a/crates/weaver_forge/README.md b/crates/weaver_forge/README.md index 4d6407c3..7268755b 100644 --- a/crates/weaver_forge/README.md +++ b/crates/weaver_forge/README.md @@ -45,15 +45,10 @@ templates/ ... ``` -The command `weaver generate registry markdown` will generate the markdown -files based on the templates located in the `templates/registry/markdown`. - -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 command `weaver generate registry rust` will generate the rust +files based on the templates located in the `templates/registry/rust`. + +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. @@ -63,6 +58,9 @@ produced from the template: ```jinja {%- set file_name = group.id | snake_case -%} {{- template.set_file_name("span/" ~ file_name ~ ".md") -}} +... +rest of the template +... ``` This mechanism allows the template to dynamically generate the name of the file @@ -91,6 +89,172 @@ The last configuration file loaded will override the previous ones. For the most complex cases, it is possible to define explicitly the list configuration files to load using the `--config` CLI n-ary parameter. +## JQ Filters + +Each template present in the `templates/registry/` directory can be associated +with a JQ filter that will be applied to the resolved semconv registry before being +delivered to the template in the `ctx` variable. The definition of the filters follows +the following syntax: + +```yaml +templates: + - pattern: "**/attributes.j2" + filter: semconv_grouped_attributes + application_mode: each + - pattern: "**/metrics.j2" + filter: semconv_grouped_metrics + application_mode: each + - ... +``` + +In this example, the `attributes.j2` and `metrics.j2` templates are associated with the +`semconv_grouped_attributes` and `semconv_grouped_metrics` JQ filters respectively. These +filters are applied to each object selected by the JQ filter before being delivered to the +template. `semconv_grouped_attributes` returns an array of objects containing the attributes +grouped by namespace. The `application_mode` is set to `each` so that the template is +applied to each object in the array, i.e., to each group of attributes for a given namespace. + +A series of JQ filters dedicated to the manipulation of semantic conventions registries is +available to template authors. + +**Process Registry Attributes** + +The following JQ filter extracts the registry attributes from the resolved registry and +returns a list of registry attributes grouped by namespace and sorted by attribute names. + +```yaml +templates: + - pattern: attributes.j2 + filter: semconv_grouped_attributes + application_mode: each +``` + +The output of the JQ filter has the following structure: + +```json5 +[ + { + "namespace": "user_agent", + "attributes": [ + { + "brief": "Value of the HTTP User-Agent", + "examples": [ ... ], + "name": "user_agent.original", + "namespace": "user_agent", + "requirement_level": "recommended", + "stability": "stable", + "type": "string", + // ... other fields + }, + // ... other attributes in the same namespace + ] + }, + // ... other namespaces +] +``` + +The `semconv_grouped_attributes` function also supports options to exclude specified namespaces +or specific stability levels. The following syntax is supported: + +```yaml +templates: + - pattern: attributes.j2 + filter: > + semconv_grouped_attributes({ + "exclude_namespace": ["url", "network"], + "exclude_stability": ["experimental"] + }) + application_mode: each +``` + +The structure of the output of `semconv_grouped_attributes` with these options is exactly the +same as without the options. The JSON object passed as a parameter describes a series of +options that can easily be extended if needed. Each of these options is optional. + +Technically, the `semconv_grouped_attributes` function is a combination of two semconv +JQ functions: + +```jq +def semconv_grouped_attributes($options): + semconv_attributes($options) + | semconv_group_attributes_by_namespace; + +def semconv_grouped_attributes: semconv_grouped_attributes({}); +``` + +The `semconv_attributes` function extracts the registry attributes and applies the given options. +The `semconv_group_attributes_by_namespace` function groups the attributes by namespace. It's +possible to combine these two functions with your own JQ filters if needed. + +**Process Metrics** + +The following JQ filter extracts the metrics from the resolved registry, sorted by group +namespace and sorted by metric names. + +```yaml +templates: + - pattern: metrics.j2 + filter: semconv_grouped_metrics + application_mode: each +``` + +The output of the JQ filter has the following structure: + +```json5 +[ + { + "namespace": "jvm", + "metrics": [ + { + "attributes": [ ... ], + "brief": "Recent CPU utilization for the process as reported by the JVM.", + "id": "metric.jvm.cpu.recent_utilization", + "instrument": "gauge", + "metric_name": "jvm.cpu.recent_utilization", + "namespace": "jvm", + "note": "The value range is [0.0,1.0]. ...", + "stability": "stable", + "type": "metric", + "unit": "1", + // ... other fields + }, + // ... other metrics in the same namespace + ] + }, + // ... other namespaces +] +``` + +The same options are supported by `semconv_grouped_metrics`, as shown in the following example: + +```yaml +templates: + - pattern: metrics.j2 + filter: > + semconv_grouped_metrics({ + "exclude_namespace": ["url", "network"], + "exclude_stability": ["experimental"] + }) + application_mode: each +``` + +**Other signals** + +The pattern is used for other signals and OTEL entities: +- `semconv_grouped_resources` +- `semconv_grouped_scopes` +- `semconv_grouped_spans` +- `semconv_grouped_events` + +All the `semconv_grouped_<...>` functions are the composition of two functions: +`semconv_<...>` and `semconv_group_<...>_by_namespace`. + +> Note: JQ is a language for querying and transforming structured data. For more +> information, see [JQ Manual](https://jqlang.github.io/jq/manual/). The +> integration into Weaver is done through the Rust library `jaq`, which is a +> reimplementation of JQ in Rust. Most JQ filters are supported. For more +> information, see [jaq GitHub repository](https://github.com/01mf02/jaq). + ## Global Variables All templates have access to the following global variables: @@ -102,7 +266,7 @@ by the command line `--param`, `-D`, or `--params` arguments. - `template`: An object exposing the `set_file_name` method to redefine the name of the file that will be produced from the template. -In the following example, the parameters `incubating` and `excluded` are passed via the command line: +In the following example, the parameter `incubating` is passed via the command line: ```shell weaver registry generate --param incubating=true From 321762e6cd12b231f5c14d63f09367c5ea7c63f6 Mon Sep 17 00:00:00 2001 From: Laurent Querel Date: Thu, 18 Jul 2024 16:22:14 -0700 Subject: [PATCH 20/29] feat(forge): Update documentation --- crates/weaver_forge/README.md | 433 ++++++++++++++++++++-------------- 1 file changed, 259 insertions(+), 174 deletions(-) diff --git a/crates/weaver_forge/README.md b/crates/weaver_forge/README.md index 7268755b..d647fd72 100644 --- a/crates/weaver_forge/README.md +++ b/crates/weaver_forge/README.md @@ -1,102 +1,168 @@ -# Weaver Forge - Template Engine +# Weaver Forge - A Jinja-based Doc/Code Generation Engine +## Table of Contents - [Introduction](#introduction) -- [Template Directory Structure and Naming Conventions](#template-directory-structure-and-naming-conventions) -- [Configuration File - `weaver.yaml`](#configuration-file---weaveryaml) -- [Jinja Filters](#jinja-filters) -- [Jinja Functions](#jinja-functions) -- [Jinja Tests](#jinja-tests) +- [General Concepts](#general-concepts) + - [Template Directory Structure and Naming Conventions](#template-directory-structure-and-naming-conventions) + - [Configuration File - `weaver.yaml`](#configuration-file---weaveryaml) + - [Global Variables](#global-variables) + - [JQ Filters](#jq-filters) +- [Step-by-Step Guide](#step-by-step-guide) + - [Step 1: Setting Up Your Template Directory](#step-1-setting-up-your-template-directory) + - [Step 2: Creating and Configuring `weaver.yaml`](#step-2-creating-and-configuring-weaveryaml) + - [Step 3: Writing Your First Template](#step-3-writing-your-first-template) +- [In-Depth Features](#in-depth-features) + - [JQ Filters Reference](#jq-filters-reference) + - [Jinja Filters Reference](#jinja-filters-reference) + - [Jinja Functions Reference](#jinja-functions-reference) + - [Jinja Tests Reference](#jinja-tests-reference) ## Introduction -OTel Weaver is capable of generating documentation or code from a semantic -convention registry or a telemetry schema (phase 2). 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. +OTel Weaver is capable of generating documentation or code from a semantic convention registry. +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. -The following diagram illustrates the documentation and code generation pipeline -using the OTel Weaver tool: +The following diagram illustrates the documentation and code generation pipeline using the OTel +Weaver tool: ![Weaver Forge](images/artifact-generation-pipeline.svg) -## Template Directory Structure and Naming Conventions +## General Concepts -By default, Weaver expects to find the `templates/` directory in the current directory -with the following structure. The location of this directory can be redefined using -the `-t` or `--templates` CLI parameter. +### Template Directory Structure and Naming Conventions + +By default, Weaver expects to find the `templates/` directory in the current directory with the +following structure. The location of this directory can be redefined using the `-t` or `--templates` +CLI parameter. ```plaintext templates/ - registry/ <-- All templates related to the semantic convention registries - go/ <-- Templates to generate the semantic conventions in Go - ... - html/ <-- Templates to generate the semantic conventions in HTML + registry/ + go/ ... - markdown/ <-- Templates to generate the semantic conventions in markdown + html/ ... - rust/ <-- Templates to generate the semantic conventions in Rust + markdown/ ... - schema/ - sdk-go/ <-- Templates to generate a Go Client SDK derived from the telemetry schema - ... - sdk-rust/ <-- Templates to generate a Rust Client SDK derived from the telemetry schema + rust/ ... + .../ ``` -The command `weaver generate registry rust` will generate the rust -files based on the templates located in the `templates/registry/rust`. +In this example, all the templates that belong to `go` must be defined in `templates/registry/go`, +and all the templates for `rust` must be defined in `templates/registry/rust`, and so on. +`go`, `html`, and `rust` are all generation targets accessible from the `weaver registry generate ` +command. For example, the command `weaver registry generate rust` will generate the rust files +based on the templates located in `templates/registry/rust`. -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. +### Configuration File - `weaver.yaml` -For example, the following snippet redefine the name of the file that will be -produced from the template: +In the simplest case, a configuration file named `weaver.yaml` is searched for by the tool +within the folder containing the templates (e.g. `templates/registry/rust/weaver.yaml`). The +syntax of this configuration file is described here [Weaver Configuration File](/docs/weaver-config.md). -```jinja -{%- set file_name = group.id | snake_case -%} -{{- template.set_file_name("span/" ~ file_name ~ ".md") -}} -... -rest of the template -... +The `weaver.yaml` files are loaded in the following order: + +- `$HOME/.weaver/weaver.yaml` +- `/weaver.yaml`, all intermediate directories containing a `weaver.yaml` file up to the +`templates/registry/` directory. +- `templates/registry//weaver.yaml` + +The last configuration file loaded will override the previous ones. You can explicitly define +the list of configuration files to load using the `--config` CLI n-ary parameter. + +You can use this overriding mechanism to share configuration segments across multiple targets. + +### JQ Filters + +JQ filters are a powerful tool integrated into Weaver to preprocess the data before it is passed +to the templates. Each template in the `templates/registry/` directory can be associated +with a JQ filter, defined in the `weaver.yaml` configuration file. These filters are applied to +the resolved semantic convention registry, allowing you to transform and manipulate the data as +needed before to being processed in the template. + +For example, you can group attributes by namespace or filter out specific stability levels. This +preprocessing ensures that the data is in the correct format and structure when it is accessed +within the corresponding Jinja templates. + +In the following example, the `attributes.j2` template is associated with the `semconv_grouped_attributes` +JQ filter. This filter is applied to each object selected by the JQ filter before being delivered +to the template. `semconv_grouped_attributes` returns an array of objects containing the attributes +grouped by namespace. The `application_mode` is set to `each` so that the template is applied to +each object in the array, i.e., to each group of attributes for a given namespace. + +```yaml +templates: + - pattern: "**/attributes.j2" + filter: semconv_grouped_attributes + application_mode: each + - ... ``` -This mechanism allows the template to dynamically generate the name of the file -to be produced and to organize the generated files in a directory structure of -its choice. +More details [here](#jq-filters-reference). -## Configuration File - `weaver.yaml` +### Global Variables -In the simplest case, a configuration file named `weaver.yaml` is searched for by -the tool within the folder containing the templates. The syntax of this configuration -file is described here [Weaver Configuration File](/docs/weaver-config.md). +All templates have access to the following global variables: -It is possible to utilize the hierarchy of folders containing the targets to share -segments of the configuration common to all targets. Similarly, you can define -Weaver configuration segments in your home directory, i.e., $HOME/.weaver/weaver.yaml. +- `ctx`: The context object that contains the resolved registry or the output of the JQ filter +if defined in the `weaver.yaml` configuration file. +- `params`: The parameters defined in the `weaver.yaml` configuration file or overridden by the +command line `--param`, `-D`, or `--params` arguments. +- `template`: An object exposing various helper functions such as the `set_file_name` method to +redefine the name of the file that will be produced from the template. -By default, the `weaver.yaml` files are loaded in the following order: +## Step-by-Step Guide -- $HOME/.weaver/weaver.yaml -- /weaver.yaml, all intermediate directories containing a `weaver.yaml` file up to the -`templates/registry/` directory. -- `templates/registry//weaver.yaml` +### Step 1: Setting Up Your Template Directory + +Create the directory for your target language: + +```shell +mkdir -p templates/registry/rust +``` + +In this guide, we will use the Rust target as an example. -The last configuration file loaded will override the previous ones. +### Step 2: Creating and Configuring `weaver.yaml` -For the most complex cases, it is possible to define explicitly the list configuration -files to load using the `--config` CLI n-ary parameter. +1. **Create a `weaver.yaml` file in the target directory:** -## JQ Filters +```yaml +text_maps: + rust_types: + int: i64 + double: f64 + boolean: bool + string: String + string[]: Vec + template[string]: String + template[string[]]: Vec + +params: + incubating: true + # ... + +templates: + - pattern: "**/attributes.j2" + filter: semconv_grouped_attributes + application_mode: each + # ... +``` -Each template present in the `templates/registry/` directory can be associated -with a JQ filter that will be applied to the resolved semconv registry before being -delivered to the template in the `ctx` variable. The definition of the filters follows -the following syntax: +In this configuration, we define a set of text maps that map semantic convention types to Rust +types. We also define a set of parameters that can be used in the templates. + +More details on the structure of the configuration file [here](/docs/weaver-config.md). + +2. **Define templates and JQ filters in your `weaver.yaml` file:** ```yaml +# ... + templates: - pattern: "**/attributes.j2" filter: semconv_grouped_attributes @@ -104,34 +170,105 @@ templates: - pattern: "**/metrics.j2" filter: semconv_grouped_metrics application_mode: each - - ... + +# ... +``` + +In this example, the `attributes.j2` template is feed with the output of the `semconv_grouped_attributes` +and `metrics.j2` with the output of the `semconv_grouped_metrics` JQ filter. + +More details on the JQ syntax and custom semconv filters [here](#jq-filters-reference). + +### Step 3: Writing Your First Template + +1. **Create a template file `attributes.j2` in the appropriate directory:** + +```jinja +{%- set file_name = ctx.namespace | snake_case -%} +{{- template.set_file_name("attributes/" ~ file_name ~ ".md") -}} +... +a valid jinja template +... +``` + +The first two lines (optional) specify the name of the file generated from the evaluation of the +current template and the inputs provided by Weaver. In this specific example, an object +containing a `namespace` and an array of `attributes`. + +2. **Use Jinja syntax to define the content and structure of the generated files.** + +Most of the Jinja syntax is supported, as well as a set of common Python functions and custom +filters, function, and tests. See the section [In-Depth Features](#in-depth-features) for more +explanations. + +Use predefined Jinja filters to format and transform data within templates: + +```jinja +{{ attribute.name | snake_case }} +``` + +Access global variables and parameters in your templates: + +```jinja +{% if params.incubating %} +... generate incubating code ... +{% endif %} ``` -In this example, the `attributes.j2` and `metrics.j2` templates are associated with the -`semconv_grouped_attributes` and `semconv_grouped_metrics` JQ filters respectively. These -filters are applied to each object selected by the JQ filter before being delivered to the -template. `semconv_grouped_attributes` returns an array of objects containing the attributes -grouped by namespace. The `application_mode` is set to `each` so that the template is +Use custom Jinja tests to apply logic based on data attributes: + +```jinja +{% if attribute is experimental %} +... generate experimental attribute documentation ... +{% endif %} +``` + +## In-Depth Features + +### JQ Filters Reference + +JQ filters allow template authors to manipulate the data before it is passed to the templates. +The filters can be defined in the `weaver.yaml` configuration file and are applied to the +resolved semantic convention registry. + +Example configuration for JQ filters in `weaver.yaml`: + +```yaml +templates: + - pattern: "**/attributes.j2" + filter: semconv_grouped_attributes + application_mode: each + - pattern: "**/metrics.j2" + filter: semconv_grouped_metrics + application_mode: each + # ... +``` + +In this example, the `attributes.j2` and `metrics.j2` templates are associated with the +`semconv_grouped_attributes` and `semconv_grouped_metrics` JQ filters respectively. These +filters are applied to each object selected by the JQ filter before being delivered to the +template. `semconv_grouped_attributes` returns an array of objects containing the attributes +grouped by namespace. The `application_mode` is set to `each` so that the template is applied to each object in the array, i.e., to each group of attributes for a given namespace. -A series of JQ filters dedicated to the manipulation of semantic conventions registries is +A series of JQ filters dedicated to the manipulation of semantic conventions registries is available to template authors. **Process Registry Attributes** -The following JQ filter extracts the registry attributes from the resolved registry and +The following JQ filter extracts the registry attributes from the resolved registry and returns a list of registry attributes grouped by namespace and sorted by attribute names. -```yaml -templates: +```yaml +templates: - pattern: attributes.j2 filter: semconv_grouped_attributes - application_mode: each -``` + application_mode: each +``` The output of the JQ filter has the following structure: -```json5 +```json5 [ { "namespace": "user_agent", @@ -145,18 +282,18 @@ The output of the JQ filter has the following structure: "stability": "stable", "type": "string", // ... other fields - }, + }, // ... other attributes in the same namespace ] }, // ... other namespaces -] -``` +] +``` -The `semconv_grouped_attributes` function also supports options to exclude specified namespaces +The `semconv_grouped_attributes` function also supports options to exclude specified namespaces or specific stability levels. The following syntax is supported: -```yaml +```yaml templates: - pattern: attributes.j2 filter: > @@ -164,43 +301,43 @@ templates: "exclude_namespace": ["url", "network"], "exclude_stability": ["experimental"] }) - application_mode: each -``` + application_mode: each +``` -The structure of the output of `semconv_grouped_attributes` with these options is exactly the -same as without the options. The JSON object passed as a parameter describes a series of +The structure of the output of `semconv_grouped_attributes` with these options is exactly the +same as without the options. The JSON object passed as a parameter describes a series of options that can easily be extended if needed. Each of these options is optional. -Technically, the `semconv_grouped_attributes` function is a combination of two semconv +Technically, the `semconv_grouped_attributes` function is a combination of two semconv JQ functions: -```jq +```jq def semconv_grouped_attributes($options): semconv_attributes($options) | semconv_group_attributes_by_namespace; -def semconv_grouped_attributes: semconv_grouped_attributes({}); -``` +def semconv_grouped_attributes: semconv_grouped_attributes({}); +``` -The `semconv_attributes` function extracts the registry attributes and applies the given options. -The `semconv_group_attributes_by_namespace` function groups the attributes by namespace. It's +The `semconv_attributes` function extracts the registry attributes and applies the given options. +The `semconv_group_attributes_by_namespace` function groups the attributes by namespace. It's possible to combine these two functions with your own JQ filters if needed. **Process Metrics** -The following JQ filter extracts the metrics from the resolved registry, sorted by group +The following JQ filter extracts the metrics from the resolved registry, sorted by group namespace and sorted by metric names. -```yaml +```yaml templates: - pattern: metrics.j2 filter: semconv_grouped_metrics application_mode: each -``` +``` The output of the JQ filter has the following structure: -```json5 +```json5 [ { "namespace": "jvm", @@ -227,7 +364,7 @@ The output of the JQ filter has the following structure: The same options are supported by `semconv_grouped_metrics`, as shown in the following example: -```yaml +```yaml templates: - pattern: metrics.j2 filter: > @@ -235,8 +372,8 @@ templates: "exclude_namespace": ["url", "network"], "exclude_stability": ["experimental"] }) - application_mode: each -``` + application_mode: each +``` **Other signals** @@ -246,75 +383,23 @@ The pattern is used for other signals and OTEL entities: - `semconv_grouped_spans` - `semconv_grouped_events` -All the `semconv_grouped_<...>` functions are the composition of two functions: +All the `semconv_grouped_<...>` functions are the composition of two functions: `semconv_<...>` and `semconv_group_<...>_by_namespace`. -> Note: JQ is a language for querying and transforming structured data. For more -> information, see [JQ Manual](https://jqlang.github.io/jq/manual/). The -> integration into Weaver is done through the Rust library `jaq`, which is a -> reimplementation of JQ in Rust. Most JQ filters are supported. For more +> Note: JQ is a language for querying and transforming structured data. For more +> information, see [JQ Manual](https://jqlang.github.io/jq/manual/). The +> integration into Weaver is done through the Rust library `jaq`, which is a +> reimplementation of JQ in Rust. Most JQ filters are supported. For more > information, see [jaq GitHub repository](https://github.com/01mf02/jaq). -## Global Variables - -All templates have access to the following global variables: - -- `ctx`: The context object that contains the resolved registry or the output of -the JQ filter if defined in the `weaver.yaml` configuration file. -- `params`: The parameters defined in the `weaver.yaml` configuration file or overridden -by the command line `--param`, `-D`, or `--params` arguments. -- `template`: An object exposing the `set_file_name` method to redefine the name of the -file that will be produced from the template. - -In the following example, the parameter `incubating` is passed via the command line: - -```shell -weaver registry generate --param incubating=true -``` - -The `weaver.yaml` configuration file can specify default values for the parameters and can also -access the parameters in the JQ filters: - -```yaml -params: - incubating: false - registry_prefix: "registry." - -templates: - - pattern: - filter: > - if $incubating then - .groups - | map(select(.type == "attribute_group")) - | map(select(.id | startswith($registry_prefix))) - | map({ id: .id, group_id: .id | split(".") | .[1], attributes: .attributes }) - | group_by(.group_id) - | map({ id: .[0].group_id, attributes: [.[].attributes[]] | sort_by(.id), output: "_incubating/attributes/", stable_package_name: "opentelemetry.semconv.attributes" }) - | map(select(.id as $id | any($excluded[]; . == $id) | not)) - | map(select(.attributes | length > 0)) - else - empty - end - application_mode: single | each -``` - -Jinja templates can also access the parameters: - -```jinja -... -{% if params.incubating %} -... generate incubating code ... -{% endif %} -... -``` - -## Jinja Filters +### Jinja Filters Reference -All the filters available in the MiniJinja template engine are available (see -this online [documentation](https://docs.rs/minijinja/latest/minijinja/filters/index.html)) and the [py_compat](https://github.com/mitsuhiko/minijinja/blob/e8a7ec5198deef7638267f2667714198ef64a1db/minijinja-contrib/src/pycompat.rs) compatibility extensions -that are also enabled in Weaver. +All the filters available in the MiniJinja template engine are available (see +this online [documentation](https://docs.rs/minijinja/latest/minijinja/filters/index.html)) and +the [py_compat](https://github.com/mitsuhiko/minijinja/blob/e8a7ec5198deef7638267f2667714198ef64a1db/minijinja-contrib/src/pycompat.rs) +compatibility extensions that are also enabled in Weaver. -In addition, OTel Weaver provides a set of custom filters to facilitate the +In addition, OTel Weaver provides a set of custom filters to facilitate the generation of documentation and code. The following filters are available: @@ -337,8 +422,8 @@ The following filters are available: - `acronym`: Replaces acronyms in the input string with the full name defined in the `acronyms` section of the `weaver.yaml` configuration file. - `split_id`: Splits a string by '.' creating a list of nested ids. - `comment_with_prefix(prefix)`: Outputs a multiline comment with the given prefix. -- `flatten`: Converts a List of Lists into a single list with all elements. -e.g. \[\[a,b\],\[c\]\] => \[a,b,c\] +- `flatten`: Converts a List of Lists into a single list with all elements. + e.g. \[\[a,b\],\[c\]\] => \[a,b,c\] - `attribute_sort`: Sorts a list of `Attribute`s by requirement level, then name. - `metric_namespace`: Converts registry.{namespace}.{other}.{components} to {namespace}. - `attribute_registry_file`: Converts registry.{namespace}.{other}.{components} to attributes-registry/{namespace}.md (kebab-case namespace). @@ -350,9 +435,9 @@ e.g. \[\[a,b\],\[c\]\] => \[a,b,c\] - `instantiated_type`: Filters a type to return the instantiated type. - `enum_type`: Filters a type to return the enum type or an error if the type is not an enum. - `markdown_to_html`: Converts a markdown string to an HTML string. -- `map_text`: Converts an input into a string based on the `text_maps` section of the `weaver.yaml` configuration file -and a named text_map. The first parameter is the name of the text_map (required). The second parameter is the default -value if the name of the text map or the input are not found in the `text_maps` section (optional). +- `map_text`: Converts an input into a string based on the `text_maps` section of the `weaver.yaml` configuration file + and a named text_map. The first parameter is the name of the text_map (required). The second parameter is the default + value if the name of the text map or the input are not found in the `text_maps` section (optional). - `ansi_black`: Format a text using the black ansi code. - `ansi_red`: Format a text using the red ansi code. - `ansi_green`: Format a text using the green ansi code. @@ -392,20 +477,20 @@ value if the name of the text map or the input are not found in the `text_maps` > Please open an issue if you have any suggestions for new filters. They are easy to implement. -## Jinja Functions +### Jinja Functions Reference -All the functions available in the MiniJinja template engine are available (see +All the functions available in the MiniJinja template engine are available (see this online [documentation](https://docs.rs/minijinja/latest/minijinja/functions/index.html)). -Right now, OTel Weaver does not provide any custom functions but feel free to +Right now, OTel Weaver does not provide any custom functions but feel free to open an issue if you have any suggestions. They are easy to implement. -## Jinja Tests +### Jinja Tests Reference -All the tests available in the MiniJinja template engine are available (see +All the tests available in the MiniJinja template engine are available (see this online [documentation](https://docs.rs/minijinja/latest/minijinja/tests/index.html)). -In addition, OTel Weaver provides a set of custom tests to facilitate the +In addition, OTel Weaver provides a set of custom tests to facilitate the generation of assets. - `stable`: Tests if an `Attribute` is stable. @@ -416,4 +501,4 @@ generation of assets. - `template_type`: Tests if a type is a template type (i.e.: template[]). - `enum_type`: Tests if a type is an enum type. -> Please open an issue if you have any suggestions for new tests. They are easy to implement. +> Please open an issue if you have any suggestions for new tests. They are easy to implement. \ No newline at end of file From c344aa885ce35c7b47c8d1cd53c33b3df3ffa05b Mon Sep 17 00:00:00 2001 From: Laurent Querel Date: Thu, 18 Jul 2024 16:52:44 -0700 Subject: [PATCH 21/29] feat(forge): Introduce concept of JQ package to import JQ functions --- Cargo.lock | 1 + crates/weaver_forge/Cargo.toml | 5 ++- crates/weaver_forge/README.md | 12 +++--- crates/weaver_forge/src/error.rs | 9 ++++ crates/weaver_forge/src/filter.rs | 41 +++++++------------ crates/weaver_forge/src/lib.rs | 34 ++++++++++++++- .../templates/semconv_jq_fn/weaver.yaml | 8 ++-- src/registry/generate.rs | 5 ++- src/registry/update_markdown.rs | 6 ++- 9 files changed, 77 insertions(+), 44 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 99b746c2..6dbb00e7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4124,6 +4124,7 @@ dependencies = [ "jaq-interpret", "jaq-parse", "jaq-std", + "jaq-syn", "markdown", "miette", "minijinja", diff --git a/crates/weaver_forge/Cargo.toml b/crates/weaver_forge/Cargo.toml index 3116bc2d..7baa1c40 100644 --- a/crates/weaver_forge/Cargo.toml +++ b/crates/weaver_forge/Cargo.toml @@ -21,10 +21,11 @@ weaver_semconv = { path = "../weaver_semconv" } minijinja = { version = "2.0.3", features = ["loader", "custom_syntax", "debug", "json", "urlencode", "macros"] } minijinja-contrib = { version="2.0.3", features = ["pycompat"] } convert_case = "0.6.0" -jaq-core = "1.2.1" +jaq-core = "1.5.0" jaq-std = "1.5.1" -jaq-interpret = "1.2.1" +jaq-interpret = "1.5.0" jaq-parse = "1.0.2" +jaq-syn = "1.1.0" indexmap = "2.2.6" regex = "1.10.5" markdown = "=1.0.0-alpha.18" diff --git a/crates/weaver_forge/README.md b/crates/weaver_forge/README.md index d647fd72..6c2b92bf 100644 --- a/crates/weaver_forge/README.md +++ b/crates/weaver_forge/README.md @@ -96,7 +96,7 @@ each object in the array, i.e., to each group of attributes for a given namespac ```yaml templates: - - pattern: "**/attributes.j2" + - pattern: "attributes.j2" # glob patterns are supported filter: semconv_grouped_attributes application_mode: each - ... @@ -147,7 +147,7 @@ params: # ... templates: - - pattern: "**/attributes.j2" + - pattern: "attributes.j2" filter: semconv_grouped_attributes application_mode: each # ... @@ -164,10 +164,10 @@ More details on the structure of the configuration file [here](/docs/weaver-conf # ... templates: - - pattern: "**/attributes.j2" + - pattern: "attributes.j2" filter: semconv_grouped_attributes application_mode: each - - pattern: "**/metrics.j2" + - pattern: "metrics.j2" filter: semconv_grouped_metrics application_mode: each @@ -235,10 +235,10 @@ Example configuration for JQ filters in `weaver.yaml`: ```yaml templates: - - pattern: "**/attributes.j2" + - pattern: "attributes.j2" filter: semconv_grouped_attributes application_mode: each - - pattern: "**/metrics.j2" + - pattern: "metrics.j2" filter: semconv_grouped_metrics application_mode: each # ... diff --git a/crates/weaver_forge/src/error.rs b/crates/weaver_forge/src/error.rs index 9c8d49d7..4af4405a 100644 --- a/crates/weaver_forge/src/error.rs +++ b/crates/weaver_forge/src/error.rs @@ -131,6 +131,15 @@ pub enum Error { error: String, }, + /// Import JQ package error. + #[error("Import JQ package '{package}' failed: {error}")] + ImportError { + /// Package that caused the error. + package: String, + /// Error message. + error: String, + }, + /// Invalid template pattern. #[error("Invalid template pattern: {error}")] InvalidTemplatePattern { diff --git a/crates/weaver_forge/src/filter.rs b/crates/weaver_forge/src/filter.rs index 803c82a4..5cf6bf94 100644 --- a/crates/weaver_forge/src/filter.rs +++ b/crates/weaver_forge/src/filter.rs @@ -6,8 +6,7 @@ use crate::error::Error; use core::fmt; use jaq_interpret::{Ctx, FilterT, RcIter, Val}; use std::fmt::Debug; - -const SEMCONV_JQ: &str = include_str!("../../../defaults/jq/semconv.jq"); +use jaq_syn::Def; /// A filter that can be applied to a JSON value. pub struct Filter { @@ -20,25 +19,15 @@ impl Filter { /// expression is invalid. /// The vars parameter is a list of variable names that can be used in the /// filter expression. - pub fn try_new(filter_expr: &str, vars: Vec) -> Result { + pub fn try_new( + filter_expr: &str, + vars: Vec, + defs: Vec + ) -> Result { let mut ctx = jaq_interpret::ParseCtx::new(vars); ctx.insert_natives(jaq_core::core()); ctx.insert_defs(jaq_std::std()); - // ToDO LQ Move this as a parameter - let (defs, errs) = jaq_parse::parse(SEMCONV_JQ, jaq_parse::defs()); - if !errs.is_empty() { - return Err(Error::CompoundError( - errs.into_iter() - .map(|e| Error::FilterError { - filter: filter_expr.to_owned(), - error: e.to_string(), - }) - .collect(), - )); - } - if let Some(defs) = defs { - ctx.insert_defs(defs); - } + ctx.insert_defs(defs); let (parsed_expr, errs) = jaq_parse::parse(filter_expr, jaq_parse::main()); @@ -103,15 +92,15 @@ mod tests { #[test] fn test_filter() { - let filter = super::Filter::try_new("true", Vec::new()).unwrap(); + let filter = super::Filter::try_new("true", Vec::new(), Vec::new()).unwrap(); let result = filter.apply(serde_json::json!({}), Vec::new()).unwrap(); assert_eq!(result, serde_json::json!(true)); - let filter = super::Filter::try_new(".", Vec::new()).unwrap(); + let filter = super::Filter::try_new(".", Vec::new(), Vec::new()).unwrap(); let result = filter.apply(serde_json::json!({}), Vec::new()).unwrap(); assert_eq!(result, serde_json::Value::Object(serde_json::Map::new())); - let filter = super::Filter::try_new(".", Vec::new()).unwrap(); + let filter = super::Filter::try_new(".", Vec::new(), Vec::new()).unwrap(); let result = filter .apply( serde_json::json!({ @@ -129,7 +118,7 @@ mod tests { }) ); - let filter = super::Filter::try_new(".key1", Vec::new()).unwrap(); + let filter = super::Filter::try_new(".key1", Vec::new(), Vec::new()).unwrap(); let result = filter .apply( serde_json::json!({ @@ -141,7 +130,7 @@ mod tests { .unwrap(); assert_eq!(result, serde_json::json!(1)); - let filter = super::Filter::try_new(".[\"key1\"]", Vec::new()).unwrap(); + let filter = super::Filter::try_new(".[\"key1\"]", Vec::new(), Vec::new()).unwrap(); let result = filter .apply( serde_json::json!({ @@ -155,7 +144,7 @@ mod tests { let vars = vec!["key".to_owned()]; let ctx = vec![Val::from(serde_json::Value::String("key1".to_owned()))]; - let filter = super::Filter::try_new(".[$key]", vars).unwrap(); + let filter = super::Filter::try_new(".[$key]", vars, Vec::new()).unwrap(); let result = filter .apply( serde_json::json!({ @@ -180,13 +169,13 @@ end"#; let vars = vec!["incubating".to_owned()]; // When incubating is true, the entire input is returned. let ctx = vec![Val::from(serde_json::Value::Bool(true))]; - let filter = super::Filter::try_new(jq_filter, vars.clone()).unwrap(); + let filter = super::Filter::try_new(jq_filter, vars.clone(), Vec::new()).unwrap(); let result = filter.apply(input.clone(), ctx).unwrap(); assert_eq!(result, input); // When incubating = false the filter should return an empty array let ctx = vec![Val::from(serde_json::Value::Bool(false))]; - let filter = super::Filter::try_new(jq_filter, vars).unwrap(); + let filter = super::Filter::try_new(jq_filter, vars, Vec::new()).unwrap(); let result = filter.apply(input.clone(), ctx).unwrap(); assert_eq!(result, serde_json::Value::Null); } diff --git a/crates/weaver_forge/src/lib.rs b/crates/weaver_forge/src/lib.rs index 389083cd..d4e1d03b 100644 --- a/crates/weaver_forge/src/lib.rs +++ b/crates/weaver_forge/src/lib.rs @@ -45,6 +45,9 @@ pub mod registry; /// Name of the Weaver configuration file. pub const WEAVER_YAML: &str = "weaver.yaml"; +/// Default jq filter for the semantic convention registry. +pub const SEMCONV_JQ: &str = include_str!("../../../defaults/jq/semconv.jq"); + // Definition of the Jinja syntax delimiters /// Constant defining the start of a Jinja block. @@ -148,6 +151,9 @@ pub struct TemplateEngine { /// Target configuration target_config: WeaverConfig, + + /// The jq packages that have been imported. + jq_packages: Vec, } /// Global context for the template engine. @@ -198,7 +204,30 @@ impl TemplateEngine { Self { file_loader: Arc::new(loader), target_config: config, + jq_packages: Vec::new(), + } + } + + /// Import a jq package into the template engine. + /// A jq package is a collection of jq functions that can be used in the templates. + pub fn import_jq_package(&mut self, package_content: &str) -> Result<(), Error> { + let (defs, errs) = jaq_parse::parse(package_content, jaq_parse::defs()); + + if !errs.is_empty() { + return Err(Error::CompoundError( + errs.into_iter() + .map(|e| Error::ImportError { + package: package_content.to_owned(), + error: e.to_string(), + }) + .collect(), + )); } + + if let Some(def) = defs { + self.jq_packages.extend(def); + } + Ok(()) } /// Generate a template snippet from serializable context and a snippet identifier. @@ -295,7 +324,7 @@ impl TemplateEngine { .into_par_iter() .filter_map(|relative_path| { for template in tmpl_matcher.matches(relative_path.clone()) { - let filter = match Filter::try_new(template.filter.as_str(), jq_vars.clone()) { + let filter = match Filter::try_new(template.filter.as_str(), jq_vars.clone(), self.jq_packages.clone()) { Ok(filter) => filter, Err(e) => return Some(e), }; @@ -834,7 +863,8 @@ mod tests { .expect("Failed to create file system loader"); let config = WeaverConfig::try_from_loader(&loader).expect("Failed to load `templates/weaver.yaml`"); - let engine = super::TemplateEngine::new(config, loader, Params::default()); + let mut engine = super::TemplateEngine::new(config, loader, Params::default()); + engine.import_jq_package(super::SEMCONV_JQ).unwrap(); let registry_id = "default"; let mut registry = SemConvRegistry::try_from_path_pattern(registry_id, "data/*.yaml") .expect("Failed to load registry"); diff --git a/crates/weaver_forge/templates/semconv_jq_fn/weaver.yaml b/crates/weaver_forge/templates/semconv_jq_fn/weaver.yaml index 4de05adf..1907f262 100644 --- a/crates/weaver_forge/templates/semconv_jq_fn/weaver.yaml +++ b/crates/weaver_forge/templates/semconv_jq_fn/weaver.yaml @@ -2,21 +2,21 @@ params: exclude_stability: ["experimental"] templates: - - pattern: "**/semconv_attributes.json" + - pattern: semconv_attributes.json filter: semconv_attributes application_mode: single - - pattern: "**/semconv_grouped_attributes.json" + - pattern: semconv_grouped_attributes.json filter: > semconv_grouped_attributes application_mode: single - - pattern: "**/semconv_grouped_attributes_without_experimental.json" + - pattern: semconv_grouped_attributes_without_experimental.json filter: > semconv_grouped_attributes({ "exclude_namespace": ["url", "network"], "exclude_stability": ["experimental"] }) application_mode: single - - pattern: "**/semconv_metrics.json" + - pattern: semconv_metrics.json filter: > semconv_grouped_metrics({"exclude_stability": ["experimental"]}) application_mode: single diff --git a/src/registry/generate.rs b/src/registry/generate.rs index 2a44fdc2..330a1635 100644 --- a/src/registry/generate.rs +++ b/src/registry/generate.rs @@ -13,7 +13,7 @@ use weaver_common::Logger; use weaver_forge::config::{Params, WeaverConfig}; use weaver_forge::file_loader::{FileLoader, FileSystemFileLoader}; use weaver_forge::registry::ResolvedRegistry; -use weaver_forge::{OutputDirective, TemplateEngine}; +use weaver_forge::{OutputDirective, SEMCONV_JQ, TemplateEngine}; use weaver_semconv::registry::SemConvRegistry; use crate::registry::{Error, RegistryArgs}; @@ -119,7 +119,8 @@ pub(crate) fn command( } else { WeaverConfig::try_from_path(loader.root()) }?; - let engine = TemplateEngine::new(config, loader, params); + let mut engine = TemplateEngine::new(config, loader, params); + engine.import_jq_package(SEMCONV_JQ)?; let template_registry = ResolvedRegistry::try_from_resolved_registry( schema diff --git a/src/registry/update_markdown.rs b/src/registry/update_markdown.rs index abfafc9b..1bd179d3 100644 --- a/src/registry/update_markdown.rs +++ b/src/registry/update_markdown.rs @@ -12,7 +12,7 @@ use weaver_common::diagnostic::DiagnosticMessages; use weaver_common::Logger; use weaver_forge::config::{Params, WeaverConfig}; use weaver_forge::file_loader::FileSystemFileLoader; -use weaver_forge::TemplateEngine; +use weaver_forge::{SEMCONV_JQ, TemplateEngine}; use weaver_semconv_gen::{update_markdown, SnippetGenerator}; /// Parameters for the `registry update-markdown` sub-command @@ -72,7 +72,9 @@ pub(crate) fn command( target, )?; let config = WeaverConfig::try_from_loader(&loader)?; - Some(TemplateEngine::new(config, loader, Params::default())) + let mut engine = TemplateEngine::new(config, loader, Params::default()); + engine.import_jq_package(SEMCONV_JQ)?; + Some(engine) } }; From ebae3461fa2ecaf19497264bc7afae09845c2163 Mon Sep 17 00:00:00 2001 From: Laurent Querel Date: Fri, 19 Jul 2024 13:31:40 -0700 Subject: [PATCH 22/29] feat(forge): Simplify the Rust example with the new filters. --- Cargo.lock | 44 ++++---- crates/weaver_codegen_test/build.rs | 6 +- .../templates/registry/alt_weaver.yaml | 1 + .../registry/rust/attributes/attributes.rs.j2 | 8 +- .../registry/rust/attributes/mod.rs.j2 | 6 +- .../registry/rust/metrics/metrics.rs.j2 | 4 +- .../templates/registry/rust/metrics/mod.rs.j2 | 6 +- .../templates/registry/rust/weaver.yaml | 100 +----------------- .../templates/registry/weaver.yaml | 1 + crates/weaver_forge/src/error.rs | 9 ++ crates/weaver_forge/src/filter.rs | 8 +- crates/weaver_forge/src/lib.rs | 48 +++++++-- defaults/jq/semconv.jq | 10 ++ src/registry/generate.rs | 2 +- src/registry/update_markdown.rs | 2 +- 15 files changed, 99 insertions(+), 156 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6dbb00e7..328dc95b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -293,9 +293,9 @@ checksum = "df8670b8c7b9dae1793364eafadf7239c40d669904660c5960d74cfd80b46a53" [[package]] name = "castaway" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a17ed5635fc8536268e5d4de1e22e81ac34419e5f052d4d51f4e01dcc263fcc" +checksum = "0abae9be0aaf9ea96a3b1b8b1b55c602ca751eba1b1500220cea4ecbafe7c0d5" dependencies = [ "rustversion", ] @@ -1338,9 +1338,9 @@ dependencies = [ [[package]] name = "gix-path" -version = "0.10.8" +version = "0.10.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca987128ffb056d732bd545db5db3d8b103d252fbf083c2567bb0796876619a4" +checksum = "8d23d5bbda31344d8abc8de7c075b3cf26e5873feba7c4a15d916bce67382bd9" dependencies = [ "bstr", "gix-trace", @@ -1925,15 +1925,6 @@ dependencies = [ "either", ] -[[package]] -name = "itertools" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" -dependencies = [ - "either", -] - [[package]] name = "itertools" version = "0.13.0" @@ -2462,9 +2453,9 @@ dependencies = [ [[package]] name = "opentelemetry_sdk" -version = "0.24.0" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a48618fd69580af9aeb349369c07f7ca9d3c30c3cd91dc274f2882a7a5a18599" +checksum = "692eac490ec80f24a17828d49b40b60f5aeaccdfe6a503f939713afd22bc28df" dependencies = [ "async-trait", "futures-channel", @@ -3383,9 +3374,9 @@ checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" [[package]] name = "stability" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ff9eaf853dec4c8802325d8b6d3dffa86cc707fd7a1a4cdbf416e13b061787a" +checksum = "d904e7009df136af5297832a3ace3370cd14ff1546a232f4f185036c2736fcac" dependencies = [ "quote", "syn", @@ -3541,18 +3532,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.62" +version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2675633b1499176c2dff06b0856a27976a8f9d436737b4cf4f312d4d91d8bbb" +checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.62" +version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d20468752b09f49e909e55a5d338caa8bedf615594e9d80bc4c565d30faf798c" +checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" dependencies = [ "proc-macro2", "quote", @@ -3609,9 +3600,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.38.0" +version = "1.38.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba4f4a02a7a80d6f274636f0aa95c7e383b912d41fe721a31f29e29698585a4a" +checksum = "eb2caba9f80616f438e09748d5acda951967e1ea58508ef53d9c6402485a46df" dependencies = [ "backtrace", "bytes", @@ -3817,11 +3808,12 @@ checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" [[package]] name = "unicode-truncate" -version = "1.0.0" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a5fbabedabe362c618c714dbefda9927b5afc8e2a8102f47f081089a9019226" +checksum = "b3644627a5af5fa321c95b9b235a72fd24cd29c648c2c379431e6628655627bf" dependencies = [ - "itertools 0.12.1", + "itertools 0.13.0", + "unicode-segmentation", "unicode-width", ] diff --git a/crates/weaver_codegen_test/build.rs b/crates/weaver_codegen_test/build.rs index 0a958927..bca904ca 100644 --- a/crates/weaver_codegen_test/build.rs +++ b/crates/weaver_codegen_test/build.rs @@ -16,7 +16,7 @@ use weaver_common::{in_memory, Logger}; use weaver_forge::config::{Params, WeaverConfig}; use weaver_forge::file_loader::FileSystemFileLoader; use weaver_forge::registry::ResolvedRegistry; -use weaver_forge::{OutputDirective, TemplateEngine}; +use weaver_forge::{OutputDirective, SEMCONV_JQ, TemplateEngine}; use weaver_resolver::SchemaResolver; use weaver_semconv::path::RegistryPath; use weaver_semconv::registry::SemConvRegistry; @@ -53,7 +53,9 @@ fn main() { .unwrap_or_else(|e| process_error(&logger, e)); let config = WeaverConfig::try_from_path("./templates/registry/rust") .unwrap_or_else(|e| process_error(&logger, e)); - let engine = TemplateEngine::new(config, loader, Params::default()); + let mut engine = TemplateEngine::new(config, loader, Params::default()); + engine.import_jq_package(SEMCONV_JQ) + .unwrap_or_else(|e| process_error(&logger, e)); let template_registry = ResolvedRegistry::try_from_resolved_registry( schema .registry(REGISTRY_ID) diff --git a/crates/weaver_codegen_test/templates/registry/alt_weaver.yaml b/crates/weaver_codegen_test/templates/registry/alt_weaver.yaml index 21edcbda..1e0eba00 100644 --- a/crates/weaver_codegen_test/templates/registry/alt_weaver.yaml +++ b/crates/weaver_codegen_test/templates/registry/alt_weaver.yaml @@ -2,4 +2,5 @@ params: attributes: true metrics: false # With this alternate configuration, the metrics are disabled + exclude_deprecated: true registry_prefix: "registry." diff --git a/crates/weaver_codegen_test/templates/registry/rust/attributes/attributes.rs.j2 b/crates/weaver_codegen_test/templates/registry/rust/attributes/attributes.rs.j2 index ee6de050..e62ec38b 100644 --- a/crates/weaver_codegen_test/templates/registry/rust/attributes/attributes.rs.j2 +++ b/crates/weaver_codegen_test/templates/registry/rust/attributes/attributes.rs.j2 @@ -1,4 +1,4 @@ -{%- set file_name = ctx.id | attribute_registry_namespace | snake_case -%} +{%- set file_name = ctx.namespace | snake_case -%} {{- template.set_file_name("attributes/" ~ file_name ~ ".rs") -}} {%- import 'attribute_macros.j2' as attribute_macros -%} @@ -7,12 +7,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -{{ ctx.brief | comment_with_prefix("//! ") }} -{%- if ctx.note %} -//! -//! Notes: -{{ ctx.note | comment_with_prefix("//! ") }} -{%- endif %} //! DO NOT EDIT, THIS FILE HAS BEEN GENERATED BY WEAVER {%- for attribute in ctx.attributes | attribute_sort %} diff --git a/crates/weaver_codegen_test/templates/registry/rust/attributes/mod.rs.j2 b/crates/weaver_codegen_test/templates/registry/rust/attributes/mod.rs.j2 index d5dc5f2d..3718a545 100644 --- a/crates/weaver_codegen_test/templates/registry/rust/attributes/mod.rs.j2 +++ b/crates/weaver_codegen_test/templates/registry/rust/attributes/mod.rs.j2 @@ -12,9 +12,9 @@ use opentelemetry::{Key, KeyValue, StringValue}; pub const ATTRIBUTES_PARAM: bool = {{ params.attributes }}; -{% for group in ctx %} -/// Attributes for the `{{ group.id | attribute_registry_namespace }}` namespace. -pub mod {{ group.id | attribute_registry_namespace | snake_case }}; +{% for attributes_namespace in ctx %} +/// Attributes for the `{{ attributes_namespace.namespace }}` namespace. +pub mod {{ attributes_namespace.namespace | snake_case }}; {%- endfor %} /// A typed attribute key. diff --git a/crates/weaver_codegen_test/templates/registry/rust/metrics/metrics.rs.j2 b/crates/weaver_codegen_test/templates/registry/rust/metrics/metrics.rs.j2 index b407e6d5..d6112fa5 100644 --- a/crates/weaver_codegen_test/templates/registry/rust/metrics/metrics.rs.j2 +++ b/crates/weaver_codegen_test/templates/registry/rust/metrics/metrics.rs.j2 @@ -1,4 +1,4 @@ -{%- set file_name = ctx.group_id | snake_case -%} +{%- set file_name = ctx.namespace | snake_case -%} {{- template.set_file_name("metrics/" ~ file_name ~ ".rs") -}} /* @@ -8,6 +8,6 @@ //! DO NOT EDIT, THIS FILE HAS BEEN GENERATED BY WEAVER -{%- for metric in ctx.groups %} +{%- for metric in ctx.metrics %} {% include "metrics/instruments/" ~ metric.instrument ~ ".j2" %} {%- endfor %} \ No newline at end of file diff --git a/crates/weaver_codegen_test/templates/registry/rust/metrics/mod.rs.j2 b/crates/weaver_codegen_test/templates/registry/rust/metrics/mod.rs.j2 index 1e9be895..5201a01d 100644 --- a/crates/weaver_codegen_test/templates/registry/rust/metrics/mod.rs.j2 +++ b/crates/weaver_codegen_test/templates/registry/rust/metrics/mod.rs.j2 @@ -10,9 +10,9 @@ pub const METRICS_PARAM: bool = {{ params.metrics }}; -{% for group in ctx %} -/// Metrics for the `{{ group.id | metric_namespace }}` namespace. -pub mod {{ group.id | metric_namespace | snake_case }}; +{% for attributes_namespace in ctx %} +/// Metrics for the `{{ attributes_namespace.namespace }}` namespace. +pub mod {{ attributes_namespace.namespace | snake_case }}; {%- endfor %} /// A trait implemented by histogram providers (e.g. `Meter`). diff --git a/crates/weaver_codegen_test/templates/registry/rust/weaver.yaml b/crates/weaver_codegen_test/templates/registry/rust/weaver.yaml index 46846fe2..9892a42c 100644 --- a/crates/weaver_codegen_test/templates/registry/rust/weaver.yaml +++ b/crates/weaver_codegen_test/templates/registry/rust/weaver.yaml @@ -15,127 +15,35 @@ templates: - pattern: lib.rs filter: . application_mode: single - - # Templates for the `attribute_group` group type - pattern: attributes/mod.rs.j2 - # The following JQ filter extracts the id, type, brief, and prefix of groups matching the following criteria: - # - groups with an id starting with the prefix `registry.` - # - groups of the type `attribute_group`. - # - groups are deduplicated by namespace. - # - groups are sorted by namespace. filter: > if $attributes then - semconv_attributes - | unique_by(.group_id) + semconv_grouped_attributes($params) else empty end application_mode: single - pattern: attributes/attributes.rs.j2 - # The following JQ filter extracts the id, type, brief, prefix, and attributes of groups matching the following - # criteria: - # - groups with an id starting with the prefix `registry.` - # - groups of the type `attribute_group`. - # - groups are sorted by namespace. filter: > if $attributes then - semconv_grouped_attributes - | map({ - id: (map(select(.id | endswith(".deprecated") | not)) | first).id, - type: (map(select(.id | endswith(".deprecated") | not)) | first).type, - brief: (map(select(.id | endswith(".deprecated") | not)) | first).brief, - prefix: (map(select(.id | endswith(".deprecated") | not)) | first).prefix, - attributes: map(.attributes) | add - }) + semconv_grouped_attributes($params) else empty end application_mode: each - - # Templates for the `metric` group type - pattern: metrics/mod.rs.j2 - # The following JQ filter extracts the id, type, brief, and prefix of groups matching the following criteria: - # - groups with an id starting with the prefix `metric.` - # - groups of the type `metric`. - # - groups are deduplicated by namespace. - # - groups are sorted by prefix. filter: > if $metrics then - semconv_metrics - | unique_by(.group_id) + semconv_grouped_metrics else empty end application_mode: single - pattern: metrics/metrics.rs.j2 - # The following JQ filter extracts the id, type, brief, prefix, and attributes of groups matching the following - # criteria: - # - groups with an id starting with the prefix `metric.` - # - groups of the type `metric`. - # - groups are sorted by namespace. filter: > if $metrics then semconv_grouped_metrics else empty end - application_mode: each - - -# .groups -# | map(select(.type == "attribute_group")) -# | map(select(.id | startswith("registry"))) -# | group_by(.id | split(".") | .[1]) -# | map({id: .[0].id | split(".") | .[1], groups: .}) - -# Other examples of filters - -# The following JQ filter extracts the id, type, brief, and prefix of groups matching the following criteria: -# - groups with an id starting with the prefix `registry.` -# - groups of the type `attribute_group`. -# - groups with a well-defined prefix. -# - groups with a non-empty list of attributes that are neither deprecated nor experimental. -# - groups are deduplicated by prefix. -# - groups are sorted by prefix. -# filter: > -# .groups -# | map(select(.id | startswith("registry."))) -# | map(select(.type == "attribute_group" and .prefix != null and .prefix != "") -# | { -# id, -# type, -# brief, -# prefix, -# attributes: (.attributes -# | map(select(.stability == "experimental" and .deprecated | not)))}) -# | map(select(.attributes | length > 0)) -# | map( -# { -# id, -# type, -# brief, -# prefix -# } -# ) -# | unique_by(.prefix) -# | sort_by(.prefix) - - -# The following JQ filter extracts the id, type, brief, prefix, and attributes of groups matching the following -# criteria: -# - groups with an id starting with the prefix `registry.` -# - groups of the type `attribute_group`. -# - groups with a well-defined prefix. -# - groups with a non-empty list of attributes that are neither deprecated nor experimental. -# - groups are sorted by prefix. -# filter: > -# .groups -# | map(select(.id | startswith("registry."))) -# | map(select(.type == "attribute_group" and .prefix != null and .prefix != "") -# | { -# id, -# type, -# brief, -# prefix, -# attributes: (.attributes | map(select(.stability == "experimental" and .deprecated | not)))}) -# | sort_by(.prefix // empty) \ No newline at end of file + application_mode: each \ No newline at end of file diff --git a/crates/weaver_codegen_test/templates/registry/weaver.yaml b/crates/weaver_codegen_test/templates/registry/weaver.yaml index 1361e29d..f667b3c0 100644 --- a/crates/weaver_codegen_test/templates/registry/weaver.yaml +++ b/crates/weaver_codegen_test/templates/registry/weaver.yaml @@ -2,4 +2,5 @@ params: attributes: true metrics: true + exclude_deprecated: true registry_prefix: "registry." diff --git a/crates/weaver_forge/src/error.rs b/crates/weaver_forge/src/error.rs index 4af4405a..301e4937 100644 --- a/crates/weaver_forge/src/error.rs +++ b/crates/weaver_forge/src/error.rs @@ -154,6 +154,15 @@ pub enum Error { error: String, }, + /// Duplicate parameter key. + #[error("Duplicate parameter key '{key}': {error}")] + DuplicateParamKey { + /// The duplicate key. + key: String, + /// Error message. + error: String, + }, + /// Invalid case convention. #[error("`{case}` is not a valid case convention. Valid case conventions are: lower_case, upper_case, title_case, snake_case, kebab_case, camel_case, pascal_case, screaming_snake_case, and screaming_kebab_case.")] InvalidCaseConvention { diff --git a/crates/weaver_forge/src/filter.rs b/crates/weaver_forge/src/filter.rs index 5cf6bf94..29dcad30 100644 --- a/crates/weaver_forge/src/filter.rs +++ b/crates/weaver_forge/src/filter.rs @@ -5,8 +5,8 @@ use crate::error::Error; use core::fmt; use jaq_interpret::{Ctx, FilterT, RcIter, Val}; -use std::fmt::Debug; use jaq_syn::Def; +use std::fmt::Debug; /// A filter that can be applied to a JSON value. pub struct Filter { @@ -19,11 +19,7 @@ impl Filter { /// expression is invalid. /// The vars parameter is a list of variable names that can be used in the /// filter expression. - pub fn try_new( - filter_expr: &str, - vars: Vec, - defs: Vec - ) -> Result { + pub fn try_new(filter_expr: &str, vars: Vec, defs: Vec) -> Result { let mut ctx = jaq_interpret::ParseCtx::new(vars); ctx.insert_natives(jaq_core::core()); ctx.insert_defs(jaq_std::std()); diff --git a/crates/weaver_forge/src/lib.rs b/crates/weaver_forge/src/lib.rs index d4e1d03b..46b3ba08 100644 --- a/crates/weaver_forge/src/lib.rs +++ b/crates/weaver_forge/src/lib.rs @@ -287,9 +287,31 @@ impl TemplateEngine { let mut errors = Vec::new(); + let params = if let Some(mut params) = self.target_config.params.clone() { + match serde_yaml::to_value(&self.target_config.params) { + Ok(value) => { + let prev = params.insert("params".to_owned(), value); + if prev.is_some() { + errors.push(Error::DuplicateParamKey { + key: "params".to_owned(), + error: "The parameter `params` is a reserved parameter name".to_string() + }); + } + } + Err(e) => { + errors.push(ContextSerializationFailed { + error: e.to_string(), + }); + } + } + Some(params) + } else { + None + }; + // Build JQ context from the params. let (jq_vars, jq_ctx): (Vec, Vec) = - self.target_config.params.as_ref().map_or_else( + params.as_ref().map_or_else( || (Vec::new(), Vec::new()), // If self.target_config.params is None, return empty vectors |params| { params @@ -324,7 +346,11 @@ impl TemplateEngine { .into_par_iter() .filter_map(|relative_path| { for template in tmpl_matcher.matches(relative_path.clone()) { - let filter = match Filter::try_new(template.filter.as_str(), jq_vars.clone(), self.jq_packages.clone()) { + let filter = match Filter::try_new( + template.filter.as_str(), + jq_vars.clone(), + self.jq_packages.clone(), + ) { Ok(filter) => filter, Err(e) => return Some(e), }; @@ -875,12 +901,12 @@ mod tests { schema.registry(registry_id).expect("registry not found"), schema.catalog(), ) - .unwrap_or_else(|e| { - panic!( - "Failed to create the context for the template evaluation: {:?}", - e - ) - }); + .unwrap_or_else(|e| { + panic!( + "Failed to create the context for the template evaluation: {:?}", + e + ) + }); // Delete all the files in the observed_output/semconv_jq_fn directory // before generating the new files. @@ -898,6 +924,10 @@ mod tests { }) .expect("Failed to generate registry assets"); - assert!(diff_dir("expected_output/semconv_jq_fn", "observed_output/semconv_jq_fn").unwrap()); + assert!(diff_dir( + "expected_output/semconv_jq_fn", + "observed_output/semconv_jq_fn" + ) + .unwrap()); } } diff --git a/defaults/jq/semconv.jq b/defaults/jq/semconv.jq index 4024eb57..d1ea3e0a 100644 --- a/defaults/jq/semconv.jq +++ b/defaults/jq/semconv.jq @@ -14,6 +14,11 @@ def semconv_attributes($options): else . end + | if ($options | has("exclude_deprecated") and $options.exclude_deprecated == true) then + map(select(has("deprecated") | not)) + else + . + end | map(. + {namespace: (if .name | index(".") then .name | split(".")[0] else "other" end)}) | if ($options | has("exclude_namespace")) then map(select(.namespace as $st | $options.exclude_namespace | index($st) | not)) @@ -43,6 +48,11 @@ def semconv_signal($signal; $options): else . end + | if ($options | has("exclude_deprecated") and $options.exclude_deprecated == true) then + map(select(.id | endswith(".deprecated") | not)) + else + . + end | map(. + {namespace: .id | split(".") | .[1]}) | if ($options | has("exclude_namespace")) then map(select(.namespace as $st | $options.exclude_namespace | index($st) | not)) diff --git a/src/registry/generate.rs b/src/registry/generate.rs index 330a1635..fffc3479 100644 --- a/src/registry/generate.rs +++ b/src/registry/generate.rs @@ -13,7 +13,7 @@ use weaver_common::Logger; use weaver_forge::config::{Params, WeaverConfig}; use weaver_forge::file_loader::{FileLoader, FileSystemFileLoader}; use weaver_forge::registry::ResolvedRegistry; -use weaver_forge::{OutputDirective, SEMCONV_JQ, TemplateEngine}; +use weaver_forge::{OutputDirective, TemplateEngine, SEMCONV_JQ}; use weaver_semconv::registry::SemConvRegistry; use crate::registry::{Error, RegistryArgs}; diff --git a/src/registry/update_markdown.rs b/src/registry/update_markdown.rs index 1bd179d3..a21e6be2 100644 --- a/src/registry/update_markdown.rs +++ b/src/registry/update_markdown.rs @@ -12,7 +12,7 @@ use weaver_common::diagnostic::DiagnosticMessages; use weaver_common::Logger; use weaver_forge::config::{Params, WeaverConfig}; use weaver_forge::file_loader::FileSystemFileLoader; -use weaver_forge::{SEMCONV_JQ, TemplateEngine}; +use weaver_forge::{TemplateEngine, SEMCONV_JQ}; use weaver_semconv_gen::{update_markdown, SnippetGenerator}; /// Parameters for the `registry update-markdown` sub-command From e8d4389ba15c9e5417de7b167de4137a36d5a9ce Mon Sep 17 00:00:00 2001 From: Laurent Querel Date: Fri, 19 Jul 2024 15:47:27 -0700 Subject: [PATCH 23/29] feat(forge): Update unit tests --- Cargo.lock | 8 +- crates/weaver_codegen_test/build.rs | 5 +- .../attribute_group/attributes_jvm_memory.md | 46 - .../attribute_group/{registry_db.md => db.md} | 54 +- .../{registry_http.md => http.md} | 8 +- .../{registry_network.md => network.md} | 34 +- .../test/attribute_group/server.md | 49 - .../{registry_url.md => url.md} | 24 +- .../{registry_user_agent.md => user_agent.md} | 8 +- .../expected_output/test/attribute_groups.md | 215 +- .../test/event/android_lifecycle_events.md | 27 - .../test/event/ios_lifecycle_events.md | 27 - .../expected_output/test/event/lifecycle.md | 57 + .../expected_output/test/events.md | 25 +- .../test/group/android_lifecycle_events.md | 31 - .../test/group/attributes_jvm_memory.md | 51 - .../expected_output/test/group/db.md | 339 -- .../test/group/db_cassandra.md | 475 -- .../expected_output/test/group/db_cosmosdb.md | 515 -- .../expected_output/test/group/db_couchdb.md | 337 -- .../test/group/db_elasticsearch.md | 467 -- .../expected_output/test/group/db_hbase.md | 338 -- .../expected_output/test/group/db_mongodb.md | 361 -- .../expected_output/test/group/db_mssql.md | 360 -- .../expected_output/test/group/db_redis.md | 363 -- .../expected_output/test/group/db_sql.md | 362 -- .../expected_output/test/group/db_tech.md | 591 -- .../test/group/ios_lifecycle_events.md | 31 - .../test/group/metric_jvm_class_count.md | 16 - .../test/group/metric_jvm_class_loaded.md | 16 - .../test/group/metric_jvm_class_unloaded.md | 16 - .../test/group/metric_jvm_cpu_count.md | 16 - .../metric_jvm_cpu_recent_utilization.md | 16 - .../test/group/metric_jvm_cpu_time.md | 16 - .../test/group/metric_jvm_gc_duration.md | 52 - .../test/group/metric_jvm_memory_committed.md | 61 - .../test/group/metric_jvm_memory_limit.md | 61 - .../test/group/metric_jvm_memory_used.md | 61 - .../metric_jvm_memory_used_after_last_gc.md | 61 - .../test/group/metric_jvm_thread_count.md | 44 - .../test/group/otel_library.md | 44 - .../expected_output/test/group/otel_scope.md | 46 - .../expected_output/test/group/registry_db.md | 478 -- .../test/group/registry_http.md | 186 - .../test/group/registry_network.md | 232 - .../test/group/registry_url.md | 100 - .../test/group/registry_user_agent.md | 33 - .../expected_output/test/group/server.md | 54 - .../expected_output/test/groups.md | 5231 ----------------- .../expected_output/test/metric/jvm.md | 327 ++ .../test/metric/metric_jvm_class_count.md | 16 - .../test/metric/metric_jvm_class_loaded.md | 16 - .../test/metric/metric_jvm_class_unloaded.md | 16 - .../test/metric/metric_jvm_cpu_count.md | 16 - .../metric_jvm_cpu_recent_utilization.md | 16 - .../test/metric/metric_jvm_cpu_time.md | 16 - .../test/metric/metric_jvm_gc_duration.md | 53 - .../metric/metric_jvm_memory_committed.md | 52 - .../test/metric/metric_jvm_memory_limit.md | 52 - .../test/metric/metric_jvm_memory_used.md | 52 - .../metric_jvm_memory_used_after_last_gc.md | 52 - .../test/metric/metric_jvm_thread_count.md | 45 - .../expected_output/test/metrics.md | 147 +- .../resource/{otel_library.md => library.md} | 11 +- .../test/resource/{otel_scope.md => scope.md} | 10 +- .../expected_output/test/resources.md | 51 +- .../span/{db_cassandra.md => cassandra.md} | 50 +- .../test/span/{db_cosmosdb.md => cosmosdb.md} | 54 +- .../test/span/{db_couchdb.md => couchdb.md} | 36 +- .../{db_elasticsearch.md => elasticsearch.md} | 46 +- .../test/span/{db_hbase.md => hbase.md} | 36 +- .../test/span/{db_mongodb.md => mongodb.md} | 38 +- .../test/span/{db_mssql.md => mssql.md} | 38 +- .../test/span/{db.md => other.md} | 36 +- .../test/span/{db_redis.md => redis.md} | 38 +- .../test/span/{db_sql.md => sql.md} | 38 +- .../test/span/{db_tech.md => tech.md} | 78 +- .../expected_output/test/spans.md | 1669 +++--- crates/weaver_forge/src/lib.rs | 44 +- .../templates/test/attribute_group.md | 10 +- .../templates/test/attribute_groups.md | 12 +- crates/weaver_forge/templates/test/event.md | 22 +- crates/weaver_forge/templates/test/events.md | 21 +- crates/weaver_forge/templates/test/metric.md | 22 +- crates/weaver_forge/templates/test/metrics.md | 25 +- .../weaver_forge/templates/test/resource.md | 14 +- .../weaver_forge/templates/test/resources.md | 16 +- crates/weaver_forge/templates/test/span.md | 22 +- crates/weaver_forge/templates/test/spans.md | 25 +- .../weaver_forge/templates/test/weaver.yaml | 32 +- defaults/jq/semconv.jq | 2 +- docs/images/dependencies.svg | 2 +- 92 files changed, 1766 insertions(+), 13656 deletions(-) delete mode 100644 crates/weaver_forge/expected_output/test/attribute_group/attributes_jvm_memory.md rename crates/weaver_forge/expected_output/test/attribute_group/{registry_db.md => db.md} (98%) rename crates/weaver_forge/expected_output/test/attribute_group/{registry_http.md => http.md} (97%) rename crates/weaver_forge/expected_output/test/attribute_group/{registry_network.md => network.md} (96%) delete mode 100644 crates/weaver_forge/expected_output/test/attribute_group/server.md rename crates/weaver_forge/expected_output/test/attribute_group/{registry_url.md => url.md} (95%) rename crates/weaver_forge/expected_output/test/attribute_group/{registry_user_agent.md => user_agent.md} (80%) delete mode 100644 crates/weaver_forge/expected_output/test/event/android_lifecycle_events.md delete mode 100644 crates/weaver_forge/expected_output/test/event/ios_lifecycle_events.md create mode 100644 crates/weaver_forge/expected_output/test/event/lifecycle.md delete mode 100644 crates/weaver_forge/expected_output/test/group/android_lifecycle_events.md delete mode 100644 crates/weaver_forge/expected_output/test/group/attributes_jvm_memory.md delete mode 100644 crates/weaver_forge/expected_output/test/group/db.md delete mode 100644 crates/weaver_forge/expected_output/test/group/db_cassandra.md delete mode 100644 crates/weaver_forge/expected_output/test/group/db_cosmosdb.md delete mode 100644 crates/weaver_forge/expected_output/test/group/db_couchdb.md delete mode 100644 crates/weaver_forge/expected_output/test/group/db_elasticsearch.md delete mode 100644 crates/weaver_forge/expected_output/test/group/db_hbase.md delete mode 100644 crates/weaver_forge/expected_output/test/group/db_mongodb.md delete mode 100644 crates/weaver_forge/expected_output/test/group/db_mssql.md delete mode 100644 crates/weaver_forge/expected_output/test/group/db_redis.md delete mode 100644 crates/weaver_forge/expected_output/test/group/db_sql.md delete mode 100644 crates/weaver_forge/expected_output/test/group/db_tech.md delete mode 100644 crates/weaver_forge/expected_output/test/group/ios_lifecycle_events.md delete mode 100644 crates/weaver_forge/expected_output/test/group/metric_jvm_class_count.md delete mode 100644 crates/weaver_forge/expected_output/test/group/metric_jvm_class_loaded.md delete mode 100644 crates/weaver_forge/expected_output/test/group/metric_jvm_class_unloaded.md delete mode 100644 crates/weaver_forge/expected_output/test/group/metric_jvm_cpu_count.md delete mode 100644 crates/weaver_forge/expected_output/test/group/metric_jvm_cpu_recent_utilization.md delete mode 100644 crates/weaver_forge/expected_output/test/group/metric_jvm_cpu_time.md delete mode 100644 crates/weaver_forge/expected_output/test/group/metric_jvm_gc_duration.md delete mode 100644 crates/weaver_forge/expected_output/test/group/metric_jvm_memory_committed.md delete mode 100644 crates/weaver_forge/expected_output/test/group/metric_jvm_memory_limit.md delete mode 100644 crates/weaver_forge/expected_output/test/group/metric_jvm_memory_used.md delete mode 100644 crates/weaver_forge/expected_output/test/group/metric_jvm_memory_used_after_last_gc.md delete mode 100644 crates/weaver_forge/expected_output/test/group/metric_jvm_thread_count.md delete mode 100644 crates/weaver_forge/expected_output/test/group/otel_library.md delete mode 100644 crates/weaver_forge/expected_output/test/group/otel_scope.md delete mode 100644 crates/weaver_forge/expected_output/test/group/registry_db.md delete mode 100644 crates/weaver_forge/expected_output/test/group/registry_http.md delete mode 100644 crates/weaver_forge/expected_output/test/group/registry_network.md delete mode 100644 crates/weaver_forge/expected_output/test/group/registry_url.md delete mode 100644 crates/weaver_forge/expected_output/test/group/registry_user_agent.md delete mode 100644 crates/weaver_forge/expected_output/test/group/server.md delete mode 100644 crates/weaver_forge/expected_output/test/groups.md create mode 100644 crates/weaver_forge/expected_output/test/metric/jvm.md delete mode 100644 crates/weaver_forge/expected_output/test/metric/metric_jvm_class_count.md delete mode 100644 crates/weaver_forge/expected_output/test/metric/metric_jvm_class_loaded.md delete mode 100644 crates/weaver_forge/expected_output/test/metric/metric_jvm_class_unloaded.md delete mode 100644 crates/weaver_forge/expected_output/test/metric/metric_jvm_cpu_count.md delete mode 100644 crates/weaver_forge/expected_output/test/metric/metric_jvm_cpu_recent_utilization.md delete mode 100644 crates/weaver_forge/expected_output/test/metric/metric_jvm_cpu_time.md delete mode 100644 crates/weaver_forge/expected_output/test/metric/metric_jvm_gc_duration.md delete mode 100644 crates/weaver_forge/expected_output/test/metric/metric_jvm_memory_committed.md delete mode 100644 crates/weaver_forge/expected_output/test/metric/metric_jvm_memory_limit.md delete mode 100644 crates/weaver_forge/expected_output/test/metric/metric_jvm_memory_used.md delete mode 100644 crates/weaver_forge/expected_output/test/metric/metric_jvm_memory_used_after_last_gc.md delete mode 100644 crates/weaver_forge/expected_output/test/metric/metric_jvm_thread_count.md rename crates/weaver_forge/expected_output/test/resource/{otel_library.md => library.md} (70%) rename crates/weaver_forge/expected_output/test/resource/{otel_scope.md => scope.md} (76%) rename crates/weaver_forge/expected_output/test/span/{db_cassandra.md => cassandra.md} (98%) rename crates/weaver_forge/expected_output/test/span/{db_cosmosdb.md => cosmosdb.md} (98%) rename crates/weaver_forge/expected_output/test/span/{db_couchdb.md => couchdb.md} (98%) rename crates/weaver_forge/expected_output/test/span/{db_elasticsearch.md => elasticsearch.md} (98%) rename crates/weaver_forge/expected_output/test/span/{db_hbase.md => hbase.md} (98%) rename crates/weaver_forge/expected_output/test/span/{db_mongodb.md => mongodb.md} (98%) rename crates/weaver_forge/expected_output/test/span/{db_mssql.md => mssql.md} (98%) rename crates/weaver_forge/expected_output/test/span/{db.md => other.md} (98%) rename crates/weaver_forge/expected_output/test/span/{db_redis.md => redis.md} (98%) rename crates/weaver_forge/expected_output/test/span/{db_sql.md => sql.md} (98%) rename crates/weaver_forge/expected_output/test/span/{db_tech.md => tech.md} (98%) diff --git a/Cargo.lock b/Cargo.lock index 328dc95b..1f808a66 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -302,9 +302,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.1.5" +version = "1.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "324c74f2155653c90b04f25b2a47a8a631360cb908f92a772695f430c7e31052" +checksum = "2aba8f4e9906c7ce3c73463f62a7f0c65183ada1a2d47e397cc8810827f9694f" [[package]] name = "cfg-if" @@ -4414,9 +4414,9 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" -version = "0.6.13" +version = "0.6.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59b5e5f6c299a3c7890b876a2a587f3115162487e704907d9b6cd29473052ba1" +checksum = "374ec40a2d767a3c1b4972d9475ecd557356637be906f2cb3f7fe17a6eb5e22f" dependencies = [ "memchr", ] diff --git a/crates/weaver_codegen_test/build.rs b/crates/weaver_codegen_test/build.rs index bca904ca..9f82f2ac 100644 --- a/crates/weaver_codegen_test/build.rs +++ b/crates/weaver_codegen_test/build.rs @@ -16,7 +16,7 @@ use weaver_common::{in_memory, Logger}; use weaver_forge::config::{Params, WeaverConfig}; use weaver_forge::file_loader::FileSystemFileLoader; use weaver_forge::registry::ResolvedRegistry; -use weaver_forge::{OutputDirective, SEMCONV_JQ, TemplateEngine}; +use weaver_forge::{OutputDirective, TemplateEngine, SEMCONV_JQ}; use weaver_resolver::SchemaResolver; use weaver_semconv::path::RegistryPath; use weaver_semconv::registry::SemConvRegistry; @@ -54,7 +54,8 @@ fn main() { let config = WeaverConfig::try_from_path("./templates/registry/rust") .unwrap_or_else(|e| process_error(&logger, e)); let mut engine = TemplateEngine::new(config, loader, Params::default()); - engine.import_jq_package(SEMCONV_JQ) + engine + .import_jq_package(SEMCONV_JQ) .unwrap_or_else(|e| process_error(&logger, e)); let template_registry = ResolvedRegistry::try_from_resolved_registry( schema diff --git a/crates/weaver_forge/expected_output/test/attribute_group/attributes_jvm_memory.md b/crates/weaver_forge/expected_output/test/attribute_group/attributes_jvm_memory.md deleted file mode 100644 index 5f3764f9..00000000 --- a/crates/weaver_forge/expected_output/test/attribute_group/attributes_jvm_memory.md +++ /dev/null @@ -1,46 +0,0 @@ -## 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/test/attribute_group/registry_db.md b/crates/weaver_forge/expected_output/test/attribute_group/db.md similarity index 98% rename from crates/weaver_forge/expected_output/test/attribute_group/registry_db.md rename to crates/weaver_forge/expected_output/test/attribute_group/db.md index f1d35ed0..648e6126 100644 --- a/crates/weaver_forge/expected_output/test/attribute_group/registry_db.md +++ b/crates/weaver_forge/expected_output/test/attribute_group/db.md @@ -1,30 +1,23 @@ -## Group `registry_db` (attribute_group) - -### Brief - -This document defines the attributes used to describe telemetry in the context of databases. - -prefix: db +## Namespace `db` ### Attributes -#### Attribute `db.cassandra.coordinator.dc` +#### Attribute `db.cassandra.consistency_level` -The data center of the coordinating node for a query. +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: string -- Examples: us-west-2 +- Type: Enum [all, each_quorum, quorum, local_quorum, one, two, three, local_one, any, serial, local_serial] -#### Attribute `db.cassandra.coordinator.id` +#### Attribute `db.cassandra.coordinator.dc` -The ID of the coordinating node for a query. +The data center of the coordinating node for a query. - Requirement Level: Recommended @@ -32,19 +25,20 @@ The ID of the coordinating node for a query. - Tag: tech-specific-cassandra - Type: string -- Examples: be13faa2-8574-4d71-926d-27f16cf8a7af +- Examples: us-west-2 -#### Attribute `db.cassandra.consistency_level` +#### Attribute `db.cassandra.coordinator.id` -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). +The ID of the coordinating node for a query. - Requirement Level: Recommended - Tag: tech-specific-cassandra -- Type: Enum [all, each_quorum, quorum, local_quorum, one, two, three, local_one, any, serial, local_serial] +- Type: string +- Examples: be13faa2-8574-4d71-926d-27f16cf8a7af #### Attribute `db.cassandra.idempotence` @@ -276,6 +270,19 @@ Many Elasticsearch url paths allow dynamic values. These SHOULD be recorded in s ] +#### 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 + + #### 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. @@ -438,17 +445,4 @@ Username for accessing the database. "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/test/attribute_group/registry_http.md b/crates/weaver_forge/expected_output/test/attribute_group/http.md similarity index 97% rename from crates/weaver_forge/expected_output/test/attribute_group/registry_http.md rename to crates/weaver_forge/expected_output/test/attribute_group/http.md index 19880802..8576b2df 100644 --- a/crates/weaver_forge/expected_output/test/attribute_group/registry_http.md +++ b/crates/weaver_forge/expected_output/test/attribute_group/http.md @@ -1,10 +1,4 @@ -## Group `registry_http` (attribute_group) - -### Brief - -This document defines semantic convention attributes in the HTTP namespace. - -prefix: http +## Namespace `http` ### Attributes diff --git a/crates/weaver_forge/expected_output/test/attribute_group/registry_network.md b/crates/weaver_forge/expected_output/test/attribute_group/network.md similarity index 96% rename from crates/weaver_forge/expected_output/test/attribute_group/registry_network.md rename to crates/weaver_forge/expected_output/test/attribute_group/network.md index 70efc78d..69da9e7f 100644 --- a/crates/weaver_forge/expected_output/test/attribute_group/registry_network.md +++ b/crates/weaver_forge/expected_output/test/attribute_group/network.md @@ -1,10 +1,4 @@ -## Group `registry_network` (attribute_group) - -### Brief - -These attributes may be used for any network related operation. - -prefix: network +## Namespace `network` ### Attributes @@ -75,6 +69,19 @@ The internet connection type. - Examples: wifi +#### Attribute `network.io.direction` + +The network IO operation direction. + + +- Requirement Level: Recommended + +- Type: Enum [transmit, receive] +- Examples: [ + "transmit", +] + + #### Attribute `network.local.address` Local address of the network connection - IP address or Unix domain socket name. @@ -210,17 +217,4 @@ The value SHOULD be normalized to lowercase. - 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/test/attribute_group/server.md b/crates/weaver_forge/expected_output/test/attribute_group/server.md deleted file mode 100644 index 06a10dbe..00000000 --- a/crates/weaver_forge/expected_output/test/attribute_group/server.md +++ /dev/null @@ -1,49 +0,0 @@ -## 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/test/attribute_group/registry_url.md b/crates/weaver_forge/expected_output/test/attribute_group/url.md similarity index 95% rename from crates/weaver_forge/expected_output/test/attribute_group/registry_url.md rename to crates/weaver_forge/expected_output/test/attribute_group/url.md index f7dfd4a8..093052c8 100644 --- a/crates/weaver_forge/expected_output/test/attribute_group/registry_url.md +++ b/crates/weaver_forge/expected_output/test/attribute_group/url.md @@ -1,26 +1,18 @@ -## Group `registry_url` (attribute_group) - -### Brief - -Attributes describing URL. - -prefix: url +## Namespace `url` ### Attributes -#### Attribute `url.scheme` +#### Attribute `url.fragment` -The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. +The [URI fragment](https://www.rfc-editor.org/rfc/rfc3986#section-3.5) component - Requirement Level: Recommended - Type: string - Examples: [ - "https", - "ftp", - "telnet", + "SemConv", ] - Stability: Stable @@ -78,16 +70,18 @@ Sensitive content provided in query string SHOULD be scrubbed when instrumentati - Stability: Stable -#### Attribute `url.fragment` +#### Attribute `url.scheme` -The [URI fragment](https://www.rfc-editor.org/rfc/rfc3986#section-3.5) component +The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. - Requirement Level: Recommended - Type: string - Examples: [ - "SemConv", + "https", + "ftp", + "telnet", ] - Stability: Stable diff --git a/crates/weaver_forge/expected_output/test/attribute_group/registry_user_agent.md b/crates/weaver_forge/expected_output/test/attribute_group/user_agent.md similarity index 80% rename from crates/weaver_forge/expected_output/test/attribute_group/registry_user_agent.md rename to crates/weaver_forge/expected_output/test/attribute_group/user_agent.md index 0b45e086..821f801d 100644 --- a/crates/weaver_forge/expected_output/test/attribute_group/registry_user_agent.md +++ b/crates/weaver_forge/expected_output/test/attribute_group/user_agent.md @@ -1,10 +1,4 @@ -## Group `registry_user_agent` (attribute_group) - -### Brief - -Describes user-agent attributes. - -prefix: user_agent +## Namespace `user_agent` ### Attributes diff --git a/crates/weaver_forge/expected_output/test/attribute_groups.md b/crates/weaver_forge/expected_output/test/attribute_groups.md index 38d2cf9c..e831b7ca 100644 --- a/crates/weaver_forge/expected_output/test/attribute_groups.md +++ b/crates/weaver_forge/expected_output/test/attribute_groups.md @@ -4,64 +4,24 @@ - one - two - three -## Group `attributes.jvm.memory` (attribute_group) - -### Brief - -Describes JVM memory metric attributes. - -prefix: jvm.memory +## Namespace `db` ### 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` +#### Attribute `db.cassandra.consistency_level` -Name of the memory pool. +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). -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 +- Tag: tech-specific-cassandra +- Type: Enum [all, each_quorum, quorum, local_quorum, one, two, three, local_one, any, serial, local_serial] -## 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. @@ -90,19 +50,6 @@ The ID of the coordinating node for a query. - 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. @@ -339,6 +286,20 @@ Many Elasticsearch url paths allow dynamic values. These SHOULD be recorded in s ] +#### 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 + + #### 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. @@ -510,28 +471,8 @@ Username for accessing the database. ] -#### 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 +## Namespace `http` ### Attributes @@ -707,13 +648,7 @@ SHOULD include the [application root](/docs/http/http-spans.md#http-server-defin -## Group `registry.network` (attribute_group) - -### Brief - -These attributes may be used for any network related operation. - -prefix: network +## Namespace `network` ### Attributes @@ -784,6 +719,19 @@ The internet connection type. - Examples: wifi +#### Attribute `network.io.direction` + +The network IO operation direction. + + +- Requirement Level: Recommended + +- Type: Enum [transmit, receive] +- Examples: [ + "transmit", +] + + #### Attribute `network.local.address` Local address of the network connection - IP address or Unix domain socket name. @@ -921,93 +869,22 @@ The value SHOULD be normalized to lowercase. - 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 +## Namespace `url` ### Attributes -#### Attribute `url.scheme` +#### Attribute `url.fragment` -The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. +The [URI fragment](https://www.rfc-editor.org/rfc/rfc3986#section-3.5) component - Requirement Level: Recommended - Type: string - Examples: [ - "https", - "ftp", - "telnet", + "SemConv", ] - Stability: Stable @@ -1065,29 +942,25 @@ Sensitive content provided in query string SHOULD be scrubbed when instrumentati - Stability: Stable -#### Attribute `url.fragment` +#### Attribute `url.scheme` -The [URI fragment](https://www.rfc-editor.org/rfc/rfc3986#section-3.5) component +The [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component identifying the used protocol. - Requirement Level: Recommended - Type: string - Examples: [ - "SemConv", + "https", + "ftp", + "telnet", ] - Stability: Stable -## Group `registry.user_agent` (attribute_group) - -### Brief - -Describes user-agent attributes. - -prefix: user_agent +## Namespace `user_agent` ### Attributes diff --git a/crates/weaver_forge/expected_output/test/event/android_lifecycle_events.md b/crates/weaver_forge/expected_output/test/event/android_lifecycle_events.md deleted file mode 100644 index de690580..00000000 --- a/crates/weaver_forge/expected_output/test/event/android_lifecycle_events.md +++ /dev/null @@ -1,27 +0,0 @@ -# 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/test/event/ios_lifecycle_events.md b/crates/weaver_forge/expected_output/test/event/ios_lifecycle_events.md deleted file mode 100644 index 83ecf5db..00000000 --- a/crates/weaver_forge/expected_output/test/event/ios_lifecycle_events.md +++ /dev/null @@ -1,27 +0,0 @@ -# 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/test/event/lifecycle.md b/crates/weaver_forge/expected_output/test/event/lifecycle.md new file mode 100644 index 00000000..456ecbc5 --- /dev/null +++ b/crates/weaver_forge/expected_output/test/event/lifecycle.md @@ -0,0 +1,57 @@ +## Events Namespace `lifecycle` + + +## Event `device.app.lifecycle` + +Note: +Brief: This event represents an occurrence of a lifecycle transition on the iOS platform. + +Requirement level: +Stability: + +### 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 + + + +## Event `device.app.lifecycle` + +Note: +Brief: This event represents an occurrence of a lifecycle transition on the Android platform. + +Requirement level: +Stability: + +### 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/test/events.md b/crates/weaver_forge/expected_output/test/events.md index 8066e504..3f6033f1 100644 --- a/crates/weaver_forge/expected_output/test/events.md +++ b/crates/weaver_forge/expected_output/test/events.md @@ -1,14 +1,14 @@ -# Semantic Convention Event Groups +# Events Namespace `lifecycle` -## Group `ios.lifecycle.events` (event) -### Brief +## Event `device.app.lifecycle` -This event represents an occurrence of a lifecycle transition on the iOS platform. +Note: +Brief: This event represents an occurrence of a lifecycle transition on the iOS platform. -Prefix: ios -Name: device.app.lifecycle +Requirement level: +Stability: ### Attributes @@ -29,14 +29,13 @@ The iOS lifecycle states are defined in the [UIApplicationDelegate documentation -## Group `android.lifecycle.events` (event) +## Event `device.app.lifecycle` -### Brief +Note: +Brief: This event represents an occurrence of a lifecycle transition on the Android platform. -This event represents an occurrence of a lifecycle transition on the Android platform. - -Prefix: android -Name: device.app.lifecycle +Requirement level: +Stability: ### Attributes @@ -56,4 +55,6 @@ The Android lifecycle states are defined in [Activity lifecycle callbacks](https - Stability: Experimental + + \ No newline at end of file diff --git a/crates/weaver_forge/expected_output/test/group/android_lifecycle_events.md b/crates/weaver_forge/expected_output/test/group/android_lifecycle_events.md deleted file mode 100644 index 1eba53e2..00000000 --- a/crates/weaver_forge/expected_output/test/group/android_lifecycle_events.md +++ /dev/null @@ -1,31 +0,0 @@ -# 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 - - - -## Lineage - -Source file: data/mobile-events.yaml - diff --git a/crates/weaver_forge/expected_output/test/group/attributes_jvm_memory.md b/crates/weaver_forge/expected_output/test/group/attributes_jvm_memory.md deleted file mode 100644 index ed1a167d..00000000 --- a/crates/weaver_forge/expected_output/test/group/attributes_jvm_memory.md +++ /dev/null @@ -1,51 +0,0 @@ -# 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 - - - -## Lineage - -Source file: data/jvm-metrics.yaml - diff --git a/crates/weaver_forge/expected_output/test/group/db.md b/crates/weaver_forge/expected_output/test/group/db.md deleted file mode 100644 index 1e993973..00000000 --- a/crates/weaver_forge/expected_output/test/group/db.md +++ /dev/null @@ -1,339 +0,0 @@ -# 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 - - - -## Lineage - -Source file: data/trace-database.yaml - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - diff --git a/crates/weaver_forge/expected_output/test/group/db_cassandra.md b/crates/weaver_forge/expected_output/test/group/db_cassandra.md deleted file mode 100644 index 1ad1b84b..00000000 --- a/crates/weaver_forge/expected_output/test/group/db_cassandra.md +++ /dev/null @@ -1,475 +0,0 @@ -# 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.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.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.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.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.idempotence` - -Whether or not the query is idempotent. - - - -- Requirement Level: Recommended - -- Tag: call-level-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: call-level-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: call-level-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: call-level-tech-specific-cassandra - -- Type: string -- Examples: mytable - - -### Attribute `db.name` - -The keyspace name in Cassandra. - - - -For Cassandra the `db.name` should be set to the Cassandra keyspace name. - -- Requirement Level: Conditionally Required - If applicable. - -- Tag: call-level-tech-specific-cassandra - -- Type: string -- Examples: [ - "mykeyspace", -] - - - -## Lineage - -Source file: data/trace-database.yaml - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - diff --git a/crates/weaver_forge/expected_output/test/group/db_cosmosdb.md b/crates/weaver_forge/expected_output/test/group/db_cosmosdb.md deleted file mode 100644 index b406fa3d..00000000 --- a/crates/weaver_forge/expected_output/test/group/db_cosmosdb.md +++ /dev/null @@ -1,515 +0,0 @@ -# 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.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.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 `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, -] - - -### 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 `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 - - - -## Lineage - -Source file: data/trace-database.yaml - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - diff --git a/crates/weaver_forge/expected_output/test/group/db_couchdb.md b/crates/weaver_forge/expected_output/test/group/db_couchdb.md deleted file mode 100644 index e1517369..00000000 --- a/crates/weaver_forge/expected_output/test/group/db_couchdb.md +++ /dev/null @@ -1,337 +0,0 @@ -# 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 `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: Conditionally Required - If `db.statement` is not applicable. - -- Tag: call-level-tech-specific - -- Type: string -- Examples: [ - "GET /{db}/{docid}", -] - - - -## Lineage - -Source file: data/trace-database.yaml - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - diff --git a/crates/weaver_forge/expected_output/test/group/db_elasticsearch.md b/crates/weaver_forge/expected_output/test/group/db_elasticsearch.md deleted file mode 100644 index 72b17cc6..00000000 --- a/crates/weaver_forge/expected_output/test/group/db_elasticsearch.md +++ /dev/null @@ -1,467 +0,0 @@ -# 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 `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.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", -] - - -### 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 `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 `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 `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: 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: Conditionally Required - If using a port other than the default port for this DBMS and if `server.address` is set. - -- Tag: call-level-tech-specific - -- Type: int -- Examples: [ - 80, - 8080, - 443, -] - -- 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: Required - -- Tag: call-level-tech-specific - -- Type: string -- Examples: [ - "https://localhost:9200/index/_search?q=user.id:kimchy", -] - -- Stability: Stable - - - -## Lineage - -Source file: data/trace-database.yaml - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - diff --git a/crates/weaver_forge/expected_output/test/group/db_hbase.md b/crates/weaver_forge/expected_output/test/group/db_hbase.md deleted file mode 100644 index 6564de85..00000000 --- a/crates/weaver_forge/expected_output/test/group/db_hbase.md +++ /dev/null @@ -1,338 +0,0 @@ -# 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.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: Conditionally Required - If applicable. - -- Tag: call-level-tech-specific - -- Type: string -- Examples: [ - "mynamespace", -] - - - -## Lineage - -Source file: data/trace-database.yaml - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - diff --git a/crates/weaver_forge/expected_output/test/group/db_mongodb.md b/crates/weaver_forge/expected_output/test/group/db_mongodb.md deleted file mode 100644 index 87f54b14..00000000 --- a/crates/weaver_forge/expected_output/test/group/db_mongodb.md +++ /dev/null @@ -1,361 +0,0 @@ -# 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", -] - - - -## Lineage - -Source file: data/trace-database.yaml - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - diff --git a/crates/weaver_forge/expected_output/test/group/db_mssql.md b/crates/weaver_forge/expected_output/test/group/db_mssql.md deleted file mode 100644 index 96245ce9..00000000 --- a/crates/weaver_forge/expected_output/test/group/db_mssql.md +++ /dev/null @@ -1,360 +0,0 @@ -# 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 - - - -## Lineage - -Source file: data/trace-database.yaml - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - diff --git a/crates/weaver_forge/expected_output/test/group/db_redis.md b/crates/weaver_forge/expected_output/test/group/db_redis.md deleted file mode 100644 index ea48f3e5..00000000 --- a/crates/weaver_forge/expected_output/test/group/db_redis.md +++ /dev/null @@ -1,363 +0,0 @@ -# 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.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: Optional - -- Tag: call-level-tech-specific - -- Type: string -- Examples: [ - "HMSET myhash field1 'Hello' field2 'World'", -] - - - -## Lineage - -Source file: data/trace-database.yaml - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - diff --git a/crates/weaver_forge/expected_output/test/group/db_sql.md b/crates/weaver_forge/expected_output/test/group/db_sql.md deleted file mode 100644 index 931a4268..00000000 --- a/crates/weaver_forge/expected_output/test/group/db_sql.md +++ /dev/null @@ -1,362 +0,0 @@ -# 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", -] - - - -## Lineage - -Source file: data/trace-database.yaml - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - diff --git a/crates/weaver_forge/expected_output/test/group/db_tech.md b/crates/weaver_forge/expected_output/test/group/db_tech.md deleted file mode 100644 index a6550929..00000000 --- a/crates/weaver_forge/expected_output/test/group/db_tech.md +++ /dev/null @@ -1,591 +0,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.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.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.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.idempotence` - -Whether or not the query is idempotent. - - - -- Requirement Level: Recommended - -- Tag: call-level-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: call-level-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: call-level-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: call-level-tech-specific-cassandra - -- Type: string -- Examples: mytable - - -### Attribute `db.name` - -The keyspace name in Cassandra. - - - -For Cassandra the `db.name` should be set to the Cassandra keyspace name. - -- Requirement Level: Conditionally Required - If applicable. - -- Tag: call-level-tech-specific-cassandra - -- Type: string -- Examples: [ - "mykeyspace", -] - - -### 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: Optional - -- 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.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.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 `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, -] - - -### 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 `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 - - - -## Lineage - -Source file: data/trace-database.yaml - diff --git a/crates/weaver_forge/expected_output/test/group/ios_lifecycle_events.md b/crates/weaver_forge/expected_output/test/group/ios_lifecycle_events.md deleted file mode 100644 index b36ffa8d..00000000 --- a/crates/weaver_forge/expected_output/test/group/ios_lifecycle_events.md +++ /dev/null @@ -1,31 +0,0 @@ -# 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 - - - -## Lineage - -Source file: data/mobile-events.yaml - diff --git a/crates/weaver_forge/expected_output/test/group/metric_jvm_class_count.md b/crates/weaver_forge/expected_output/test/group/metric_jvm_class_count.md deleted file mode 100644 index b71335f5..00000000 --- a/crates/weaver_forge/expected_output/test/group/metric_jvm_class_count.md +++ /dev/null @@ -1,16 +0,0 @@ -# Group `metric.jvm.class.count` (metric) - -## Brief - -Number of classes currently loaded. - -prefix: - -## Attributes - - - -## Lineage - -Source file: data/jvm-metrics.yaml - diff --git a/crates/weaver_forge/expected_output/test/group/metric_jvm_class_loaded.md b/crates/weaver_forge/expected_output/test/group/metric_jvm_class_loaded.md deleted file mode 100644 index 073fd6ec..00000000 --- a/crates/weaver_forge/expected_output/test/group/metric_jvm_class_loaded.md +++ /dev/null @@ -1,16 +0,0 @@ -# Group `metric.jvm.class.loaded` (metric) - -## Brief - -Number of classes loaded since JVM start. - -prefix: - -## Attributes - - - -## Lineage - -Source file: data/jvm-metrics.yaml - diff --git a/crates/weaver_forge/expected_output/test/group/metric_jvm_class_unloaded.md b/crates/weaver_forge/expected_output/test/group/metric_jvm_class_unloaded.md deleted file mode 100644 index e31aaf34..00000000 --- a/crates/weaver_forge/expected_output/test/group/metric_jvm_class_unloaded.md +++ /dev/null @@ -1,16 +0,0 @@ -# Group `metric.jvm.class.unloaded` (metric) - -## Brief - -Number of classes unloaded since JVM start. - -prefix: - -## Attributes - - - -## Lineage - -Source file: data/jvm-metrics.yaml - diff --git a/crates/weaver_forge/expected_output/test/group/metric_jvm_cpu_count.md b/crates/weaver_forge/expected_output/test/group/metric_jvm_cpu_count.md deleted file mode 100644 index 02f9d644..00000000 --- a/crates/weaver_forge/expected_output/test/group/metric_jvm_cpu_count.md +++ /dev/null @@ -1,16 +0,0 @@ -# Group `metric.jvm.cpu.count` (metric) - -## Brief - -Number of processors available to the Java virtual machine. - -prefix: - -## Attributes - - - -## Lineage - -Source file: data/jvm-metrics.yaml - diff --git a/crates/weaver_forge/expected_output/test/group/metric_jvm_cpu_recent_utilization.md b/crates/weaver_forge/expected_output/test/group/metric_jvm_cpu_recent_utilization.md deleted file mode 100644 index f6576c4c..00000000 --- a/crates/weaver_forge/expected_output/test/group/metric_jvm_cpu_recent_utilization.md +++ /dev/null @@ -1,16 +0,0 @@ -# Group `metric.jvm.cpu.recent_utilization` (metric) - -## Brief - -Recent CPU utilization for the process as reported by the JVM. - -prefix: - -## Attributes - - - -## Lineage - -Source file: data/jvm-metrics.yaml - diff --git a/crates/weaver_forge/expected_output/test/group/metric_jvm_cpu_time.md b/crates/weaver_forge/expected_output/test/group/metric_jvm_cpu_time.md deleted file mode 100644 index d6f9df68..00000000 --- a/crates/weaver_forge/expected_output/test/group/metric_jvm_cpu_time.md +++ /dev/null @@ -1,16 +0,0 @@ -# Group `metric.jvm.cpu.time` (metric) - -## Brief - -CPU time used by the process as reported by the JVM. - -prefix: - -## Attributes - - - -## Lineage - -Source file: data/jvm-metrics.yaml - diff --git a/crates/weaver_forge/expected_output/test/group/metric_jvm_gc_duration.md b/crates/weaver_forge/expected_output/test/group/metric_jvm_gc_duration.md deleted file mode 100644 index 6392dd23..00000000 --- a/crates/weaver_forge/expected_output/test/group/metric_jvm_gc_duration.md +++ /dev/null @@ -1,52 +0,0 @@ -# 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 - - - -## Lineage - -Source file: data/jvm-metrics.yaml - diff --git a/crates/weaver_forge/expected_output/test/group/metric_jvm_memory_committed.md b/crates/weaver_forge/expected_output/test/group/metric_jvm_memory_committed.md deleted file mode 100644 index 9f92cb32..00000000 --- a/crates/weaver_forge/expected_output/test/group/metric_jvm_memory_committed.md +++ /dev/null @@ -1,61 +0,0 @@ -# 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 - - - -## Lineage - -Source file: data/jvm-metrics.yaml - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - diff --git a/crates/weaver_forge/expected_output/test/group/metric_jvm_memory_limit.md b/crates/weaver_forge/expected_output/test/group/metric_jvm_memory_limit.md deleted file mode 100644 index 4fd250f1..00000000 --- a/crates/weaver_forge/expected_output/test/group/metric_jvm_memory_limit.md +++ /dev/null @@ -1,61 +0,0 @@ -# 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 - - - -## Lineage - -Source file: data/jvm-metrics.yaml - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - diff --git a/crates/weaver_forge/expected_output/test/group/metric_jvm_memory_used.md b/crates/weaver_forge/expected_output/test/group/metric_jvm_memory_used.md deleted file mode 100644 index 6d867206..00000000 --- a/crates/weaver_forge/expected_output/test/group/metric_jvm_memory_used.md +++ /dev/null @@ -1,61 +0,0 @@ -# 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 - - - -## Lineage - -Source file: data/jvm-metrics.yaml - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - diff --git a/crates/weaver_forge/expected_output/test/group/metric_jvm_memory_used_after_last_gc.md b/crates/weaver_forge/expected_output/test/group/metric_jvm_memory_used_after_last_gc.md deleted file mode 100644 index f89e34a9..00000000 --- a/crates/weaver_forge/expected_output/test/group/metric_jvm_memory_used_after_last_gc.md +++ /dev/null @@ -1,61 +0,0 @@ -# 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 - - - -## Lineage - -Source file: data/jvm-metrics.yaml - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - -attribute: - - source group: - - inherited fields: - - locally overridden fields: - diff --git a/crates/weaver_forge/expected_output/test/group/metric_jvm_thread_count.md b/crates/weaver_forge/expected_output/test/group/metric_jvm_thread_count.md deleted file mode 100644 index 3a650076..00000000 --- a/crates/weaver_forge/expected_output/test/group/metric_jvm_thread_count.md +++ /dev/null @@ -1,44 +0,0 @@ -# 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 - - - -## Lineage - -Source file: data/jvm-metrics.yaml - diff --git a/crates/weaver_forge/expected_output/test/group/otel_library.md b/crates/weaver_forge/expected_output/test/group/otel_library.md deleted file mode 100644 index 7c532bbc..00000000 --- a/crates/weaver_forge/expected_output/test/group/otel_library.md +++ /dev/null @@ -1,44 +0,0 @@ -# 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. - - - -## Lineage - -Source file: data/exporter.yaml - diff --git a/crates/weaver_forge/expected_output/test/group/otel_scope.md b/crates/weaver_forge/expected_output/test/group/otel_scope.md deleted file mode 100644 index 96d71a0f..00000000 --- a/crates/weaver_forge/expected_output/test/group/otel_scope.md +++ /dev/null @@ -1,46 +0,0 @@ -# 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 - - - -## Lineage - -Source file: data/exporter.yaml - diff --git a/crates/weaver_forge/expected_output/test/group/registry_db.md b/crates/weaver_forge/expected_output/test/group/registry_db.md deleted file mode 100644 index 48a30ef2..00000000 --- a/crates/weaver_forge/expected_output/test/group/registry_db.md +++ /dev/null @@ -1,478 +0,0 @@ -# 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 - - - -## Lineage - -Source file: data/registry-db.yaml - diff --git a/crates/weaver_forge/expected_output/test/group/registry_http.md b/crates/weaver_forge/expected_output/test/group/registry_http.md deleted file mode 100644 index d5d4caa3..00000000 --- a/crates/weaver_forge/expected_output/test/group/registry_http.md +++ /dev/null @@ -1,186 +0,0 @@ -# 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 - - - -## Lineage - -Source file: data/registry-http.yaml - diff --git a/crates/weaver_forge/expected_output/test/group/registry_network.md b/crates/weaver_forge/expected_output/test/group/registry_network.md deleted file mode 100644 index 2518bed7..00000000 --- a/crates/weaver_forge/expected_output/test/group/registry_network.md +++ /dev/null @@ -1,232 +0,0 @@ -# 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", -] - - - -## Lineage - -Source file: data/registry-network.yaml - diff --git a/crates/weaver_forge/expected_output/test/group/registry_url.md b/crates/weaver_forge/expected_output/test/group/registry_url.md deleted file mode 100644 index 8c2d3035..00000000 --- a/crates/weaver_forge/expected_output/test/group/registry_url.md +++ /dev/null @@ -1,100 +0,0 @@ -# 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 - - - -## Lineage - -Source file: data/registry-url.yaml - diff --git a/crates/weaver_forge/expected_output/test/group/registry_user_agent.md b/crates/weaver_forge/expected_output/test/group/registry_user_agent.md deleted file mode 100644 index bf21b667..00000000 --- a/crates/weaver_forge/expected_output/test/group/registry_user_agent.md +++ /dev/null @@ -1,33 +0,0 @@ -# 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 - - - -## Lineage - -Source file: data/registry-user-agent.yaml - diff --git a/crates/weaver_forge/expected_output/test/group/server.md b/crates/weaver_forge/expected_output/test/group/server.md deleted file mode 100644 index caa11176..00000000 --- a/crates/weaver_forge/expected_output/test/group/server.md +++ /dev/null @@ -1,54 +0,0 @@ -# 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 - - - -## Lineage - -Source file: data/registry-server.yaml - diff --git a/crates/weaver_forge/expected_output/test/groups.md b/crates/weaver_forge/expected_output/test/groups.md deleted file mode 100644 index bb89d4df..00000000 --- a/crates/weaver_forge/expected_output/test/groups.md +++ /dev/null @@ -1,5231 +0,0 @@ -# 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.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.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.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.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.idempotence` - -Whether or not the query is idempotent. - - - -- Requirement Level: Recommended - -- Tag: call-level-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: call-level-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: call-level-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: call-level-tech-specific-cassandra - -- Type: string -- Examples: mytable - - -#### Attribute `db.name` - -The keyspace name in Cassandra. - - - -For Cassandra the `db.name` should be set to the Cassandra keyspace name. - -- Requirement Level: Conditionally Required - If applicable. - -- Tag: call-level-tech-specific-cassandra - -- Type: string -- Examples: [ - "mykeyspace", -] - - - -## 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.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: Conditionally Required - If applicable. - -- 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 `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: Conditionally Required - If `db.statement` is not applicable. - -- 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.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: Optional - -- 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 `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.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", -] - - -#### 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 `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 `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 `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: 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: Conditionally Required - If using a port other than the default port for this DBMS and if `server.address` is set. - -- Tag: call-level-tech-specific - -- Type: int -- Examples: [ - 80, - 8080, - 443, -] - -- 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: Required - -- Tag: call-level-tech-specific - -- Type: string -- Examples: [ - "https://localhost:9200/index/_search?q=user.id:kimchy", -] - -- Stability: Stable - - - -## 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.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.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 `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, -] - - -#### 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 `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 - - - -## 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.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.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.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.idempotence` - -Whether or not the query is idempotent. - - - -- Requirement Level: Recommended - -- Tag: call-level-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: call-level-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: call-level-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: call-level-tech-specific-cassandra - -- Type: string -- Examples: mytable - - -#### Attribute `db.name` - -The keyspace name in Cassandra. - - - -For Cassandra the `db.name` should be set to the Cassandra keyspace name. - -- Requirement Level: Conditionally Required - If applicable. - -- Tag: call-level-tech-specific-cassandra - -- Type: string -- Examples: [ - "mykeyspace", -] - - -#### 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: Optional - -- 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.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.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 `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, -] - - -#### 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 `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 - - diff --git a/crates/weaver_forge/expected_output/test/metric/jvm.md b/crates/weaver_forge/expected_output/test/metric/jvm.md new file mode 100644 index 00000000..7dbbb85f --- /dev/null +++ b/crates/weaver_forge/expected_output/test/metric/jvm.md @@ -0,0 +1,327 @@ +## Metrics Namespace `jvm` + + +## 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 + + + +## 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 + + + +## 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 + + + +## 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 + + + +## 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 + + + +## 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 + + + +## Metric `jvm.class.loaded` + +Instrument: counter +Unit: {class} +Stability: stable + +### Attributes + + + +## Metric `jvm.class.unloaded` + +Instrument: counter +Unit: {class} +Stability: stable + +### Attributes + + + +## Metric `jvm.class.count` + +Instrument: updowncounter +Unit: {class} +Stability: stable + +### Attributes + + + +## Metric `jvm.cpu.count` + +Instrument: updowncounter +Unit: {cpu} +Stability: stable + +### Attributes + + + +## Metric `jvm.cpu.time` + +Instrument: counter +Unit: s +Stability: stable + +### Attributes + + + +## 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/test/metric/metric_jvm_class_count.md b/crates/weaver_forge/expected_output/test/metric/metric_jvm_class_count.md deleted file mode 100644 index 052e9335..00000000 --- a/crates/weaver_forge/expected_output/test/metric/metric_jvm_class_count.md +++ /dev/null @@ -1,16 +0,0 @@ -## 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/test/metric/metric_jvm_class_loaded.md b/crates/weaver_forge/expected_output/test/metric/metric_jvm_class_loaded.md deleted file mode 100644 index d82ce127..00000000 --- a/crates/weaver_forge/expected_output/test/metric/metric_jvm_class_loaded.md +++ /dev/null @@ -1,16 +0,0 @@ -## 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/test/metric/metric_jvm_class_unloaded.md b/crates/weaver_forge/expected_output/test/metric/metric_jvm_class_unloaded.md deleted file mode 100644 index 8c5cb1c8..00000000 --- a/crates/weaver_forge/expected_output/test/metric/metric_jvm_class_unloaded.md +++ /dev/null @@ -1,16 +0,0 @@ -## 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/test/metric/metric_jvm_cpu_count.md b/crates/weaver_forge/expected_output/test/metric/metric_jvm_cpu_count.md deleted file mode 100644 index a4f5168a..00000000 --- a/crates/weaver_forge/expected_output/test/metric/metric_jvm_cpu_count.md +++ /dev/null @@ -1,16 +0,0 @@ -## 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/test/metric/metric_jvm_cpu_recent_utilization.md b/crates/weaver_forge/expected_output/test/metric/metric_jvm_cpu_recent_utilization.md deleted file mode 100644 index 1b01d182..00000000 --- a/crates/weaver_forge/expected_output/test/metric/metric_jvm_cpu_recent_utilization.md +++ /dev/null @@ -1,16 +0,0 @@ -## 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/test/metric/metric_jvm_cpu_time.md b/crates/weaver_forge/expected_output/test/metric/metric_jvm_cpu_time.md deleted file mode 100644 index 92e917a8..00000000 --- a/crates/weaver_forge/expected_output/test/metric/metric_jvm_cpu_time.md +++ /dev/null @@ -1,16 +0,0 @@ -## 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/test/metric/metric_jvm_gc_duration.md b/crates/weaver_forge/expected_output/test/metric/metric_jvm_gc_duration.md deleted file mode 100644 index 42faa7c2..00000000 --- a/crates/weaver_forge/expected_output/test/metric/metric_jvm_gc_duration.md +++ /dev/null @@ -1,53 +0,0 @@ -## 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/test/metric/metric_jvm_memory_committed.md b/crates/weaver_forge/expected_output/test/metric/metric_jvm_memory_committed.md deleted file mode 100644 index 1708ad6d..00000000 --- a/crates/weaver_forge/expected_output/test/metric/metric_jvm_memory_committed.md +++ /dev/null @@ -1,52 +0,0 @@ -## 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/test/metric/metric_jvm_memory_limit.md b/crates/weaver_forge/expected_output/test/metric/metric_jvm_memory_limit.md deleted file mode 100644 index d2dca2c7..00000000 --- a/crates/weaver_forge/expected_output/test/metric/metric_jvm_memory_limit.md +++ /dev/null @@ -1,52 +0,0 @@ -## 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/test/metric/metric_jvm_memory_used.md b/crates/weaver_forge/expected_output/test/metric/metric_jvm_memory_used.md deleted file mode 100644 index 66ec1681..00000000 --- a/crates/weaver_forge/expected_output/test/metric/metric_jvm_memory_used.md +++ /dev/null @@ -1,52 +0,0 @@ -## 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/test/metric/metric_jvm_memory_used_after_last_gc.md b/crates/weaver_forge/expected_output/test/metric/metric_jvm_memory_used_after_last_gc.md deleted file mode 100644 index 6f71ae44..00000000 --- a/crates/weaver_forge/expected_output/test/metric/metric_jvm_memory_used_after_last_gc.md +++ /dev/null @@ -1,52 +0,0 @@ -## 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/test/metric/metric_jvm_thread_count.md b/crates/weaver_forge/expected_output/test/metric/metric_jvm_thread_count.md deleted file mode 100644 index 03ec08d1..00000000 --- a/crates/weaver_forge/expected_output/test/metric/metric_jvm_thread_count.md +++ /dev/null @@ -1,45 +0,0 @@ -## 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/test/metrics.md b/crates/weaver_forge/expected_output/test/metrics.md index f255e743..1850ee4f 100644 --- a/crates/weaver_forge/expected_output/test/metrics.md +++ b/crates/weaver_forge/expected_output/test/metrics.md @@ -1,19 +1,12 @@ -# Semantic Convention Metric Groups +# Metric Namespace `jvm` -## Group `metric.jvm.memory.used` (metric) -### Brief +## Metric `jvm.memory.used` -Measure of memory used. - - - -Prefix: -Metric: jvm.memory.used Instrument: updowncounter Unit: By -Stability: Stable +Stability: stable ### Attributes @@ -54,19 +47,11 @@ Pool names are generally obtained via [MemoryPoolMXBean#getName()](https://docs. -## Group `metric.jvm.memory.committed` (metric) - -### Brief - -Measure of memory committed. - +## Metric `jvm.memory.committed` - -Prefix: -Metric: jvm.memory.committed Instrument: updowncounter Unit: By -Stability: Stable +Stability: stable ### Attributes @@ -107,19 +92,11 @@ Pool names are generally obtained via [MemoryPoolMXBean#getName()](https://docs. -## Group `metric.jvm.memory.limit` (metric) - -### Brief - -Measure of max obtainable memory. +## Metric `jvm.memory.limit` - - -Prefix: -Metric: jvm.memory.limit Instrument: updowncounter Unit: By -Stability: Stable +Stability: stable ### Attributes @@ -160,19 +137,11 @@ Pool names are generally obtained via [MemoryPoolMXBean#getName()](https://docs. -## Group `metric.jvm.memory.used_after_last_gc` (metric) - -### Brief +## Metric `jvm.memory.used_after_last_gc` -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 +Stability: stable ### Attributes @@ -213,19 +182,11 @@ Pool names are generally obtained via [MemoryPoolMXBean#getName()](https://docs. -## Group `metric.jvm.gc.duration` (metric) - -### Brief - -Duration of JVM garbage collection actions. - +## Metric `jvm.gc.duration` - -Prefix: jvm.gc -Metric: jvm.gc.duration Instrument: histogram Unit: s -Stability: Stable +Stability: stable ### Attributes @@ -267,19 +228,11 @@ Garbage collector action is generally obtained via [GarbageCollectionNotificatio -## Group `metric.jvm.thread.count` (metric) - -### Brief - -Number of executing platform threads. +## Metric `jvm.thread.count` - - -Prefix: -Metric: jvm.thread.count Instrument: updowncounter Unit: {thread} -Stability: Stable +Stability: stable ### Attributes @@ -313,111 +266,65 @@ State of the thread. -## Group `metric.jvm.class.loaded` (metric) - -### Brief +## Metric `jvm.class.loaded` -Number of classes loaded since JVM start. - - - -Prefix: -Metric: jvm.class.loaded Instrument: counter Unit: {class} -Stability: Stable +Stability: stable ### Attributes -## Group `metric.jvm.class.unloaded` (metric) - -### Brief - -Number of classes unloaded since JVM start. - +## Metric `jvm.class.unloaded` - -Prefix: -Metric: jvm.class.unloaded Instrument: counter Unit: {class} -Stability: Stable +Stability: stable ### Attributes -## Group `metric.jvm.class.count` (metric) - -### Brief - -Number of classes currently loaded. +## Metric `jvm.class.count` - - -Prefix: -Metric: jvm.class.count Instrument: updowncounter Unit: {class} -Stability: Stable +Stability: stable ### Attributes -## Group `metric.jvm.cpu.count` (metric) - -### Brief +## Metric `jvm.cpu.count` -Number of processors available to the Java virtual machine. - - - -Prefix: -Metric: jvm.cpu.count Instrument: updowncounter Unit: {cpu} -Stability: Stable +Stability: stable ### Attributes -## Group `metric.jvm.cpu.time` (metric) - -### Brief - -CPU time used by the process as reported by the JVM. - +## Metric `jvm.cpu.time` - -Prefix: -Metric: jvm.cpu.time Instrument: counter Unit: s -Stability: Stable +Stability: stable ### Attributes -## Group `metric.jvm.cpu.recent_utilization` (metric) - -### Brief - -Recent CPU utilization for the process as reported by the JVM. +## Metric `jvm.cpu.recent_utilization` -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 +Stability: stable ### Attributes + + \ No newline at end of file diff --git a/crates/weaver_forge/expected_output/test/resource/otel_library.md b/crates/weaver_forge/expected_output/test/resource/library.md similarity index 70% rename from crates/weaver_forge/expected_output/test/resource/otel_library.md rename to crates/weaver_forge/expected_output/test/resource/library.md index cc192999..4d7dbc05 100644 --- a/crates/weaver_forge/expected_output/test/resource/otel_library.md +++ b/crates/weaver_forge/expected_output/test/resource/library.md @@ -1,10 +1,12 @@ -## Group `otel.library` (resource) +## Namespace Resource `library` -### Brief -Span attributes used by non-OTLP exporters to represent OpenTelemetry Scope's concepts. -prefix: otel.library +## Resource `otel.library` + +Note: +Brief: Span attributes used by non-OTLP exporters to represent OpenTelemetry Scope's concepts. + ### Attributes @@ -36,4 +38,5 @@ prefix: otel.library ] - Deprecated: use the `otel.scope.version` attribute. + \ No newline at end of file diff --git a/crates/weaver_forge/expected_output/test/resource/otel_scope.md b/crates/weaver_forge/expected_output/test/resource/scope.md similarity index 76% rename from crates/weaver_forge/expected_output/test/resource/otel_scope.md rename to crates/weaver_forge/expected_output/test/resource/scope.md index 9fcb8e68..efaa54bc 100644 --- a/crates/weaver_forge/expected_output/test/resource/otel_scope.md +++ b/crates/weaver_forge/expected_output/test/resource/scope.md @@ -1,10 +1,11 @@ -## Group `otel.scope` (resource) +## Namespace Resource `scope` -### Brief -Attributes used by non-OTLP exporters to represent OpenTelemetry Scope's concepts. -prefix: otel.scope +## Resource `otel.scope` + +Note: +Brief: Attributes used by non-OTLP exporters to represent OpenTelemetry Scope's concepts. ### Attributes @@ -38,4 +39,5 @@ The version of the instrumentation scope - (`InstrumentationScope.Version` in OT - Stability: Stable + \ No newline at end of file diff --git a/crates/weaver_forge/expected_output/test/resources.md b/crates/weaver_forge/expected_output/test/resources.md index 1554f001..bb21a7f9 100644 --- a/crates/weaver_forge/expected_output/test/resources.md +++ b/crates/weaver_forge/expected_output/test/resources.md @@ -1,20 +1,22 @@ # Semantic Convention Resource Groups -## Group `otel.scope` (resource) +## Namespace Resource `library` -### Brief -Attributes used by non-OTLP exporters to represent OpenTelemetry Scope's concepts. -prefix: otel.scope +## Resource `otel.library` + +Note: +Brief: Span attributes used by non-OTLP exporters to represent OpenTelemetry Scope's concepts. + ### Attributes -#### Attribute `otel.scope.name` +#### Attribute `otel.library.name` + -The name of the instrumentation scope - (`InstrumentationScope.Name` in OTLP). - Requirement Level: Recommended @@ -23,13 +25,12 @@ The name of the instrumentation scope - (`InstrumentationScope.Name` in OTLP). - Examples: [ "io.opentelemetry.contrib.mongodb", ] - -- Stability: Stable +- Deprecated: use the `otel.scope.name` attribute. -#### Attribute `otel.scope.version` +#### Attribute `otel.library.version` + -The version of the instrumentation scope - (`InstrumentationScope.Version` in OTLP). - Requirement Level: Recommended @@ -38,25 +39,26 @@ The version of the instrumentation scope - (`InstrumentationScope.Version` in OT - Examples: [ "1.0.0", ] - -- Stability: Stable +- Deprecated: use the `otel.scope.version` attribute. -## Group `otel.library` (resource) +- +## Namespace Resource `scope` -### Brief -Span attributes used by non-OTLP exporters to represent OpenTelemetry Scope's concepts. -prefix: otel.library +## Resource `otel.scope` -### Attributes +Note: +Brief: Attributes used by non-OTLP exporters to represent OpenTelemetry Scope's concepts. +### Attributes -#### Attribute `otel.library.name` +#### Attribute `otel.scope.name` +The name of the instrumentation scope - (`InstrumentationScope.Name` in OTLP). - Requirement Level: Recommended @@ -65,12 +67,13 @@ prefix: otel.library - Examples: [ "io.opentelemetry.contrib.mongodb", ] -- Deprecated: use the `otel.scope.name` attribute. +- Stability: Stable -#### Attribute `otel.library.version` - + +#### Attribute `otel.scope.version` +The version of the instrumentation scope - (`InstrumentationScope.Version` in OTLP). - Requirement Level: Recommended @@ -79,7 +82,9 @@ prefix: otel.library - Examples: [ "1.0.0", ] -- Deprecated: use the `otel.scope.version` attribute. + +- Stability: Stable + - \ No newline at end of file +- \ No newline at end of file diff --git a/crates/weaver_forge/expected_output/test/span/db_cassandra.md b/crates/weaver_forge/expected_output/test/span/cassandra.md similarity index 98% rename from crates/weaver_forge/expected_output/test/span/db_cassandra.md rename to crates/weaver_forge/expected_output/test/span/cassandra.md index 00ca15eb..54f68f73 100644 --- a/crates/weaver_forge/expected_output/test/span/db_cassandra.md +++ b/crates/weaver_forge/expected_output/test/span/cassandra.md @@ -1,10 +1,9 @@ -## Group `db.cassandra` (span) +## Namespace Span `cassandra` -### Brief - -Call-level attributes for Cassandra +## Span `db.cassandra` +Call-level attributes for Cassandra Prefix: Kind: none @@ -23,7 +22,7 @@ An identifier for the database management system (DBMS) product being used. See - 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. @@ -37,7 +36,7 @@ The connection string used to connect to the database. It is recommended to remo - Type: string - Examples: Server=(localdb)\v11.0;Integrated Security=true; - + #### Attribute `db.user` Username for accessing the database. @@ -54,7 +53,7 @@ Username for accessing the database. "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. @@ -71,7 +70,7 @@ The fully-qualified class name of the [Java Database Connectivity (JDBC)](https: "com.microsoft.sqlserver.jdbc.SQLServerDriver", ] - + #### Attribute `db.statement` The database statement being executed. @@ -88,7 +87,7 @@ The database statement being executed. "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. @@ -108,7 +107,7 @@ When setting this to an SQL keyword, it is not recommended to attempt any client "SELECT", ] - + #### Attribute `server.address` Name of the database host. @@ -130,7 +129,7 @@ When observed from the client side, and when communicating through an intermedia - Stability: Stable - + #### Attribute `server.port` Server port number. @@ -151,7 +150,7 @@ When observed from the client side, and when communicating through an intermedia - Stability: Stable - + #### Attribute `network.peer.address` Peer address of the network connection - IP address or Unix domain socket name. @@ -169,7 +168,7 @@ Peer address of the network connection - IP address or Unix domain socket name. - Stability: Stable - + #### Attribute `network.peer.port` Peer port number of the network connection. @@ -186,7 +185,7 @@ Peer port number of the network connection. - 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). @@ -211,7 +210,7 @@ different processes could be listening on TCP port 12345 and UDP port 12345. - Stability: Stable - + #### Attribute `network.type` [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. @@ -231,7 +230,7 @@ The value SHOULD be normalized to lowercase. - 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`. @@ -245,7 +244,7 @@ An identifier (address, unique name, or any other identifier) of the database in - Type: string - Examples: mysql-e26b99z.example.com - + #### 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). @@ -258,7 +257,7 @@ The consistency level of the query. Based on consistency values from [CQL](https - Type: Enum [all, each_quorum, quorum, local_quorum, one, two, three, local_one, any, serial, local_serial] - + #### Attribute `db.cassandra.coordinator.dc` The data center of the coordinating node for a query. @@ -272,7 +271,7 @@ The data center of the coordinating node for a query. - Type: string - Examples: us-west-2 - + #### Attribute `db.cassandra.coordinator.id` The ID of the coordinating node for a query. @@ -286,7 +285,7 @@ The ID of the coordinating node for a query. - Type: string - Examples: be13faa2-8574-4d71-926d-27f16cf8a7af - + #### Attribute `db.cassandra.idempotence` Whether or not the query is idempotent. @@ -299,7 +298,7 @@ Whether or not the query is idempotent. - Type: boolean - + #### Attribute `db.cassandra.page_size` The fetch size used for paging, i.e. how many rows will be returned at once. @@ -315,7 +314,7 @@ The fetch size used for paging, i.e. how many rows will be returned at once. 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. @@ -332,7 +331,7 @@ The number of times a query was speculatively executed. Not set or `0` if the qu 2, ] - + #### Attribute `db.cassandra.table` The name of the primary Cassandra table that the operation is acting upon, including the keyspace name (if applicable). @@ -347,7 +346,7 @@ This mirrors the db.sql.table attribute but references cassandra rather than sql - Type: string - Examples: mytable - + #### Attribute `db.name` The keyspace name in Cassandra. @@ -365,4 +364,5 @@ For Cassandra the `db.name` should be set to the Cassandra keyspace name. "mykeyspace", ] - \ No newline at end of file + + \ No newline at end of file diff --git a/crates/weaver_forge/expected_output/test/span/db_cosmosdb.md b/crates/weaver_forge/expected_output/test/span/cosmosdb.md similarity index 98% rename from crates/weaver_forge/expected_output/test/span/db_cosmosdb.md rename to crates/weaver_forge/expected_output/test/span/cosmosdb.md index 4cb0a0ea..76fde666 100644 --- a/crates/weaver_forge/expected_output/test/span/db_cosmosdb.md +++ b/crates/weaver_forge/expected_output/test/span/cosmosdb.md @@ -1,10 +1,9 @@ -## Group `db.cosmosdb` (span) +## Namespace Span `cosmosdb` -### Brief - -Call-level attributes for Cosmos DB. +## Span `db.cosmosdb` +Call-level attributes for Cosmos DB. Prefix: db.cosmosdb Kind: none @@ -23,7 +22,7 @@ An identifier for the database management system (DBMS) product being used. See - 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. @@ -37,7 +36,7 @@ The connection string used to connect to the database. It is recommended to remo - Type: string - Examples: Server=(localdb)\v11.0;Integrated Security=true; - + #### Attribute `db.user` Username for accessing the database. @@ -54,7 +53,7 @@ Username for accessing the database. "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. @@ -71,7 +70,7 @@ The fully-qualified class name of the [Java Database Connectivity (JDBC)](https: "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). @@ -90,7 +89,7 @@ In some SQL databases, the database name to be used is called "schema name". In "main", ] - + #### Attribute `db.statement` The database statement being executed. @@ -107,7 +106,7 @@ The database statement being executed. "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. @@ -127,7 +126,7 @@ When setting this to an SQL keyword, it is not recommended to attempt any client "SELECT", ] - + #### Attribute `server.address` Name of the database host. @@ -149,7 +148,7 @@ When observed from the client side, and when communicating through an intermedia - Stability: Stable - + #### Attribute `server.port` Server port number. @@ -170,7 +169,7 @@ When observed from the client side, and when communicating through an intermedia - Stability: Stable - + #### Attribute `network.peer.address` Peer address of the network connection - IP address or Unix domain socket name. @@ -188,7 +187,7 @@ Peer address of the network connection - IP address or Unix domain socket name. - Stability: Stable - + #### Attribute `network.peer.port` Peer port number of the network connection. @@ -205,7 +204,7 @@ Peer port number of the network connection. - 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). @@ -230,7 +229,7 @@ different processes could be listening on TCP port 12345 and UDP port 12345. - Stability: Stable - + #### Attribute `network.type` [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. @@ -250,7 +249,7 @@ The value SHOULD be normalized to lowercase. - 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`. @@ -264,7 +263,7 @@ An identifier (address, unique name, or any other identifier) of the database in - Type: string - Examples: mysql-e26b99z.example.com - + #### Attribute `db.cosmosdb.client_id` Unique Cosmos client instance id. @@ -277,7 +276,7 @@ Unique Cosmos client instance id. - Type: string - Examples: 3ba4827d-4422-483f-b59f-85b74211c11d - + #### Attribute `db.cosmosdb.connection_mode` Cosmos client connection mode. @@ -289,7 +288,7 @@ Cosmos client connection mode. - Type: Enum [gateway, direct] - + #### Attribute `db.cosmosdb.container` Cosmos DB container name. @@ -302,7 +301,7 @@ Cosmos DB container name. - Type: string - Examples: anystring - + #### Attribute `db.cosmosdb.operation_type` CosmosDB Operation Type. @@ -314,7 +313,7 @@ CosmosDB Operation Type. - 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 @@ -330,7 +329,7 @@ RU consumed for that operation 1.0, ] - + #### Attribute `db.cosmosdb.request_content_length` Request payload size in bytes @@ -342,7 +341,7 @@ Request payload size in bytes - Type: int - + #### Attribute `db.cosmosdb.status_code` Cosmos DB status code. @@ -358,7 +357,7 @@ Cosmos DB status code. 201, ] - + #### Attribute `db.cosmosdb.sub_status_code` Cosmos DB sub status code. @@ -374,7 +373,7 @@ Cosmos DB sub status code. 1002, ] - + #### Attribute `user_agent.original` Full user-agent string is generated by Cosmos DB SDK @@ -395,4 +394,5 @@ The user-agent value is generated by SDK which is a combination of
`sdk_vers - Stability: Stable - \ No newline at end of file + + \ No newline at end of file diff --git a/crates/weaver_forge/expected_output/test/span/db_couchdb.md b/crates/weaver_forge/expected_output/test/span/couchdb.md similarity index 98% rename from crates/weaver_forge/expected_output/test/span/db_couchdb.md rename to crates/weaver_forge/expected_output/test/span/couchdb.md index 7441755d..7e0aab60 100644 --- a/crates/weaver_forge/expected_output/test/span/db_couchdb.md +++ b/crates/weaver_forge/expected_output/test/span/couchdb.md @@ -1,10 +1,9 @@ -## Group `db.couchdb` (span) +## Namespace Span `couchdb` -### Brief - -Call-level attributes for CouchDB +## Span `db.couchdb` +Call-level attributes for CouchDB Prefix: Kind: none @@ -23,7 +22,7 @@ An identifier for the database management system (DBMS) product being used. See - 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. @@ -37,7 +36,7 @@ The connection string used to connect to the database. It is recommended to remo - Type: string - Examples: Server=(localdb)\v11.0;Integrated Security=true; - + #### Attribute `db.user` Username for accessing the database. @@ -54,7 +53,7 @@ Username for accessing the database. "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. @@ -71,7 +70,7 @@ The fully-qualified class name of the [Java Database Connectivity (JDBC)](https: "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). @@ -90,7 +89,7 @@ In some SQL databases, the database name to be used is called "schema name". In "main", ] - + #### Attribute `db.statement` The database statement being executed. @@ -107,7 +106,7 @@ The database statement being executed. "SET mykey \"WuValue\"", ] - + #### Attribute `server.address` Name of the database host. @@ -129,7 +128,7 @@ When observed from the client side, and when communicating through an intermedia - Stability: Stable - + #### Attribute `server.port` Server port number. @@ -150,7 +149,7 @@ When observed from the client side, and when communicating through an intermedia - Stability: Stable - + #### Attribute `network.peer.address` Peer address of the network connection - IP address or Unix domain socket name. @@ -168,7 +167,7 @@ Peer address of the network connection - IP address or Unix domain socket name. - Stability: Stable - + #### Attribute `network.peer.port` Peer port number of the network connection. @@ -185,7 +184,7 @@ Peer port number of the network connection. - 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). @@ -210,7 +209,7 @@ different processes could be listening on TCP port 12345 and UDP port 12345. - Stability: Stable - + #### Attribute `network.type` [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. @@ -230,7 +229,7 @@ The value SHOULD be normalized to lowercase. - 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`. @@ -244,7 +243,7 @@ An identifier (address, unique name, or any other identifier) of the database in - Type: string - Examples: mysql-e26b99z.example.com - + #### Attribute `db.operation` The HTTP method + the target REST route. @@ -262,4 +261,5 @@ In **CouchDB**, `db.operation` should be set to the HTTP method + the target RES "GET /{db}/{docid}", ] - \ No newline at end of file + + \ No newline at end of file diff --git a/crates/weaver_forge/expected_output/test/span/db_elasticsearch.md b/crates/weaver_forge/expected_output/test/span/elasticsearch.md similarity index 98% rename from crates/weaver_forge/expected_output/test/span/db_elasticsearch.md rename to crates/weaver_forge/expected_output/test/span/elasticsearch.md index f22e18bc..656aa442 100644 --- a/crates/weaver_forge/expected_output/test/span/db_elasticsearch.md +++ b/crates/weaver_forge/expected_output/test/span/elasticsearch.md @@ -1,10 +1,9 @@ -## Group `db.elasticsearch` (span) +## Namespace Span `elasticsearch` -### Brief - -Call-level attributes for Elasticsearch +## Span `db.elasticsearch` +Call-level attributes for Elasticsearch Prefix: Kind: none @@ -23,7 +22,7 @@ An identifier for the database management system (DBMS) product being used. See - 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. @@ -37,7 +36,7 @@ The connection string used to connect to the database. It is recommended to remo - Type: string - Examples: Server=(localdb)\v11.0;Integrated Security=true; - + #### Attribute `db.user` Username for accessing the database. @@ -54,7 +53,7 @@ Username for accessing the database. "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. @@ -71,7 +70,7 @@ The fully-qualified class name of the [Java Database Connectivity (JDBC)](https: "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). @@ -90,7 +89,7 @@ In some SQL databases, the database name to be used is called "schema name". In "main", ] - + #### Attribute `network.peer.address` Peer address of the network connection - IP address or Unix domain socket name. @@ -108,7 +107,7 @@ Peer address of the network connection - IP address or Unix domain socket name. - Stability: Stable - + #### Attribute `network.peer.port` Peer port number of the network connection. @@ -125,7 +124,7 @@ Peer port number of the network connection. - 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). @@ -150,7 +149,7 @@ different processes could be listening on TCP port 12345 and UDP port 12345. - Stability: Stable - + #### Attribute `network.type` [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. @@ -170,7 +169,7 @@ The value SHOULD be normalized to lowercase. - 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`. @@ -184,7 +183,7 @@ An identifier (address, unique name, or any other identifier) of the database in - Type: string - Examples: mysql-e26b99z.example.com - + #### Attribute `db.elasticsearch.cluster.name` Represents the identifier of an Elasticsearch cluster. @@ -200,7 +199,7 @@ Represents the identifier of an Elasticsearch cluster. "e9106fc68e3044f0b1475b04bf4ffd5f", ] - + #### Attribute `db.elasticsearch.node.name` Represents the human-readable identifier of the node/instance to which a request was routed. @@ -216,7 +215,7 @@ Represents the human-readable identifier of the node/instance to which a request "instance-0000000001", ] - + #### Attribute `db.elasticsearch.path_parts` A dynamic value in the url path. @@ -235,7 +234,7 @@ Many Elasticsearch url paths allow dynamic values. These SHOULD be recorded in s "db.elasticsearch.path_parts.doc_id=123", ] - + #### Attribute `db.operation` The endpoint identifier for the request. @@ -254,7 +253,7 @@ When setting this to an SQL keyword, it is not recommended to attempt any client "cat.aliases", ] - + #### 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. @@ -269,7 +268,7 @@ The request body for a [search-type query](https://www.elastic.co/guide/en/elast "\"{\\\"query\\\":{\\\"term\\\":{\\\"user.id\\\":\\\"kimchy\\\"}}}\"", ] - + #### Attribute `http.request.method` HTTP request method. @@ -303,7 +302,7 @@ Tracing instrumentations that do so, MUST also set `http.request.method_original - Stability: Stable - + #### Attribute `server.address` Name of the database host. @@ -325,7 +324,7 @@ When observed from the client side, and when communicating through an intermedia - Stability: Stable - + #### Attribute `server.port` Server port number. @@ -346,7 +345,7 @@ When observed from the client side, and when communicating through an intermedia - Stability: Stable - + #### Attribute `url.full` Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986) @@ -367,4 +366,5 @@ For network calls, URL usually has `scheme://host[:port][path][?query][#fragment - Stability: Stable - \ No newline at end of file + + \ No newline at end of file diff --git a/crates/weaver_forge/expected_output/test/span/db_hbase.md b/crates/weaver_forge/expected_output/test/span/hbase.md similarity index 98% rename from crates/weaver_forge/expected_output/test/span/db_hbase.md rename to crates/weaver_forge/expected_output/test/span/hbase.md index a841c53b..e1b582e5 100644 --- a/crates/weaver_forge/expected_output/test/span/db_hbase.md +++ b/crates/weaver_forge/expected_output/test/span/hbase.md @@ -1,10 +1,9 @@ -## Group `db.hbase` (span) +## Namespace Span `hbase` -### Brief - -Call-level attributes for HBase +## Span `db.hbase` +Call-level attributes for HBase Prefix: Kind: none @@ -23,7 +22,7 @@ An identifier for the database management system (DBMS) product being used. See - 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. @@ -37,7 +36,7 @@ The connection string used to connect to the database. It is recommended to remo - Type: string - Examples: Server=(localdb)\v11.0;Integrated Security=true; - + #### Attribute `db.user` Username for accessing the database. @@ -54,7 +53,7 @@ Username for accessing the database. "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. @@ -71,7 +70,7 @@ The fully-qualified class name of the [Java Database Connectivity (JDBC)](https: "com.microsoft.sqlserver.jdbc.SQLServerDriver", ] - + #### Attribute `db.statement` The database statement being executed. @@ -88,7 +87,7 @@ The database statement being executed. "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. @@ -108,7 +107,7 @@ When setting this to an SQL keyword, it is not recommended to attempt any client "SELECT", ] - + #### Attribute `server.address` Name of the database host. @@ -130,7 +129,7 @@ When observed from the client side, and when communicating through an intermedia - Stability: Stable - + #### Attribute `server.port` Server port number. @@ -151,7 +150,7 @@ When observed from the client side, and when communicating through an intermedia - Stability: Stable - + #### Attribute `network.peer.address` Peer address of the network connection - IP address or Unix domain socket name. @@ -169,7 +168,7 @@ Peer address of the network connection - IP address or Unix domain socket name. - Stability: Stable - + #### Attribute `network.peer.port` Peer port number of the network connection. @@ -186,7 +185,7 @@ Peer port number of the network connection. - 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). @@ -211,7 +210,7 @@ different processes could be listening on TCP port 12345 and UDP port 12345. - Stability: Stable - + #### Attribute `network.type` [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. @@ -231,7 +230,7 @@ The value SHOULD be normalized to lowercase. - 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`. @@ -245,7 +244,7 @@ An identifier (address, unique name, or any other identifier) of the database in - Type: string - Examples: mysql-e26b99z.example.com - + #### Attribute `db.name` The HBase namespace. @@ -263,4 +262,5 @@ For HBase the `db.name` should be set to the HBase namespace. "mynamespace", ] - \ No newline at end of file + + \ No newline at end of file diff --git a/crates/weaver_forge/expected_output/test/span/db_mongodb.md b/crates/weaver_forge/expected_output/test/span/mongodb.md similarity index 98% rename from crates/weaver_forge/expected_output/test/span/db_mongodb.md rename to crates/weaver_forge/expected_output/test/span/mongodb.md index 57458795..081bdca7 100644 --- a/crates/weaver_forge/expected_output/test/span/db_mongodb.md +++ b/crates/weaver_forge/expected_output/test/span/mongodb.md @@ -1,10 +1,9 @@ -## Group `db.mongodb` (span) +## Namespace Span `mongodb` -### Brief - -Call-level attributes for MongoDB +## Span `db.mongodb` +Call-level attributes for MongoDB Prefix: Kind: none @@ -23,7 +22,7 @@ An identifier for the database management system (DBMS) product being used. See - 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. @@ -37,7 +36,7 @@ The connection string used to connect to the database. It is recommended to remo - Type: string - Examples: Server=(localdb)\v11.0;Integrated Security=true; - + #### Attribute `db.user` Username for accessing the database. @@ -54,7 +53,7 @@ Username for accessing the database. "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. @@ -71,7 +70,7 @@ The fully-qualified class name of the [Java Database Connectivity (JDBC)](https: "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). @@ -90,7 +89,7 @@ In some SQL databases, the database name to be used is called "schema name". In "main", ] - + #### Attribute `db.statement` The database statement being executed. @@ -107,7 +106,7 @@ The database statement being executed. "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. @@ -127,7 +126,7 @@ When setting this to an SQL keyword, it is not recommended to attempt any client "SELECT", ] - + #### Attribute `server.address` Name of the database host. @@ -149,7 +148,7 @@ When observed from the client side, and when communicating through an intermedia - Stability: Stable - + #### Attribute `server.port` Server port number. @@ -170,7 +169,7 @@ When observed from the client side, and when communicating through an intermedia - Stability: Stable - + #### Attribute `network.peer.address` Peer address of the network connection - IP address or Unix domain socket name. @@ -188,7 +187,7 @@ Peer address of the network connection - IP address or Unix domain socket name. - Stability: Stable - + #### Attribute `network.peer.port` Peer port number of the network connection. @@ -205,7 +204,7 @@ Peer port number of the network connection. - 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). @@ -230,7 +229,7 @@ different processes could be listening on TCP port 12345 and UDP port 12345. - Stability: Stable - + #### Attribute `network.type` [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. @@ -250,7 +249,7 @@ The value SHOULD be normalized to lowercase. - 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`. @@ -264,7 +263,7 @@ An identifier (address, unique name, or any other identifier) of the database in - Type: string - Examples: mysql-e26b99z.example.com - + #### Attribute `db.mongodb.collection` The MongoDB collection being accessed within the database stated in `db.name`. @@ -281,4 +280,5 @@ The MongoDB collection being accessed within the database stated in `db.name`. "products", ] - \ No newline at end of file + + \ No newline at end of file diff --git a/crates/weaver_forge/expected_output/test/span/db_mssql.md b/crates/weaver_forge/expected_output/test/span/mssql.md similarity index 98% rename from crates/weaver_forge/expected_output/test/span/db_mssql.md rename to crates/weaver_forge/expected_output/test/span/mssql.md index 8ecd58f9..38723ea0 100644 --- a/crates/weaver_forge/expected_output/test/span/db_mssql.md +++ b/crates/weaver_forge/expected_output/test/span/mssql.md @@ -1,10 +1,9 @@ -## Group `db.mssql` (span) +## Namespace Span `mssql` -### Brief - -Connection-level attributes for Microsoft SQL Server +## Span `db.mssql` +Connection-level attributes for Microsoft SQL Server Prefix: Kind: none @@ -23,7 +22,7 @@ An identifier for the database management system (DBMS) product being used. See - 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. @@ -37,7 +36,7 @@ The connection string used to connect to the database. It is recommended to remo - Type: string - Examples: Server=(localdb)\v11.0;Integrated Security=true; - + #### Attribute `db.user` Username for accessing the database. @@ -54,7 +53,7 @@ Username for accessing the database. "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. @@ -71,7 +70,7 @@ The fully-qualified class name of the [Java Database Connectivity (JDBC)](https: "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). @@ -90,7 +89,7 @@ In some SQL databases, the database name to be used is called "schema name". In "main", ] - + #### Attribute `db.statement` The database statement being executed. @@ -107,7 +106,7 @@ The database statement being executed. "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. @@ -127,7 +126,7 @@ When setting this to an SQL keyword, it is not recommended to attempt any client "SELECT", ] - + #### Attribute `server.address` Name of the database host. @@ -149,7 +148,7 @@ When observed from the client side, and when communicating through an intermedia - Stability: Stable - + #### Attribute `server.port` Server port number. @@ -170,7 +169,7 @@ When observed from the client side, and when communicating through an intermedia - Stability: Stable - + #### Attribute `network.peer.address` Peer address of the network connection - IP address or Unix domain socket name. @@ -188,7 +187,7 @@ Peer address of the network connection - IP address or Unix domain socket name. - Stability: Stable - + #### Attribute `network.peer.port` Peer port number of the network connection. @@ -205,7 +204,7 @@ Peer port number of the network connection. - 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). @@ -230,7 +229,7 @@ different processes could be listening on TCP port 12345 and UDP port 12345. - Stability: Stable - + #### Attribute `network.type` [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. @@ -250,7 +249,7 @@ The value SHOULD be normalized to lowercase. - 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`. @@ -264,7 +263,7 @@ An identifier (address, unique name, or any other identifier) of the database in - 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. @@ -280,4 +279,5 @@ If setting a `db.mssql.instance_name`, `server.port` is no longer required (but - Type: string - Examples: MSSQLSERVER - \ No newline at end of file + + \ No newline at end of file diff --git a/crates/weaver_forge/expected_output/test/span/db.md b/crates/weaver_forge/expected_output/test/span/other.md similarity index 98% rename from crates/weaver_forge/expected_output/test/span/db.md rename to crates/weaver_forge/expected_output/test/span/other.md index 8b6ec00a..521fdc48 100644 --- a/crates/weaver_forge/expected_output/test/span/db.md +++ b/crates/weaver_forge/expected_output/test/span/other.md @@ -1,10 +1,9 @@ -## Group `db` (span) +## Namespace Span `other` -### Brief - -This document defines the attributes used to perform database client calls. +## Span `db` +This document defines the attributes used to perform database client calls. Prefix: Kind: client @@ -23,7 +22,7 @@ An identifier for the database management system (DBMS) product being used. See - 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. @@ -37,7 +36,7 @@ The connection string used to connect to the database. It is recommended to remo - Type: string - Examples: Server=(localdb)\v11.0;Integrated Security=true; - + #### Attribute `db.user` Username for accessing the database. @@ -54,7 +53,7 @@ Username for accessing the database. "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. @@ -71,7 +70,7 @@ The fully-qualified class name of the [Java Database Connectivity (JDBC)](https: "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). @@ -90,7 +89,7 @@ In some SQL databases, the database name to be used is called "schema name". In "main", ] - + #### Attribute `db.statement` The database statement being executed. @@ -107,7 +106,7 @@ The database statement being executed. "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. @@ -127,7 +126,7 @@ When setting this to an SQL keyword, it is not recommended to attempt any client "SELECT", ] - + #### Attribute `server.address` Name of the database host. @@ -149,7 +148,7 @@ When observed from the client side, and when communicating through an intermedia - Stability: Stable - + #### Attribute `server.port` Server port number. @@ -170,7 +169,7 @@ When observed from the client side, and when communicating through an intermedia - Stability: Stable - + #### Attribute `network.peer.address` Peer address of the network connection - IP address or Unix domain socket name. @@ -188,7 +187,7 @@ Peer address of the network connection - IP address or Unix domain socket name. - Stability: Stable - + #### Attribute `network.peer.port` Peer port number of the network connection. @@ -205,7 +204,7 @@ Peer port number of the network connection. - 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). @@ -230,7 +229,7 @@ different processes could be listening on TCP port 12345 and UDP port 12345. - Stability: Stable - + #### Attribute `network.type` [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. @@ -250,7 +249,7 @@ The value SHOULD be normalized to lowercase. - 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`. @@ -264,4 +263,5 @@ An identifier (address, unique name, or any other identifier) of the database in - Type: string - Examples: mysql-e26b99z.example.com - \ No newline at end of file + + \ No newline at end of file diff --git a/crates/weaver_forge/expected_output/test/span/db_redis.md b/crates/weaver_forge/expected_output/test/span/redis.md similarity index 98% rename from crates/weaver_forge/expected_output/test/span/db_redis.md rename to crates/weaver_forge/expected_output/test/span/redis.md index f2b3c78d..dcbe2ab8 100644 --- a/crates/weaver_forge/expected_output/test/span/db_redis.md +++ b/crates/weaver_forge/expected_output/test/span/redis.md @@ -1,10 +1,9 @@ -## Group `db.redis` (span) +## Namespace Span `redis` -### Brief - -Call-level attributes for Redis +## Span `db.redis` +Call-level attributes for Redis Prefix: Kind: none @@ -23,7 +22,7 @@ An identifier for the database management system (DBMS) product being used. See - 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. @@ -37,7 +36,7 @@ The connection string used to connect to the database. It is recommended to remo - Type: string - Examples: Server=(localdb)\v11.0;Integrated Security=true; - + #### Attribute `db.user` Username for accessing the database. @@ -54,7 +53,7 @@ Username for accessing the database. "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. @@ -71,7 +70,7 @@ The fully-qualified class name of the [Java Database Connectivity (JDBC)](https: "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). @@ -90,7 +89,7 @@ In some SQL databases, the database name to be used is called "schema name". In "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. @@ -110,7 +109,7 @@ When setting this to an SQL keyword, it is not recommended to attempt any client "SELECT", ] - + #### Attribute `server.address` Name of the database host. @@ -132,7 +131,7 @@ When observed from the client side, and when communicating through an intermedia - Stability: Stable - + #### Attribute `server.port` Server port number. @@ -153,7 +152,7 @@ When observed from the client side, and when communicating through an intermedia - Stability: Stable - + #### Attribute `network.peer.address` Peer address of the network connection - IP address or Unix domain socket name. @@ -171,7 +170,7 @@ Peer address of the network connection - IP address or Unix domain socket name. - Stability: Stable - + #### Attribute `network.peer.port` Peer port number of the network connection. @@ -188,7 +187,7 @@ Peer port number of the network connection. - 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). @@ -213,7 +212,7 @@ different processes could be listening on TCP port 12345 and UDP port 12345. - Stability: Stable - + #### Attribute `network.type` [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. @@ -233,7 +232,7 @@ The value SHOULD be normalized to lowercase. - 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`. @@ -247,7 +246,7 @@ An identifier (address, unique name, or any other identifier) of the database in - 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. @@ -265,7 +264,7 @@ The index of the database being accessed as used in the [`SELECT` command](https 15, ] - + #### Attribute `db.statement` The full syntax of the Redis CLI command. @@ -283,4 +282,5 @@ For **Redis**, the value provided for `db.statement` SHOULD correspond to the sy "HMSET myhash field1 'Hello' field2 'World'", ] - \ No newline at end of file + + \ No newline at end of file diff --git a/crates/weaver_forge/expected_output/test/span/db_sql.md b/crates/weaver_forge/expected_output/test/span/sql.md similarity index 98% rename from crates/weaver_forge/expected_output/test/span/db_sql.md rename to crates/weaver_forge/expected_output/test/span/sql.md index a4572016..14d3619a 100644 --- a/crates/weaver_forge/expected_output/test/span/db_sql.md +++ b/crates/weaver_forge/expected_output/test/span/sql.md @@ -1,10 +1,9 @@ -## Group `db.sql` (span) +## Namespace Span `sql` -### Brief - -Call-level attributes for SQL databases +## Span `db.sql` +Call-level attributes for SQL databases Prefix: Kind: none @@ -23,7 +22,7 @@ An identifier for the database management system (DBMS) product being used. See - 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. @@ -37,7 +36,7 @@ The connection string used to connect to the database. It is recommended to remo - Type: string - Examples: Server=(localdb)\v11.0;Integrated Security=true; - + #### Attribute `db.user` Username for accessing the database. @@ -54,7 +53,7 @@ Username for accessing the database. "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. @@ -71,7 +70,7 @@ The fully-qualified class name of the [Java Database Connectivity (JDBC)](https: "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). @@ -90,7 +89,7 @@ In some SQL databases, the database name to be used is called "schema name". In "main", ] - + #### Attribute `db.statement` The database statement being executed. @@ -107,7 +106,7 @@ The database statement being executed. "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. @@ -127,7 +126,7 @@ When setting this to an SQL keyword, it is not recommended to attempt any client "SELECT", ] - + #### Attribute `server.address` Name of the database host. @@ -149,7 +148,7 @@ When observed from the client side, and when communicating through an intermedia - Stability: Stable - + #### Attribute `server.port` Server port number. @@ -170,7 +169,7 @@ When observed from the client side, and when communicating through an intermedia - Stability: Stable - + #### Attribute `network.peer.address` Peer address of the network connection - IP address or Unix domain socket name. @@ -188,7 +187,7 @@ Peer address of the network connection - IP address or Unix domain socket name. - Stability: Stable - + #### Attribute `network.peer.port` Peer port number of the network connection. @@ -205,7 +204,7 @@ Peer port number of the network connection. - 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). @@ -230,7 +229,7 @@ different processes could be listening on TCP port 12345 and UDP port 12345. - Stability: Stable - + #### Attribute `network.type` [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. @@ -250,7 +249,7 @@ The value SHOULD be normalized to lowercase. - 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`. @@ -264,7 +263,7 @@ An identifier (address, unique name, or any other identifier) of the database in - 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). @@ -282,4 +281,5 @@ It is not recommended to attempt any client-side parsing of `db.statement` just "customers", ] - \ No newline at end of file + + \ No newline at end of file diff --git a/crates/weaver_forge/expected_output/test/span/db_tech.md b/crates/weaver_forge/expected_output/test/span/tech.md similarity index 98% rename from crates/weaver_forge/expected_output/test/span/db_tech.md rename to crates/weaver_forge/expected_output/test/span/tech.md index fb45d1df..54ec4d72 100644 --- a/crates/weaver_forge/expected_output/test/span/db_tech.md +++ b/crates/weaver_forge/expected_output/test/span/tech.md @@ -1,10 +1,9 @@ -## Group `db.tech` (span) +## Namespace Span `tech` -### Brief - -Semantic convention group for specific technologies +## Span `db.tech` +Semantic convention group for specific technologies Prefix: Kind: none @@ -23,7 +22,7 @@ An identifier for the database management system (DBMS) product being used. See - 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. @@ -37,7 +36,7 @@ The connection string used to connect to the database. It is recommended to remo - Type: string - Examples: Server=(localdb)\v11.0;Integrated Security=true; - + #### Attribute `db.user` Username for accessing the database. @@ -54,7 +53,7 @@ Username for accessing the database. "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. @@ -71,7 +70,7 @@ The fully-qualified class name of the [Java Database Connectivity (JDBC)](https: "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). @@ -90,7 +89,7 @@ In some SQL databases, the database name to be used is called "schema name". In "main", ] - + #### Attribute `db.statement` The database statement being executed. @@ -107,7 +106,7 @@ The database statement being executed. "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. @@ -127,7 +126,7 @@ When setting this to an SQL keyword, it is not recommended to attempt any client "SELECT", ] - + #### Attribute `server.address` Name of the database host. @@ -149,7 +148,7 @@ When observed from the client side, and when communicating through an intermedia - Stability: Stable - + #### Attribute `server.port` Server port number. @@ -170,7 +169,7 @@ When observed from the client side, and when communicating through an intermedia - Stability: Stable - + #### Attribute `network.peer.address` Peer address of the network connection - IP address or Unix domain socket name. @@ -188,7 +187,7 @@ Peer address of the network connection - IP address or Unix domain socket name. - Stability: Stable - + #### Attribute `network.peer.port` Peer port number of the network connection. @@ -205,7 +204,7 @@ Peer port number of the network connection. - 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). @@ -230,7 +229,7 @@ different processes could be listening on TCP port 12345 and UDP port 12345. - Stability: Stable - + #### Attribute `network.type` [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. @@ -250,7 +249,7 @@ The value SHOULD be normalized to lowercase. - 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`. @@ -264,7 +263,7 @@ An identifier (address, unique name, or any other identifier) of the database in - Type: string - Examples: mysql-e26b99z.example.com - + #### 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). @@ -277,7 +276,7 @@ The consistency level of the query. Based on consistency values from [CQL](https - Type: Enum [all, each_quorum, quorum, local_quorum, one, two, three, local_one, any, serial, local_serial] - + #### Attribute `db.cassandra.coordinator.dc` The data center of the coordinating node for a query. @@ -291,7 +290,7 @@ The data center of the coordinating node for a query. - Type: string - Examples: us-west-2 - + #### Attribute `db.cassandra.coordinator.id` The ID of the coordinating node for a query. @@ -305,7 +304,7 @@ The ID of the coordinating node for a query. - Type: string - Examples: be13faa2-8574-4d71-926d-27f16cf8a7af - + #### Attribute `db.cassandra.idempotence` Whether or not the query is idempotent. @@ -318,7 +317,7 @@ Whether or not the query is idempotent. - Type: boolean - + #### Attribute `db.cassandra.page_size` The fetch size used for paging, i.e. how many rows will be returned at once. @@ -334,7 +333,7 @@ The fetch size used for paging, i.e. how many rows will be returned at once. 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. @@ -351,7 +350,7 @@ The number of times a query was speculatively executed. Not set or `0` if the qu 2, ] - + #### Attribute `db.cassandra.table` The name of the primary Cassandra table that the operation is acting upon, including the keyspace name (if applicable). @@ -366,7 +365,7 @@ This mirrors the db.sql.table attribute but references cassandra rather than sql - Type: string - Examples: mytable - + #### Attribute `db.name` The keyspace name in Cassandra. @@ -384,7 +383,7 @@ For Cassandra the `db.name` should be set to the Cassandra keyspace name. "mykeyspace", ] - + #### 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. @@ -402,7 +401,7 @@ The index of the database being accessed as used in the [`SELECT` command](https 15, ] - + #### Attribute `db.statement` The full syntax of the Redis CLI command. @@ -420,7 +419,7 @@ For **Redis**, the value provided for `db.statement` SHOULD correspond to the sy "HMSET myhash field1 'Hello' field2 'World'", ] - + #### Attribute `db.mongodb.collection` The MongoDB collection being accessed within the database stated in `db.name`. @@ -437,7 +436,7 @@ The MongoDB collection being accessed within the database stated in `db.name`. "products", ] - + #### Attribute `db.sql.table` The name of the primary table that the operation is acting upon, including the database name (if applicable). @@ -455,7 +454,7 @@ It is not recommended to attempt any client-side parsing of `db.statement` just "customers", ] - + #### Attribute `db.cosmosdb.client_id` Unique Cosmos client instance id. @@ -468,7 +467,7 @@ Unique Cosmos client instance id. - Type: string - Examples: 3ba4827d-4422-483f-b59f-85b74211c11d - + #### Attribute `db.cosmosdb.connection_mode` Cosmos client connection mode. @@ -480,7 +479,7 @@ Cosmos client connection mode. - Type: Enum [gateway, direct] - + #### Attribute `db.cosmosdb.container` Cosmos DB container name. @@ -493,7 +492,7 @@ Cosmos DB container name. - Type: string - Examples: anystring - + #### Attribute `db.cosmosdb.operation_type` CosmosDB Operation Type. @@ -505,7 +504,7 @@ CosmosDB Operation Type. - 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 @@ -521,7 +520,7 @@ RU consumed for that operation 1.0, ] - + #### Attribute `db.cosmosdb.request_content_length` Request payload size in bytes @@ -533,7 +532,7 @@ Request payload size in bytes - Type: int - + #### Attribute `db.cosmosdb.status_code` Cosmos DB status code. @@ -549,7 +548,7 @@ Cosmos DB status code. 201, ] - + #### Attribute `db.cosmosdb.sub_status_code` Cosmos DB sub status code. @@ -565,7 +564,7 @@ Cosmos DB sub status code. 1002, ] - + #### Attribute `user_agent.original` Full user-agent string is generated by Cosmos DB SDK @@ -586,4 +585,5 @@ The user-agent value is generated by SDK which is a combination of
`sdk_vers - Stability: Stable - \ No newline at end of file + + \ No newline at end of file diff --git a/crates/weaver_forge/expected_output/test/spans.md b/crates/weaver_forge/expected_output/test/spans.md index 38c6cdb2..952c6200 100644 --- a/crates/weaver_forge/expected_output/test/spans.md +++ b/crates/weaver_forge/expected_output/test/spans.md @@ -1,16 +1,15 @@ # Semantic Convention Span Groups -## Group `db` (span) +## Namespace Spans `cassandra` -### Brief - -This document defines the attributes used to perform database client calls. +## Span `db.cassandra` +Call-level attributes for Cassandra Prefix: -Kind: client +Kind: none ### Attributes @@ -26,7 +25,7 @@ An identifier for the database management system (DBMS) product being used. See - 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. @@ -40,7 +39,7 @@ The connection string used to connect to the database. It is recommended to remo - Type: string - Examples: Server=(localdb)\v11.0;Integrated Security=true; - + #### Attribute `db.user` Username for accessing the database. @@ -57,7 +56,7 @@ Username for accessing the database. "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. @@ -74,26 +73,7 @@ The fully-qualified class name of the [Java Database Connectivity (JDBC)](https: "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. @@ -110,7 +90,7 @@ The database statement being executed. "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. @@ -130,7 +110,7 @@ When setting this to an SQL keyword, it is not recommended to attempt any client "SELECT", ] - + #### Attribute `server.address` Name of the database host. @@ -152,7 +132,7 @@ When observed from the client side, and when communicating through an intermedia - Stability: Stable - + #### Attribute `server.port` Server port number. @@ -173,7 +153,7 @@ When observed from the client side, and when communicating through an intermedia - Stability: Stable - + #### Attribute `network.peer.address` Peer address of the network connection - IP address or Unix domain socket name. @@ -191,7 +171,7 @@ Peer address of the network connection - IP address or Unix domain socket name. - Stability: Stable - + #### Attribute `network.peer.port` Peer port number of the network connection. @@ -208,7 +188,7 @@ Peer port number of the network connection. - 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). @@ -233,7 +213,7 @@ different processes could be listening on TCP port 12345 and UDP port 12345. - Stability: Stable - + #### Attribute `network.type` [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. @@ -253,7 +233,7 @@ The value SHOULD be normalized to lowercase. - 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`. @@ -267,17 +247,137 @@ An identifier (address, unique name, or any other identifier) of the database in - Type: string - Examples: mysql-e26b99z.example.com + +#### 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] -## Group `db.mssql` (span) -### Brief +#### Attribute `db.cassandra.coordinator.dc` -Connection-level attributes for Microsoft SQL Server +The data center of the coordinating node for a query. -Prefix: +- Requirement Level: Recommended + +- Tag: call-level-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: call-level-tech-specific-cassandra + +- Type: string +- Examples: be13faa2-8574-4d71-926d-27f16cf8a7af + + +#### 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.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.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.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.name` + +The keyspace name in Cassandra. + + + +For Cassandra the `db.name` should be set to the Cassandra keyspace name. + +- Requirement Level: Conditionally Required - If applicable. + +- Tag: call-level-tech-specific-cassandra + +- Type: string +- Examples: [ + "mykeyspace", +] + + + + +## Namespace Spans `cosmosdb` + + +## Span `db.cosmosdb` + +Call-level attributes for Cosmos DB. + +Prefix: db.cosmosdb Kind: none ### Attributes @@ -294,7 +394,7 @@ An identifier for the database management system (DBMS) product being used. See - 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. @@ -308,7 +408,7 @@ The connection string used to connect to the database. It is recommended to remo - Type: string - Examples: Server=(localdb)\v11.0;Integrated Security=true; - + #### Attribute `db.user` Username for accessing the database. @@ -325,7 +425,7 @@ Username for accessing the database. "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. @@ -342,7 +442,7 @@ The fully-qualified class name of the [Java Database Connectivity (JDBC)](https: "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). @@ -361,7 +461,7 @@ In some SQL databases, the database name to be used is called "schema name". In "main", ] - + #### Attribute `db.statement` The database statement being executed. @@ -378,7 +478,7 @@ The database statement being executed. "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. @@ -398,7 +498,7 @@ When setting this to an SQL keyword, it is not recommended to attempt any client "SELECT", ] - + #### Attribute `server.address` Name of the database host. @@ -420,7 +520,7 @@ When observed from the client side, and when communicating through an intermedia - Stability: Stable - + #### Attribute `server.port` Server port number. @@ -441,7 +541,7 @@ When observed from the client side, and when communicating through an intermedia - Stability: Stable - + #### Attribute `network.peer.address` Peer address of the network connection - IP address or Unix domain socket name. @@ -459,7 +559,7 @@ Peer address of the network connection - IP address or Unix domain socket name. - Stability: Stable - + #### Attribute `network.peer.port` Peer port number of the network connection. @@ -476,7 +576,7 @@ Peer port number of the network connection. - 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). @@ -501,7 +601,7 @@ different processes could be listening on TCP port 12345 and UDP port 12345. - Stability: Stable - + #### Attribute `network.type` [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. @@ -521,7 +621,7 @@ The value SHOULD be normalized to lowercase. - 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`. @@ -535,400 +635,146 @@ An identifier (address, unique name, or any other identifier) of the database in - 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. +#### Attribute `db.cosmosdb.client_id` +Unique Cosmos client instance id. -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 +- Tag: call-level-tech-specific - Type: string -- Examples: MSSQLSERVER - - +- Examples: 3ba4827d-4422-483f-b59f-85b74211c11d -## Group `db.cassandra` (span) - -### Brief - -Call-level attributes for Cassandra - +#### Attribute `db.cosmosdb.connection_mode` -Prefix: -Kind: none +Cosmos client connection mode. -### Attributes +- Requirement Level: Conditionally Required - if not `direct` (or pick gw as default) + +- Tag: call-level-tech-specific + +- Type: Enum [gateway, direct] + -#### Attribute `db.system` +#### Attribute `db.cosmosdb.container` -An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers. +Cosmos DB container name. -- Requirement Level: Required - -- Tag: connection-level +- Requirement Level: Conditionally Required - if available -- 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] +- Tag: call-level-tech-specific +- Type: string +- Examples: anystring -#### Attribute `db.connection_string` -The connection string used to connect to the database. It is recommended to remove embedded credentials. +#### Attribute `db.cosmosdb.operation_type` +CosmosDB Operation Type. -- Requirement Level: Recommended - -- Tag: connection-level +- Requirement Level: Conditionally Required - when performing one of the operations in this list -- Type: string -- Examples: Server=(localdb)\v11.0;Integrated Security=true; +- Tag: call-level-tech-specific +- Type: Enum [Invalid, Create, Patch, Read, ReadFeed, Delete, Replace, Execute, Query, Head, HeadFeed, Upsert, Batch, QueryPlan, ExecuteJavaScript] -#### Attribute `db.user` -Username for accessing the database. +#### Attribute `db.cosmosdb.request_charge` +RU consumed for that operation -- Requirement Level: Recommended +- Requirement Level: Conditionally Required - when available -- Tag: connection-level +- Tag: call-level-tech-specific -- 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.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 +- Type: double - Examples: [ - "findAndModify", - "HMSET", - "SELECT", + 46.18, + 1.0, ] - -#### Attribute `server.address` -Name of the database host. +#### Attribute `db.cosmosdb.request_content_length` +Request payload size in bytes -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 +- Tag: call-level-tech-specific - 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. +#### Attribute `db.cosmosdb.status_code` -- 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. +Cosmos DB status code. -- Requirement Level: Optional +- Requirement Level: Conditionally Required - if response was received -- Tag: connection-level +- Tag: call-level-tech-specific - 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", + 200, + 201, ] -- Stability: Stable - - -#### Attribute `network.type` -[OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. +#### Attribute `db.cosmosdb.sub_status_code` +Cosmos DB sub status code. -The value SHOULD be normalized to lowercase. -- Requirement Level: Recommended +- Requirement Level: Conditionally Required - when response was received and contained sub-code. -- Tag: connection-level +- Tag: call-level-tech-specific -- Type: Enum [ipv4, ipv6] +- Type: int - Examples: [ - "ipv4", - "ipv6", + 1000, + 1002, ] -- 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.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.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.cassandra.coordinator.id` +#### Attribute `user_agent.original` -The ID of the coordinating node for a query. +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-cassandra +- Tag: call-level-tech-specific - Type: string -- Examples: be13faa2-8574-4d71-926d-27f16cf8a7af - - -#### 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.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.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, + "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.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.name` -The keyspace name in Cassandra. +## Namespace Spans `couchdb` -For Cassandra the `db.name` should be set to the Cassandra keyspace name. - -- Requirement Level: Conditionally Required - If applicable. - -- Tag: call-level-tech-specific-cassandra - -- Type: string -- Examples: [ - "mykeyspace", -] - - - -## Group `db.hbase` (span) - -### Brief - -Call-level attributes for HBase +## Span `db.couchdb` +Call-level attributes for CouchDB Prefix: Kind: none @@ -947,7 +793,7 @@ An identifier for the database management system (DBMS) product being used. See - 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. @@ -961,7 +807,7 @@ The connection string used to connect to the database. It is recommended to remo - Type: string - Examples: Server=(localdb)\v11.0;Integrated Security=true; - + #### Attribute `db.user` Username for accessing the database. @@ -978,7 +824,7 @@ Username for accessing the database. "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. @@ -995,44 +841,43 @@ The fully-qualified class name of the [Java Database Connectivity (JDBC)](https: "com.microsoft.sqlserver.jdbc.SQLServerDriver", ] - -#### Attribute `db.statement` -The database statement being executed. +#### 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). -- Requirement Level: Optional +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: [ - "SELECT * FROM wuser_table", - "SET mykey \"WuValue\"", + "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. +#### Attribute `db.statement` +The database statement being executed. -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. +- Requirement Level: Optional - Tag: call-level - Type: string - Examples: [ - "findAndModify", - "HMSET", - "SELECT", + "SELECT * FROM wuser_table", + "SET mykey \"WuValue\"", ] - + #### Attribute `server.address` Name of the database host. @@ -1054,7 +899,7 @@ When observed from the client side, and when communicating through an intermedia - Stability: Stable - + #### Attribute `server.port` Server port number. @@ -1075,7 +920,7 @@ When observed from the client side, and when communicating through an intermedia - Stability: Stable - + #### Attribute `network.peer.address` Peer address of the network connection - IP address or Unix domain socket name. @@ -1093,7 +938,7 @@ Peer address of the network connection - IP address or Unix domain socket name. - Stability: Stable - + #### Attribute `network.peer.port` Peer port number of the network connection. @@ -1110,7 +955,7 @@ Peer port number of the network connection. - 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). @@ -1135,7 +980,7 @@ different processes could be listening on TCP port 12345 and UDP port 12345. - Stability: Stable - + #### Attribute `network.type` [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. @@ -1155,7 +1000,7 @@ The value SHOULD be normalized to lowercase. - 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`. @@ -1169,33 +1014,33 @@ An identifier (address, unique name, or any other identifier) of the database in - Type: string - Examples: mysql-e26b99z.example.com - -#### Attribute `db.name` -The HBase namespace. +#### Attribute `db.operation` +The HTTP method + the target REST route. -For HBase the `db.name` should be set to the HBase namespace. -- Requirement Level: Conditionally Required - If applicable. +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: Conditionally Required - If `db.statement` is not applicable. - Tag: call-level-tech-specific - Type: string - Examples: [ - "mynamespace", + "GET /{db}/{docid}", ] - - -## Group `db.couchdb` (span) -### Brief -Call-level attributes for CouchDB + +## Namespace Spans `elasticsearch` +## Span `db.elasticsearch` + +Call-level attributes for Elasticsearch Prefix: Kind: none @@ -1214,7 +1059,7 @@ An identifier for the database management system (DBMS) product being used. See - 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. @@ -1228,7 +1073,7 @@ The connection string used to connect to the database. It is recommended to remo - Type: string - Examples: Server=(localdb)\v11.0;Integrated Security=true; - + #### Attribute `db.user` Username for accessing the database. @@ -1245,7 +1090,7 @@ Username for accessing the database. "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. @@ -1262,7 +1107,7 @@ The fully-qualified class name of the [Java Database Connectivity (JDBC)](https: "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). @@ -1281,187 +1126,292 @@ In some SQL databases, the database name to be used is called "schema name". In "main", ] + +#### 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 `db.statement` -The database statement being executed. +#### Attribute `network.peer.port` +Peer port number of the network connection. - Requirement Level: Optional -- Tag: call-level +- Tag: connection-level -- Type: string +- Type: int - Examples: [ - "SELECT * FROM wuser_table", - "SET mykey \"WuValue\"", + 65123, ] +- Stability: Stable -#### Attribute `server.address` -Name of the database host. +#### Attribute `network.transport` +[OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). -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. + +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: string +- Type: Enum [tcp, udp, pipe, unix] - Examples: [ - "example.com", - "10.1.2.80", - "/tmp/my.sock", + "tcp", + "udp", ] - Stability: Stable - -#### Attribute `server.port` -Server port number. +#### Attribute `network.type` +[OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. -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. +The value SHOULD be normalized to lowercase. + +- Requirement Level: Recommended - Tag: connection-level -- Type: int +- Type: Enum [ipv4, ipv6] - Examples: [ - 80, - 8080, - 443, + "ipv4", + "ipv6", ] - Stability: Stable - -#### Attribute `network.peer.address` -Peer address of the network connection - IP address or Unix domain socket name. +#### 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 + + +- Requirement Level: Optional - Tag: connection-level +- Type: string +- Examples: mysql-e26b99z.example.com + + +#### Attribute `db.elasticsearch.cluster.name` + +Represents the identifier of an Elasticsearch cluster. + + + +- Requirement Level: Optional + +- Tag: call-level-tech-specific + - Type: string - Examples: [ - "10.1.2.80", - "/tmp/my.sock", + "e9106fc68e3044f0b1475b04bf4ffd5f", ] -- Stability: Stable + +#### 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 `network.peer.port` -Peer port number of the network connection. +#### Attribute `db.elasticsearch.path_parts` +A dynamic value in the url path. -- Requirement Level: Optional + + +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: connection-level +- Tag: call-level-tech-specific -- Type: int +- Type: template[string] - Examples: [ - 65123, + "db.elasticsearch.path_parts.index=test-index", + "db.elasticsearch.path_parts.doc_id=123", ] -- 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 `network.transport` -[OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication). +#### 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. -The value SHOULD be normalized to lowercase. +- Requirement Level: Optional + +- Tag: call-level-tech-specific + +- Type: string +- Examples: [ + "\"{\\\"query\\\":{\\\"term\\\":{\\\"user.id\\\":\\\"kimchy\\\"}}}\"", +] + -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. +#### Attribute `http.request.method` -- Requirement Level: Recommended +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: connection-level +- Tag: call-level-tech-specific -- Type: Enum [tcp, udp, pipe, unix] +- Type: Enum [CONNECT, DELETE, GET, HEAD, OPTIONS, PATCH, POST, PUT, TRACE, _OTHER] - Examples: [ - "tcp", - "udp", + "GET", + "POST", + "HEAD", ] - Stability: Stable - -#### Attribute `network.type` -[OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. +#### Attribute `server.address` + +Name of the database host. -The value SHOULD be normalized to lowercase. + +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 +- Tag: call-level-tech-specific -- Type: Enum [ipv4, ipv6] +- Type: string - Examples: [ - "ipv4", - "ipv6", + "example.com", + "10.1.2.80", + "/tmp/my.sock", ] - 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`. +#### 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: Optional +- 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 +- Tag: call-level-tech-specific -- Type: string -- Examples: mysql-e26b99z.example.com +- Type: int +- Examples: [ + 80, + 8080, + 443, +] +- Stability: Stable -#### Attribute `db.operation` -The HTTP method + the target REST route. +#### Attribute `url.full` +Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986) -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). +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: Conditionally Required - If `db.statement` is not applicable. +- Requirement Level: Required - Tag: call-level-tech-specific - Type: string - Examples: [ - "GET /{db}/{docid}", + "https://localhost:9200/index/_search?q=user.id:kimchy", ] +- Stability: Stable - -## Group `db.redis` (span) -### Brief -Call-level attributes for Redis +## Namespace Spans `hbase` + + +## Span `db.hbase` +Call-level attributes for HBase Prefix: Kind: none @@ -1480,7 +1430,7 @@ An identifier for the database management system (DBMS) product being used. See - 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. @@ -1494,7 +1444,7 @@ The connection string used to connect to the database. It is recommended to remo - Type: string - Examples: Server=(localdb)\v11.0;Integrated Security=true; - + #### Attribute `db.user` Username for accessing the database. @@ -1511,7 +1461,7 @@ Username for accessing the database. "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. @@ -1528,26 +1478,24 @@ The fully-qualified class name of the [Java Database Connectivity (JDBC)](https: "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). +#### Attribute `db.statement` +The database statement being executed. -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. +- Requirement Level: Optional - Tag: call-level - Type: string - Examples: [ - "customers", - "main", + "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. @@ -1567,7 +1515,7 @@ When setting this to an SQL keyword, it is not recommended to attempt any client "SELECT", ] - + #### Attribute `server.address` Name of the database host. @@ -1589,7 +1537,7 @@ When observed from the client side, and when communicating through an intermedia - Stability: Stable - + #### Attribute `server.port` Server port number. @@ -1610,7 +1558,7 @@ When observed from the client side, and when communicating through an intermedia - Stability: Stable - + #### Attribute `network.peer.address` Peer address of the network connection - IP address or Unix domain socket name. @@ -1628,7 +1576,7 @@ Peer address of the network connection - IP address or Unix domain socket name. - Stability: Stable - + #### Attribute `network.peer.port` Peer port number of the network connection. @@ -1645,7 +1593,7 @@ Peer port number of the network connection. - 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). @@ -1670,7 +1618,7 @@ different processes could be listening on TCP port 12345 and UDP port 12345. - Stability: Stable - + #### Attribute `network.type` [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. @@ -1690,7 +1638,7 @@ The value SHOULD be normalized to lowercase. - 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`. @@ -1704,51 +1652,33 @@ An identifier (address, unique name, or any other identifier) of the database in - 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. - +#### Attribute `db.name` -- 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. +The HBase namespace. -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`. +For HBase the `db.name` should be set to the HBase namespace. -- Requirement Level: Optional +- Requirement Level: Conditionally Required - If applicable. - Tag: call-level-tech-specific - Type: string - Examples: [ - "HMSET myhash field1 'Hello' field2 'World'", + "mynamespace", ] - - -## Group `db.mongodb` (span) -### Brief -Call-level attributes for MongoDB +## Namespace Spans `mongodb` + + +## Span `db.mongodb` +Call-level attributes for MongoDB Prefix: Kind: none @@ -1767,7 +1697,7 @@ An identifier for the database management system (DBMS) product being used. See - 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. @@ -1781,7 +1711,7 @@ The connection string used to connect to the database. It is recommended to remo - Type: string - Examples: Server=(localdb)\v11.0;Integrated Security=true; - + #### Attribute `db.user` Username for accessing the database. @@ -1798,7 +1728,7 @@ Username for accessing the database. "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. @@ -1815,7 +1745,7 @@ The fully-qualified class name of the [Java Database Connectivity (JDBC)](https: "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). @@ -1834,7 +1764,7 @@ In some SQL databases, the database name to be used is called "schema name". In "main", ] - + #### Attribute `db.statement` The database statement being executed. @@ -1851,7 +1781,7 @@ The database statement being executed. "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. @@ -1871,7 +1801,7 @@ When setting this to an SQL keyword, it is not recommended to attempt any client "SELECT", ] - + #### Attribute `server.address` Name of the database host. @@ -1893,7 +1823,7 @@ When observed from the client side, and when communicating through an intermedia - Stability: Stable - + #### Attribute `server.port` Server port number. @@ -1914,7 +1844,7 @@ When observed from the client side, and when communicating through an intermedia - Stability: Stable - + #### Attribute `network.peer.address` Peer address of the network connection - IP address or Unix domain socket name. @@ -1932,7 +1862,7 @@ Peer address of the network connection - IP address or Unix domain socket name. - Stability: Stable - + #### Attribute `network.peer.port` Peer port number of the network connection. @@ -1949,7 +1879,7 @@ Peer port number of the network connection. - 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). @@ -1974,7 +1904,7 @@ different processes could be listening on TCP port 12345 and UDP port 12345. - Stability: Stable - + #### Attribute `network.type` [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. @@ -1994,7 +1924,7 @@ The value SHOULD be normalized to lowercase. - 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`. @@ -2008,7 +1938,7 @@ An identifier (address, unique name, or any other identifier) of the database in - Type: string - Examples: mysql-e26b99z.example.com - + #### Attribute `db.mongodb.collection` The MongoDB collection being accessed within the database stated in `db.name`. @@ -2025,16 +1955,16 @@ The MongoDB collection being accessed within the database stated in `db.name`. "products", ] - - -## Group `db.elasticsearch` (span) -### Brief -Call-level attributes for Elasticsearch +## Namespace Spans `mssql` +## Span `db.mssql` + +Connection-level attributes for Microsoft SQL Server + Prefix: Kind: none @@ -2052,7 +1982,7 @@ An identifier for the database management system (DBMS) product being used. See - 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. @@ -2066,7 +1996,7 @@ The connection string used to connect to the database. It is recommended to remo - Type: string - Examples: Server=(localdb)\v11.0;Integrated Security=true; - + #### Attribute `db.user` Username for accessing the database. @@ -2083,7 +2013,7 @@ Username for accessing the database. "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. @@ -2100,7 +2030,7 @@ The fully-qualified class name of the [Java Database Connectivity (JDBC)](https: "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). @@ -2119,7 +2049,87 @@ In some SQL databases, the database name to be used is called "schema name". In "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. @@ -2137,7 +2147,7 @@ Peer address of the network connection - IP address or Unix domain socket name. - Stability: Stable - + #### Attribute `network.peer.port` Peer port number of the network connection. @@ -2154,7 +2164,7 @@ Peer port number of the network connection. - 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). @@ -2179,7 +2189,7 @@ different processes could be listening on TCP port 12345 and UDP port 12345. - Stability: Stable - + #### Attribute `network.type` [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. @@ -2199,7 +2209,7 @@ The value SHOULD be normalized to lowercase. - 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`. @@ -2210,129 +2220,157 @@ An identifier (address, unique name, or any other identifier) of the database in - Tag: connection-level -- Type: string -- Examples: mysql-e26b99z.example.com - +- 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 + + + + +## Namespace Spans `other` + + +## Span `db` + +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.elasticsearch.cluster.name` -Represents the identifier of an Elasticsearch cluster. +#### Attribute `db.connection_string` +The connection string used to connect to the database. It is recommended to remove embedded credentials. -- Requirement Level: Optional + +- Requirement Level: Recommended -- Tag: call-level-tech-specific +- Tag: connection-level - Type: string -- Examples: [ - "e9106fc68e3044f0b1475b04bf4ffd5f", -] - +- Examples: Server=(localdb)\v11.0;Integrated Security=true; -#### Attribute `db.elasticsearch.node.name` -Represents the human-readable identifier of the node/instance to which a request was routed. +#### Attribute `db.user` +Username for accessing the database. -- Requirement Level: Optional + +- Requirement Level: Recommended -- Tag: call-level-tech-specific +- Tag: connection-level - Type: string - Examples: [ - "instance-0000000001", + "readonly_user", + "reporting_user", ] - -#### Attribute `db.elasticsearch.path_parts` -A dynamic value in the url path. +#### 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. -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 +- Requirement Level: Recommended -- Tag: call-level-tech-specific +- Tag: connection-level-tech-specific -- Type: template[string] +- Type: string - Examples: [ - "db.elasticsearch.path_parts.index=test-index", - "db.elasticsearch.path_parts.doc_id=123", + "org.postgresql.Driver", + "com.microsoft.sqlserver.jdbc.SQLServerDriver", ] - -#### Attribute `db.operation` -The endpoint identifier for the request. +#### 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). -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 +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-tech-specific +- Tag: call-level - Type: string - Examples: [ - "search", - "ml.close_job", - "cat.aliases", + "customers", + "main", ] - + #### 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. +The database statement being executed. + - Requirement Level: Optional -- Tag: call-level-tech-specific +- Tag: call-level - Type: string - Examples: [ - "\"{\\\"query\\\":{\\\"term\\\":{\\\"user.id\\\":\\\"kimchy\\\"}}}\"", + "SELECT * FROM wuser_table", + "SET mykey \"WuValue\"", ] - -#### Attribute `http.request.method` - -HTTP request method. +#### Attribute `db.operation` -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). +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. -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. +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 +- Requirement Level: Conditionally Required - If `db.statement` is not applicable. -- Tag: call-level-tech-specific +- Tag: call-level -- Type: Enum [CONNECT, DELETE, GET, HEAD, OPTIONS, PATCH, POST, PUT, TRACE, _OTHER] +- Type: string - Examples: [ - "GET", - "POST", - "HEAD", + "findAndModify", + "HMSET", + "SELECT", ] -- Stability: Stable - - + #### Attribute `server.address` Name of the database host. @@ -2343,7 +2381,7 @@ When observed from the client side, and when communicating through an intermedia - Requirement Level: Recommended -- Tag: call-level-tech-specific +- Tag: connection-level - Type: string - Examples: [ @@ -2354,7 +2392,7 @@ When observed from the client side, and when communicating through an intermedia - Stability: Stable - + #### Attribute `server.port` Server port number. @@ -2364,7 +2402,7 @@ When observed from the client side, and when communicating through an intermedia - Requirement Level: Conditionally Required - If using a port other than the default port for this DBMS and if `server.address` is set. -- Tag: call-level-tech-specific +- Tag: connection-level - Type: int - Examples: [ @@ -2375,36 +2413,109 @@ When observed from the client side, and when communicating through an intermedia - Stability: Stable - -#### Attribute `url.full` -Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986) +#### Attribute `network.peer.address` +Peer address of the network connection - IP address or Unix domain socket name. -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 +- Requirement Level: Recommended -- Tag: call-level-tech-specific +- Tag: connection-level - Type: string - Examples: [ - "https://localhost:9200/index/_search?q=user.id:kimchy", + "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 -## Group `db.sql` (span) -### Brief +#### 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 + -Call-level attributes for SQL databases +## Namespace Spans `redis` + + +## Span `db.redis` + +Call-level attributes for Redis Prefix: Kind: none @@ -2423,7 +2534,7 @@ An identifier for the database management system (DBMS) product being used. See - 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. @@ -2437,7 +2548,7 @@ The connection string used to connect to the database. It is recommended to remo - Type: string - Examples: Server=(localdb)\v11.0;Integrated Security=true; - + #### Attribute `db.user` Username for accessing the database. @@ -2454,7 +2565,7 @@ Username for accessing the database. "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. @@ -2471,7 +2582,7 @@ The fully-qualified class name of the [Java Database Connectivity (JDBC)](https: "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). @@ -2490,24 +2601,7 @@ In some SQL databases, the database name to be used is called "schema name". In "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. @@ -2527,7 +2621,7 @@ When setting this to an SQL keyword, it is not recommended to attempt any client "SELECT", ] - + #### Attribute `server.address` Name of the database host. @@ -2549,7 +2643,7 @@ When observed from the client side, and when communicating through an intermedia - Stability: Stable - + #### Attribute `server.port` Server port number. @@ -2570,7 +2664,7 @@ When observed from the client side, and when communicating through an intermedia - Stability: Stable - + #### Attribute `network.peer.address` Peer address of the network connection - IP address or Unix domain socket name. @@ -2588,7 +2682,7 @@ Peer address of the network connection - IP address or Unix domain socket name. - Stability: Stable - + #### Attribute `network.peer.port` Peer port number of the network connection. @@ -2605,7 +2699,7 @@ Peer port number of the network connection. - 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). @@ -2630,7 +2724,7 @@ different processes could be listening on TCP port 12345 and UDP port 12345. - Stability: Stable - + #### Attribute `network.type` [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. @@ -2650,7 +2744,7 @@ The value SHOULD be normalized to lowercase. - 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`. @@ -2661,38 +2755,56 @@ An identifier (address, unique name, or any other identifier) of the database in - Tag: connection-level -- Type: string -- Examples: mysql-e26b99z.example.com +- 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.sql.table` -The name of the primary table that the operation is acting upon, including the database name (if applicable). +#### Attribute `db.statement` + +The full syntax of the Redis CLI command. -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 +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: Optional - Tag: call-level-tech-specific - Type: string - Examples: [ - "public.users", - "customers", + "HMSET myhash field1 'Hello' field2 'World'", ] - - -## Group `db.cosmosdb` (span) -### Brief -Call-level attributes for Cosmos DB. +## Namespace Spans `sql` -Prefix: db.cosmosdb +## Span `db.sql` + +Call-level attributes for SQL databases + +Prefix: Kind: none ### Attributes @@ -2709,7 +2821,7 @@ An identifier for the database management system (DBMS) product being used. See - 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. @@ -2723,7 +2835,7 @@ The connection string used to connect to the database. It is recommended to remo - Type: string - Examples: Server=(localdb)\v11.0;Integrated Security=true; - + #### Attribute `db.user` Username for accessing the database. @@ -2740,7 +2852,7 @@ Username for accessing the database. "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. @@ -2757,7 +2869,7 @@ The fully-qualified class name of the [Java Database Connectivity (JDBC)](https: "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). @@ -2776,7 +2888,7 @@ In some SQL databases, the database name to be used is called "schema name". In "main", ] - + #### Attribute `db.statement` The database statement being executed. @@ -2793,7 +2905,7 @@ The database statement being executed. "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. @@ -2813,7 +2925,7 @@ When setting this to an SQL keyword, it is not recommended to attempt any client "SELECT", ] - + #### Attribute `server.address` Name of the database host. @@ -2835,7 +2947,7 @@ When observed from the client side, and when communicating through an intermedia - Stability: Stable - + #### Attribute `server.port` Server port number. @@ -2856,7 +2968,7 @@ When observed from the client side, and when communicating through an intermedia - Stability: Stable - + #### Attribute `network.peer.address` Peer address of the network connection - IP address or Unix domain socket name. @@ -2874,7 +2986,7 @@ Peer address of the network connection - IP address or Unix domain socket name. - Stability: Stable - + #### Attribute `network.peer.port` Peer port number of the network connection. @@ -2891,7 +3003,7 @@ Peer port number of the network connection. - 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). @@ -2916,7 +3028,7 @@ different processes could be listening on TCP port 12345 and UDP port 12345. - Stability: Stable - + #### Attribute `network.type` [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. @@ -2936,7 +3048,7 @@ The value SHOULD be normalized to lowercase. - 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`. @@ -2950,147 +3062,34 @@ An identifier (address, unique name, or any other identifier) of the database in - 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.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.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 `db.cosmosdb.request_charge` - -RU consumed for that operation +#### Attribute `db.sql.table` -- Requirement Level: Conditionally Required - when available - -- Tag: call-level-tech-specific - -- Type: double -- Examples: [ - 46.18, - 1.0, -] - - -#### Attribute `db.cosmosdb.request_content_length` +The name of the primary table that the operation is acting upon, including the database name (if applicable). -Request payload size in bytes +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: 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 +- Type: string - Examples: [ - 1000, - 1002, + "public.users", + "customers", ] - -#### 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". +## Namespace Spans `tech` -- 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 - - - -## Group `db.tech` (span) -### Brief +## Span `db.tech` Semantic convention group for specific technologies - - Prefix: Kind: none @@ -3108,7 +3107,7 @@ An identifier for the database management system (DBMS) product being used. See - 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. @@ -3122,7 +3121,7 @@ The connection string used to connect to the database. It is recommended to remo - Type: string - Examples: Server=(localdb)\v11.0;Integrated Security=true; - + #### Attribute `db.user` Username for accessing the database. @@ -3139,7 +3138,7 @@ Username for accessing the database. "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. @@ -3156,7 +3155,7 @@ The fully-qualified class name of the [Java Database Connectivity (JDBC)](https: "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). @@ -3175,7 +3174,7 @@ In some SQL databases, the database name to be used is called "schema name". In "main", ] - + #### Attribute `db.statement` The database statement being executed. @@ -3192,7 +3191,7 @@ The database statement being executed. "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. @@ -3212,7 +3211,7 @@ When setting this to an SQL keyword, it is not recommended to attempt any client "SELECT", ] - + #### Attribute `server.address` Name of the database host. @@ -3234,7 +3233,7 @@ When observed from the client side, and when communicating through an intermedia - Stability: Stable - + #### Attribute `server.port` Server port number. @@ -3255,7 +3254,7 @@ When observed from the client side, and when communicating through an intermedia - Stability: Stable - + #### Attribute `network.peer.address` Peer address of the network connection - IP address or Unix domain socket name. @@ -3273,7 +3272,7 @@ Peer address of the network connection - IP address or Unix domain socket name. - Stability: Stable - + #### Attribute `network.peer.port` Peer port number of the network connection. @@ -3290,7 +3289,7 @@ Peer port number of the network connection. - 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). @@ -3315,7 +3314,7 @@ different processes could be listening on TCP port 12345 and UDP port 12345. - Stability: Stable - + #### Attribute `network.type` [OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent. @@ -3335,7 +3334,7 @@ The value SHOULD be normalized to lowercase. - 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`. @@ -3349,7 +3348,7 @@ An identifier (address, unique name, or any other identifier) of the database in - Type: string - Examples: mysql-e26b99z.example.com - + #### 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). @@ -3362,7 +3361,7 @@ The consistency level of the query. Based on consistency values from [CQL](https - Type: Enum [all, each_quorum, quorum, local_quorum, one, two, three, local_one, any, serial, local_serial] - + #### Attribute `db.cassandra.coordinator.dc` The data center of the coordinating node for a query. @@ -3376,7 +3375,7 @@ The data center of the coordinating node for a query. - Type: string - Examples: us-west-2 - + #### Attribute `db.cassandra.coordinator.id` The ID of the coordinating node for a query. @@ -3390,7 +3389,7 @@ The ID of the coordinating node for a query. - Type: string - Examples: be13faa2-8574-4d71-926d-27f16cf8a7af - + #### Attribute `db.cassandra.idempotence` Whether or not the query is idempotent. @@ -3403,7 +3402,7 @@ Whether or not the query is idempotent. - Type: boolean - + #### Attribute `db.cassandra.page_size` The fetch size used for paging, i.e. how many rows will be returned at once. @@ -3419,7 +3418,7 @@ The fetch size used for paging, i.e. how many rows will be returned at once. 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. @@ -3436,7 +3435,7 @@ The number of times a query was speculatively executed. Not set or `0` if the qu 2, ] - + #### Attribute `db.cassandra.table` The name of the primary Cassandra table that the operation is acting upon, including the keyspace name (if applicable). @@ -3451,7 +3450,7 @@ This mirrors the db.sql.table attribute but references cassandra rather than sql - Type: string - Examples: mytable - + #### Attribute `db.name` The keyspace name in Cassandra. @@ -3469,7 +3468,7 @@ For Cassandra the `db.name` should be set to the Cassandra keyspace name. "mykeyspace", ] - + #### 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. @@ -3487,7 +3486,7 @@ The index of the database being accessed as used in the [`SELECT` command](https 15, ] - + #### Attribute `db.statement` The full syntax of the Redis CLI command. @@ -3505,7 +3504,7 @@ For **Redis**, the value provided for `db.statement` SHOULD correspond to the sy "HMSET myhash field1 'Hello' field2 'World'", ] - + #### Attribute `db.mongodb.collection` The MongoDB collection being accessed within the database stated in `db.name`. @@ -3522,7 +3521,7 @@ The MongoDB collection being accessed within the database stated in `db.name`. "products", ] - + #### Attribute `db.sql.table` The name of the primary table that the operation is acting upon, including the database name (if applicable). @@ -3540,7 +3539,7 @@ It is not recommended to attempt any client-side parsing of `db.statement` just "customers", ] - + #### Attribute `db.cosmosdb.client_id` Unique Cosmos client instance id. @@ -3553,7 +3552,7 @@ Unique Cosmos client instance id. - Type: string - Examples: 3ba4827d-4422-483f-b59f-85b74211c11d - + #### Attribute `db.cosmosdb.connection_mode` Cosmos client connection mode. @@ -3565,7 +3564,7 @@ Cosmos client connection mode. - Type: Enum [gateway, direct] - + #### Attribute `db.cosmosdb.container` Cosmos DB container name. @@ -3578,7 +3577,7 @@ Cosmos DB container name. - Type: string - Examples: anystring - + #### Attribute `db.cosmosdb.operation_type` CosmosDB Operation Type. @@ -3590,7 +3589,7 @@ CosmosDB Operation Type. - 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 @@ -3606,7 +3605,7 @@ RU consumed for that operation 1.0, ] - + #### Attribute `db.cosmosdb.request_content_length` Request payload size in bytes @@ -3618,7 +3617,7 @@ Request payload size in bytes - Type: int - + #### Attribute `db.cosmosdb.status_code` Cosmos DB status code. @@ -3634,7 +3633,7 @@ Cosmos DB status code. 201, ] - + #### Attribute `db.cosmosdb.sub_status_code` Cosmos DB sub status code. @@ -3650,7 +3649,7 @@ Cosmos DB sub status code. 1002, ] - + #### Attribute `user_agent.original` Full user-agent string is generated by Cosmos DB SDK @@ -3671,5 +3670,7 @@ The user-agent value is generated by SDK which is a combination of
`sdk_vers - Stability: Stable - + + + \ No newline at end of file diff --git a/crates/weaver_forge/src/lib.rs b/crates/weaver_forge/src/lib.rs index 46b3ba08..c90c487e 100644 --- a/crates/weaver_forge/src/lib.rs +++ b/crates/weaver_forge/src/lib.rs @@ -294,7 +294,7 @@ impl TemplateEngine { if prev.is_some() { errors.push(Error::DuplicateParamKey { key: "params".to_owned(), - error: "The parameter `params` is a reserved parameter name".to_string() + error: "The parameter `params` is a reserved parameter name".to_owned(), }); } } @@ -310,27 +310,26 @@ impl TemplateEngine { }; // Build JQ context from the params. - let (jq_vars, jq_ctx): (Vec, Vec) = - params.as_ref().map_or_else( - || (Vec::new(), Vec::new()), // If self.target_config.params is None, return empty vectors - |params| { - params - .iter() - .filter_map(|(k, v)| { - let json_value = match serde_json::to_value(v) { - Ok(json_value) => json_value, - Err(e) => { - errors.push(ContextSerializationFailed { - error: e.to_string(), - }); - return None; - } - }; - Some((k.clone(), json_value)) - }) - .unzip() - }, - ); + let (jq_vars, jq_ctx): (Vec, Vec) = params.as_ref().map_or_else( + || (Vec::new(), Vec::new()), // If self.target_config.params is None, return empty vectors + |params| { + params + .iter() + .filter_map(|(k, v)| { + let json_value = match serde_json::to_value(v) { + Ok(json_value) => json_value, + Err(e) => { + errors.push(ContextSerializationFailed { + error: e.to_string(), + }); + return None; + } + }; + Some((k.clone(), json_value)) + }) + .unzip() + }, + ); // Process all files in parallel // - Filter the files that match the template pattern @@ -763,6 +762,7 @@ mod tests { let config = WeaverConfig::try_from_loader(&loader).expect("Failed to load `templates/weaver.yaml`"); let mut engine = super::TemplateEngine::new(config, loader, Params::default()); + engine.import_jq_package(super::SEMCONV_JQ).unwrap(); // Add a template configuration for converter.md on top // of the default template configuration. This is useful diff --git a/crates/weaver_forge/templates/test/attribute_group.md b/crates/weaver_forge/templates/test/attribute_group.md index fd90cae0..f96f527d 100644 --- a/crates/weaver_forge/templates/test/attribute_group.md +++ b/crates/weaver_forge/templates/test/attribute_group.md @@ -1,13 +1,7 @@ -{%- set file_name = ctx.id | snake_case -%} +{%- set file_name = ctx.namespace | snake_case -%} {{- template.set_file_name("attribute_group/" ~ file_name ~ ".md") -}} -## Group `{{ ctx.id | split_id | list | join("_") }}` ({{ ctx.type }}) - -### Brief - -{{ ctx.brief | trim }} - -prefix: {{ ctx.prefix }} +## Namespace `{{ ctx.namespace }}` ### Attributes diff --git a/crates/weaver_forge/templates/test/attribute_groups.md b/crates/weaver_forge/templates/test/attribute_groups.md index 4a03936e..f2d04dad 100644 --- a/crates/weaver_forge/templates/test/attribute_groups.md +++ b/crates/weaver_forge/templates/test/attribute_groups.md @@ -6,18 +6,12 @@ - {{item}} {%- endfor -%} -{% for group in ctx %} -## Group `{{ group.id }}` ({{ group.type }}) - -### Brief - -{{ group.brief | trim }} - -prefix: {{ group.prefix }} +{% for grouped_attributes in ctx %} +## Namespace `{{ grouped_attributes.namespace }}` ### Attributes -{% for attribute in group.attributes %} +{% for attribute in grouped_attributes.attributes %} #### Attribute `{{ attribute.name }}` {{ attribute.brief }} diff --git a/crates/weaver_forge/templates/test/event.md b/crates/weaver_forge/templates/test/event.md index ecdeac3d..17ef1ee8 100644 --- a/crates/weaver_forge/templates/test/event.md +++ b/crates/weaver_forge/templates/test/event.md @@ -1,19 +1,20 @@ -{%- set file_name = ctx.id | snake_case -%} +{%- set file_name = ctx.namespace | snake_case -%} {{- template.set_file_name("event/" ~ file_name ~ ".md") -}} -# Group `{{ ctx.id }}` ({{ ctx.type }}) +## Events Namespace `{{ ctx.namespace }}` -## Brief +{% for event in ctx.events %} +## Event `{{ event.name }}` -{{ ctx.brief | trim }} +Note: {{ event.note }} +Brief: {{ event.brief }} +Requirement level: {{ event.requirement_level }} +Stability: {{ event.stability }} -Prefix: {{ ctx.prefix }} -Name: {{ ctx.name }} +### Attributes -## Attributes - -{% for attribute in ctx.attributes %} -### Attribute `{{ attribute.name }}` +{% for attribute in event.attributes %} +#### Attribute `{{ attribute.name }}` {{ attribute.brief }} @@ -45,3 +46,4 @@ Name: {{ ctx.name }} - Stability: {{ attribute.stability | capitalize }} {% endif %} {% endfor %} + {% endfor %} \ No newline at end of file diff --git a/crates/weaver_forge/templates/test/events.md b/crates/weaver_forge/templates/test/events.md index eae78bc1..a4fe860b 100644 --- a/crates/weaver_forge/templates/test/events.md +++ b/crates/weaver_forge/templates/test/events.md @@ -1,18 +1,17 @@ -# Semantic Convention Event Groups +{% for grouped_events in ctx %} +# Events Namespace `{{ grouped_events.namespace }}` -{% for group in ctx %} -## Group `{{ group.id }}` ({{ group.type }}) +{% for event in grouped_events.events %} +## Event `{{ event.name }}` -### Brief - -{{ group.brief | trim }} - -Prefix: {{ group.prefix }} -Name: {{ group.name }} +Note: {{ event.note }} +Brief: {{ event.brief }} +Requirement level: {{ event.requirement_level }} +Stability: {{ event.stability }} ### Attributes -{% for attribute in group.attributes %} +{% for attribute in event.attributes %} #### Attribute `{{ attribute.name }}` {{ attribute.brief }} @@ -46,3 +45,5 @@ Name: {{ group.name }} {% endif %} {% endfor %} {% endfor %} + {% endfor %} + \ No newline at end of file diff --git a/crates/weaver_forge/templates/test/metric.md b/crates/weaver_forge/templates/test/metric.md index ea30d22a..bcabf034 100644 --- a/crates/weaver_forge/templates/test/metric.md +++ b/crates/weaver_forge/templates/test/metric.md @@ -1,23 +1,18 @@ -{%- set file_name = ctx.id | snake_case -%} +{%- set file_name = ctx.namespace | snake_case -%} {{- template.set_file_name("metric/" ~ file_name ~ ".md") -}} -## Group `{{ ctx.id }}` ({{ ctx.type }}) +## Metrics Namespace `{{ ctx.namespace }}` -### Brief +{% for metric in ctx.metrics %} +## Metric `{{ metric.metric_name }}` -{{ ctx.brief | trim }} - -{{ ctx.note | trim }} - -Prefix: {{ ctx.prefix }} -Metric: {{ ctx.metric_name }} -Instrument: {{ ctx.instrument }} -Unit: {{ ctx.unit }} -Stability: {{ ctx.stability | capitalize }} +Instrument: {{ metric.instrument }} +Unit: {{ metric.unit }} +Stability: {{ metric.stability }} ### Attributes -{% for attribute in ctx.attributes %} +{% for attribute in metric.attributes %} #### Attribute `{{ attribute.name }}` {{ attribute.brief }} @@ -50,3 +45,4 @@ Stability: {{ ctx.stability | capitalize }} - Stability: {{ attribute.stability | capitalize }} {% endif %} {% endfor %} + {% endfor %} \ No newline at end of file diff --git a/crates/weaver_forge/templates/test/metrics.md b/crates/weaver_forge/templates/test/metrics.md index 641805cb..40feb4c1 100644 --- a/crates/weaver_forge/templates/test/metrics.md +++ b/crates/weaver_forge/templates/test/metrics.md @@ -1,23 +1,16 @@ -# Semantic Convention Metric Groups +{% for grouped_metrics in ctx %} +# Metric Namespace `{{ grouped_metrics.namespace }}` -{% for group in ctx %} -## Group `{{ group.id }}` ({{ group.type }}) +{% for metric in grouped_metrics.metrics %} +## Metric `{{ metric.metric_name }}` -### Brief - -{{ group.brief | trim }} - -{{ group.note | trim }} - -Prefix: {{ group.prefix }} -Metric: {{ group.metric_name }} -Instrument: {{ group.instrument }} -Unit: {{ group.unit }} -Stability: {{ group.stability | capitalize }} +Instrument: {{ metric.instrument }} +Unit: {{ metric.unit }} +Stability: {{ metric.stability }} ### Attributes -{% for attribute in group.attributes %} +{% for attribute in metric.attributes %} #### Attribute `{{ attribute.name }}` {{ attribute.brief }} @@ -51,3 +44,5 @@ Stability: {{ group.stability | capitalize }} {% endif %} {% endfor %} {% endfor %} + {% 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 b4ab50a9..217d387f 100644 --- a/crates/weaver_forge/templates/test/resource.md +++ b/crates/weaver_forge/templates/test/resource.md @@ -1,17 +1,18 @@ -{%- set file_name = ctx.id | snake_case -%} +{%- set file_name = ctx.namespace | snake_case -%} {{- template.set_file_name("resource/" ~ file_name ~ ".md") -}} -## Group `{{ ctx.id }}` ({{ ctx.type }}) +## Namespace Resource `{{ ctx.namespace }}` -### Brief +{% for resource in ctx.resources %} -{{ ctx.brief | trim }} +## Resource `{{ resource.id }}` -prefix: {{ ctx.prefix }} +Note: {{ resource.note }} +Brief: {{ resource.brief }} ### Attributes -{% for attribute in ctx.attributes %} +{% for attribute in resource.attributes %} #### Attribute `{{ attribute.name }}` {{ attribute.brief }} @@ -44,3 +45,4 @@ prefix: {{ ctx.prefix }} - Stability: {{ attribute.stability | capitalize }} {% endif %} {% endfor %} + {% endfor %} \ No newline at end of file diff --git a/crates/weaver_forge/templates/test/resources.md b/crates/weaver_forge/templates/test/resources.md index 955b76fc..a2bd9b71 100644 --- a/crates/weaver_forge/templates/test/resources.md +++ b/crates/weaver_forge/templates/test/resources.md @@ -1,17 +1,18 @@ # Semantic Convention Resource Groups -{% for group in ctx %} -## Group `{{ group.id }}` ({{ group.type }}) +{% for grouped_resources in ctx %} +## Namespace Resource `{{ grouped_resources.namespace }}` -### Brief +{% for resource in grouped_resources.resources %} -{{ group.brief | trim }} +## Resource `{{ resource.id }}` -prefix: {{ group.prefix }} +Note: {{ resource.note }} +Brief: {{ resource.brief }} ### Attributes -{% for attribute in group.attributes %} +{% for attribute in resource.attributes %} #### Attribute `{{ attribute.name }}` {{ attribute.brief }} @@ -44,4 +45,5 @@ prefix: {{ group.prefix }} - Stability: {{ attribute.stability | capitalize }} {% endif %} {% endfor %} - {% endfor %} \ No newline at end of file + {% 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 6f00ffc3..f870d87e 100644 --- a/crates/weaver_forge/templates/test/span.md +++ b/crates/weaver_forge/templates/test/span.md @@ -1,20 +1,19 @@ -{%- set file_name = ctx.id | snake_case -%} +{%- set file_name = ctx.namespace | snake_case -%} {{- template.set_file_name("span/" ~ file_name ~ ".md") -}} -## Group `{{ ctx.id }}` ({{ ctx.type }}) +## Namespace Span `{{ ctx.namespace }}` -### Brief +{% for span in ctx.spans %} +## Span `{{ span.id }}` -{{ ctx.brief | trim }} - -{{ ctx.note | trim }} - -Prefix: {{ ctx.prefix }} -Kind: {{ ctx.span_kind }} +{{ span.brief | trim }} +{{ span.note | trim }} +Prefix: {{ span.prefix }} +Kind: {{ span.span_kind }} ### Attributes -{% for attribute in ctx.attributes %} +{% for attribute in span.attributes %} #### Attribute `{{ attribute.name }}` {{ attribute.brief }} @@ -46,4 +45,5 @@ Kind: {{ ctx.span_kind }} {% if attribute.stability %} - Stability: {{ attribute.stability | capitalize }} {% endif %} - {% endfor %} \ No newline at end of file +{% endfor %} +{% 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 28083c2a..8a54d485 100644 --- a/crates/weaver_forge/templates/test/spans.md +++ b/crates/weaver_forge/templates/test/spans.md @@ -1,20 +1,19 @@ # Semantic Convention Span Groups -{% for group in ctx %} -## Group `{{ group.id }}` ({{ group.type }}) +{% for grouped_spans in ctx %} +## Namespace Spans `{{ grouped_spans.namespace }}` -### Brief +{% for span in grouped_spans.spans %} +## Span `{{ span.id }}` -{{ group.brief | trim }} - -{{ group.note | trim }} - -Prefix: {{ group.prefix }} -Kind: {{ group.span_kind }} +{{ span.brief | trim }} +{{ span.note | trim }} +Prefix: {{ span.prefix }} +Kind: {{ span.span_kind }} ### Attributes -{% for attribute in group.attributes %} +{% for attribute in span.attributes %} #### Attribute `{{ attribute.name }}` {{ attribute.brief }} @@ -46,5 +45,7 @@ Kind: {{ group.span_kind }} {% if attribute.stability %} - Stability: {{ attribute.stability | capitalize }} {% endif %} - {% endfor %} - {% endfor %} \ No newline at end of file +{% endfor %} +{% endfor %} +{% endfor %} + \ No newline at end of file diff --git a/crates/weaver_forge/templates/test/weaver.yaml b/crates/weaver_forge/templates/test/weaver.yaml index e0bde633..0b8bd626 100644 --- a/crates/weaver_forge/templates/test/weaver.yaml +++ b/crates/weaver_forge/templates/test/weaver.yaml @@ -21,44 +21,32 @@ templates: filter: "." application_mode: single - pattern: "**/attribute_group.md" - filter: semconv_attributes + filter: semconv_grouped_attributes application_mode: each - pattern: "**/attribute_groups.md" - filter: semconv_attributes + filter: semconv_grouped_attributes application_mode: single - pattern: "**/event.md" - filter: semconv_events + filter: semconv_grouped_events application_mode: each - pattern: "**/events.md" - filter: semconv_events - application_mode: single - - pattern: "**/group.md" - filter: ".groups" - application_mode: each - - pattern: "**/groups.md" - filter: ".groups" + filter: semconv_grouped_events application_mode: single - pattern: "**/metric.md" - filter: semconv_metrics + filter: semconv_grouped_metrics application_mode: each - pattern: "**/metrics.md" - filter: semconv_metrics + filter: semconv_grouped_metrics application_mode: single - pattern: "**/resource.md" - filter: semconv_resources + filter: semconv_grouped_resources application_mode: each - pattern: "**/resources.md" - filter: semconv_resources - application_mode: single - - pattern: "**/scope.md" - filter: semconv_scopes - application_mode: each - - pattern: "**/scopes.md" - filter: semconv_scopes + filter: semconv_grouped_resources application_mode: single - pattern: "**/span.md" - filter: semconv_spans + filter: semconv_grouped_spans application_mode: each - pattern: "**/spans.md" - filter: semconv_spans + filter: semconv_grouped_spans application_mode: single \ No newline at end of file diff --git a/defaults/jq/semconv.jq b/defaults/jq/semconv.jq index d1ea3e0a..a6b20905 100644 --- a/defaults/jq/semconv.jq +++ b/defaults/jq/semconv.jq @@ -53,7 +53,7 @@ def semconv_signal($signal; $options): else . end - | map(. + {namespace: .id | split(".") | .[1]}) + | map(. + {namespace: (if .id | index(".") then .id | split(".") | .[1] else "other" end)}) | if ($options | has("exclude_namespace")) then map(select(.namespace as $st | $options.exclude_namespace | index($st) | not)) else diff --git a/docs/images/dependencies.svg b/docs/images/dependencies.svg index 4a273d14..4a084088 100644 --- a/docs/images/dependencies.svg +++ b/docs/images/dependencies.svg @@ -1,7 +1,7 @@ - Date: Fri, 19 Jul 2024 17:24:15 -0700 Subject: [PATCH 24/29] feat(forge): Enable whitespace control on the Rust example --- .../templates/registry/alt_weaver.yaml | 3 +- .../registry/rust/attribute_macros.j2 | 56 +++++++++---------- .../registry/rust/attributes/attributes.rs.j2 | 55 ++++++++++-------- .../registry/rust/attributes/mod.rs.j2 | 2 +- .../rust/metrics/instruments/counter.j2 | 43 +++++++------- .../rust/metrics/instruments/gauge.j2 | 30 +++++----- .../rust/metrics/instruments/histogram.j2 | 41 ++++++++------ .../rust/metrics/instruments/updowncounter.j2 | 30 +++++----- .../registry/rust/metrics/metrics.rs.j2 | 5 +- .../templates/registry/rust/metrics/mod.rs.j2 | 2 +- .../templates/registry/rust/weaver.yaml | 5 ++ .../templates/registry/weaver.yaml | 3 +- crates/weaver_forge/README.md | 18 ++++-- 13 files changed, 166 insertions(+), 127 deletions(-) diff --git a/crates/weaver_codegen_test/templates/registry/alt_weaver.yaml b/crates/weaver_codegen_test/templates/registry/alt_weaver.yaml index 1e0eba00..c0380e85 100644 --- a/crates/weaver_codegen_test/templates/registry/alt_weaver.yaml +++ b/crates/weaver_codegen_test/templates/registry/alt_weaver.yaml @@ -2,5 +2,4 @@ params: attributes: true metrics: false # With this alternate configuration, the metrics are disabled - exclude_deprecated: true - registry_prefix: "registry." + exclude_deprecated: true \ No newline at end of file diff --git a/crates/weaver_codegen_test/templates/registry/rust/attribute_macros.j2 b/crates/weaver_codegen_test/templates/registry/rust/attribute_macros.j2 index 447c6b74..93074674 100644 --- a/crates/weaver_codegen_test/templates/registry/rust/attribute_macros.j2 +++ b/crates/weaver_codegen_test/templates/registry/rust/attribute_macros.j2 @@ -1,60 +1,60 @@ {%- macro comments(attribute, prefix) -%} -{%- if attribute.brief %} + {% if attribute.brief %} {{ attribute.brief | comment_with_prefix(prefix ~ " ") }} -{%- endif %} -{%- if attribute.note %} + {% endif %} + {% if attribute.note %} {{ prefix }} {{ prefix }} Notes: {{ attribute.note | comment_with_prefix(prefix ~ " ") }} -{%- endif %} -{%- if attribute.examples %} -{%- if attribute.examples is sequence %} + {% endif %} + {% if attribute.examples %} + {% if attribute.examples is sequence %} {{ prefix }} {{ prefix }} Examples: -{%- for example in attribute.examples %} + {% for example in attribute.examples %} {{ example | comment_with_prefix(prefix ~ " - ") }} -{%- endfor %} -{%- else %} + {% endfor %} + {% else %} {{ prefix }} {{ prefix }} Example: {{ attribute.examples | trim }} -{%- endif %} -{%- endif %} -{%- endmacro %} + {% endif %} + {% endif %} +{% endmacro %} {%- macro attributes_to_key_values(required_attributes, not_required_attributes) -%} let mut attributes = vec![ - {%- for attribute in required_attributes | attribute_sort %} - {%- if attribute is experimental %} + {% for attribute in required_attributes | attribute_sort %} + {% if attribute is experimental %} #[cfg(feature = "semconv_experimental")] - {%- endif %} - {%- if attribute.type.members is defined %} + {% endif %} + {% if attribute.type.members is defined %} crate::attributes::{{ attribute.name | attribute_namespace }}::{{ attribute.name | screaming_snake_case }}.value(&required_attributes.{{ attribute.name | snake_case }}), - {%- elif attribute.type == "string" %} + {% elif attribute.type == "string" %} crate::attributes::{{ attribute.name | attribute_namespace }}::{{ attribute.name | screaming_snake_case }}.value(required_attributes.{{ attribute.name | snake_case }}.to_owned().into()), - {%- else %} + {% else %} crate::attributes::{{ attribute.name | attribute_namespace }}::{{ attribute.name | screaming_snake_case }}.value(required_attributes.{{ attribute.name | snake_case }}), - {%- endif %} - {%- endfor %} + {% endif %} + {% endfor %} ]; if let Some(value) = ¬_required_attributes { - {%- for attribute in not_required_attributes | attribute_sort %} - {%- if attribute is experimental %} + {% for attribute in not_required_attributes | attribute_sort %} + {% if attribute is experimental %} #[cfg(feature = "semconv_experimental")] - {%- endif %} - {%- if attribute.type.members is defined %} + {% endif %} + {% if attribute.type.members is defined %} if let Some({{ attribute.name | snake_case }}) = &value.{{ attribute.name | snake_case }} { attributes.push(crate::attributes::{{ attribute.name | attribute_namespace }}::{{ attribute.name | screaming_snake_case }}.value({{ attribute.name | snake_case }})); } - {%- elif attribute.type == "string" %} + {% elif attribute.type == "string" %} if let Some({{ attribute.name | snake_case }}) = &value.{{ attribute.name | snake_case }} { attributes.push(crate::attributes::{{ attribute.name | attribute_namespace }}::{{ attribute.name | screaming_snake_case }}.value({{ attribute.name | snake_case }}.to_owned().into())); } - {%- else %} + {% else %} if let Some({{ attribute.name | snake_case }}) = value.{{ attribute.name | snake_case }} { attributes.push(crate::attributes::{{ attribute.name | attribute_namespace }}::{{ attribute.name | screaming_snake_case }}.value({{ attribute.name | snake_case }})); } - {%- endif %} - {%- endfor %} + {% endif %} + {% endfor %} } {%- endmacro %} \ No newline at end of file diff --git a/crates/weaver_codegen_test/templates/registry/rust/attributes/attributes.rs.j2 b/crates/weaver_codegen_test/templates/registry/rust/attributes/attributes.rs.j2 index e62ec38b..c5fc19a3 100644 --- a/crates/weaver_codegen_test/templates/registry/rust/attributes/attributes.rs.j2 +++ b/crates/weaver_codegen_test/templates/registry/rust/attributes/attributes.rs.j2 @@ -9,34 +9,39 @@ //! DO NOT EDIT, THIS FILE HAS BEEN GENERATED BY WEAVER -{%- for attribute in ctx.attributes | attribute_sort %} -{{ attribute_macros.comments(attribute, "///") }} -{%- if attribute is experimental %} +{% for attribute in ctx.attributes | attribute_sort %} +{{ attribute_macros.comments(attribute, "///") -}} + {% if attribute is experimental %} #[cfg(feature = "semconv_experimental")] -{%- endif %} -{%- if attribute is deprecated %} + {% endif %} + {% if attribute is deprecated %} #[deprecated(note="{{ attribute.deprecated }}")] -{%- endif %} -{%- if attribute.type.allow_custom_values is defined %} + {% endif %} + {% if attribute.type.allow_custom_values is defined %} pub const {{ attribute.name | screaming_snake_case }}: crate::attributes::AttributeKey<{{ attribute.name | pascal_case }}> = crate::attributes::AttributeKey::new("{{ attribute.name }}"); -{%- elif attribute.type == "string" %} + {% elif attribute.type == "string" %} pub const {{ attribute.name | screaming_snake_case }}: crate::attributes::AttributeKey = crate::attributes::AttributeKey::new("{{ attribute.name }}"); -{%- else %} + {% else %} pub const {{ attribute.name | screaming_snake_case }}: crate::attributes::AttributeKey<{{ attribute.type | map_text("rust_types") }}> = crate::attributes::AttributeKey::new("{{ attribute.name }}"); -{%- endif %} -{%- if attribute.type.members is defined %} + {% endif %} -{% if attribute.brief %}{{ attribute.brief | comment_with_prefix("/// ") }}{%- endif %} + {% if attribute.type.members is defined %} + {% if attribute.brief %} +{{ attribute.brief | comment_with_prefix("/// ") }} + {% endif %} #[derive(Debug, Clone)] #[non_exhaustive] pub enum {{ attribute.name | pascal_case }} { -{%- for variant in attribute.type.members %} - {{ variant.brief | default("No brief") | comment_with_prefix(" /// ") }} - {%- if variant.note %}{{ variant.note | comment_with_prefix(" /// ") }}{% endif %} - {%- if variant is experimental %} - #[cfg(feature = "semconv_experimental")] {% endif %} + {% for variant in attribute.type.members %} + {{ variant.brief | default("No brief") | comment_with_prefix("/// ") }} + {% if variant.note %} + {{ variant.note | comment_with_prefix("/// ") }} + {% endif %} + {% if variant is experimental %} + #[cfg(feature = "semconv_experimental")] + {% endif %} {{ variant.id | pascal_case }}, -{%- endfor %} + {% endfor %} /// This variant allows defining a custom entry in the enum. _Custom(String), } @@ -46,11 +51,12 @@ impl {{ attribute.name | pascal_case }} { #[must_use] pub fn as_str(&self) -> &str { match self { - {%- for variant in attribute.type.members %} - {%- if variant is experimental %} - #[cfg(feature = "semconv_experimental")] {% endif %} + {% for variant in attribute.type.members %} + {% if variant is experimental %} + #[cfg(feature = "semconv_experimental")] + {% endif %} {{ attribute.name | pascal_case }}::{{ variant.id | pascal_case }} => "{{ variant.value }}", - {%- endfor %} + {% endfor %} {{ attribute.name | pascal_case }}::_Custom(v) => v.as_str(), // Without this default case, the match expression would not // contain any variants if all variants are annotated with the @@ -75,5 +81,6 @@ impl crate::attributes::AttributeKey<{{ attribute.name | pascal_case }}> { opentelemetry::KeyValue::new(self.key.clone(), v.to_string()) } } -{%- endif %} -{%- endfor %} \ No newline at end of file + + {% endif %} +{% endfor %} \ No newline at end of file diff --git a/crates/weaver_codegen_test/templates/registry/rust/attributes/mod.rs.j2 b/crates/weaver_codegen_test/templates/registry/rust/attributes/mod.rs.j2 index 3718a545..5119aa5d 100644 --- a/crates/weaver_codegen_test/templates/registry/rust/attributes/mod.rs.j2 +++ b/crates/weaver_codegen_test/templates/registry/rust/attributes/mod.rs.j2 @@ -15,7 +15,7 @@ pub const ATTRIBUTES_PARAM: bool = {{ params.attributes }}; {% for attributes_namespace in ctx %} /// Attributes for the `{{ attributes_namespace.namespace }}` namespace. pub mod {{ attributes_namespace.namespace | snake_case }}; -{%- endfor %} +{% endfor %} /// A typed attribute key. pub struct AttributeKey { diff --git a/crates/weaver_codegen_test/templates/registry/rust/metrics/instruments/counter.j2 b/crates/weaver_codegen_test/templates/registry/rust/metrics/instruments/counter.j2 index aa6fc758..6e6416a3 100644 --- a/crates/weaver_codegen_test/templates/registry/rust/metrics/instruments/counter.j2 +++ b/crates/weaver_codegen_test/templates/registry/rust/metrics/instruments/counter.j2 @@ -1,10 +1,10 @@ -{%- import 'attribute_macros.j2' as attribute_macros %} -{%- if metric.brief %} +{% import 'attribute_macros.j2' as attribute_macros %} +{% if metric.brief %} {{ metric.brief | comment_with_prefix("/// ") }} -{%- endif %} -{%- if metric is experimental %} +{% endif %} +{% if metric is experimental %} #[cfg(feature = "semconv_experimental")] -{%- endif %} +{% endif %} #[must_use] pub fn create_{{ metric.metric_name | snake_case }}(meter: &opentelemetry::metrics::Meter) -> opentelemetry::metrics::Counter where opentelemetry::metrics::Meter: crate::metrics::CounterProvider { @@ -21,17 +21,18 @@ pub struct {{ metric.metric_name | pascal_case }}(opentelemetry::metrics::Cou {%- set not_required_attributes = metric.attributes | not_required %} {% if required_attributes %} + /// Required attributes for the `{{ metric.metric_name }}` metric. #[derive(Debug, Clone)] pub struct {{ metric.metric_name | pascal_case }}ReqAttributes { - {%- for attribute in required_attributes | attribute_sort %} - {{ attribute_macros.comments(attribute, " ///") }} - {%- if attribute.type.members is defined %} + {% for attribute in required_attributes | attribute_sort %} + {{- attribute_macros.comments(attribute, " ///") }} + {%- if attribute.type.members is defined %} pub {{ attribute.name | snake_case }}: crate::attributes::{{ attribute.name | attribute_namespace }}::{{ attribute.name | pascal_case }}, - {%- else %} + {%- else %} pub {{ attribute.name | snake_case }}: {{ attribute.type | map_text("rust_types") }}, - {%- endif %} - {%- endfor %} + {% endif %} + {% endfor %} } {% endif %} @@ -39,14 +40,14 @@ pub struct {{ metric.metric_name | pascal_case }}ReqAttributes { /// Not required attributes for the `{{ metric.metric_name }}` metric. #[derive(Debug, Clone, Default)] pub struct {{ metric.metric_name | pascal_case }}OptAttributes { - {%- for attribute in not_required_attributes | attribute_sort %} - {{ attribute_macros.comments(attribute, " ///") }} - {%- if attribute.type.members is defined %} + {% for attribute in not_required_attributes | attribute_sort %} +{{ attribute_macros.comments(attribute, " ///") }} + {%- if attribute.type.members is defined %} pub {{ attribute.name | snake_case }}: Option, - {%- else %} + {%- else %} pub {{ attribute.name | snake_case }}: Option<{{ attribute.type | map_text("rust_types") }}>, - {%- endif %} - {%- endfor %} + {% endif %} + {% endfor %} } {% endif %} @@ -62,8 +63,12 @@ impl {{ metric.metric_name | pascal_case }} { pub fn add( &self, value: T, - {% if required_attributes %}required_attributes: &{{ metric.metric_name | pascal_case }}ReqAttributes,{% endif %} - {% if not_required_attributes %}not_required_attributes: Option<&{{ metric.metric_name | pascal_case }}OptAttributes>,{% endif %} + {% if required_attributes %} + required_attributes: &{{ metric.metric_name | pascal_case }}ReqAttributes, + {% endif %} + {% if not_required_attributes %} + not_required_attributes: Option<&{{ metric.metric_name | pascal_case }}OptAttributes>, + {% endif %} ) { {{ attribute_macros.attributes_to_key_values(required_attributes, not_required_attributes) }} self.0.add(value, &attributes); diff --git a/crates/weaver_codegen_test/templates/registry/rust/metrics/instruments/gauge.j2 b/crates/weaver_codegen_test/templates/registry/rust/metrics/instruments/gauge.j2 index 8a477a5f..7bfb194b 100644 --- a/crates/weaver_codegen_test/templates/registry/rust/metrics/instruments/gauge.j2 +++ b/crates/weaver_codegen_test/templates/registry/rust/metrics/instruments/gauge.j2 @@ -1,10 +1,10 @@ {%- import 'attribute_macros.j2' as attribute_macros %} -{%- if metric.brief %} +{% if metric.brief %} {{ metric.brief | comment_with_prefix("/// ") }} -{%- endif %} -{%- if metric is experimental %} +{% endif %} +{% if metric is experimental %} #[cfg(feature = "semconv_experimental")] -{%- endif %} +{% endif %} #[must_use] pub fn create_{{ metric.metric_name | snake_case }}(meter: &opentelemetry::metrics::Meter) -> opentelemetry::metrics::Gauge where opentelemetry::metrics::Meter: crate::metrics::GaugeProvider { @@ -24,14 +24,14 @@ pub struct {{ metric.metric_name | pascal_case }}(opentelemetry::metrics::Gau /// Required attributes for the `{{ metric.metric_name }}` metric. #[derive(Debug, Clone)] pub struct {{ metric.metric_name | pascal_case }}ReqAttributes { - {%- for attribute in required_attributes | attribute_sort %} + {% for attribute in required_attributes | attribute_sort %} {{ attribute_macros.comments(attribute, " ///") }} {%- if attribute.type.members is defined %} pub {{ attribute.name | snake_case }}: crate::attributes::{{ attribute.name | attribute_namespace }}::{{ attribute.name | pascal_case }}, {%- else %} pub {{ attribute.name | snake_case }}: {{ attribute.type | map_text("rust_types") }}, - {%- endif %} - {%- endfor %} + {% endif %} + {% endfor %} } {% endif %} @@ -39,14 +39,14 @@ pub struct {{ metric.metric_name | pascal_case }}ReqAttributes { /// Not required attributes for the `{{ metric.metric_name }}` metric. #[derive(Debug, Clone, Default)] pub struct {{ metric.metric_name | pascal_case }}OptAttributes { - {%- for attribute in not_required_attributes | attribute_sort %} - {{ attribute_macros.comments(attribute, " ///") }} + {% for attribute in not_required_attributes | attribute_sort %} + {{- attribute_macros.comments(attribute, " ///") }} {%- if attribute.type.members is defined %} pub {{ attribute.name | snake_case }}: Option, {%- else %} pub {{ attribute.name | snake_case }}: Option<{{ attribute.type | map_text("rust_types") }}>, - {%- endif %} - {%- endfor %} + {% endif %} + {% endfor %} } {% endif %} @@ -62,8 +62,12 @@ impl {{ metric.metric_name | pascal_case }} { pub fn record( &self, value: T, - {% if required_attributes %}required_attributes: &{{ metric.metric_name | pascal_case }}ReqAttributes,{% endif %} - {% if not_required_attributes %}not_required_attributes: Option<&{{ metric.metric_name | pascal_case }}OptAttributes>,{% endif %} + {% if required_attributes %} + required_attributes: &{{ metric.metric_name | pascal_case }}ReqAttributes, + {% endif %} + {% if not_required_attributes %} + not_required_attributes: Option<&{{ metric.metric_name | pascal_case }}OptAttributes>, + {% endif %} ) { {{ attribute_macros.attributes_to_key_values(required_attributes, not_required_attributes) }} self.0.record(value, &attributes); diff --git a/crates/weaver_codegen_test/templates/registry/rust/metrics/instruments/histogram.j2 b/crates/weaver_codegen_test/templates/registry/rust/metrics/instruments/histogram.j2 index cd6342d9..ab95ebbe 100644 --- a/crates/weaver_codegen_test/templates/registry/rust/metrics/instruments/histogram.j2 +++ b/crates/weaver_codegen_test/templates/registry/rust/metrics/instruments/histogram.j2 @@ -1,10 +1,10 @@ {%- import 'attribute_macros.j2' as attribute_macros %} -{%- if metric.brief %} +{% if metric.brief %} {{ metric.brief | comment_with_prefix("/// ") }} -{%- endif %} -{%- if metric is experimental %} +{% endif %} +{% if metric is experimental %} #[cfg(feature = "semconv_experimental")] -{%- endif %} +{% endif %} #[must_use] pub fn create_{{ metric.metric_name | snake_case }}(meter: &opentelemetry::metrics::Meter) -> opentelemetry::metrics::Histogram where opentelemetry::metrics::Meter: crate::metrics::HistogramProvider { @@ -21,17 +21,18 @@ pub struct {{ metric.metric_name | pascal_case }}(opentelemetry::metrics::His {%- set not_required_attributes = metric.attributes | not_required %} {% if required_attributes %} + /// Required attributes for the `{{ metric.metric_name }}` metric. #[derive(Debug, Clone)] pub struct {{ metric.metric_name | pascal_case }}ReqAttributes { - {%- for attribute in required_attributes | attribute_sort %} - {{ attribute_macros.comments(attribute, " ///") }} - {%- if attribute.type.members is defined %} + {% for attribute in required_attributes | attribute_sort %} + {{- attribute_macros.comments(attribute, " ///") }} + {%- if attribute.type.members is defined %} pub {{ attribute.name | snake_case }}: crate::attributes::{{ attribute.name | attribute_namespace }}::{{ attribute.name | pascal_case }}, - {%- else %} + {%- else %} pub {{ attribute.name | snake_case }}: {{ attribute.type | map_text("rust_types") }}, - {%- endif %} - {%- endfor %} + {% endif %} + {% endfor %} } {% endif %} @@ -39,14 +40,14 @@ pub struct {{ metric.metric_name | pascal_case }}ReqAttributes { /// Not required attributes for the `{{ metric.metric_name }}` metric. #[derive(Debug, Clone, Default)] pub struct {{ metric.metric_name | pascal_case }}OptAttributes { - {%- for attribute in not_required_attributes | attribute_sort %} - {{ attribute_macros.comments(attribute, " ///") }} - {%- if attribute.type.members is defined %} + {% for attribute in not_required_attributes | attribute_sort %} + {{- attribute_macros.comments(attribute, " ///") }} + {%- if attribute.type.members is defined %} pub {{ attribute.name | snake_case }}: Option, - {%- else %} + {%- else %} pub {{ attribute.name | snake_case }}: Option<{{ attribute.type | map_text("rust_types") }}>, - {%- endif %} - {%- endfor %} + {% endif %} + {% endfor %} } {% endif %} @@ -62,8 +63,12 @@ impl {{ metric.metric_name | pascal_case }} { pub fn record( &self, value: T, - {% if required_attributes %}required_attributes: &{{ metric.metric_name | pascal_case }}ReqAttributes,{% endif %} - {% if not_required_attributes %}not_required_attributes: Option<&{{ metric.metric_name | pascal_case }}OptAttributes>,{% endif %} + {% if required_attributes %} + required_attributes: &{{ metric.metric_name | pascal_case }}ReqAttributes, + {% endif %} + {% if not_required_attributes %} + not_required_attributes: Option<&{{ metric.metric_name | pascal_case }}OptAttributes>, + {% endif %} ) { {{ attribute_macros.attributes_to_key_values(required_attributes, not_required_attributes) }} self.0.record(value, &attributes); diff --git a/crates/weaver_codegen_test/templates/registry/rust/metrics/instruments/updowncounter.j2 b/crates/weaver_codegen_test/templates/registry/rust/metrics/instruments/updowncounter.j2 index f44b5bd4..7fbd388e 100644 --- a/crates/weaver_codegen_test/templates/registry/rust/metrics/instruments/updowncounter.j2 +++ b/crates/weaver_codegen_test/templates/registry/rust/metrics/instruments/updowncounter.j2 @@ -1,10 +1,10 @@ {%- import 'attribute_macros.j2' as attribute_macros %} -{%- if metric.brief %} +{% if metric.brief %} {{ metric.brief | comment_with_prefix("/// ") }} -{%- endif %} -{%- if metric is experimental %} +{% endif %} +{% if metric is experimental %} #[cfg(feature = "semconv_experimental")] -{%- endif %} +{% endif %} #[must_use] pub fn create_{{ metric.metric_name | snake_case }}(meter: &opentelemetry::metrics::Meter) -> opentelemetry::metrics::UpDownCounter where opentelemetry::metrics::Meter: crate::metrics::UpDownCounterProvider { @@ -25,14 +25,14 @@ pub struct {{ metric.metric_name | pascal_case }}(opentelemetry::metrics::UpD /// Attributes for the `{{ metric.metric_name }}` metric. #[derive(Debug, Clone)] pub struct {{ metric.metric_name | pascal_case }}ReqAttributes { - {%- for attribute in required_attributes | attribute_sort %} + {% for attribute in required_attributes | attribute_sort %} {{ attribute_macros.comments(attribute, " ///") }} {%- if attribute.type.members is defined %} pub {{ attribute.name | snake_case }}: crate::attributes::{{ attribute.name | attribute_namespace }}::{{ attribute.name | pascal_case }}, {%- else %} pub {{ attribute.name | snake_case }}: {{ attribute.type | map_text("rust_types") }}, - {%- endif %} - {%- endfor %} + {% endif %} + {% endfor %} } {% endif %} @@ -40,14 +40,14 @@ pub struct {{ metric.metric_name | pascal_case }}ReqAttributes { /// Not required attributes for the `{{ metric.metric_name }}` metric. #[derive(Debug, Clone, Default)] pub struct {{ metric.metric_name | pascal_case }}OptAttributes { - {%- for attribute in not_required_attributes | attribute_sort %} - {{ attribute_macros.comments(attribute, " ///") }} + {% for attribute in not_required_attributes | attribute_sort %} + {{- attribute_macros.comments(attribute, " ///") }} {%- if attribute.type.members is defined %} pub {{ attribute.name | snake_case }}: Option, {%- else %} pub {{ attribute.name | snake_case }}: Option<{{ attribute.type | map_text("rust_types") }}>, - {%- endif %} - {%- endfor %} + {% endif %} + {% endfor %} } {% endif %} @@ -63,8 +63,12 @@ impl {{ metric.metric_name | pascal_case }} { pub fn add( &self, value: T, - {% if required_attributes %}required_attributes: &{{ metric.metric_name | pascal_case }}ReqAttributes,{% endif %} - {% if not_required_attributes %}not_required_attributes: Option<&{{ metric.metric_name | pascal_case }}OptAttributes>,{% endif %} + {% if required_attributes %} + required_attributes: &{{ metric.metric_name | pascal_case }}ReqAttributes, + {% endif %} + {% if not_required_attributes %} + not_required_attributes: Option<&{{ metric.metric_name | pascal_case }}OptAttributes>, + {% endif %} ) { {{ attribute_macros.attributes_to_key_values(required_attributes, not_required_attributes) }} self.0.add(value, &attributes); diff --git a/crates/weaver_codegen_test/templates/registry/rust/metrics/metrics.rs.j2 b/crates/weaver_codegen_test/templates/registry/rust/metrics/metrics.rs.j2 index d6112fa5..e6d32aaf 100644 --- a/crates/weaver_codegen_test/templates/registry/rust/metrics/metrics.rs.j2 +++ b/crates/weaver_codegen_test/templates/registry/rust/metrics/metrics.rs.j2 @@ -8,6 +8,7 @@ //! DO NOT EDIT, THIS FILE HAS BEEN GENERATED BY WEAVER -{%- for metric in ctx.metrics %} +{% for metric in ctx.metrics %} {% include "metrics/instruments/" ~ metric.instrument ~ ".j2" %} -{%- endfor %} \ No newline at end of file + +{% endfor %} \ No newline at end of file diff --git a/crates/weaver_codegen_test/templates/registry/rust/metrics/mod.rs.j2 b/crates/weaver_codegen_test/templates/registry/rust/metrics/mod.rs.j2 index 5201a01d..ee94c235 100644 --- a/crates/weaver_codegen_test/templates/registry/rust/metrics/mod.rs.j2 +++ b/crates/weaver_codegen_test/templates/registry/rust/metrics/mod.rs.j2 @@ -13,7 +13,7 @@ pub const METRICS_PARAM: bool = {{ params.metrics }}; {% for attributes_namespace in ctx %} /// Metrics for the `{{ attributes_namespace.namespace }}` namespace. pub mod {{ attributes_namespace.namespace | snake_case }}; -{%- endfor %} +{% endfor %} /// A trait implemented by histogram providers (e.g. `Meter`). pub trait HistogramProvider { diff --git a/crates/weaver_codegen_test/templates/registry/rust/weaver.yaml b/crates/weaver_codegen_test/templates/registry/rust/weaver.yaml index 9892a42c..fa9226f8 100644 --- a/crates/weaver_codegen_test/templates/registry/rust/weaver.yaml +++ b/crates/weaver_codegen_test/templates/registry/rust/weaver.yaml @@ -8,6 +8,11 @@ text_maps: template[string]: String # Not yet properly handled in codegen template[string[]]: Vec # Not yet properly handled in codegen +# Whitespace control settings to simplify the definition of templates +whitespace_control: + trim_blocks: true + lstrip_blocks: true + templates: - pattern: README.md filter: . diff --git a/crates/weaver_codegen_test/templates/registry/weaver.yaml b/crates/weaver_codegen_test/templates/registry/weaver.yaml index f667b3c0..2dcabac0 100644 --- a/crates/weaver_codegen_test/templates/registry/weaver.yaml +++ b/crates/weaver_codegen_test/templates/registry/weaver.yaml @@ -2,5 +2,4 @@ params: attributes: true metrics: true - exclude_deprecated: true - registry_prefix: "registry." + exclude_deprecated: true \ No newline at end of file diff --git a/crates/weaver_forge/README.md b/crates/weaver_forge/README.md index 6c2b92bf..16af0fa0 100644 --- a/crates/weaver_forge/README.md +++ b/crates/weaver_forge/README.md @@ -146,6 +146,14 @@ params: incubating: true # ... +# Jinja Engine Whitespace Control Settings +# With both trim_blocks and lstrip_blocks enabled, you can put block tags on +# their own lines, and the entire block line will be removed when rendered, +# preserving the whitespace of the contents. +whitespace_control: + trim_blocks: true + lstrip_blocks: true + templates: - pattern: "attributes.j2" filter: semconv_grouped_attributes @@ -290,8 +298,8 @@ The output of the JQ filter has the following structure: ] ``` -The `semconv_grouped_attributes` function also supports options to exclude specified namespaces -or specific stability levels. The following syntax is supported: +The `semconv_grouped_attributes` function also supports options to exclude specified namespaces, +specific stability levels, and deprecated entities. The following syntax is supported: ```yaml templates: @@ -299,7 +307,8 @@ templates: filter: > semconv_grouped_attributes({ "exclude_namespace": ["url", "network"], - "exclude_stability": ["experimental"] + "exclude_stability": ["experimental"], + "exclude_deprecated": true }) application_mode: each ``` @@ -370,7 +379,8 @@ templates: filter: > semconv_grouped_metrics({ "exclude_namespace": ["url", "network"], - "exclude_stability": ["experimental"] + "exclude_stability": ["experimental"], + "exclude_deprecated": true }) application_mode: each ``` From 726ecb70efb921fed01cc45283d4e5f0434b27fa Mon Sep 17 00:00:00 2001 From: Laurent Querel Date: Sun, 21 Jul 2024 17:26:05 -0700 Subject: [PATCH 25/29] feat(forge): Improve documentation intro --- crates/weaver_forge/README.md | 33 +++++++++++++++---- .../images/artifact-generation-pipeline.svg | 2 +- 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/crates/weaver_forge/README.md b/crates/weaver_forge/README.md index 16af0fa0..2aa01a32 100644 --- a/crates/weaver_forge/README.md +++ b/crates/weaver_forge/README.md @@ -19,17 +19,36 @@ ## Introduction -OTel Weaver is capable of generating documentation or code from a semantic convention registry. -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. - -The following diagram illustrates the documentation and code generation pipeline using the OTel +Weaver Forge is a component of OTEL Weaver that facilitates documentation and +code generation from a semantic convention registry. It uses MiniJinja, a +template engine compatible with Jinja2 syntax, which provides extensive +customization options (refer to this [GitHub repository](https://github.com/mitsuhiko/minijinja) +for more details). To streamline template creation for semantic conventions, +additional filters, functions, tests, and naming conventions have been +integrated with the standard Jinja logic. + +Weaver Forge also incorporates a YAML/JSON processor compatible with JQ to +preprocess resolved registries before they are processed by Jinja templates. +This integration helps avoid complex logic within the templates. A set of +specialized JQ filters is available to extract and organize attributes, metrics, +spans, and events, making them directly usable by the templates. This allows +template authors to focus on rendering rather than filtering, transforming, or +ordering logic in Jinja. + +The following diagram illustrates the documentation and code generation pipeline using the OTEL Weaver tool: ![Weaver Forge](images/artifact-generation-pipeline.svg) +Weaver's resolution process simplifies the semantic conventions by eliminating +references, extend statements, and other complex constructs, creating a fully +resolved, easy-to-use, self-contained version of the registry. This resolved +registry can be optionally filtered, grouped, sorted, and processed using a +JQ-based transformation before being used by the Jinja-based template engine +for documentation and code generation. Additionally, a set of templates and a +configuration file, stored alongside these templates, are processed by the +template engine to generate the desired artifacts. + ## General Concepts ### Template Directory Structure and Naming Conventions diff --git a/crates/weaver_forge/images/artifact-generation-pipeline.svg b/crates/weaver_forge/images/artifact-generation-pipeline.svg index 07ce9728..429f8462 100644 --- a/crates/weaver_forge/images/artifact-generation-pipeline.svg +++ b/crates/weaver_forge/images/artifact-generation-pipeline.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file From d3594a734e08f0081032a7487e9d076b1751f6ac Mon Sep 17 00:00:00 2001 From: Laurent Querel Date: Sun, 21 Jul 2024 19:09:26 -0700 Subject: [PATCH 26/29] feat(forge): Improve documentation section Template Directory Structure --- crates/weaver_forge/README.md | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/crates/weaver_forge/README.md b/crates/weaver_forge/README.md index 2aa01a32..30abcd60 100644 --- a/crates/weaver_forge/README.md +++ b/crates/weaver_forge/README.md @@ -53,9 +53,11 @@ template engine to generate the desired artifacts. ### Template Directory Structure and Naming Conventions -By default, Weaver expects to find the `templates/` directory in the current directory with the -following structure. The location of this directory can be redefined using the `-t` or `--templates` -CLI parameter. +By default, Weaver looks for a directory named `templates/`, which contains +several collection of templates, also referred to as targets (e.g. go, html, +markdown, rust, ...). The hierarchical structure of the `templates` directory +is detailed below. Note that this location can be changed using the `-t` or +`--templates` CLI parameter. ```plaintext templates/ @@ -71,11 +73,17 @@ templates/ .../ ``` -In this example, all the templates that belong to `go` must be defined in `templates/registry/go`, -and all the templates for `rust` must be defined in `templates/registry/rust`, and so on. -`go`, `html`, and `rust` are all generation targets accessible from the `weaver registry generate ` -command. For example, the command `weaver registry generate rust` will generate the rust files -based on the templates located in `templates/registry/rust`. +In this example, all templates for the `go` target are located in +`templates/registry/go`, and all templates for the `rust` target are in +`templates/registry/rust`. Similarly, other targets such as `html` have their +respective templates in designated folders. These targets (`go`, `html`, and +`rust`) are used for code and documentation generation via the +`weaver registry generate ` command. For instance, running +`weaver registry generate rust` will generate Rust files based on the templates +in `templates/registry/rust`. The intermediary `registry` directory groups +targets that convert a semantic convention registry into generated artifacts. +In a future version of Weaver, a new class of targets will be introduced to +generate artifacts from application telemetry schemas (`templates/schema/`). ### Configuration File - `weaver.yaml` From 7d516c3cd9955dc7db0d6734db03dee7aecade21 Mon Sep 17 00:00:00 2001 From: Laurent Querel Date: Sun, 21 Jul 2024 21:34:10 -0700 Subject: [PATCH 27/29] feat(forge): Improve documentation section Configuration file --- crates/weaver_forge/README.md | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/crates/weaver_forge/README.md b/crates/weaver_forge/README.md index 30abcd60..c81fd5f4 100644 --- a/crates/weaver_forge/README.md +++ b/crates/weaver_forge/README.md @@ -87,21 +87,30 @@ generate artifacts from application telemetry schemas (`templates/schema/` +directory. This file guides Weaver on which Jinja templates to use, the context +to provide during evaluation, and how to apply them. The template input can be +applied to the entire document with `application_mode` set to `single`, or to +each part of the document (if it is an array of objects) with `application_mode` +set to `multiple`. The file also configures filters (e.g., `map_text` or `acronym` +filters), controls whitespace handling, and includes other configurations +detailed in the in-depth section. The complete syntax for this configuration +file is described [here](/docs/weaver-config.md). + +Weaver supports sharing common configuration parts through an overriding +mechanism, loading configuration files in this order: - `$HOME/.weaver/weaver.yaml` -- `/weaver.yaml`, all intermediate directories containing a `weaver.yaml` file up to the -`templates/registry/` directory. +- `/weaver.yaml` and any intermediate directories containing a `weaver.yaml` +file up to the `templates/registry/` directory. - `templates/registry//weaver.yaml` -The last configuration file loaded will override the previous ones. You can explicitly define -the list of configuration files to load using the `--config` CLI n-ary parameter. +Each subsequent configuration file overrides the previous ones, up to the +`weaver.yaml` in the home directory (if it exists). To define your own +configuration file list, use the `--config` CLI parameter. -You can use this overriding mechanism to share configuration segments across multiple targets. +A common use of this configuration hierarchy is to share configuration +segments across multiple targets. ### JQ Filters From 5dbcc118ff7c5196b0bb02bc5465f8f05a0d3e24 Mon Sep 17 00:00:00 2001 From: Laurent Querel Date: Mon, 22 Jul 2024 14:05:43 -0700 Subject: [PATCH 28/29] feat(forge): Change namespace to root_namespace and improve docs --- CHANGELOG.md | 32 ++++++ Cargo.lock | 53 +++++---- Cargo.toml | 2 +- crates/weaver_cache/Cargo.toml | 2 +- crates/weaver_checker/Cargo.toml | 2 +- crates/weaver_codegen_test/Cargo.toml | 2 +- .../registry/rust/attributes/attributes.rs.j2 | 2 +- .../registry/rust/attributes/mod.rs.j2 | 6 +- .../registry/rust/metrics/metrics.rs.j2 | 2 +- .../templates/registry/rust/metrics/mod.rs.j2 | 6 +- crates/weaver_common/Cargo.toml | 2 +- crates/weaver_diff/Cargo.toml | 2 +- crates/weaver_forge/Cargo.toml | 2 +- crates/weaver_forge/README.md | 56 ++++----- .../semconv_jq_fn/semconv_attributes.json | 2 +- .../semconv_grouped_attributes.json | 2 +- ...ouped_attributes_without_experimental.json | 2 +- .../semconv_jq_fn/semconv_metrics.json | 2 +- .../images/artifact-generation-pipeline.svg | 2 +- .../templates/test/attribute_group.md | 4 +- .../templates/test/attribute_groups.md | 2 +- crates/weaver_forge/templates/test/event.md | 4 +- crates/weaver_forge/templates/test/events.md | 2 +- crates/weaver_forge/templates/test/metric.md | 4 +- crates/weaver_forge/templates/test/metrics.md | 2 +- .../weaver_forge/templates/test/resource.md | 4 +- .../weaver_forge/templates/test/resources.md | 2 +- crates/weaver_forge/templates/test/span.md | 4 +- crates/weaver_forge/templates/test/spans.md | 2 +- .../weaver_forge/templates/test/weaver.yaml | 12 +- crates/weaver_resolved_schema/Cargo.toml | 2 +- crates/weaver_resolver/Cargo.toml | 2 +- crates/weaver_semconv/Cargo.toml | 2 +- crates/weaver_semconv_gen/Cargo.toml | 2 +- crates/weaver_version/Cargo.toml | 2 +- defaults/jq/semconv.jq | 106 ++++++++++-------- 36 files changed, 185 insertions(+), 154 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b7590d96..044c641c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,38 @@ All notable changes to this project will be documented in this file. +## [0.7.0] - 2024-07-22 + +What's Changed + +* Add support for new custom semconv JQ filters by @lquerel. +* Update Weaver Forge documentation and include a step-by-step guide for codegen authors by @lquerel. + +The following new filters have been added to the Weaver Forge: + +* `semconv_group_attributes_by_root_namespace`: Groups the attributes by their root namespace. +* `semconv_attributes($options)`: Extracts and processes semantic convention attributes based on provided options. $options is an object that can contain: + * `exclude_stability`: a list of stability statuses to exclude. + * `exclude_deprecated`: a boolean to exclude deprecated metrics. + * `exclude_root_namespace`: a list of root namespaces to exclude. +* `semconv_attributes`: Convenience function to extract all attributes without any filtering options. +* `semconv_grouped_attributes($options)`: Groups the processed attributes by their root namespace based on provided options. $options is an object that can contain: + * `exclude_stability`: a list of stability statuses to exclude. + * `exclude_deprecated`: a boolean to exclude deprecated metrics. + * `exclude_root_namespace`: a list of root namespaces to exclude. +* `semconv_grouped_attributes`: Convenience function to group all attributes by their root namespace without any filtering options. +* `semconv_group_metrics_by_root_namespace`: Groups the metrics by their root namespace. +* `semconv_metrics($options)`: Extracts and processes semantic convention metrics based on provided options. $options is an object that can contain: + * `exclude_stability`: a list of stability statuses to exclude. + * `exclude_deprecated`: a boolean to exclude deprecated metrics. + * `exclude_root_namespace`: a list of root namespaces to exclude. +* `semconv_metrics`: Convenience function to extract all metrics without any filtering options. +* `semconv_grouped_metrics($options)`: Groups the processed metrics by their root namespace based on provided options. $options is an object that can contain: + * `exclude_stability`: a list of stability statuses to exclude. + * `exclude_deprecated`: a boolean to exclude deprecated metrics. + * `exclude_root_namespace`: a list of root namespaces to exclude. +* `semconv_grouped_metrics`: Convenience function to group all metrics by their root namespace without any filtering options. + ## [0.6.0] - 2024-07-16 What's Changed diff --git a/Cargo.lock b/Cargo.lock index fc865f7b..aca807af 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2066,9 +2066,9 @@ dependencies = [ [[package]] name = "kstring" -version = "2.0.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec3066350882a1cd6d950d055997f379ac37fd39f81cd4d8ed186032eb3c5747" +checksum = "e703acfd696000db3f6d1238e23b3d1f889192e1e439969c44e8423bb7a5655e" dependencies = [ "static_assertions", ] @@ -2727,14 +2727,13 @@ dependencies = [ [[package]] name = "quinn-udp" -version = "0.5.2" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9096629c45860fc7fb143e125eb826b5e721e10be3263160c7d60ca832cf8c46" +checksum = "8bffec3605b73c6f1754535084a85229fa8a30f86014e6c81aeec4abb68b0285" dependencies = [ "libc", "once_cell", "socket2", - "tracing", "windows-sys 0.52.0", ] @@ -3076,9 +3075,9 @@ checksum = "976295e77ce332211c0d24d92c0e83e50f5c5f046d11082cea19f3df13a3562d" [[package]] name = "rustls-webpki" -version = "0.102.5" +version = "0.102.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9a6fccd794a42c2c105b513a2f62bc3fd8f3ba57a4593677ceb0bd035164d78" +checksum = "8e6b52d4fda176fd835fdc55a835d4a89b8499cad995885a21149d5ad62f852e" dependencies = [ "ring", "rustls-pki-types", @@ -3260,9 +3259,9 @@ dependencies = [ [[package]] name = "sha1_smol" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae1a47186c03a32177042e55dbc5fd5aee900b8e0069a8d70fba96a9375cd012" +checksum = "bbfa15b3dddfee50a0fff136974b3e1bde555604ba463834a7eb7deb6417705d" [[package]] name = "sha2" @@ -3313,9 +3312,9 @@ dependencies = [ [[package]] name = "similar" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa42c91313f1d05da9b26f267f931cf178d4aba455b4c4622dd7355eb80c6640" +checksum = "1de1d4f81173b03af4c0cbed3c898f6bff5b870e4a7f5d6f4057d62a7a4b686e" [[package]] name = "simple_asn1" @@ -3445,9 +3444,9 @@ checksum = "b7401a30af6cb5818bb64852270bb722533397edcfc7344954a38f420819ece2" [[package]] name = "syn" -version = "2.0.71" +version = "2.0.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b146dcf730474b4bcd16c311627b31ede9ab149045db4d6088b3becaea046462" +checksum = "dc4b9b9bf2add8093d3f2c0204471e951b2285580335de42f9d2534f3ae7a8af" dependencies = [ "proc-macro2", "quote", @@ -4012,7 +4011,7 @@ dependencies = [ [[package]] name = "weaver" -version = "0.6.0" +version = "0.7.0" dependencies = [ "assert_cmd", "clap", @@ -4043,7 +4042,7 @@ dependencies = [ [[package]] name = "weaver_cache" -version = "0.6.0" +version = "0.7.0" dependencies = [ "dirs", "gix", @@ -4056,7 +4055,7 @@ dependencies = [ [[package]] name = "weaver_checker" -version = "0.6.0" +version = "0.7.0" dependencies = [ "globset", "miette", @@ -4071,7 +4070,7 @@ dependencies = [ [[package]] name = "weaver_codegen_test" -version = "0.6.0" +version = "0.7.0" dependencies = [ "dirs", "opentelemetry 0.23.0", @@ -4085,7 +4084,7 @@ dependencies = [ [[package]] name = "weaver_common" -version = "0.6.0" +version = "0.7.0" dependencies = [ "miette", "paris", @@ -4096,7 +4095,7 @@ dependencies = [ [[package]] name = "weaver_diff" -version = "0.6.0" +version = "0.7.0" dependencies = [ "similar", "walkdir", @@ -4104,7 +4103,7 @@ dependencies = [ [[package]] name = "weaver_forge" -version = "0.6.0" +version = "0.7.0" dependencies = [ "convert_case", "dirs", @@ -4141,7 +4140,7 @@ dependencies = [ [[package]] name = "weaver_resolved_schema" -version = "0.6.0" +version = "0.7.0" dependencies = [ "ordered-float", "schemars", @@ -4154,7 +4153,7 @@ dependencies = [ [[package]] name = "weaver_resolver" -version = "0.6.0" +version = "0.7.0" dependencies = [ "glob", "miette", @@ -4172,7 +4171,7 @@ dependencies = [ [[package]] name = "weaver_semconv" -version = "0.6.0" +version = "0.7.0" dependencies = [ "glob", "miette", @@ -4187,7 +4186,7 @@ dependencies = [ [[package]] name = "weaver_semconv_gen" -version = "0.6.0" +version = "0.7.0" dependencies = [ "itertools 0.13.0", "miette", @@ -4205,7 +4204,7 @@ dependencies = [ [[package]] name = "weaver_version" -version = "0.6.0" +version = "0.7.0" dependencies = [ "schemars", "semver", @@ -4414,9 +4413,9 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" -version = "0.6.14" +version = "0.6.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "374ec40a2d767a3c1b4972d9475ecd557356637be906f2cb3f7fe17a6eb5e22f" +checksum = "557404e450152cd6795bb558bca69e43c585055f4606e3bcae5894fc6dac9ba0" dependencies = [ "memchr", ] diff --git a/Cargo.toml b/Cargo.toml index c82dc912..e48adcad 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "weaver" -version = "0.6.0" +version = "0.7.0" authors = ["OpenTelemetry"] edition = "2021" repository = "https://github.com/open-telemetry/weaver" diff --git a/crates/weaver_cache/Cargo.toml b/crates/weaver_cache/Cargo.toml index ef08dde4..7acd11a3 100644 --- a/crates/weaver_cache/Cargo.toml +++ b/crates/weaver_cache/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "weaver_cache" -version = "0.6.0" +version = "0.7.0" authors.workspace = true repository.workspace = true license.workspace = true diff --git a/crates/weaver_checker/Cargo.toml b/crates/weaver_checker/Cargo.toml index 9104b6d5..fc114933 100644 --- a/crates/weaver_checker/Cargo.toml +++ b/crates/weaver_checker/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "weaver_checker" -version = "0.6.0" +version = "0.7.0" authors.workspace = true repository.workspace = true license.workspace = true diff --git a/crates/weaver_codegen_test/Cargo.toml b/crates/weaver_codegen_test/Cargo.toml index eb3feaba..dae1928b 100644 --- a/crates/weaver_codegen_test/Cargo.toml +++ b/crates/weaver_codegen_test/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "weaver_codegen_test" -version = "0.6.0" +version = "0.7.0" authors.workspace = true repository.workspace = true license.workspace = true diff --git a/crates/weaver_codegen_test/templates/registry/rust/attributes/attributes.rs.j2 b/crates/weaver_codegen_test/templates/registry/rust/attributes/attributes.rs.j2 index c5fc19a3..4d84ccd9 100644 --- a/crates/weaver_codegen_test/templates/registry/rust/attributes/attributes.rs.j2 +++ b/crates/weaver_codegen_test/templates/registry/rust/attributes/attributes.rs.j2 @@ -1,4 +1,4 @@ -{%- set file_name = ctx.namespace | snake_case -%} +{%- set file_name = ctx.root_namespace | snake_case -%} {{- template.set_file_name("attributes/" ~ file_name ~ ".rs") -}} {%- import 'attribute_macros.j2' as attribute_macros -%} diff --git a/crates/weaver_codegen_test/templates/registry/rust/attributes/mod.rs.j2 b/crates/weaver_codegen_test/templates/registry/rust/attributes/mod.rs.j2 index 5119aa5d..1f19b39b 100644 --- a/crates/weaver_codegen_test/templates/registry/rust/attributes/mod.rs.j2 +++ b/crates/weaver_codegen_test/templates/registry/rust/attributes/mod.rs.j2 @@ -12,9 +12,9 @@ use opentelemetry::{Key, KeyValue, StringValue}; pub const ATTRIBUTES_PARAM: bool = {{ params.attributes }}; -{% for attributes_namespace in ctx %} -/// Attributes for the `{{ attributes_namespace.namespace }}` namespace. -pub mod {{ attributes_namespace.namespace | snake_case }}; +{% for attributes_root_namespace in ctx %} +/// Attributes for the `{{ attributes_root_namespace.root_namespace }}` namespace. +pub mod {{ attributes_root_namespace.root_namespace | snake_case }}; {% endfor %} /// A typed attribute key. diff --git a/crates/weaver_codegen_test/templates/registry/rust/metrics/metrics.rs.j2 b/crates/weaver_codegen_test/templates/registry/rust/metrics/metrics.rs.j2 index e6d32aaf..bb948997 100644 --- a/crates/weaver_codegen_test/templates/registry/rust/metrics/metrics.rs.j2 +++ b/crates/weaver_codegen_test/templates/registry/rust/metrics/metrics.rs.j2 @@ -1,4 +1,4 @@ -{%- set file_name = ctx.namespace | snake_case -%} +{%- set file_name = ctx.root_namespace | snake_case -%} {{- template.set_file_name("metrics/" ~ file_name ~ ".rs") -}} /* diff --git a/crates/weaver_codegen_test/templates/registry/rust/metrics/mod.rs.j2 b/crates/weaver_codegen_test/templates/registry/rust/metrics/mod.rs.j2 index ee94c235..b7ee0c6f 100644 --- a/crates/weaver_codegen_test/templates/registry/rust/metrics/mod.rs.j2 +++ b/crates/weaver_codegen_test/templates/registry/rust/metrics/mod.rs.j2 @@ -10,9 +10,9 @@ pub const METRICS_PARAM: bool = {{ params.metrics }}; -{% for attributes_namespace in ctx %} -/// Metrics for the `{{ attributes_namespace.namespace }}` namespace. -pub mod {{ attributes_namespace.namespace | snake_case }}; +{% for attributes_root_namespace in ctx %} +/// Metrics for the `{{ attributes_root_namespace.root_namespace }}` namespace. +pub mod {{ attributes_root_namespace.root_namespace | snake_case }}; {% endfor %} /// A trait implemented by histogram providers (e.g. `Meter`). diff --git a/crates/weaver_common/Cargo.toml b/crates/weaver_common/Cargo.toml index 7b91b030..1456510c 100644 --- a/crates/weaver_common/Cargo.toml +++ b/crates/weaver_common/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "weaver_common" -version = "0.6.0" +version = "0.7.0" authors.workspace = true repository.workspace = true license.workspace = true diff --git a/crates/weaver_diff/Cargo.toml b/crates/weaver_diff/Cargo.toml index bd47846b..0b3590de 100644 --- a/crates/weaver_diff/Cargo.toml +++ b/crates/weaver_diff/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "weaver_diff" -version = "0.6.0" +version = "0.7.0" authors.workspace = true repository.workspace = true license.workspace = true diff --git a/crates/weaver_forge/Cargo.toml b/crates/weaver_forge/Cargo.toml index 7baa1c40..c92a6631 100644 --- a/crates/weaver_forge/Cargo.toml +++ b/crates/weaver_forge/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "weaver_forge" -version = "0.6.0" +version = "0.7.0" authors.workspace = true repository.workspace = true license.workspace = true diff --git a/crates/weaver_forge/README.md b/crates/weaver_forge/README.md index c81fd5f4..ea832e37 100644 --- a/crates/weaver_forge/README.md +++ b/crates/weaver_forge/README.md @@ -30,8 +30,8 @@ integrated with the standard Jinja logic. Weaver Forge also incorporates a YAML/JSON processor compatible with JQ to preprocess resolved registries before they are processed by Jinja templates. This integration helps avoid complex logic within the templates. A set of -specialized JQ filters is available to extract and organize attributes, metrics, -spans, and events, making them directly usable by the templates. This allows +specialized JQ filters is available to extract and organize attributes and +metrics, making them directly usable by the templates. This allows template authors to focus on rendering rather than filtering, transforming, or ordering logic in Jinja. @@ -120,15 +120,15 @@ with a JQ filter, defined in the `weaver.yaml` configuration file. These filters the resolved semantic convention registry, allowing you to transform and manipulate the data as needed before to being processed in the template. -For example, you can group attributes by namespace or filter out specific stability levels. This +For example, you can group attributes by root namespace or filter out specific stability levels. This preprocessing ensures that the data is in the correct format and structure when it is accessed within the corresponding Jinja templates. In the following example, the `attributes.j2` template is associated with the `semconv_grouped_attributes` JQ filter. This filter is applied to each object selected by the JQ filter before being delivered to the template. `semconv_grouped_attributes` returns an array of objects containing the attributes -grouped by namespace. The `application_mode` is set to `each` so that the template is applied to -each object in the array, i.e., to each group of attributes for a given namespace. +grouped by root namespace. The `application_mode` is set to `each` so that the template is applied to +each object in the array, i.e., to each group of attributes for a given root namespace. ```yaml templates: @@ -228,7 +228,7 @@ More details on the JQ syntax and custom semconv filters [here](#jq-filters-refe 1. **Create a template file `attributes.j2` in the appropriate directory:** ```jinja -{%- set file_name = ctx.namespace | snake_case -%} +{%- set file_name = ctx.root_namespace | snake_case -%} {{- template.set_file_name("attributes/" ~ file_name ~ ".md") -}} ... a valid jinja template @@ -237,7 +237,7 @@ a valid jinja template The first two lines (optional) specify the name of the file generated from the evaluation of the current template and the inputs provided by Weaver. In this specific example, an object -containing a `namespace` and an array of `attributes`. +containing a `root_namespace` and an array of `attributes`. 2. **Use Jinja syntax to define the content and structure of the generated files.** @@ -292,8 +292,8 @@ In this example, the `attributes.j2` and `metrics.j2` templates are associated w `semconv_grouped_attributes` and `semconv_grouped_metrics` JQ filters respectively. These filters are applied to each object selected by the JQ filter before being delivered to the template. `semconv_grouped_attributes` returns an array of objects containing the attributes -grouped by namespace. The `application_mode` is set to `each` so that the template is -applied to each object in the array, i.e., to each group of attributes for a given namespace. +grouped by root namespace. The `application_mode` is set to `each` so that the template is +applied to each object in the array, i.e., to each group of attributes for a given root namespace. A series of JQ filters dedicated to the manipulation of semantic conventions registries is available to template authors. @@ -301,7 +301,7 @@ available to template authors. **Process Registry Attributes** The following JQ filter extracts the registry attributes from the resolved registry and -returns a list of registry attributes grouped by namespace and sorted by attribute names. +returns a list of registry attributes grouped by root namespace and sorted by attribute names. ```yaml templates: @@ -315,7 +315,7 @@ The output of the JQ filter has the following structure: ```json5 [ { - "namespace": "user_agent", + "root_namespace": "user_agent", "attributes": [ { "brief": "Value of the HTTP User-Agent", @@ -327,14 +327,14 @@ The output of the JQ filter has the following structure: "type": "string", // ... other fields }, - // ... other attributes in the same namespace + // ... other attributes in the same root namespace ] }, - // ... other namespaces + // ... other root namespaces ] ``` -The `semconv_grouped_attributes` function also supports options to exclude specified namespaces, +The `semconv_grouped_attributes` function also supports options to exclude specified root namespaces, specific stability levels, and deprecated entities. The following syntax is supported: ```yaml @@ -342,7 +342,7 @@ templates: - pattern: attributes.j2 filter: > semconv_grouped_attributes({ - "exclude_namespace": ["url", "network"], + "exclude_root_namespace": ["url", "network"], "exclude_stability": ["experimental"], "exclude_deprecated": true }) @@ -359,19 +359,19 @@ JQ functions: ```jq def semconv_grouped_attributes($options): semconv_attributes($options) - | semconv_group_attributes_by_namespace; + | semconv_group_attributes_by_root_namespace; def semconv_grouped_attributes: semconv_grouped_attributes({}); ``` The `semconv_attributes` function extracts the registry attributes and applies the given options. -The `semconv_group_attributes_by_namespace` function groups the attributes by namespace. It's +The `semconv_group_attributes_by_root_namespace` function groups the attributes by root namespace. It's possible to combine these two functions with your own JQ filters if needed. **Process Metrics** The following JQ filter extracts the metrics from the resolved registry, sorted by group -namespace and sorted by metric names. +root namespace and sorted by metric names. ```yaml templates: @@ -385,7 +385,7 @@ The output of the JQ filter has the following structure: ```json5 [ { - "namespace": "jvm", + "root_namespace": "jvm", "metrics": [ { "attributes": [ ... ], @@ -393,17 +393,17 @@ The output of the JQ filter has the following structure: "id": "metric.jvm.cpu.recent_utilization", "instrument": "gauge", "metric_name": "jvm.cpu.recent_utilization", - "namespace": "jvm", + "root_namespace": "jvm", "note": "The value range is [0.0,1.0]. ...", "stability": "stable", "type": "metric", "unit": "1", // ... other fields }, - // ... other metrics in the same namespace + // ... other metrics in the same root namespace ] }, - // ... other namespaces + // ... other root namespaces ] ``` @@ -414,23 +414,15 @@ templates: - pattern: metrics.j2 filter: > semconv_grouped_metrics({ - "exclude_namespace": ["url", "network"], + "exclude_root_namespace": ["url", "network"], "exclude_stability": ["experimental"], "exclude_deprecated": true }) application_mode: each ``` -**Other signals** - -The pattern is used for other signals and OTEL entities: -- `semconv_grouped_resources` -- `semconv_grouped_scopes` -- `semconv_grouped_spans` -- `semconv_grouped_events` - All the `semconv_grouped_<...>` functions are the composition of two functions: -`semconv_<...>` and `semconv_group_<...>_by_namespace`. +`semconv_<...>` and `semconv_group_<...>_by_root_namespace`. > Note: JQ is a language for querying and transforming structured data. For more > information, see [JQ Manual](https://jqlang.github.io/jq/manual/). The diff --git a/crates/weaver_forge/expected_output/semconv_jq_fn/semconv_attributes.json b/crates/weaver_forge/expected_output/semconv_jq_fn/semconv_attributes.json index 1baced83..f3b7465b 100644 --- a/crates/weaver_forge/expected_output/semconv_jq_fn/semconv_attributes.json +++ b/crates/weaver_forge/expected_output/semconv_jq_fn/semconv_attributes.json @@ -1 +1 @@ -[{"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","name":"db.cassandra.consistency_level","namespace":"db","requirement_level":"recommended","tag":"tech-specific-cassandra","type":{"allow_custom_values":true,"members":[{"brief":null,"deprecated":null,"id":"all","note":null,"stability":null,"value":"all"},{"brief":null,"deprecated":null,"id":"each_quorum","note":null,"stability":null,"value":"each_quorum"},{"brief":null,"deprecated":null,"id":"quorum","note":null,"stability":null,"value":"quorum"},{"brief":null,"deprecated":null,"id":"local_quorum","note":null,"stability":null,"value":"local_quorum"},{"brief":null,"deprecated":null,"id":"one","note":null,"stability":null,"value":"one"},{"brief":null,"deprecated":null,"id":"two","note":null,"stability":null,"value":"two"},{"brief":null,"deprecated":null,"id":"three","note":null,"stability":null,"value":"three"},{"brief":null,"deprecated":null,"id":"local_one","note":null,"stability":null,"value":"local_one"},{"brief":null,"deprecated":null,"id":"any","note":null,"stability":null,"value":"any"},{"brief":null,"deprecated":null,"id":"serial","note":null,"stability":null,"value":"serial"},{"brief":null,"deprecated":null,"id":"local_serial","note":null,"stability":null,"value":"local_serial"}]}},{"brief":"The data center of the coordinating node for a query.\n","examples":"us-west-2","name":"db.cassandra.coordinator.dc","namespace":"db","requirement_level":"recommended","tag":"tech-specific-cassandra","type":"string"},{"brief":"The ID of the coordinating node for a query.\n","examples":"be13faa2-8574-4d71-926d-27f16cf8a7af","name":"db.cassandra.coordinator.id","namespace":"db","requirement_level":"recommended","tag":"tech-specific-cassandra","type":"string"},{"brief":"Whether or not the query is idempotent.\n","name":"db.cassandra.idempotence","namespace":"db","requirement_level":"recommended","tag":"tech-specific-cassandra","type":"boolean"},{"brief":"The fetch size used for paging, i.e. how many rows will be returned at once.\n","examples":[5000],"name":"db.cassandra.page_size","namespace":"db","requirement_level":"recommended","tag":"tech-specific-cassandra","type":"int"},{"brief":"The number of times a query was speculatively executed. Not set or `0` if the query was not executed speculatively.\n","examples":[0,2],"name":"db.cassandra.speculative_execution_count","namespace":"db","requirement_level":"recommended","tag":"tech-specific-cassandra","type":"int"},{"brief":"The name of the primary Cassandra table that the operation is acting upon, including the keyspace name (if applicable).","examples":"mytable","name":"db.cassandra.table","namespace":"db","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","requirement_level":"recommended","tag":"tech-specific-cassandra","type":"string"},{"brief":"The connection string used to connect to the database. It is recommended to remove embedded credentials.\n","examples":"Server=(localdb)\\v11.0;Integrated Security=true;","name":"db.connection_string","namespace":"db","requirement_level":"recommended","tag":"db-generic","type":"string"},{"brief":"Unique Cosmos client instance id.","examples":"3ba4827d-4422-483f-b59f-85b74211c11d","name":"db.cosmosdb.client_id","namespace":"db","requirement_level":"recommended","tag":"tech-specific-cosmosdb","type":"string"},{"brief":"Cosmos client connection mode.","name":"db.cosmosdb.connection_mode","namespace":"db","requirement_level":"recommended","tag":"tech-specific-cosmosdb","type":{"allow_custom_values":false,"members":[{"brief":"Gateway (HTTP) connections mode","deprecated":null,"id":"gateway","note":null,"stability":null,"value":"gateway"},{"brief":"Direct connection.","deprecated":null,"id":"direct","note":null,"stability":null,"value":"direct"}]}},{"brief":"Cosmos DB container name.","examples":"anystring","name":"db.cosmosdb.container","namespace":"db","requirement_level":"recommended","tag":"tech-specific-cosmosdb","type":"string"},{"brief":"CosmosDB Operation Type.","name":"db.cosmosdb.operation_type","namespace":"db","requirement_level":"recommended","tag":"tech-specific-cosmosdb","type":{"allow_custom_values":true,"members":[{"brief":null,"deprecated":null,"id":"invalid","note":null,"stability":null,"value":"Invalid"},{"brief":null,"deprecated":null,"id":"create","note":null,"stability":null,"value":"Create"},{"brief":null,"deprecated":null,"id":"patch","note":null,"stability":null,"value":"Patch"},{"brief":null,"deprecated":null,"id":"read","note":null,"stability":null,"value":"Read"},{"brief":null,"deprecated":null,"id":"read_feed","note":null,"stability":null,"value":"ReadFeed"},{"brief":null,"deprecated":null,"id":"delete","note":null,"stability":null,"value":"Delete"},{"brief":null,"deprecated":null,"id":"replace","note":null,"stability":null,"value":"Replace"},{"brief":null,"deprecated":null,"id":"execute","note":null,"stability":null,"value":"Execute"},{"brief":null,"deprecated":null,"id":"query","note":null,"stability":null,"value":"Query"},{"brief":null,"deprecated":null,"id":"head","note":null,"stability":null,"value":"Head"},{"brief":null,"deprecated":null,"id":"head_feed","note":null,"stability":null,"value":"HeadFeed"},{"brief":null,"deprecated":null,"id":"upsert","note":null,"stability":null,"value":"Upsert"},{"brief":null,"deprecated":null,"id":"batch","note":null,"stability":null,"value":"Batch"},{"brief":null,"deprecated":null,"id":"query_plan","note":null,"stability":null,"value":"QueryPlan"},{"brief":null,"deprecated":null,"id":"execute_javascript","note":null,"stability":null,"value":"ExecuteJavaScript"}]}},{"brief":"RU consumed for that operation","examples":[46.18,1.0],"name":"db.cosmosdb.request_charge","namespace":"db","requirement_level":"recommended","tag":"tech-specific-cosmosdb","type":"double"},{"brief":"Request payload size in bytes","name":"db.cosmosdb.request_content_length","namespace":"db","requirement_level":"recommended","tag":"tech-specific-cosmosdb","type":"int"},{"brief":"Cosmos DB status code.","examples":[200,201],"name":"db.cosmosdb.status_code","namespace":"db","requirement_level":"recommended","tag":"tech-specific-cosmosdb","type":"int"},{"brief":"Cosmos DB sub status code.","examples":[1000,1002],"name":"db.cosmosdb.sub_status_code","namespace":"db","requirement_level":"recommended","tag":"tech-specific-cosmosdb","type":"int"},{"brief":"Represents the identifier of an Elasticsearch cluster.\n","examples":["e9106fc68e3044f0b1475b04bf4ffd5f"],"name":"db.elasticsearch.cluster.name","namespace":"db","requirement_level":"recommended","tag":"tech-specific-elasticsearch","type":"string"},{"brief":"Represents the human-readable identifier of the node/instance to which a request was routed.\n","examples":["instance-0000000001"],"name":"db.elasticsearch.node.name","namespace":"db","requirement_level":"recommended","tag":"tech-specific-elasticsearch","type":"string"},{"brief":"A dynamic value in the url path.\n","examples":["db.elasticsearch.path_parts.index=test-index","db.elasticsearch.path_parts.doc_id=123"],"name":"db.elasticsearch.path_parts","namespace":"db","note":"Many Elasticsearch url paths allow dynamic values. These SHOULD be recorded in span attributes in the format `db.elasticsearch.path_parts.\u003ckey\u003e`, where `\u003ckey\u003e` 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","requirement_level":"recommended","tag":"tech-specific-elasticsearch","type":"template[string]"},{"brief":"An identifier (address, unique name, or any other identifier) of the database instance that is executing queries or mutations on the current connection. This is useful in cases where the database is running in a clustered environment and the instrumentation is able to record the node executing the query. The client may obtain this value in databases like MySQL using queries like `select @@hostname`.\n","examples":"mysql-e26b99z.example.com","name":"db.instance.id","namespace":"db","requirement_level":"recommended","tag":"db-generic","type":"string"},{"brief":"The fully-qualified class name of the [Java Database Connectivity (JDBC)](https://docs.oracle.com/javase/8/docs/technotes/guides/jdbc/) driver used to connect.\n","examples":["org.postgresql.Driver","com.microsoft.sqlserver.jdbc.SQLServerDriver"],"name":"db.jdbc.driver_classname","namespace":"db","requirement_level":"recommended","tag":"tech-specific-jdbc","type":"string"},{"brief":"The MongoDB collection being accessed within the database stated in `db.name`.\n","examples":["customers","products"],"name":"db.mongodb.collection","namespace":"db","requirement_level":"recommended","tag":"tech-specific-mongodb","type":"string"},{"brief":"The Microsoft SQL Server [instance name](https://docs.microsoft.com/sql/connect/jdbc/building-the-connection-url?view=sql-server-ver15) connecting to. This name is used to determine the port of a named instance.\n","examples":"MSSQLSERVER","name":"db.mssql.instance_name","namespace":"db","note":"If setting a `db.mssql.instance_name`, `server.port` is no longer required (but still recommended if non-standard).\n","requirement_level":"recommended","tag":"tech-specific-mssql","type":"string"},{"brief":"This attribute is used to report the name of the database being accessed. For commands that switch the database, this should be set to the target database (even if the command fails).\n","examples":["customers","main"],"name":"db.name","namespace":"db","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","requirement_level":"recommended","tag":"db-generic","type":"string"},{"brief":"The name of the operation being executed, e.g. the [MongoDB command name](https://docs.mongodb.com/manual/reference/command/#database-operations) such as `findAndModify`, or the SQL keyword.\n","examples":["findAndModify","HMSET","SELECT"],"name":"db.operation","namespace":"db","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","requirement_level":"recommended","tag":"db-generic","type":"string"},{"brief":"The index of the database being accessed as used in the [`SELECT` command](https://redis.io/commands/select), provided as an integer. To be used instead of the generic `db.name` attribute.\n","examples":[0,1,15],"name":"db.redis.database_index","namespace":"db","requirement_level":"recommended","tag":"tech-specific-redis","type":"int"},{"brief":"The name of the primary table that the operation is acting upon, including the database name (if applicable).","examples":["public.users","customers"],"name":"db.sql.table","namespace":"db","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","requirement_level":"recommended","tag":"tech-specific-sql","type":"string"},{"brief":"The database statement being executed.\n","examples":["SELECT * FROM wuser_table","SET mykey \"WuValue\""],"name":"db.statement","namespace":"db","requirement_level":"recommended","tag":"db-generic","type":"string"},{"brief":"An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers.","name":"db.system","namespace":"db","requirement_level":"recommended","tag":"db-generic","type":{"allow_custom_values":true,"members":[{"brief":"Some other SQL database. Fallback only. See notes.","deprecated":null,"id":"other_sql","note":null,"stability":null,"value":"other_sql"},{"brief":"Microsoft SQL Server","deprecated":null,"id":"mssql","note":null,"stability":null,"value":"mssql"},{"brief":"Microsoft SQL Server Compact","deprecated":null,"id":"mssqlcompact","note":null,"stability":null,"value":"mssqlcompact"},{"brief":"MySQL","deprecated":null,"id":"mysql","note":null,"stability":null,"value":"mysql"},{"brief":"Oracle Database","deprecated":null,"id":"oracle","note":null,"stability":null,"value":"oracle"},{"brief":"IBM Db2","deprecated":null,"id":"db2","note":null,"stability":null,"value":"db2"},{"brief":"PostgreSQL","deprecated":null,"id":"postgresql","note":null,"stability":null,"value":"postgresql"},{"brief":"Amazon Redshift","deprecated":null,"id":"redshift","note":null,"stability":null,"value":"redshift"},{"brief":"Apache Hive","deprecated":null,"id":"hive","note":null,"stability":null,"value":"hive"},{"brief":"Cloudscape","deprecated":null,"id":"cloudscape","note":null,"stability":null,"value":"cloudscape"},{"brief":"HyperSQL DataBase","deprecated":null,"id":"hsqldb","note":null,"stability":null,"value":"hsqldb"},{"brief":"Progress Database","deprecated":null,"id":"progress","note":null,"stability":null,"value":"progress"},{"brief":"SAP MaxDB","deprecated":null,"id":"maxdb","note":null,"stability":null,"value":"maxdb"},{"brief":"SAP HANA","deprecated":null,"id":"hanadb","note":null,"stability":null,"value":"hanadb"},{"brief":"Ingres","deprecated":null,"id":"ingres","note":null,"stability":null,"value":"ingres"},{"brief":"FirstSQL","deprecated":null,"id":"firstsql","note":null,"stability":null,"value":"firstsql"},{"brief":"EnterpriseDB","deprecated":null,"id":"edb","note":null,"stability":null,"value":"edb"},{"brief":"InterSystems Caché","deprecated":null,"id":"cache","note":null,"stability":null,"value":"cache"},{"brief":"Adabas (Adaptable Database System)","deprecated":null,"id":"adabas","note":null,"stability":null,"value":"adabas"},{"brief":"Firebird","deprecated":null,"id":"firebird","note":null,"stability":null,"value":"firebird"},{"brief":"Apache Derby","deprecated":null,"id":"derby","note":null,"stability":null,"value":"derby"},{"brief":"FileMaker","deprecated":null,"id":"filemaker","note":null,"stability":null,"value":"filemaker"},{"brief":"Informix","deprecated":null,"id":"informix","note":null,"stability":null,"value":"informix"},{"brief":"InstantDB","deprecated":null,"id":"instantdb","note":null,"stability":null,"value":"instantdb"},{"brief":"InterBase","deprecated":null,"id":"interbase","note":null,"stability":null,"value":"interbase"},{"brief":"MariaDB","deprecated":null,"id":"mariadb","note":null,"stability":null,"value":"mariadb"},{"brief":"Netezza","deprecated":null,"id":"netezza","note":null,"stability":null,"value":"netezza"},{"brief":"Pervasive PSQL","deprecated":null,"id":"pervasive","note":null,"stability":null,"value":"pervasive"},{"brief":"PointBase","deprecated":null,"id":"pointbase","note":null,"stability":null,"value":"pointbase"},{"brief":"SQLite","deprecated":null,"id":"sqlite","note":null,"stability":null,"value":"sqlite"},{"brief":"Sybase","deprecated":null,"id":"sybase","note":null,"stability":null,"value":"sybase"},{"brief":"Teradata","deprecated":null,"id":"teradata","note":null,"stability":null,"value":"teradata"},{"brief":"Vertica","deprecated":null,"id":"vertica","note":null,"stability":null,"value":"vertica"},{"brief":"H2","deprecated":null,"id":"h2","note":null,"stability":null,"value":"h2"},{"brief":"ColdFusion IMQ","deprecated":null,"id":"coldfusion","note":null,"stability":null,"value":"coldfusion"},{"brief":"Apache Cassandra","deprecated":null,"id":"cassandra","note":null,"stability":null,"value":"cassandra"},{"brief":"Apache HBase","deprecated":null,"id":"hbase","note":null,"stability":null,"value":"hbase"},{"brief":"MongoDB","deprecated":null,"id":"mongodb","note":null,"stability":null,"value":"mongodb"},{"brief":"Redis","deprecated":null,"id":"redis","note":null,"stability":null,"value":"redis"},{"brief":"Couchbase","deprecated":null,"id":"couchbase","note":null,"stability":null,"value":"couchbase"},{"brief":"CouchDB","deprecated":null,"id":"couchdb","note":null,"stability":null,"value":"couchdb"},{"brief":"Microsoft Azure Cosmos DB","deprecated":null,"id":"cosmosdb","note":null,"stability":null,"value":"cosmosdb"},{"brief":"Amazon DynamoDB","deprecated":null,"id":"dynamodb","note":null,"stability":null,"value":"dynamodb"},{"brief":"Neo4j","deprecated":null,"id":"neo4j","note":null,"stability":null,"value":"neo4j"},{"brief":"Apache Geode","deprecated":null,"id":"geode","note":null,"stability":null,"value":"geode"},{"brief":"Elasticsearch","deprecated":null,"id":"elasticsearch","note":null,"stability":null,"value":"elasticsearch"},{"brief":"Memcached","deprecated":null,"id":"memcached","note":null,"stability":null,"value":"memcached"},{"brief":"CockroachDB","deprecated":null,"id":"cockroachdb","note":null,"stability":null,"value":"cockroachdb"},{"brief":"OpenSearch","deprecated":null,"id":"opensearch","note":null,"stability":null,"value":"opensearch"},{"brief":"ClickHouse","deprecated":null,"id":"clickhouse","note":null,"stability":null,"value":"clickhouse"},{"brief":"Cloud Spanner","deprecated":null,"id":"spanner","note":null,"stability":null,"value":"spanner"},{"brief":"Trino","deprecated":null,"id":"trino","note":null,"stability":null,"value":"trino"}]}},{"brief":"Username for accessing the database.\n","examples":["readonly_user","reporting_user"],"name":"db.user","namespace":"db","requirement_level":"recommended","tag":"db-generic","type":"string"},{"brief":"The size of the request payload body in bytes. This is the number of bytes transferred excluding headers and is often, but not always, present as the [Content-Length](https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length) header. For requests using transport encoding, this should be the compressed size.\n","examples":3495,"name":"http.request.body.size","namespace":"http","requirement_level":"recommended","stability":"experimental","type":"int"},{"brief":"HTTP request headers, `\u003ckey\u003e` being the normalized HTTP Header name (lowercase), the value being the header values.\n","examples":["http.request.header.content-type=[\"application/json\"]","http.request.header.x-forwarded-for=[\"1.2.3.4\", \"1.2.3.5\"]"],"name":"http.request.header","namespace":"http","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","requirement_level":"recommended","stability":"stable","type":"template[string[]]"},{"brief":"HTTP request method.","examples":["GET","POST","HEAD"],"name":"http.request.method","namespace":"http","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","requirement_level":"recommended","stability":"stable","type":{"allow_custom_values":true,"members":[{"brief":"CONNECT method.","deprecated":null,"id":"connect","note":null,"stability":null,"value":"CONNECT"},{"brief":"DELETE method.","deprecated":null,"id":"delete","note":null,"stability":null,"value":"DELETE"},{"brief":"GET method.","deprecated":null,"id":"get","note":null,"stability":null,"value":"GET"},{"brief":"HEAD method.","deprecated":null,"id":"head","note":null,"stability":null,"value":"HEAD"},{"brief":"OPTIONS method.","deprecated":null,"id":"options","note":null,"stability":null,"value":"OPTIONS"},{"brief":"PATCH method.","deprecated":null,"id":"patch","note":null,"stability":null,"value":"PATCH"},{"brief":"POST method.","deprecated":null,"id":"post","note":null,"stability":null,"value":"POST"},{"brief":"PUT method.","deprecated":null,"id":"put","note":null,"stability":null,"value":"PUT"},{"brief":"TRACE method.","deprecated":null,"id":"trace","note":null,"stability":null,"value":"TRACE"},{"brief":"Any HTTP method that the instrumentation has no prior knowledge of.","deprecated":null,"id":"other","note":null,"stability":null,"value":"_OTHER"}]}},{"brief":"Original HTTP method sent by the client in the request line.","examples":["GeT","ACL","foo"],"name":"http.request.method_original","namespace":"http","requirement_level":"recommended","stability":"stable","type":"string"},{"brief":"The ordinal number of request resending attempt (for any reason, including redirects).\n","examples":3,"name":"http.request.resend_count","namespace":"http","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","requirement_level":"recommended","stability":"stable","type":"int"},{"brief":"The size of the response payload body in bytes. This is the number of bytes transferred excluding headers and is often, but not always, present as the [Content-Length](https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length) header. For requests using transport encoding, this should be the compressed size.\n","examples":3495,"name":"http.response.body.size","namespace":"http","requirement_level":"recommended","stability":"experimental","type":"int"},{"brief":"HTTP response headers, `\u003ckey\u003e` being the normalized HTTP Header name (lowercase), the value being the header values.\n","examples":["http.response.header.content-type=[\"application/json\"]","http.response.header.my-custom-header=[\"abc\", \"def\"]"],"name":"http.response.header","namespace":"http","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","requirement_level":"recommended","stability":"stable","type":"template[string[]]"},{"brief":"[HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6).","examples":[200],"name":"http.response.status_code","namespace":"http","requirement_level":"recommended","stability":"stable","type":"int"},{"brief":"The matched route, that is, the path template in the format used by the respective server framework.\n","examples":["/users/:userID?","{controller}/{action}/{id?}"],"name":"http.route","namespace":"http","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.","requirement_level":"recommended","stability":"stable","type":"string"},{"brief":"The ISO 3166-1 alpha-2 2-character country code associated with the mobile carrier network.","examples":"DE","name":"network.carrier.icc","namespace":"network","requirement_level":"recommended","type":"string"},{"brief":"The mobile carrier country code.","examples":"310","name":"network.carrier.mcc","namespace":"network","requirement_level":"recommended","type":"string"},{"brief":"The mobile carrier network code.","examples":"001","name":"network.carrier.mnc","namespace":"network","requirement_level":"recommended","type":"string"},{"brief":"The name of the mobile carrier.","examples":"sprint","name":"network.carrier.name","namespace":"network","requirement_level":"recommended","type":"string"},{"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","name":"network.connection.subtype","namespace":"network","requirement_level":"recommended","type":{"allow_custom_values":true,"members":[{"brief":"GPRS","deprecated":null,"id":"gprs","note":null,"stability":null,"value":"gprs"},{"brief":"EDGE","deprecated":null,"id":"edge","note":null,"stability":null,"value":"edge"},{"brief":"UMTS","deprecated":null,"id":"umts","note":null,"stability":null,"value":"umts"},{"brief":"CDMA","deprecated":null,"id":"cdma","note":null,"stability":null,"value":"cdma"},{"brief":"EVDO Rel. 0","deprecated":null,"id":"evdo_0","note":null,"stability":null,"value":"evdo_0"},{"brief":"EVDO Rev. A","deprecated":null,"id":"evdo_a","note":null,"stability":null,"value":"evdo_a"},{"brief":"CDMA2000 1XRTT","deprecated":null,"id":"cdma2000_1xrtt","note":null,"stability":null,"value":"cdma2000_1xrtt"},{"brief":"HSDPA","deprecated":null,"id":"hsdpa","note":null,"stability":null,"value":"hsdpa"},{"brief":"HSUPA","deprecated":null,"id":"hsupa","note":null,"stability":null,"value":"hsupa"},{"brief":"HSPA","deprecated":null,"id":"hspa","note":null,"stability":null,"value":"hspa"},{"brief":"IDEN","deprecated":null,"id":"iden","note":null,"stability":null,"value":"iden"},{"brief":"EVDO Rev. B","deprecated":null,"id":"evdo_b","note":null,"stability":null,"value":"evdo_b"},{"brief":"LTE","deprecated":null,"id":"lte","note":null,"stability":null,"value":"lte"},{"brief":"EHRPD","deprecated":null,"id":"ehrpd","note":null,"stability":null,"value":"ehrpd"},{"brief":"HSPAP","deprecated":null,"id":"hspap","note":null,"stability":null,"value":"hspap"},{"brief":"GSM","deprecated":null,"id":"gsm","note":null,"stability":null,"value":"gsm"},{"brief":"TD-SCDMA","deprecated":null,"id":"td_scdma","note":null,"stability":null,"value":"td_scdma"},{"brief":"IWLAN","deprecated":null,"id":"iwlan","note":null,"stability":null,"value":"iwlan"},{"brief":"5G NR (New Radio)","deprecated":null,"id":"nr","note":null,"stability":null,"value":"nr"},{"brief":"5G NRNSA (New Radio Non-Standalone)","deprecated":null,"id":"nrnsa","note":null,"stability":null,"value":"nrnsa"},{"brief":"LTE CA","deprecated":null,"id":"lte_ca","note":null,"stability":null,"value":"lte_ca"}]}},{"brief":"The internet connection type.","examples":"wifi","name":"network.connection.type","namespace":"network","requirement_level":"recommended","type":{"allow_custom_values":true,"members":[{"brief":null,"deprecated":null,"id":"wifi","note":null,"stability":null,"value":"wifi"},{"brief":null,"deprecated":null,"id":"wired","note":null,"stability":null,"value":"wired"},{"brief":null,"deprecated":null,"id":"cell","note":null,"stability":null,"value":"cell"},{"brief":null,"deprecated":null,"id":"unavailable","note":null,"stability":null,"value":"unavailable"},{"brief":null,"deprecated":null,"id":"unknown","note":null,"stability":null,"value":"unknown"}]}},{"brief":"The network IO operation direction.","examples":["transmit"],"name":"network.io.direction","namespace":"network","requirement_level":"recommended","type":{"allow_custom_values":false,"members":[{"brief":null,"deprecated":null,"id":"transmit","note":null,"stability":null,"value":"transmit"},{"brief":null,"deprecated":null,"id":"receive","note":null,"stability":null,"value":"receive"}]}},{"brief":"Local address of the network connection - IP address or Unix domain socket name.","examples":["10.1.2.80","/tmp/my.sock"],"name":"network.local.address","namespace":"network","requirement_level":"recommended","stability":"stable","type":"string"},{"brief":"Local port number of the network connection.","examples":[65123],"name":"network.local.port","namespace":"network","requirement_level":"recommended","stability":"stable","type":"int"},{"brief":"Peer address of the network connection - IP address or Unix domain socket name.","examples":["10.1.2.80","/tmp/my.sock"],"name":"network.peer.address","namespace":"network","requirement_level":"recommended","stability":"stable","type":"string"},{"brief":"Peer port number of the network connection.","examples":[65123],"name":"network.peer.port","namespace":"network","requirement_level":"recommended","stability":"stable","type":"int"},{"brief":"[OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent.","examples":["amqp","http","mqtt"],"name":"network.protocol.name","namespace":"network","note":"The value SHOULD be normalized to lowercase.","requirement_level":"recommended","stability":"stable","type":"string"},{"brief":"Version of the protocol specified in `network.protocol.name`.","examples":"3.1.1","name":"network.protocol.version","namespace":"network","note":"`network.protocol.version` refers to the version of the protocol used and might be different from the protocol client\u0027s 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","requirement_level":"recommended","stability":"stable","type":"string"},{"brief":"[OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication).\n","examples":["tcp","udp"],"name":"network.transport","namespace":"network","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","requirement_level":"recommended","stability":"stable","type":{"allow_custom_values":true,"members":[{"brief":"TCP","deprecated":null,"id":"tcp","note":null,"stability":null,"value":"tcp"},{"brief":"UDP","deprecated":null,"id":"udp","note":null,"stability":null,"value":"udp"},{"brief":"Named or anonymous pipe.","deprecated":null,"id":"pipe","note":null,"stability":null,"value":"pipe"},{"brief":"Unix domain socket","deprecated":null,"id":"unix","note":null,"stability":null,"value":"unix"}]}},{"brief":"[OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent.","examples":["ipv4","ipv6"],"name":"network.type","namespace":"network","note":"The value SHOULD be normalized to lowercase.","requirement_level":"recommended","stability":"stable","type":{"allow_custom_values":true,"members":[{"brief":"IPv4","deprecated":null,"id":"ipv4","note":null,"stability":null,"value":"ipv4"},{"brief":"IPv6","deprecated":null,"id":"ipv6","note":null,"stability":null,"value":"ipv6"}]}},{"brief":"The [URI fragment](https://www.rfc-editor.org/rfc/rfc3986#section-3.5) component","examples":["SemConv"],"name":"url.fragment","namespace":"url","requirement_level":"recommended","stability":"stable","type":"string"},{"brief":"Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986)","examples":["https://www.foo.bar/search?q=OpenTelemetry#SemConv","//localhost"],"name":"url.full","namespace":"url","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\u0027s 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","requirement_level":"recommended","stability":"stable","type":"string"},{"brief":"The [URI path](https://www.rfc-editor.org/rfc/rfc3986#section-3.3) component","examples":["/search"],"name":"url.path","namespace":"url","requirement_level":"recommended","stability":"stable","type":"string"},{"brief":"The [URI query](https://www.rfc-editor.org/rfc/rfc3986#section-3.4) component","examples":["q=OpenTelemetry"],"name":"url.query","namespace":"url","note":"Sensitive content provided in query string SHOULD be scrubbed when instrumentations can identify it.","requirement_level":"recommended","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"],"name":"url.scheme","namespace":"url","requirement_level":"recommended","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.\n","examples":["CERN-LineMode/2.15 libwww/2.17b3","Mozilla/5.0 (iPhone; CPU iPhone OS 14_7_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.2 Mobile/15E148 Safari/604.1"],"name":"user_agent.original","namespace":"user_agent","requirement_level":"recommended","stability":"stable","type":"string"}] \ No newline at end of file +[{"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","name":"db.cassandra.consistency_level","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-cassandra","type":{"allow_custom_values":true,"members":[{"brief":null,"deprecated":null,"id":"all","note":null,"stability":null,"value":"all"},{"brief":null,"deprecated":null,"id":"each_quorum","note":null,"stability":null,"value":"each_quorum"},{"brief":null,"deprecated":null,"id":"quorum","note":null,"stability":null,"value":"quorum"},{"brief":null,"deprecated":null,"id":"local_quorum","note":null,"stability":null,"value":"local_quorum"},{"brief":null,"deprecated":null,"id":"one","note":null,"stability":null,"value":"one"},{"brief":null,"deprecated":null,"id":"two","note":null,"stability":null,"value":"two"},{"brief":null,"deprecated":null,"id":"three","note":null,"stability":null,"value":"three"},{"brief":null,"deprecated":null,"id":"local_one","note":null,"stability":null,"value":"local_one"},{"brief":null,"deprecated":null,"id":"any","note":null,"stability":null,"value":"any"},{"brief":null,"deprecated":null,"id":"serial","note":null,"stability":null,"value":"serial"},{"brief":null,"deprecated":null,"id":"local_serial","note":null,"stability":null,"value":"local_serial"}]}},{"brief":"The data center of the coordinating node for a query.\n","examples":"us-west-2","name":"db.cassandra.coordinator.dc","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-cassandra","type":"string"},{"brief":"The ID of the coordinating node for a query.\n","examples":"be13faa2-8574-4d71-926d-27f16cf8a7af","name":"db.cassandra.coordinator.id","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-cassandra","type":"string"},{"brief":"Whether or not the query is idempotent.\n","name":"db.cassandra.idempotence","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-cassandra","type":"boolean"},{"brief":"The fetch size used for paging, i.e. how many rows will be returned at once.\n","examples":[5000],"name":"db.cassandra.page_size","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-cassandra","type":"int"},{"brief":"The number of times a query was speculatively executed. Not set or `0` if the query was not executed speculatively.\n","examples":[0,2],"name":"db.cassandra.speculative_execution_count","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-cassandra","type":"int"},{"brief":"The name of the primary Cassandra table that the operation is acting upon, including the keyspace name (if applicable).","examples":"mytable","name":"db.cassandra.table","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","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-cassandra","type":"string"},{"brief":"The connection string used to connect to the database. It is recommended to remove embedded credentials.\n","examples":"Server=(localdb)\\v11.0;Integrated Security=true;","name":"db.connection_string","requirement_level":"recommended","root_namespace":"db","tag":"db-generic","type":"string"},{"brief":"Unique Cosmos client instance id.","examples":"3ba4827d-4422-483f-b59f-85b74211c11d","name":"db.cosmosdb.client_id","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-cosmosdb","type":"string"},{"brief":"Cosmos client connection mode.","name":"db.cosmosdb.connection_mode","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-cosmosdb","type":{"allow_custom_values":false,"members":[{"brief":"Gateway (HTTP) connections mode","deprecated":null,"id":"gateway","note":null,"stability":null,"value":"gateway"},{"brief":"Direct connection.","deprecated":null,"id":"direct","note":null,"stability":null,"value":"direct"}]}},{"brief":"Cosmos DB container name.","examples":"anystring","name":"db.cosmosdb.container","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-cosmosdb","type":"string"},{"brief":"CosmosDB Operation Type.","name":"db.cosmosdb.operation_type","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-cosmosdb","type":{"allow_custom_values":true,"members":[{"brief":null,"deprecated":null,"id":"invalid","note":null,"stability":null,"value":"Invalid"},{"brief":null,"deprecated":null,"id":"create","note":null,"stability":null,"value":"Create"},{"brief":null,"deprecated":null,"id":"patch","note":null,"stability":null,"value":"Patch"},{"brief":null,"deprecated":null,"id":"read","note":null,"stability":null,"value":"Read"},{"brief":null,"deprecated":null,"id":"read_feed","note":null,"stability":null,"value":"ReadFeed"},{"brief":null,"deprecated":null,"id":"delete","note":null,"stability":null,"value":"Delete"},{"brief":null,"deprecated":null,"id":"replace","note":null,"stability":null,"value":"Replace"},{"brief":null,"deprecated":null,"id":"execute","note":null,"stability":null,"value":"Execute"},{"brief":null,"deprecated":null,"id":"query","note":null,"stability":null,"value":"Query"},{"brief":null,"deprecated":null,"id":"head","note":null,"stability":null,"value":"Head"},{"brief":null,"deprecated":null,"id":"head_feed","note":null,"stability":null,"value":"HeadFeed"},{"brief":null,"deprecated":null,"id":"upsert","note":null,"stability":null,"value":"Upsert"},{"brief":null,"deprecated":null,"id":"batch","note":null,"stability":null,"value":"Batch"},{"brief":null,"deprecated":null,"id":"query_plan","note":null,"stability":null,"value":"QueryPlan"},{"brief":null,"deprecated":null,"id":"execute_javascript","note":null,"stability":null,"value":"ExecuteJavaScript"}]}},{"brief":"RU consumed for that operation","examples":[46.18,1.0],"name":"db.cosmosdb.request_charge","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-cosmosdb","type":"double"},{"brief":"Request payload size in bytes","name":"db.cosmosdb.request_content_length","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-cosmosdb","type":"int"},{"brief":"Cosmos DB status code.","examples":[200,201],"name":"db.cosmosdb.status_code","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-cosmosdb","type":"int"},{"brief":"Cosmos DB sub status code.","examples":[1000,1002],"name":"db.cosmosdb.sub_status_code","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-cosmosdb","type":"int"},{"brief":"Represents the identifier of an Elasticsearch cluster.\n","examples":["e9106fc68e3044f0b1475b04bf4ffd5f"],"name":"db.elasticsearch.cluster.name","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-elasticsearch","type":"string"},{"brief":"Represents the human-readable identifier of the node/instance to which a request was routed.\n","examples":["instance-0000000001"],"name":"db.elasticsearch.node.name","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-elasticsearch","type":"string"},{"brief":"A dynamic value in the url path.\n","examples":["db.elasticsearch.path_parts.index=test-index","db.elasticsearch.path_parts.doc_id=123"],"name":"db.elasticsearch.path_parts","note":"Many Elasticsearch url paths allow dynamic values. These SHOULD be recorded in span attributes in the format `db.elasticsearch.path_parts.\u003ckey\u003e`, where `\u003ckey\u003e` 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","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-elasticsearch","type":"template[string]"},{"brief":"An identifier (address, unique name, or any other identifier) of the database instance that is executing queries or mutations on the current connection. This is useful in cases where the database is running in a clustered environment and the instrumentation is able to record the node executing the query. The client may obtain this value in databases like MySQL using queries like `select @@hostname`.\n","examples":"mysql-e26b99z.example.com","name":"db.instance.id","requirement_level":"recommended","root_namespace":"db","tag":"db-generic","type":"string"},{"brief":"The fully-qualified class name of the [Java Database Connectivity (JDBC)](https://docs.oracle.com/javase/8/docs/technotes/guides/jdbc/) driver used to connect.\n","examples":["org.postgresql.Driver","com.microsoft.sqlserver.jdbc.SQLServerDriver"],"name":"db.jdbc.driver_classname","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-jdbc","type":"string"},{"brief":"The MongoDB collection being accessed within the database stated in `db.name`.\n","examples":["customers","products"],"name":"db.mongodb.collection","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-mongodb","type":"string"},{"brief":"The Microsoft SQL Server [instance name](https://docs.microsoft.com/sql/connect/jdbc/building-the-connection-url?view=sql-server-ver15) connecting to. This name is used to determine the port of a named instance.\n","examples":"MSSQLSERVER","name":"db.mssql.instance_name","note":"If setting a `db.mssql.instance_name`, `server.port` is no longer required (but still recommended if non-standard).\n","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-mssql","type":"string"},{"brief":"This attribute is used to report the name of the database being accessed. For commands that switch the database, this should be set to the target database (even if the command fails).\n","examples":["customers","main"],"name":"db.name","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","requirement_level":"recommended","root_namespace":"db","tag":"db-generic","type":"string"},{"brief":"The name of the operation being executed, e.g. the [MongoDB command name](https://docs.mongodb.com/manual/reference/command/#database-operations) such as `findAndModify`, or the SQL keyword.\n","examples":["findAndModify","HMSET","SELECT"],"name":"db.operation","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","requirement_level":"recommended","root_namespace":"db","tag":"db-generic","type":"string"},{"brief":"The index of the database being accessed as used in the [`SELECT` command](https://redis.io/commands/select), provided as an integer. To be used instead of the generic `db.name` attribute.\n","examples":[0,1,15],"name":"db.redis.database_index","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-redis","type":"int"},{"brief":"The name of the primary table that the operation is acting upon, including the database name (if applicable).","examples":["public.users","customers"],"name":"db.sql.table","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","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-sql","type":"string"},{"brief":"The database statement being executed.\n","examples":["SELECT * FROM wuser_table","SET mykey \"WuValue\""],"name":"db.statement","requirement_level":"recommended","root_namespace":"db","tag":"db-generic","type":"string"},{"brief":"An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers.","name":"db.system","requirement_level":"recommended","root_namespace":"db","tag":"db-generic","type":{"allow_custom_values":true,"members":[{"brief":"Some other SQL database. Fallback only. See notes.","deprecated":null,"id":"other_sql","note":null,"stability":null,"value":"other_sql"},{"brief":"Microsoft SQL Server","deprecated":null,"id":"mssql","note":null,"stability":null,"value":"mssql"},{"brief":"Microsoft SQL Server Compact","deprecated":null,"id":"mssqlcompact","note":null,"stability":null,"value":"mssqlcompact"},{"brief":"MySQL","deprecated":null,"id":"mysql","note":null,"stability":null,"value":"mysql"},{"brief":"Oracle Database","deprecated":null,"id":"oracle","note":null,"stability":null,"value":"oracle"},{"brief":"IBM Db2","deprecated":null,"id":"db2","note":null,"stability":null,"value":"db2"},{"brief":"PostgreSQL","deprecated":null,"id":"postgresql","note":null,"stability":null,"value":"postgresql"},{"brief":"Amazon Redshift","deprecated":null,"id":"redshift","note":null,"stability":null,"value":"redshift"},{"brief":"Apache Hive","deprecated":null,"id":"hive","note":null,"stability":null,"value":"hive"},{"brief":"Cloudscape","deprecated":null,"id":"cloudscape","note":null,"stability":null,"value":"cloudscape"},{"brief":"HyperSQL DataBase","deprecated":null,"id":"hsqldb","note":null,"stability":null,"value":"hsqldb"},{"brief":"Progress Database","deprecated":null,"id":"progress","note":null,"stability":null,"value":"progress"},{"brief":"SAP MaxDB","deprecated":null,"id":"maxdb","note":null,"stability":null,"value":"maxdb"},{"brief":"SAP HANA","deprecated":null,"id":"hanadb","note":null,"stability":null,"value":"hanadb"},{"brief":"Ingres","deprecated":null,"id":"ingres","note":null,"stability":null,"value":"ingres"},{"brief":"FirstSQL","deprecated":null,"id":"firstsql","note":null,"stability":null,"value":"firstsql"},{"brief":"EnterpriseDB","deprecated":null,"id":"edb","note":null,"stability":null,"value":"edb"},{"brief":"InterSystems Caché","deprecated":null,"id":"cache","note":null,"stability":null,"value":"cache"},{"brief":"Adabas (Adaptable Database System)","deprecated":null,"id":"adabas","note":null,"stability":null,"value":"adabas"},{"brief":"Firebird","deprecated":null,"id":"firebird","note":null,"stability":null,"value":"firebird"},{"brief":"Apache Derby","deprecated":null,"id":"derby","note":null,"stability":null,"value":"derby"},{"brief":"FileMaker","deprecated":null,"id":"filemaker","note":null,"stability":null,"value":"filemaker"},{"brief":"Informix","deprecated":null,"id":"informix","note":null,"stability":null,"value":"informix"},{"brief":"InstantDB","deprecated":null,"id":"instantdb","note":null,"stability":null,"value":"instantdb"},{"brief":"InterBase","deprecated":null,"id":"interbase","note":null,"stability":null,"value":"interbase"},{"brief":"MariaDB","deprecated":null,"id":"mariadb","note":null,"stability":null,"value":"mariadb"},{"brief":"Netezza","deprecated":null,"id":"netezza","note":null,"stability":null,"value":"netezza"},{"brief":"Pervasive PSQL","deprecated":null,"id":"pervasive","note":null,"stability":null,"value":"pervasive"},{"brief":"PointBase","deprecated":null,"id":"pointbase","note":null,"stability":null,"value":"pointbase"},{"brief":"SQLite","deprecated":null,"id":"sqlite","note":null,"stability":null,"value":"sqlite"},{"brief":"Sybase","deprecated":null,"id":"sybase","note":null,"stability":null,"value":"sybase"},{"brief":"Teradata","deprecated":null,"id":"teradata","note":null,"stability":null,"value":"teradata"},{"brief":"Vertica","deprecated":null,"id":"vertica","note":null,"stability":null,"value":"vertica"},{"brief":"H2","deprecated":null,"id":"h2","note":null,"stability":null,"value":"h2"},{"brief":"ColdFusion IMQ","deprecated":null,"id":"coldfusion","note":null,"stability":null,"value":"coldfusion"},{"brief":"Apache Cassandra","deprecated":null,"id":"cassandra","note":null,"stability":null,"value":"cassandra"},{"brief":"Apache HBase","deprecated":null,"id":"hbase","note":null,"stability":null,"value":"hbase"},{"brief":"MongoDB","deprecated":null,"id":"mongodb","note":null,"stability":null,"value":"mongodb"},{"brief":"Redis","deprecated":null,"id":"redis","note":null,"stability":null,"value":"redis"},{"brief":"Couchbase","deprecated":null,"id":"couchbase","note":null,"stability":null,"value":"couchbase"},{"brief":"CouchDB","deprecated":null,"id":"couchdb","note":null,"stability":null,"value":"couchdb"},{"brief":"Microsoft Azure Cosmos DB","deprecated":null,"id":"cosmosdb","note":null,"stability":null,"value":"cosmosdb"},{"brief":"Amazon DynamoDB","deprecated":null,"id":"dynamodb","note":null,"stability":null,"value":"dynamodb"},{"brief":"Neo4j","deprecated":null,"id":"neo4j","note":null,"stability":null,"value":"neo4j"},{"brief":"Apache Geode","deprecated":null,"id":"geode","note":null,"stability":null,"value":"geode"},{"brief":"Elasticsearch","deprecated":null,"id":"elasticsearch","note":null,"stability":null,"value":"elasticsearch"},{"brief":"Memcached","deprecated":null,"id":"memcached","note":null,"stability":null,"value":"memcached"},{"brief":"CockroachDB","deprecated":null,"id":"cockroachdb","note":null,"stability":null,"value":"cockroachdb"},{"brief":"OpenSearch","deprecated":null,"id":"opensearch","note":null,"stability":null,"value":"opensearch"},{"brief":"ClickHouse","deprecated":null,"id":"clickhouse","note":null,"stability":null,"value":"clickhouse"},{"brief":"Cloud Spanner","deprecated":null,"id":"spanner","note":null,"stability":null,"value":"spanner"},{"brief":"Trino","deprecated":null,"id":"trino","note":null,"stability":null,"value":"trino"}]}},{"brief":"Username for accessing the database.\n","examples":["readonly_user","reporting_user"],"name":"db.user","requirement_level":"recommended","root_namespace":"db","tag":"db-generic","type":"string"},{"brief":"The size of the request payload body in bytes. This is the number of bytes transferred excluding headers and is often, but not always, present as the [Content-Length](https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length) header. For requests using transport encoding, this should be the compressed size.\n","examples":3495,"name":"http.request.body.size","requirement_level":"recommended","root_namespace":"http","stability":"experimental","type":"int"},{"brief":"HTTP request headers, `\u003ckey\u003e` being the normalized HTTP Header name (lowercase), the value being the header values.\n","examples":["http.request.header.content-type=[\"application/json\"]","http.request.header.x-forwarded-for=[\"1.2.3.4\", \"1.2.3.5\"]"],"name":"http.request.header","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","requirement_level":"recommended","root_namespace":"http","stability":"stable","type":"template[string[]]"},{"brief":"HTTP request method.","examples":["GET","POST","HEAD"],"name":"http.request.method","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","requirement_level":"recommended","root_namespace":"http","stability":"stable","type":{"allow_custom_values":true,"members":[{"brief":"CONNECT method.","deprecated":null,"id":"connect","note":null,"stability":null,"value":"CONNECT"},{"brief":"DELETE method.","deprecated":null,"id":"delete","note":null,"stability":null,"value":"DELETE"},{"brief":"GET method.","deprecated":null,"id":"get","note":null,"stability":null,"value":"GET"},{"brief":"HEAD method.","deprecated":null,"id":"head","note":null,"stability":null,"value":"HEAD"},{"brief":"OPTIONS method.","deprecated":null,"id":"options","note":null,"stability":null,"value":"OPTIONS"},{"brief":"PATCH method.","deprecated":null,"id":"patch","note":null,"stability":null,"value":"PATCH"},{"brief":"POST method.","deprecated":null,"id":"post","note":null,"stability":null,"value":"POST"},{"brief":"PUT method.","deprecated":null,"id":"put","note":null,"stability":null,"value":"PUT"},{"brief":"TRACE method.","deprecated":null,"id":"trace","note":null,"stability":null,"value":"TRACE"},{"brief":"Any HTTP method that the instrumentation has no prior knowledge of.","deprecated":null,"id":"other","note":null,"stability":null,"value":"_OTHER"}]}},{"brief":"Original HTTP method sent by the client in the request line.","examples":["GeT","ACL","foo"],"name":"http.request.method_original","requirement_level":"recommended","root_namespace":"http","stability":"stable","type":"string"},{"brief":"The ordinal number of request resending attempt (for any reason, including redirects).\n","examples":3,"name":"http.request.resend_count","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","requirement_level":"recommended","root_namespace":"http","stability":"stable","type":"int"},{"brief":"The size of the response payload body in bytes. This is the number of bytes transferred excluding headers and is often, but not always, present as the [Content-Length](https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length) header. For requests using transport encoding, this should be the compressed size.\n","examples":3495,"name":"http.response.body.size","requirement_level":"recommended","root_namespace":"http","stability":"experimental","type":"int"},{"brief":"HTTP response headers, `\u003ckey\u003e` being the normalized HTTP Header name (lowercase), the value being the header values.\n","examples":["http.response.header.content-type=[\"application/json\"]","http.response.header.my-custom-header=[\"abc\", \"def\"]"],"name":"http.response.header","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","requirement_level":"recommended","root_namespace":"http","stability":"stable","type":"template[string[]]"},{"brief":"[HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6).","examples":[200],"name":"http.response.status_code","requirement_level":"recommended","root_namespace":"http","stability":"stable","type":"int"},{"brief":"The matched route, that is, the path template in the format used by the respective server framework.\n","examples":["/users/:userID?","{controller}/{action}/{id?}"],"name":"http.route","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.","requirement_level":"recommended","root_namespace":"http","stability":"stable","type":"string"},{"brief":"The ISO 3166-1 alpha-2 2-character country code associated with the mobile carrier network.","examples":"DE","name":"network.carrier.icc","requirement_level":"recommended","root_namespace":"network","type":"string"},{"brief":"The mobile carrier country code.","examples":"310","name":"network.carrier.mcc","requirement_level":"recommended","root_namespace":"network","type":"string"},{"brief":"The mobile carrier network code.","examples":"001","name":"network.carrier.mnc","requirement_level":"recommended","root_namespace":"network","type":"string"},{"brief":"The name of the mobile carrier.","examples":"sprint","name":"network.carrier.name","requirement_level":"recommended","root_namespace":"network","type":"string"},{"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","name":"network.connection.subtype","requirement_level":"recommended","root_namespace":"network","type":{"allow_custom_values":true,"members":[{"brief":"GPRS","deprecated":null,"id":"gprs","note":null,"stability":null,"value":"gprs"},{"brief":"EDGE","deprecated":null,"id":"edge","note":null,"stability":null,"value":"edge"},{"brief":"UMTS","deprecated":null,"id":"umts","note":null,"stability":null,"value":"umts"},{"brief":"CDMA","deprecated":null,"id":"cdma","note":null,"stability":null,"value":"cdma"},{"brief":"EVDO Rel. 0","deprecated":null,"id":"evdo_0","note":null,"stability":null,"value":"evdo_0"},{"brief":"EVDO Rev. A","deprecated":null,"id":"evdo_a","note":null,"stability":null,"value":"evdo_a"},{"brief":"CDMA2000 1XRTT","deprecated":null,"id":"cdma2000_1xrtt","note":null,"stability":null,"value":"cdma2000_1xrtt"},{"brief":"HSDPA","deprecated":null,"id":"hsdpa","note":null,"stability":null,"value":"hsdpa"},{"brief":"HSUPA","deprecated":null,"id":"hsupa","note":null,"stability":null,"value":"hsupa"},{"brief":"HSPA","deprecated":null,"id":"hspa","note":null,"stability":null,"value":"hspa"},{"brief":"IDEN","deprecated":null,"id":"iden","note":null,"stability":null,"value":"iden"},{"brief":"EVDO Rev. B","deprecated":null,"id":"evdo_b","note":null,"stability":null,"value":"evdo_b"},{"brief":"LTE","deprecated":null,"id":"lte","note":null,"stability":null,"value":"lte"},{"brief":"EHRPD","deprecated":null,"id":"ehrpd","note":null,"stability":null,"value":"ehrpd"},{"brief":"HSPAP","deprecated":null,"id":"hspap","note":null,"stability":null,"value":"hspap"},{"brief":"GSM","deprecated":null,"id":"gsm","note":null,"stability":null,"value":"gsm"},{"brief":"TD-SCDMA","deprecated":null,"id":"td_scdma","note":null,"stability":null,"value":"td_scdma"},{"brief":"IWLAN","deprecated":null,"id":"iwlan","note":null,"stability":null,"value":"iwlan"},{"brief":"5G NR (New Radio)","deprecated":null,"id":"nr","note":null,"stability":null,"value":"nr"},{"brief":"5G NRNSA (New Radio Non-Standalone)","deprecated":null,"id":"nrnsa","note":null,"stability":null,"value":"nrnsa"},{"brief":"LTE CA","deprecated":null,"id":"lte_ca","note":null,"stability":null,"value":"lte_ca"}]}},{"brief":"The internet connection type.","examples":"wifi","name":"network.connection.type","requirement_level":"recommended","root_namespace":"network","type":{"allow_custom_values":true,"members":[{"brief":null,"deprecated":null,"id":"wifi","note":null,"stability":null,"value":"wifi"},{"brief":null,"deprecated":null,"id":"wired","note":null,"stability":null,"value":"wired"},{"brief":null,"deprecated":null,"id":"cell","note":null,"stability":null,"value":"cell"},{"brief":null,"deprecated":null,"id":"unavailable","note":null,"stability":null,"value":"unavailable"},{"brief":null,"deprecated":null,"id":"unknown","note":null,"stability":null,"value":"unknown"}]}},{"brief":"The network IO operation direction.","examples":["transmit"],"name":"network.io.direction","requirement_level":"recommended","root_namespace":"network","type":{"allow_custom_values":false,"members":[{"brief":null,"deprecated":null,"id":"transmit","note":null,"stability":null,"value":"transmit"},{"brief":null,"deprecated":null,"id":"receive","note":null,"stability":null,"value":"receive"}]}},{"brief":"Local address of the network connection - IP address or Unix domain socket name.","examples":["10.1.2.80","/tmp/my.sock"],"name":"network.local.address","requirement_level":"recommended","root_namespace":"network","stability":"stable","type":"string"},{"brief":"Local port number of the network connection.","examples":[65123],"name":"network.local.port","requirement_level":"recommended","root_namespace":"network","stability":"stable","type":"int"},{"brief":"Peer address of the network connection - IP address or Unix domain socket name.","examples":["10.1.2.80","/tmp/my.sock"],"name":"network.peer.address","requirement_level":"recommended","root_namespace":"network","stability":"stable","type":"string"},{"brief":"Peer port number of the network connection.","examples":[65123],"name":"network.peer.port","requirement_level":"recommended","root_namespace":"network","stability":"stable","type":"int"},{"brief":"[OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent.","examples":["amqp","http","mqtt"],"name":"network.protocol.name","note":"The value SHOULD be normalized to lowercase.","requirement_level":"recommended","root_namespace":"network","stability":"stable","type":"string"},{"brief":"Version of the protocol specified in `network.protocol.name`.","examples":"3.1.1","name":"network.protocol.version","note":"`network.protocol.version` refers to the version of the protocol used and might be different from the protocol client\u0027s 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","requirement_level":"recommended","root_namespace":"network","stability":"stable","type":"string"},{"brief":"[OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication).\n","examples":["tcp","udp"],"name":"network.transport","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","requirement_level":"recommended","root_namespace":"network","stability":"stable","type":{"allow_custom_values":true,"members":[{"brief":"TCP","deprecated":null,"id":"tcp","note":null,"stability":null,"value":"tcp"},{"brief":"UDP","deprecated":null,"id":"udp","note":null,"stability":null,"value":"udp"},{"brief":"Named or anonymous pipe.","deprecated":null,"id":"pipe","note":null,"stability":null,"value":"pipe"},{"brief":"Unix domain socket","deprecated":null,"id":"unix","note":null,"stability":null,"value":"unix"}]}},{"brief":"[OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent.","examples":["ipv4","ipv6"],"name":"network.type","note":"The value SHOULD be normalized to lowercase.","requirement_level":"recommended","root_namespace":"network","stability":"stable","type":{"allow_custom_values":true,"members":[{"brief":"IPv4","deprecated":null,"id":"ipv4","note":null,"stability":null,"value":"ipv4"},{"brief":"IPv6","deprecated":null,"id":"ipv6","note":null,"stability":null,"value":"ipv6"}]}},{"brief":"The [URI fragment](https://www.rfc-editor.org/rfc/rfc3986#section-3.5) component","examples":["SemConv"],"name":"url.fragment","requirement_level":"recommended","root_namespace":"url","stability":"stable","type":"string"},{"brief":"Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986)","examples":["https://www.foo.bar/search?q=OpenTelemetry#SemConv","//localhost"],"name":"url.full","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\u0027s 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","requirement_level":"recommended","root_namespace":"url","stability":"stable","type":"string"},{"brief":"The [URI path](https://www.rfc-editor.org/rfc/rfc3986#section-3.3) component","examples":["/search"],"name":"url.path","requirement_level":"recommended","root_namespace":"url","stability":"stable","type":"string"},{"brief":"The [URI query](https://www.rfc-editor.org/rfc/rfc3986#section-3.4) component","examples":["q=OpenTelemetry"],"name":"url.query","note":"Sensitive content provided in query string SHOULD be scrubbed when instrumentations can identify it.","requirement_level":"recommended","root_namespace":"url","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"],"name":"url.scheme","requirement_level":"recommended","root_namespace":"url","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.\n","examples":["CERN-LineMode/2.15 libwww/2.17b3","Mozilla/5.0 (iPhone; CPU iPhone OS 14_7_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.2 Mobile/15E148 Safari/604.1"],"name":"user_agent.original","requirement_level":"recommended","root_namespace":"user_agent","stability":"stable","type":"string"}] \ No newline at end of file diff --git a/crates/weaver_forge/expected_output/semconv_jq_fn/semconv_grouped_attributes.json b/crates/weaver_forge/expected_output/semconv_jq_fn/semconv_grouped_attributes.json index b9065fa7..7239c2dd 100644 --- a/crates/weaver_forge/expected_output/semconv_jq_fn/semconv_grouped_attributes.json +++ b/crates/weaver_forge/expected_output/semconv_jq_fn/semconv_grouped_attributes.json @@ -1 +1 @@ -[{"attributes":[{"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","name":"db.cassandra.consistency_level","namespace":"db","requirement_level":"recommended","tag":"tech-specific-cassandra","type":{"allow_custom_values":true,"members":[{"brief":null,"deprecated":null,"id":"all","note":null,"stability":null,"value":"all"},{"brief":null,"deprecated":null,"id":"each_quorum","note":null,"stability":null,"value":"each_quorum"},{"brief":null,"deprecated":null,"id":"quorum","note":null,"stability":null,"value":"quorum"},{"brief":null,"deprecated":null,"id":"local_quorum","note":null,"stability":null,"value":"local_quorum"},{"brief":null,"deprecated":null,"id":"one","note":null,"stability":null,"value":"one"},{"brief":null,"deprecated":null,"id":"two","note":null,"stability":null,"value":"two"},{"brief":null,"deprecated":null,"id":"three","note":null,"stability":null,"value":"three"},{"brief":null,"deprecated":null,"id":"local_one","note":null,"stability":null,"value":"local_one"},{"brief":null,"deprecated":null,"id":"any","note":null,"stability":null,"value":"any"},{"brief":null,"deprecated":null,"id":"serial","note":null,"stability":null,"value":"serial"},{"brief":null,"deprecated":null,"id":"local_serial","note":null,"stability":null,"value":"local_serial"}]}},{"brief":"The data center of the coordinating node for a query.\n","examples":"us-west-2","name":"db.cassandra.coordinator.dc","namespace":"db","requirement_level":"recommended","tag":"tech-specific-cassandra","type":"string"},{"brief":"The ID of the coordinating node for a query.\n","examples":"be13faa2-8574-4d71-926d-27f16cf8a7af","name":"db.cassandra.coordinator.id","namespace":"db","requirement_level":"recommended","tag":"tech-specific-cassandra","type":"string"},{"brief":"Whether or not the query is idempotent.\n","name":"db.cassandra.idempotence","namespace":"db","requirement_level":"recommended","tag":"tech-specific-cassandra","type":"boolean"},{"brief":"The fetch size used for paging, i.e. how many rows will be returned at once.\n","examples":[5000],"name":"db.cassandra.page_size","namespace":"db","requirement_level":"recommended","tag":"tech-specific-cassandra","type":"int"},{"brief":"The number of times a query was speculatively executed. Not set or `0` if the query was not executed speculatively.\n","examples":[0,2],"name":"db.cassandra.speculative_execution_count","namespace":"db","requirement_level":"recommended","tag":"tech-specific-cassandra","type":"int"},{"brief":"The name of the primary Cassandra table that the operation is acting upon, including the keyspace name (if applicable).","examples":"mytable","name":"db.cassandra.table","namespace":"db","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","requirement_level":"recommended","tag":"tech-specific-cassandra","type":"string"},{"brief":"The connection string used to connect to the database. It is recommended to remove embedded credentials.\n","examples":"Server=(localdb)\\v11.0;Integrated Security=true;","name":"db.connection_string","namespace":"db","requirement_level":"recommended","tag":"db-generic","type":"string"},{"brief":"Unique Cosmos client instance id.","examples":"3ba4827d-4422-483f-b59f-85b74211c11d","name":"db.cosmosdb.client_id","namespace":"db","requirement_level":"recommended","tag":"tech-specific-cosmosdb","type":"string"},{"brief":"Cosmos client connection mode.","name":"db.cosmosdb.connection_mode","namespace":"db","requirement_level":"recommended","tag":"tech-specific-cosmosdb","type":{"allow_custom_values":false,"members":[{"brief":"Gateway (HTTP) connections mode","deprecated":null,"id":"gateway","note":null,"stability":null,"value":"gateway"},{"brief":"Direct connection.","deprecated":null,"id":"direct","note":null,"stability":null,"value":"direct"}]}},{"brief":"Cosmos DB container name.","examples":"anystring","name":"db.cosmosdb.container","namespace":"db","requirement_level":"recommended","tag":"tech-specific-cosmosdb","type":"string"},{"brief":"CosmosDB Operation Type.","name":"db.cosmosdb.operation_type","namespace":"db","requirement_level":"recommended","tag":"tech-specific-cosmosdb","type":{"allow_custom_values":true,"members":[{"brief":null,"deprecated":null,"id":"invalid","note":null,"stability":null,"value":"Invalid"},{"brief":null,"deprecated":null,"id":"create","note":null,"stability":null,"value":"Create"},{"brief":null,"deprecated":null,"id":"patch","note":null,"stability":null,"value":"Patch"},{"brief":null,"deprecated":null,"id":"read","note":null,"stability":null,"value":"Read"},{"brief":null,"deprecated":null,"id":"read_feed","note":null,"stability":null,"value":"ReadFeed"},{"brief":null,"deprecated":null,"id":"delete","note":null,"stability":null,"value":"Delete"},{"brief":null,"deprecated":null,"id":"replace","note":null,"stability":null,"value":"Replace"},{"brief":null,"deprecated":null,"id":"execute","note":null,"stability":null,"value":"Execute"},{"brief":null,"deprecated":null,"id":"query","note":null,"stability":null,"value":"Query"},{"brief":null,"deprecated":null,"id":"head","note":null,"stability":null,"value":"Head"},{"brief":null,"deprecated":null,"id":"head_feed","note":null,"stability":null,"value":"HeadFeed"},{"brief":null,"deprecated":null,"id":"upsert","note":null,"stability":null,"value":"Upsert"},{"brief":null,"deprecated":null,"id":"batch","note":null,"stability":null,"value":"Batch"},{"brief":null,"deprecated":null,"id":"query_plan","note":null,"stability":null,"value":"QueryPlan"},{"brief":null,"deprecated":null,"id":"execute_javascript","note":null,"stability":null,"value":"ExecuteJavaScript"}]}},{"brief":"RU consumed for that operation","examples":[46.18,1.0],"name":"db.cosmosdb.request_charge","namespace":"db","requirement_level":"recommended","tag":"tech-specific-cosmosdb","type":"double"},{"brief":"Request payload size in bytes","name":"db.cosmosdb.request_content_length","namespace":"db","requirement_level":"recommended","tag":"tech-specific-cosmosdb","type":"int"},{"brief":"Cosmos DB status code.","examples":[200,201],"name":"db.cosmosdb.status_code","namespace":"db","requirement_level":"recommended","tag":"tech-specific-cosmosdb","type":"int"},{"brief":"Cosmos DB sub status code.","examples":[1000,1002],"name":"db.cosmosdb.sub_status_code","namespace":"db","requirement_level":"recommended","tag":"tech-specific-cosmosdb","type":"int"},{"brief":"Represents the identifier of an Elasticsearch cluster.\n","examples":["e9106fc68e3044f0b1475b04bf4ffd5f"],"name":"db.elasticsearch.cluster.name","namespace":"db","requirement_level":"recommended","tag":"tech-specific-elasticsearch","type":"string"},{"brief":"Represents the human-readable identifier of the node/instance to which a request was routed.\n","examples":["instance-0000000001"],"name":"db.elasticsearch.node.name","namespace":"db","requirement_level":"recommended","tag":"tech-specific-elasticsearch","type":"string"},{"brief":"A dynamic value in the url path.\n","examples":["db.elasticsearch.path_parts.index=test-index","db.elasticsearch.path_parts.doc_id=123"],"name":"db.elasticsearch.path_parts","namespace":"db","note":"Many Elasticsearch url paths allow dynamic values. These SHOULD be recorded in span attributes in the format `db.elasticsearch.path_parts.\u003ckey\u003e`, where `\u003ckey\u003e` 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","requirement_level":"recommended","tag":"tech-specific-elasticsearch","type":"template[string]"},{"brief":"An identifier (address, unique name, or any other identifier) of the database instance that is executing queries or mutations on the current connection. This is useful in cases where the database is running in a clustered environment and the instrumentation is able to record the node executing the query. The client may obtain this value in databases like MySQL using queries like `select @@hostname`.\n","examples":"mysql-e26b99z.example.com","name":"db.instance.id","namespace":"db","requirement_level":"recommended","tag":"db-generic","type":"string"},{"brief":"The fully-qualified class name of the [Java Database Connectivity (JDBC)](https://docs.oracle.com/javase/8/docs/technotes/guides/jdbc/) driver used to connect.\n","examples":["org.postgresql.Driver","com.microsoft.sqlserver.jdbc.SQLServerDriver"],"name":"db.jdbc.driver_classname","namespace":"db","requirement_level":"recommended","tag":"tech-specific-jdbc","type":"string"},{"brief":"The MongoDB collection being accessed within the database stated in `db.name`.\n","examples":["customers","products"],"name":"db.mongodb.collection","namespace":"db","requirement_level":"recommended","tag":"tech-specific-mongodb","type":"string"},{"brief":"The Microsoft SQL Server [instance name](https://docs.microsoft.com/sql/connect/jdbc/building-the-connection-url?view=sql-server-ver15) connecting to. This name is used to determine the port of a named instance.\n","examples":"MSSQLSERVER","name":"db.mssql.instance_name","namespace":"db","note":"If setting a `db.mssql.instance_name`, `server.port` is no longer required (but still recommended if non-standard).\n","requirement_level":"recommended","tag":"tech-specific-mssql","type":"string"},{"brief":"This attribute is used to report the name of the database being accessed. For commands that switch the database, this should be set to the target database (even if the command fails).\n","examples":["customers","main"],"name":"db.name","namespace":"db","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","requirement_level":"recommended","tag":"db-generic","type":"string"},{"brief":"The name of the operation being executed, e.g. the [MongoDB command name](https://docs.mongodb.com/manual/reference/command/#database-operations) such as `findAndModify`, or the SQL keyword.\n","examples":["findAndModify","HMSET","SELECT"],"name":"db.operation","namespace":"db","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","requirement_level":"recommended","tag":"db-generic","type":"string"},{"brief":"The index of the database being accessed as used in the [`SELECT` command](https://redis.io/commands/select), provided as an integer. To be used instead of the generic `db.name` attribute.\n","examples":[0,1,15],"name":"db.redis.database_index","namespace":"db","requirement_level":"recommended","tag":"tech-specific-redis","type":"int"},{"brief":"The name of the primary table that the operation is acting upon, including the database name (if applicable).","examples":["public.users","customers"],"name":"db.sql.table","namespace":"db","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","requirement_level":"recommended","tag":"tech-specific-sql","type":"string"},{"brief":"The database statement being executed.\n","examples":["SELECT * FROM wuser_table","SET mykey \"WuValue\""],"name":"db.statement","namespace":"db","requirement_level":"recommended","tag":"db-generic","type":"string"},{"brief":"An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers.","name":"db.system","namespace":"db","requirement_level":"recommended","tag":"db-generic","type":{"allow_custom_values":true,"members":[{"brief":"Some other SQL database. Fallback only. See notes.","deprecated":null,"id":"other_sql","note":null,"stability":null,"value":"other_sql"},{"brief":"Microsoft SQL Server","deprecated":null,"id":"mssql","note":null,"stability":null,"value":"mssql"},{"brief":"Microsoft SQL Server Compact","deprecated":null,"id":"mssqlcompact","note":null,"stability":null,"value":"mssqlcompact"},{"brief":"MySQL","deprecated":null,"id":"mysql","note":null,"stability":null,"value":"mysql"},{"brief":"Oracle Database","deprecated":null,"id":"oracle","note":null,"stability":null,"value":"oracle"},{"brief":"IBM Db2","deprecated":null,"id":"db2","note":null,"stability":null,"value":"db2"},{"brief":"PostgreSQL","deprecated":null,"id":"postgresql","note":null,"stability":null,"value":"postgresql"},{"brief":"Amazon Redshift","deprecated":null,"id":"redshift","note":null,"stability":null,"value":"redshift"},{"brief":"Apache Hive","deprecated":null,"id":"hive","note":null,"stability":null,"value":"hive"},{"brief":"Cloudscape","deprecated":null,"id":"cloudscape","note":null,"stability":null,"value":"cloudscape"},{"brief":"HyperSQL DataBase","deprecated":null,"id":"hsqldb","note":null,"stability":null,"value":"hsqldb"},{"brief":"Progress Database","deprecated":null,"id":"progress","note":null,"stability":null,"value":"progress"},{"brief":"SAP MaxDB","deprecated":null,"id":"maxdb","note":null,"stability":null,"value":"maxdb"},{"brief":"SAP HANA","deprecated":null,"id":"hanadb","note":null,"stability":null,"value":"hanadb"},{"brief":"Ingres","deprecated":null,"id":"ingres","note":null,"stability":null,"value":"ingres"},{"brief":"FirstSQL","deprecated":null,"id":"firstsql","note":null,"stability":null,"value":"firstsql"},{"brief":"EnterpriseDB","deprecated":null,"id":"edb","note":null,"stability":null,"value":"edb"},{"brief":"InterSystems Caché","deprecated":null,"id":"cache","note":null,"stability":null,"value":"cache"},{"brief":"Adabas (Adaptable Database System)","deprecated":null,"id":"adabas","note":null,"stability":null,"value":"adabas"},{"brief":"Firebird","deprecated":null,"id":"firebird","note":null,"stability":null,"value":"firebird"},{"brief":"Apache Derby","deprecated":null,"id":"derby","note":null,"stability":null,"value":"derby"},{"brief":"FileMaker","deprecated":null,"id":"filemaker","note":null,"stability":null,"value":"filemaker"},{"brief":"Informix","deprecated":null,"id":"informix","note":null,"stability":null,"value":"informix"},{"brief":"InstantDB","deprecated":null,"id":"instantdb","note":null,"stability":null,"value":"instantdb"},{"brief":"InterBase","deprecated":null,"id":"interbase","note":null,"stability":null,"value":"interbase"},{"brief":"MariaDB","deprecated":null,"id":"mariadb","note":null,"stability":null,"value":"mariadb"},{"brief":"Netezza","deprecated":null,"id":"netezza","note":null,"stability":null,"value":"netezza"},{"brief":"Pervasive PSQL","deprecated":null,"id":"pervasive","note":null,"stability":null,"value":"pervasive"},{"brief":"PointBase","deprecated":null,"id":"pointbase","note":null,"stability":null,"value":"pointbase"},{"brief":"SQLite","deprecated":null,"id":"sqlite","note":null,"stability":null,"value":"sqlite"},{"brief":"Sybase","deprecated":null,"id":"sybase","note":null,"stability":null,"value":"sybase"},{"brief":"Teradata","deprecated":null,"id":"teradata","note":null,"stability":null,"value":"teradata"},{"brief":"Vertica","deprecated":null,"id":"vertica","note":null,"stability":null,"value":"vertica"},{"brief":"H2","deprecated":null,"id":"h2","note":null,"stability":null,"value":"h2"},{"brief":"ColdFusion IMQ","deprecated":null,"id":"coldfusion","note":null,"stability":null,"value":"coldfusion"},{"brief":"Apache Cassandra","deprecated":null,"id":"cassandra","note":null,"stability":null,"value":"cassandra"},{"brief":"Apache HBase","deprecated":null,"id":"hbase","note":null,"stability":null,"value":"hbase"},{"brief":"MongoDB","deprecated":null,"id":"mongodb","note":null,"stability":null,"value":"mongodb"},{"brief":"Redis","deprecated":null,"id":"redis","note":null,"stability":null,"value":"redis"},{"brief":"Couchbase","deprecated":null,"id":"couchbase","note":null,"stability":null,"value":"couchbase"},{"brief":"CouchDB","deprecated":null,"id":"couchdb","note":null,"stability":null,"value":"couchdb"},{"brief":"Microsoft Azure Cosmos DB","deprecated":null,"id":"cosmosdb","note":null,"stability":null,"value":"cosmosdb"},{"brief":"Amazon DynamoDB","deprecated":null,"id":"dynamodb","note":null,"stability":null,"value":"dynamodb"},{"brief":"Neo4j","deprecated":null,"id":"neo4j","note":null,"stability":null,"value":"neo4j"},{"brief":"Apache Geode","deprecated":null,"id":"geode","note":null,"stability":null,"value":"geode"},{"brief":"Elasticsearch","deprecated":null,"id":"elasticsearch","note":null,"stability":null,"value":"elasticsearch"},{"brief":"Memcached","deprecated":null,"id":"memcached","note":null,"stability":null,"value":"memcached"},{"brief":"CockroachDB","deprecated":null,"id":"cockroachdb","note":null,"stability":null,"value":"cockroachdb"},{"brief":"OpenSearch","deprecated":null,"id":"opensearch","note":null,"stability":null,"value":"opensearch"},{"brief":"ClickHouse","deprecated":null,"id":"clickhouse","note":null,"stability":null,"value":"clickhouse"},{"brief":"Cloud Spanner","deprecated":null,"id":"spanner","note":null,"stability":null,"value":"spanner"},{"brief":"Trino","deprecated":null,"id":"trino","note":null,"stability":null,"value":"trino"}]}},{"brief":"Username for accessing the database.\n","examples":["readonly_user","reporting_user"],"name":"db.user","namespace":"db","requirement_level":"recommended","tag":"db-generic","type":"string"}],"namespace":"db"},{"attributes":[{"brief":"The size of the request payload body in bytes. This is the number of bytes transferred excluding headers and is often, but not always, present as the [Content-Length](https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length) header. For requests using transport encoding, this should be the compressed size.\n","examples":3495,"name":"http.request.body.size","namespace":"http","requirement_level":"recommended","stability":"experimental","type":"int"},{"brief":"HTTP request headers, `\u003ckey\u003e` being the normalized HTTP Header name (lowercase), the value being the header values.\n","examples":["http.request.header.content-type=[\"application/json\"]","http.request.header.x-forwarded-for=[\"1.2.3.4\", \"1.2.3.5\"]"],"name":"http.request.header","namespace":"http","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","requirement_level":"recommended","stability":"stable","type":"template[string[]]"},{"brief":"HTTP request method.","examples":["GET","POST","HEAD"],"name":"http.request.method","namespace":"http","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","requirement_level":"recommended","stability":"stable","type":{"allow_custom_values":true,"members":[{"brief":"CONNECT method.","deprecated":null,"id":"connect","note":null,"stability":null,"value":"CONNECT"},{"brief":"DELETE method.","deprecated":null,"id":"delete","note":null,"stability":null,"value":"DELETE"},{"brief":"GET method.","deprecated":null,"id":"get","note":null,"stability":null,"value":"GET"},{"brief":"HEAD method.","deprecated":null,"id":"head","note":null,"stability":null,"value":"HEAD"},{"brief":"OPTIONS method.","deprecated":null,"id":"options","note":null,"stability":null,"value":"OPTIONS"},{"brief":"PATCH method.","deprecated":null,"id":"patch","note":null,"stability":null,"value":"PATCH"},{"brief":"POST method.","deprecated":null,"id":"post","note":null,"stability":null,"value":"POST"},{"brief":"PUT method.","deprecated":null,"id":"put","note":null,"stability":null,"value":"PUT"},{"brief":"TRACE method.","deprecated":null,"id":"trace","note":null,"stability":null,"value":"TRACE"},{"brief":"Any HTTP method that the instrumentation has no prior knowledge of.","deprecated":null,"id":"other","note":null,"stability":null,"value":"_OTHER"}]}},{"brief":"Original HTTP method sent by the client in the request line.","examples":["GeT","ACL","foo"],"name":"http.request.method_original","namespace":"http","requirement_level":"recommended","stability":"stable","type":"string"},{"brief":"The ordinal number of request resending attempt (for any reason, including redirects).\n","examples":3,"name":"http.request.resend_count","namespace":"http","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","requirement_level":"recommended","stability":"stable","type":"int"},{"brief":"The size of the response payload body in bytes. This is the number of bytes transferred excluding headers and is often, but not always, present as the [Content-Length](https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length) header. For requests using transport encoding, this should be the compressed size.\n","examples":3495,"name":"http.response.body.size","namespace":"http","requirement_level":"recommended","stability":"experimental","type":"int"},{"brief":"HTTP response headers, `\u003ckey\u003e` being the normalized HTTP Header name (lowercase), the value being the header values.\n","examples":["http.response.header.content-type=[\"application/json\"]","http.response.header.my-custom-header=[\"abc\", \"def\"]"],"name":"http.response.header","namespace":"http","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","requirement_level":"recommended","stability":"stable","type":"template[string[]]"},{"brief":"[HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6).","examples":[200],"name":"http.response.status_code","namespace":"http","requirement_level":"recommended","stability":"stable","type":"int"},{"brief":"The matched route, that is, the path template in the format used by the respective server framework.\n","examples":["/users/:userID?","{controller}/{action}/{id?}"],"name":"http.route","namespace":"http","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.","requirement_level":"recommended","stability":"stable","type":"string"}],"namespace":"http"},{"attributes":[{"brief":"The ISO 3166-1 alpha-2 2-character country code associated with the mobile carrier network.","examples":"DE","name":"network.carrier.icc","namespace":"network","requirement_level":"recommended","type":"string"},{"brief":"The mobile carrier country code.","examples":"310","name":"network.carrier.mcc","namespace":"network","requirement_level":"recommended","type":"string"},{"brief":"The mobile carrier network code.","examples":"001","name":"network.carrier.mnc","namespace":"network","requirement_level":"recommended","type":"string"},{"brief":"The name of the mobile carrier.","examples":"sprint","name":"network.carrier.name","namespace":"network","requirement_level":"recommended","type":"string"},{"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","name":"network.connection.subtype","namespace":"network","requirement_level":"recommended","type":{"allow_custom_values":true,"members":[{"brief":"GPRS","deprecated":null,"id":"gprs","note":null,"stability":null,"value":"gprs"},{"brief":"EDGE","deprecated":null,"id":"edge","note":null,"stability":null,"value":"edge"},{"brief":"UMTS","deprecated":null,"id":"umts","note":null,"stability":null,"value":"umts"},{"brief":"CDMA","deprecated":null,"id":"cdma","note":null,"stability":null,"value":"cdma"},{"brief":"EVDO Rel. 0","deprecated":null,"id":"evdo_0","note":null,"stability":null,"value":"evdo_0"},{"brief":"EVDO Rev. A","deprecated":null,"id":"evdo_a","note":null,"stability":null,"value":"evdo_a"},{"brief":"CDMA2000 1XRTT","deprecated":null,"id":"cdma2000_1xrtt","note":null,"stability":null,"value":"cdma2000_1xrtt"},{"brief":"HSDPA","deprecated":null,"id":"hsdpa","note":null,"stability":null,"value":"hsdpa"},{"brief":"HSUPA","deprecated":null,"id":"hsupa","note":null,"stability":null,"value":"hsupa"},{"brief":"HSPA","deprecated":null,"id":"hspa","note":null,"stability":null,"value":"hspa"},{"brief":"IDEN","deprecated":null,"id":"iden","note":null,"stability":null,"value":"iden"},{"brief":"EVDO Rev. B","deprecated":null,"id":"evdo_b","note":null,"stability":null,"value":"evdo_b"},{"brief":"LTE","deprecated":null,"id":"lte","note":null,"stability":null,"value":"lte"},{"brief":"EHRPD","deprecated":null,"id":"ehrpd","note":null,"stability":null,"value":"ehrpd"},{"brief":"HSPAP","deprecated":null,"id":"hspap","note":null,"stability":null,"value":"hspap"},{"brief":"GSM","deprecated":null,"id":"gsm","note":null,"stability":null,"value":"gsm"},{"brief":"TD-SCDMA","deprecated":null,"id":"td_scdma","note":null,"stability":null,"value":"td_scdma"},{"brief":"IWLAN","deprecated":null,"id":"iwlan","note":null,"stability":null,"value":"iwlan"},{"brief":"5G NR (New Radio)","deprecated":null,"id":"nr","note":null,"stability":null,"value":"nr"},{"brief":"5G NRNSA (New Radio Non-Standalone)","deprecated":null,"id":"nrnsa","note":null,"stability":null,"value":"nrnsa"},{"brief":"LTE CA","deprecated":null,"id":"lte_ca","note":null,"stability":null,"value":"lte_ca"}]}},{"brief":"The internet connection type.","examples":"wifi","name":"network.connection.type","namespace":"network","requirement_level":"recommended","type":{"allow_custom_values":true,"members":[{"brief":null,"deprecated":null,"id":"wifi","note":null,"stability":null,"value":"wifi"},{"brief":null,"deprecated":null,"id":"wired","note":null,"stability":null,"value":"wired"},{"brief":null,"deprecated":null,"id":"cell","note":null,"stability":null,"value":"cell"},{"brief":null,"deprecated":null,"id":"unavailable","note":null,"stability":null,"value":"unavailable"},{"brief":null,"deprecated":null,"id":"unknown","note":null,"stability":null,"value":"unknown"}]}},{"brief":"The network IO operation direction.","examples":["transmit"],"name":"network.io.direction","namespace":"network","requirement_level":"recommended","type":{"allow_custom_values":false,"members":[{"brief":null,"deprecated":null,"id":"transmit","note":null,"stability":null,"value":"transmit"},{"brief":null,"deprecated":null,"id":"receive","note":null,"stability":null,"value":"receive"}]}},{"brief":"Local address of the network connection - IP address or Unix domain socket name.","examples":["10.1.2.80","/tmp/my.sock"],"name":"network.local.address","namespace":"network","requirement_level":"recommended","stability":"stable","type":"string"},{"brief":"Local port number of the network connection.","examples":[65123],"name":"network.local.port","namespace":"network","requirement_level":"recommended","stability":"stable","type":"int"},{"brief":"Peer address of the network connection - IP address or Unix domain socket name.","examples":["10.1.2.80","/tmp/my.sock"],"name":"network.peer.address","namespace":"network","requirement_level":"recommended","stability":"stable","type":"string"},{"brief":"Peer port number of the network connection.","examples":[65123],"name":"network.peer.port","namespace":"network","requirement_level":"recommended","stability":"stable","type":"int"},{"brief":"[OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent.","examples":["amqp","http","mqtt"],"name":"network.protocol.name","namespace":"network","note":"The value SHOULD be normalized to lowercase.","requirement_level":"recommended","stability":"stable","type":"string"},{"brief":"Version of the protocol specified in `network.protocol.name`.","examples":"3.1.1","name":"network.protocol.version","namespace":"network","note":"`network.protocol.version` refers to the version of the protocol used and might be different from the protocol client\u0027s 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","requirement_level":"recommended","stability":"stable","type":"string"},{"brief":"[OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication).\n","examples":["tcp","udp"],"name":"network.transport","namespace":"network","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","requirement_level":"recommended","stability":"stable","type":{"allow_custom_values":true,"members":[{"brief":"TCP","deprecated":null,"id":"tcp","note":null,"stability":null,"value":"tcp"},{"brief":"UDP","deprecated":null,"id":"udp","note":null,"stability":null,"value":"udp"},{"brief":"Named or anonymous pipe.","deprecated":null,"id":"pipe","note":null,"stability":null,"value":"pipe"},{"brief":"Unix domain socket","deprecated":null,"id":"unix","note":null,"stability":null,"value":"unix"}]}},{"brief":"[OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent.","examples":["ipv4","ipv6"],"name":"network.type","namespace":"network","note":"The value SHOULD be normalized to lowercase.","requirement_level":"recommended","stability":"stable","type":{"allow_custom_values":true,"members":[{"brief":"IPv4","deprecated":null,"id":"ipv4","note":null,"stability":null,"value":"ipv4"},{"brief":"IPv6","deprecated":null,"id":"ipv6","note":null,"stability":null,"value":"ipv6"}]}}],"namespace":"network"},{"attributes":[{"brief":"The [URI fragment](https://www.rfc-editor.org/rfc/rfc3986#section-3.5) component","examples":["SemConv"],"name":"url.fragment","namespace":"url","requirement_level":"recommended","stability":"stable","type":"string"},{"brief":"Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986)","examples":["https://www.foo.bar/search?q=OpenTelemetry#SemConv","//localhost"],"name":"url.full","namespace":"url","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\u0027s 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","requirement_level":"recommended","stability":"stable","type":"string"},{"brief":"The [URI path](https://www.rfc-editor.org/rfc/rfc3986#section-3.3) component","examples":["/search"],"name":"url.path","namespace":"url","requirement_level":"recommended","stability":"stable","type":"string"},{"brief":"The [URI query](https://www.rfc-editor.org/rfc/rfc3986#section-3.4) component","examples":["q=OpenTelemetry"],"name":"url.query","namespace":"url","note":"Sensitive content provided in query string SHOULD be scrubbed when instrumentations can identify it.","requirement_level":"recommended","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"],"name":"url.scheme","namespace":"url","requirement_level":"recommended","stability":"stable","type":"string"}],"namespace":"url"},{"attributes":[{"brief":"Value of the [HTTP User-Agent](https://www.rfc-editor.org/rfc/rfc9110.html#field.user-agent) header sent by the client.\n","examples":["CERN-LineMode/2.15 libwww/2.17b3","Mozilla/5.0 (iPhone; CPU iPhone OS 14_7_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.2 Mobile/15E148 Safari/604.1"],"name":"user_agent.original","namespace":"user_agent","requirement_level":"recommended","stability":"stable","type":"string"}],"namespace":"user_agent"}] \ No newline at end of file +[{"attributes":[{"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","name":"db.cassandra.consistency_level","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-cassandra","type":{"allow_custom_values":true,"members":[{"brief":null,"deprecated":null,"id":"all","note":null,"stability":null,"value":"all"},{"brief":null,"deprecated":null,"id":"each_quorum","note":null,"stability":null,"value":"each_quorum"},{"brief":null,"deprecated":null,"id":"quorum","note":null,"stability":null,"value":"quorum"},{"brief":null,"deprecated":null,"id":"local_quorum","note":null,"stability":null,"value":"local_quorum"},{"brief":null,"deprecated":null,"id":"one","note":null,"stability":null,"value":"one"},{"brief":null,"deprecated":null,"id":"two","note":null,"stability":null,"value":"two"},{"brief":null,"deprecated":null,"id":"three","note":null,"stability":null,"value":"three"},{"brief":null,"deprecated":null,"id":"local_one","note":null,"stability":null,"value":"local_one"},{"brief":null,"deprecated":null,"id":"any","note":null,"stability":null,"value":"any"},{"brief":null,"deprecated":null,"id":"serial","note":null,"stability":null,"value":"serial"},{"brief":null,"deprecated":null,"id":"local_serial","note":null,"stability":null,"value":"local_serial"}]}},{"brief":"The data center of the coordinating node for a query.\n","examples":"us-west-2","name":"db.cassandra.coordinator.dc","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-cassandra","type":"string"},{"brief":"The ID of the coordinating node for a query.\n","examples":"be13faa2-8574-4d71-926d-27f16cf8a7af","name":"db.cassandra.coordinator.id","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-cassandra","type":"string"},{"brief":"Whether or not the query is idempotent.\n","name":"db.cassandra.idempotence","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-cassandra","type":"boolean"},{"brief":"The fetch size used for paging, i.e. how many rows will be returned at once.\n","examples":[5000],"name":"db.cassandra.page_size","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-cassandra","type":"int"},{"brief":"The number of times a query was speculatively executed. Not set or `0` if the query was not executed speculatively.\n","examples":[0,2],"name":"db.cassandra.speculative_execution_count","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-cassandra","type":"int"},{"brief":"The name of the primary Cassandra table that the operation is acting upon, including the keyspace name (if applicable).","examples":"mytable","name":"db.cassandra.table","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","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-cassandra","type":"string"},{"brief":"The connection string used to connect to the database. It is recommended to remove embedded credentials.\n","examples":"Server=(localdb)\\v11.0;Integrated Security=true;","name":"db.connection_string","requirement_level":"recommended","root_namespace":"db","tag":"db-generic","type":"string"},{"brief":"Unique Cosmos client instance id.","examples":"3ba4827d-4422-483f-b59f-85b74211c11d","name":"db.cosmosdb.client_id","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-cosmosdb","type":"string"},{"brief":"Cosmos client connection mode.","name":"db.cosmosdb.connection_mode","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-cosmosdb","type":{"allow_custom_values":false,"members":[{"brief":"Gateway (HTTP) connections mode","deprecated":null,"id":"gateway","note":null,"stability":null,"value":"gateway"},{"brief":"Direct connection.","deprecated":null,"id":"direct","note":null,"stability":null,"value":"direct"}]}},{"brief":"Cosmos DB container name.","examples":"anystring","name":"db.cosmosdb.container","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-cosmosdb","type":"string"},{"brief":"CosmosDB Operation Type.","name":"db.cosmosdb.operation_type","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-cosmosdb","type":{"allow_custom_values":true,"members":[{"brief":null,"deprecated":null,"id":"invalid","note":null,"stability":null,"value":"Invalid"},{"brief":null,"deprecated":null,"id":"create","note":null,"stability":null,"value":"Create"},{"brief":null,"deprecated":null,"id":"patch","note":null,"stability":null,"value":"Patch"},{"brief":null,"deprecated":null,"id":"read","note":null,"stability":null,"value":"Read"},{"brief":null,"deprecated":null,"id":"read_feed","note":null,"stability":null,"value":"ReadFeed"},{"brief":null,"deprecated":null,"id":"delete","note":null,"stability":null,"value":"Delete"},{"brief":null,"deprecated":null,"id":"replace","note":null,"stability":null,"value":"Replace"},{"brief":null,"deprecated":null,"id":"execute","note":null,"stability":null,"value":"Execute"},{"brief":null,"deprecated":null,"id":"query","note":null,"stability":null,"value":"Query"},{"brief":null,"deprecated":null,"id":"head","note":null,"stability":null,"value":"Head"},{"brief":null,"deprecated":null,"id":"head_feed","note":null,"stability":null,"value":"HeadFeed"},{"brief":null,"deprecated":null,"id":"upsert","note":null,"stability":null,"value":"Upsert"},{"brief":null,"deprecated":null,"id":"batch","note":null,"stability":null,"value":"Batch"},{"brief":null,"deprecated":null,"id":"query_plan","note":null,"stability":null,"value":"QueryPlan"},{"brief":null,"deprecated":null,"id":"execute_javascript","note":null,"stability":null,"value":"ExecuteJavaScript"}]}},{"brief":"RU consumed for that operation","examples":[46.18,1.0],"name":"db.cosmosdb.request_charge","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-cosmosdb","type":"double"},{"brief":"Request payload size in bytes","name":"db.cosmosdb.request_content_length","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-cosmosdb","type":"int"},{"brief":"Cosmos DB status code.","examples":[200,201],"name":"db.cosmosdb.status_code","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-cosmosdb","type":"int"},{"brief":"Cosmos DB sub status code.","examples":[1000,1002],"name":"db.cosmosdb.sub_status_code","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-cosmosdb","type":"int"},{"brief":"Represents the identifier of an Elasticsearch cluster.\n","examples":["e9106fc68e3044f0b1475b04bf4ffd5f"],"name":"db.elasticsearch.cluster.name","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-elasticsearch","type":"string"},{"brief":"Represents the human-readable identifier of the node/instance to which a request was routed.\n","examples":["instance-0000000001"],"name":"db.elasticsearch.node.name","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-elasticsearch","type":"string"},{"brief":"A dynamic value in the url path.\n","examples":["db.elasticsearch.path_parts.index=test-index","db.elasticsearch.path_parts.doc_id=123"],"name":"db.elasticsearch.path_parts","note":"Many Elasticsearch url paths allow dynamic values. These SHOULD be recorded in span attributes in the format `db.elasticsearch.path_parts.\u003ckey\u003e`, where `\u003ckey\u003e` 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","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-elasticsearch","type":"template[string]"},{"brief":"An identifier (address, unique name, or any other identifier) of the database instance that is executing queries or mutations on the current connection. This is useful in cases where the database is running in a clustered environment and the instrumentation is able to record the node executing the query. The client may obtain this value in databases like MySQL using queries like `select @@hostname`.\n","examples":"mysql-e26b99z.example.com","name":"db.instance.id","requirement_level":"recommended","root_namespace":"db","tag":"db-generic","type":"string"},{"brief":"The fully-qualified class name of the [Java Database Connectivity (JDBC)](https://docs.oracle.com/javase/8/docs/technotes/guides/jdbc/) driver used to connect.\n","examples":["org.postgresql.Driver","com.microsoft.sqlserver.jdbc.SQLServerDriver"],"name":"db.jdbc.driver_classname","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-jdbc","type":"string"},{"brief":"The MongoDB collection being accessed within the database stated in `db.name`.\n","examples":["customers","products"],"name":"db.mongodb.collection","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-mongodb","type":"string"},{"brief":"The Microsoft SQL Server [instance name](https://docs.microsoft.com/sql/connect/jdbc/building-the-connection-url?view=sql-server-ver15) connecting to. This name is used to determine the port of a named instance.\n","examples":"MSSQLSERVER","name":"db.mssql.instance_name","note":"If setting a `db.mssql.instance_name`, `server.port` is no longer required (but still recommended if non-standard).\n","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-mssql","type":"string"},{"brief":"This attribute is used to report the name of the database being accessed. For commands that switch the database, this should be set to the target database (even if the command fails).\n","examples":["customers","main"],"name":"db.name","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","requirement_level":"recommended","root_namespace":"db","tag":"db-generic","type":"string"},{"brief":"The name of the operation being executed, e.g. the [MongoDB command name](https://docs.mongodb.com/manual/reference/command/#database-operations) such as `findAndModify`, or the SQL keyword.\n","examples":["findAndModify","HMSET","SELECT"],"name":"db.operation","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","requirement_level":"recommended","root_namespace":"db","tag":"db-generic","type":"string"},{"brief":"The index of the database being accessed as used in the [`SELECT` command](https://redis.io/commands/select), provided as an integer. To be used instead of the generic `db.name` attribute.\n","examples":[0,1,15],"name":"db.redis.database_index","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-redis","type":"int"},{"brief":"The name of the primary table that the operation is acting upon, including the database name (if applicable).","examples":["public.users","customers"],"name":"db.sql.table","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","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-sql","type":"string"},{"brief":"The database statement being executed.\n","examples":["SELECT * FROM wuser_table","SET mykey \"WuValue\""],"name":"db.statement","requirement_level":"recommended","root_namespace":"db","tag":"db-generic","type":"string"},{"brief":"An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers.","name":"db.system","requirement_level":"recommended","root_namespace":"db","tag":"db-generic","type":{"allow_custom_values":true,"members":[{"brief":"Some other SQL database. Fallback only. See notes.","deprecated":null,"id":"other_sql","note":null,"stability":null,"value":"other_sql"},{"brief":"Microsoft SQL Server","deprecated":null,"id":"mssql","note":null,"stability":null,"value":"mssql"},{"brief":"Microsoft SQL Server Compact","deprecated":null,"id":"mssqlcompact","note":null,"stability":null,"value":"mssqlcompact"},{"brief":"MySQL","deprecated":null,"id":"mysql","note":null,"stability":null,"value":"mysql"},{"brief":"Oracle Database","deprecated":null,"id":"oracle","note":null,"stability":null,"value":"oracle"},{"brief":"IBM Db2","deprecated":null,"id":"db2","note":null,"stability":null,"value":"db2"},{"brief":"PostgreSQL","deprecated":null,"id":"postgresql","note":null,"stability":null,"value":"postgresql"},{"brief":"Amazon Redshift","deprecated":null,"id":"redshift","note":null,"stability":null,"value":"redshift"},{"brief":"Apache Hive","deprecated":null,"id":"hive","note":null,"stability":null,"value":"hive"},{"brief":"Cloudscape","deprecated":null,"id":"cloudscape","note":null,"stability":null,"value":"cloudscape"},{"brief":"HyperSQL DataBase","deprecated":null,"id":"hsqldb","note":null,"stability":null,"value":"hsqldb"},{"brief":"Progress Database","deprecated":null,"id":"progress","note":null,"stability":null,"value":"progress"},{"brief":"SAP MaxDB","deprecated":null,"id":"maxdb","note":null,"stability":null,"value":"maxdb"},{"brief":"SAP HANA","deprecated":null,"id":"hanadb","note":null,"stability":null,"value":"hanadb"},{"brief":"Ingres","deprecated":null,"id":"ingres","note":null,"stability":null,"value":"ingres"},{"brief":"FirstSQL","deprecated":null,"id":"firstsql","note":null,"stability":null,"value":"firstsql"},{"brief":"EnterpriseDB","deprecated":null,"id":"edb","note":null,"stability":null,"value":"edb"},{"brief":"InterSystems Caché","deprecated":null,"id":"cache","note":null,"stability":null,"value":"cache"},{"brief":"Adabas (Adaptable Database System)","deprecated":null,"id":"adabas","note":null,"stability":null,"value":"adabas"},{"brief":"Firebird","deprecated":null,"id":"firebird","note":null,"stability":null,"value":"firebird"},{"brief":"Apache Derby","deprecated":null,"id":"derby","note":null,"stability":null,"value":"derby"},{"brief":"FileMaker","deprecated":null,"id":"filemaker","note":null,"stability":null,"value":"filemaker"},{"brief":"Informix","deprecated":null,"id":"informix","note":null,"stability":null,"value":"informix"},{"brief":"InstantDB","deprecated":null,"id":"instantdb","note":null,"stability":null,"value":"instantdb"},{"brief":"InterBase","deprecated":null,"id":"interbase","note":null,"stability":null,"value":"interbase"},{"brief":"MariaDB","deprecated":null,"id":"mariadb","note":null,"stability":null,"value":"mariadb"},{"brief":"Netezza","deprecated":null,"id":"netezza","note":null,"stability":null,"value":"netezza"},{"brief":"Pervasive PSQL","deprecated":null,"id":"pervasive","note":null,"stability":null,"value":"pervasive"},{"brief":"PointBase","deprecated":null,"id":"pointbase","note":null,"stability":null,"value":"pointbase"},{"brief":"SQLite","deprecated":null,"id":"sqlite","note":null,"stability":null,"value":"sqlite"},{"brief":"Sybase","deprecated":null,"id":"sybase","note":null,"stability":null,"value":"sybase"},{"brief":"Teradata","deprecated":null,"id":"teradata","note":null,"stability":null,"value":"teradata"},{"brief":"Vertica","deprecated":null,"id":"vertica","note":null,"stability":null,"value":"vertica"},{"brief":"H2","deprecated":null,"id":"h2","note":null,"stability":null,"value":"h2"},{"brief":"ColdFusion IMQ","deprecated":null,"id":"coldfusion","note":null,"stability":null,"value":"coldfusion"},{"brief":"Apache Cassandra","deprecated":null,"id":"cassandra","note":null,"stability":null,"value":"cassandra"},{"brief":"Apache HBase","deprecated":null,"id":"hbase","note":null,"stability":null,"value":"hbase"},{"brief":"MongoDB","deprecated":null,"id":"mongodb","note":null,"stability":null,"value":"mongodb"},{"brief":"Redis","deprecated":null,"id":"redis","note":null,"stability":null,"value":"redis"},{"brief":"Couchbase","deprecated":null,"id":"couchbase","note":null,"stability":null,"value":"couchbase"},{"brief":"CouchDB","deprecated":null,"id":"couchdb","note":null,"stability":null,"value":"couchdb"},{"brief":"Microsoft Azure Cosmos DB","deprecated":null,"id":"cosmosdb","note":null,"stability":null,"value":"cosmosdb"},{"brief":"Amazon DynamoDB","deprecated":null,"id":"dynamodb","note":null,"stability":null,"value":"dynamodb"},{"brief":"Neo4j","deprecated":null,"id":"neo4j","note":null,"stability":null,"value":"neo4j"},{"brief":"Apache Geode","deprecated":null,"id":"geode","note":null,"stability":null,"value":"geode"},{"brief":"Elasticsearch","deprecated":null,"id":"elasticsearch","note":null,"stability":null,"value":"elasticsearch"},{"brief":"Memcached","deprecated":null,"id":"memcached","note":null,"stability":null,"value":"memcached"},{"brief":"CockroachDB","deprecated":null,"id":"cockroachdb","note":null,"stability":null,"value":"cockroachdb"},{"brief":"OpenSearch","deprecated":null,"id":"opensearch","note":null,"stability":null,"value":"opensearch"},{"brief":"ClickHouse","deprecated":null,"id":"clickhouse","note":null,"stability":null,"value":"clickhouse"},{"brief":"Cloud Spanner","deprecated":null,"id":"spanner","note":null,"stability":null,"value":"spanner"},{"brief":"Trino","deprecated":null,"id":"trino","note":null,"stability":null,"value":"trino"}]}},{"brief":"Username for accessing the database.\n","examples":["readonly_user","reporting_user"],"name":"db.user","requirement_level":"recommended","root_namespace":"db","tag":"db-generic","type":"string"}],"root_namespace":"db"},{"attributes":[{"brief":"The size of the request payload body in bytes. This is the number of bytes transferred excluding headers and is often, but not always, present as the [Content-Length](https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length) header. For requests using transport encoding, this should be the compressed size.\n","examples":3495,"name":"http.request.body.size","requirement_level":"recommended","root_namespace":"http","stability":"experimental","type":"int"},{"brief":"HTTP request headers, `\u003ckey\u003e` being the normalized HTTP Header name (lowercase), the value being the header values.\n","examples":["http.request.header.content-type=[\"application/json\"]","http.request.header.x-forwarded-for=[\"1.2.3.4\", \"1.2.3.5\"]"],"name":"http.request.header","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","requirement_level":"recommended","root_namespace":"http","stability":"stable","type":"template[string[]]"},{"brief":"HTTP request method.","examples":["GET","POST","HEAD"],"name":"http.request.method","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","requirement_level":"recommended","root_namespace":"http","stability":"stable","type":{"allow_custom_values":true,"members":[{"brief":"CONNECT method.","deprecated":null,"id":"connect","note":null,"stability":null,"value":"CONNECT"},{"brief":"DELETE method.","deprecated":null,"id":"delete","note":null,"stability":null,"value":"DELETE"},{"brief":"GET method.","deprecated":null,"id":"get","note":null,"stability":null,"value":"GET"},{"brief":"HEAD method.","deprecated":null,"id":"head","note":null,"stability":null,"value":"HEAD"},{"brief":"OPTIONS method.","deprecated":null,"id":"options","note":null,"stability":null,"value":"OPTIONS"},{"brief":"PATCH method.","deprecated":null,"id":"patch","note":null,"stability":null,"value":"PATCH"},{"brief":"POST method.","deprecated":null,"id":"post","note":null,"stability":null,"value":"POST"},{"brief":"PUT method.","deprecated":null,"id":"put","note":null,"stability":null,"value":"PUT"},{"brief":"TRACE method.","deprecated":null,"id":"trace","note":null,"stability":null,"value":"TRACE"},{"brief":"Any HTTP method that the instrumentation has no prior knowledge of.","deprecated":null,"id":"other","note":null,"stability":null,"value":"_OTHER"}]}},{"brief":"Original HTTP method sent by the client in the request line.","examples":["GeT","ACL","foo"],"name":"http.request.method_original","requirement_level":"recommended","root_namespace":"http","stability":"stable","type":"string"},{"brief":"The ordinal number of request resending attempt (for any reason, including redirects).\n","examples":3,"name":"http.request.resend_count","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","requirement_level":"recommended","root_namespace":"http","stability":"stable","type":"int"},{"brief":"The size of the response payload body in bytes. This is the number of bytes transferred excluding headers and is often, but not always, present as the [Content-Length](https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length) header. For requests using transport encoding, this should be the compressed size.\n","examples":3495,"name":"http.response.body.size","requirement_level":"recommended","root_namespace":"http","stability":"experimental","type":"int"},{"brief":"HTTP response headers, `\u003ckey\u003e` being the normalized HTTP Header name (lowercase), the value being the header values.\n","examples":["http.response.header.content-type=[\"application/json\"]","http.response.header.my-custom-header=[\"abc\", \"def\"]"],"name":"http.response.header","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","requirement_level":"recommended","root_namespace":"http","stability":"stable","type":"template[string[]]"},{"brief":"[HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6).","examples":[200],"name":"http.response.status_code","requirement_level":"recommended","root_namespace":"http","stability":"stable","type":"int"},{"brief":"The matched route, that is, the path template in the format used by the respective server framework.\n","examples":["/users/:userID?","{controller}/{action}/{id?}"],"name":"http.route","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.","requirement_level":"recommended","root_namespace":"http","stability":"stable","type":"string"}],"root_namespace":"http"},{"attributes":[{"brief":"The ISO 3166-1 alpha-2 2-character country code associated with the mobile carrier network.","examples":"DE","name":"network.carrier.icc","requirement_level":"recommended","root_namespace":"network","type":"string"},{"brief":"The mobile carrier country code.","examples":"310","name":"network.carrier.mcc","requirement_level":"recommended","root_namespace":"network","type":"string"},{"brief":"The mobile carrier network code.","examples":"001","name":"network.carrier.mnc","requirement_level":"recommended","root_namespace":"network","type":"string"},{"brief":"The name of the mobile carrier.","examples":"sprint","name":"network.carrier.name","requirement_level":"recommended","root_namespace":"network","type":"string"},{"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","name":"network.connection.subtype","requirement_level":"recommended","root_namespace":"network","type":{"allow_custom_values":true,"members":[{"brief":"GPRS","deprecated":null,"id":"gprs","note":null,"stability":null,"value":"gprs"},{"brief":"EDGE","deprecated":null,"id":"edge","note":null,"stability":null,"value":"edge"},{"brief":"UMTS","deprecated":null,"id":"umts","note":null,"stability":null,"value":"umts"},{"brief":"CDMA","deprecated":null,"id":"cdma","note":null,"stability":null,"value":"cdma"},{"brief":"EVDO Rel. 0","deprecated":null,"id":"evdo_0","note":null,"stability":null,"value":"evdo_0"},{"brief":"EVDO Rev. A","deprecated":null,"id":"evdo_a","note":null,"stability":null,"value":"evdo_a"},{"brief":"CDMA2000 1XRTT","deprecated":null,"id":"cdma2000_1xrtt","note":null,"stability":null,"value":"cdma2000_1xrtt"},{"brief":"HSDPA","deprecated":null,"id":"hsdpa","note":null,"stability":null,"value":"hsdpa"},{"brief":"HSUPA","deprecated":null,"id":"hsupa","note":null,"stability":null,"value":"hsupa"},{"brief":"HSPA","deprecated":null,"id":"hspa","note":null,"stability":null,"value":"hspa"},{"brief":"IDEN","deprecated":null,"id":"iden","note":null,"stability":null,"value":"iden"},{"brief":"EVDO Rev. B","deprecated":null,"id":"evdo_b","note":null,"stability":null,"value":"evdo_b"},{"brief":"LTE","deprecated":null,"id":"lte","note":null,"stability":null,"value":"lte"},{"brief":"EHRPD","deprecated":null,"id":"ehrpd","note":null,"stability":null,"value":"ehrpd"},{"brief":"HSPAP","deprecated":null,"id":"hspap","note":null,"stability":null,"value":"hspap"},{"brief":"GSM","deprecated":null,"id":"gsm","note":null,"stability":null,"value":"gsm"},{"brief":"TD-SCDMA","deprecated":null,"id":"td_scdma","note":null,"stability":null,"value":"td_scdma"},{"brief":"IWLAN","deprecated":null,"id":"iwlan","note":null,"stability":null,"value":"iwlan"},{"brief":"5G NR (New Radio)","deprecated":null,"id":"nr","note":null,"stability":null,"value":"nr"},{"brief":"5G NRNSA (New Radio Non-Standalone)","deprecated":null,"id":"nrnsa","note":null,"stability":null,"value":"nrnsa"},{"brief":"LTE CA","deprecated":null,"id":"lte_ca","note":null,"stability":null,"value":"lte_ca"}]}},{"brief":"The internet connection type.","examples":"wifi","name":"network.connection.type","requirement_level":"recommended","root_namespace":"network","type":{"allow_custom_values":true,"members":[{"brief":null,"deprecated":null,"id":"wifi","note":null,"stability":null,"value":"wifi"},{"brief":null,"deprecated":null,"id":"wired","note":null,"stability":null,"value":"wired"},{"brief":null,"deprecated":null,"id":"cell","note":null,"stability":null,"value":"cell"},{"brief":null,"deprecated":null,"id":"unavailable","note":null,"stability":null,"value":"unavailable"},{"brief":null,"deprecated":null,"id":"unknown","note":null,"stability":null,"value":"unknown"}]}},{"brief":"The network IO operation direction.","examples":["transmit"],"name":"network.io.direction","requirement_level":"recommended","root_namespace":"network","type":{"allow_custom_values":false,"members":[{"brief":null,"deprecated":null,"id":"transmit","note":null,"stability":null,"value":"transmit"},{"brief":null,"deprecated":null,"id":"receive","note":null,"stability":null,"value":"receive"}]}},{"brief":"Local address of the network connection - IP address or Unix domain socket name.","examples":["10.1.2.80","/tmp/my.sock"],"name":"network.local.address","requirement_level":"recommended","root_namespace":"network","stability":"stable","type":"string"},{"brief":"Local port number of the network connection.","examples":[65123],"name":"network.local.port","requirement_level":"recommended","root_namespace":"network","stability":"stable","type":"int"},{"brief":"Peer address of the network connection - IP address or Unix domain socket name.","examples":["10.1.2.80","/tmp/my.sock"],"name":"network.peer.address","requirement_level":"recommended","root_namespace":"network","stability":"stable","type":"string"},{"brief":"Peer port number of the network connection.","examples":[65123],"name":"network.peer.port","requirement_level":"recommended","root_namespace":"network","stability":"stable","type":"int"},{"brief":"[OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent.","examples":["amqp","http","mqtt"],"name":"network.protocol.name","note":"The value SHOULD be normalized to lowercase.","requirement_level":"recommended","root_namespace":"network","stability":"stable","type":"string"},{"brief":"Version of the protocol specified in `network.protocol.name`.","examples":"3.1.1","name":"network.protocol.version","note":"`network.protocol.version` refers to the version of the protocol used and might be different from the protocol client\u0027s 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","requirement_level":"recommended","root_namespace":"network","stability":"stable","type":"string"},{"brief":"[OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication).\n","examples":["tcp","udp"],"name":"network.transport","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","requirement_level":"recommended","root_namespace":"network","stability":"stable","type":{"allow_custom_values":true,"members":[{"brief":"TCP","deprecated":null,"id":"tcp","note":null,"stability":null,"value":"tcp"},{"brief":"UDP","deprecated":null,"id":"udp","note":null,"stability":null,"value":"udp"},{"brief":"Named or anonymous pipe.","deprecated":null,"id":"pipe","note":null,"stability":null,"value":"pipe"},{"brief":"Unix domain socket","deprecated":null,"id":"unix","note":null,"stability":null,"value":"unix"}]}},{"brief":"[OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent.","examples":["ipv4","ipv6"],"name":"network.type","note":"The value SHOULD be normalized to lowercase.","requirement_level":"recommended","root_namespace":"network","stability":"stable","type":{"allow_custom_values":true,"members":[{"brief":"IPv4","deprecated":null,"id":"ipv4","note":null,"stability":null,"value":"ipv4"},{"brief":"IPv6","deprecated":null,"id":"ipv6","note":null,"stability":null,"value":"ipv6"}]}}],"root_namespace":"network"},{"attributes":[{"brief":"The [URI fragment](https://www.rfc-editor.org/rfc/rfc3986#section-3.5) component","examples":["SemConv"],"name":"url.fragment","requirement_level":"recommended","root_namespace":"url","stability":"stable","type":"string"},{"brief":"Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986)","examples":["https://www.foo.bar/search?q=OpenTelemetry#SemConv","//localhost"],"name":"url.full","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\u0027s 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","requirement_level":"recommended","root_namespace":"url","stability":"stable","type":"string"},{"brief":"The [URI path](https://www.rfc-editor.org/rfc/rfc3986#section-3.3) component","examples":["/search"],"name":"url.path","requirement_level":"recommended","root_namespace":"url","stability":"stable","type":"string"},{"brief":"The [URI query](https://www.rfc-editor.org/rfc/rfc3986#section-3.4) component","examples":["q=OpenTelemetry"],"name":"url.query","note":"Sensitive content provided in query string SHOULD be scrubbed when instrumentations can identify it.","requirement_level":"recommended","root_namespace":"url","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"],"name":"url.scheme","requirement_level":"recommended","root_namespace":"url","stability":"stable","type":"string"}],"root_namespace":"url"},{"attributes":[{"brief":"Value of the [HTTP User-Agent](https://www.rfc-editor.org/rfc/rfc9110.html#field.user-agent) header sent by the client.\n","examples":["CERN-LineMode/2.15 libwww/2.17b3","Mozilla/5.0 (iPhone; CPU iPhone OS 14_7_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.2 Mobile/15E148 Safari/604.1"],"name":"user_agent.original","requirement_level":"recommended","root_namespace":"user_agent","stability":"stable","type":"string"}],"root_namespace":"user_agent"}] \ No newline at end of file diff --git a/crates/weaver_forge/expected_output/semconv_jq_fn/semconv_grouped_attributes_without_experimental.json b/crates/weaver_forge/expected_output/semconv_jq_fn/semconv_grouped_attributes_without_experimental.json index 6a25d5b6..24649758 100644 --- a/crates/weaver_forge/expected_output/semconv_jq_fn/semconv_grouped_attributes_without_experimental.json +++ b/crates/weaver_forge/expected_output/semconv_jq_fn/semconv_grouped_attributes_without_experimental.json @@ -1 +1 @@ -[{"attributes":[{"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","name":"db.cassandra.consistency_level","namespace":"db","requirement_level":"recommended","tag":"tech-specific-cassandra","type":{"allow_custom_values":true,"members":[{"brief":null,"deprecated":null,"id":"all","note":null,"stability":null,"value":"all"},{"brief":null,"deprecated":null,"id":"each_quorum","note":null,"stability":null,"value":"each_quorum"},{"brief":null,"deprecated":null,"id":"quorum","note":null,"stability":null,"value":"quorum"},{"brief":null,"deprecated":null,"id":"local_quorum","note":null,"stability":null,"value":"local_quorum"},{"brief":null,"deprecated":null,"id":"one","note":null,"stability":null,"value":"one"},{"brief":null,"deprecated":null,"id":"two","note":null,"stability":null,"value":"two"},{"brief":null,"deprecated":null,"id":"three","note":null,"stability":null,"value":"three"},{"brief":null,"deprecated":null,"id":"local_one","note":null,"stability":null,"value":"local_one"},{"brief":null,"deprecated":null,"id":"any","note":null,"stability":null,"value":"any"},{"brief":null,"deprecated":null,"id":"serial","note":null,"stability":null,"value":"serial"},{"brief":null,"deprecated":null,"id":"local_serial","note":null,"stability":null,"value":"local_serial"}]}},{"brief":"The data center of the coordinating node for a query.\n","examples":"us-west-2","name":"db.cassandra.coordinator.dc","namespace":"db","requirement_level":"recommended","tag":"tech-specific-cassandra","type":"string"},{"brief":"The ID of the coordinating node for a query.\n","examples":"be13faa2-8574-4d71-926d-27f16cf8a7af","name":"db.cassandra.coordinator.id","namespace":"db","requirement_level":"recommended","tag":"tech-specific-cassandra","type":"string"},{"brief":"Whether or not the query is idempotent.\n","name":"db.cassandra.idempotence","namespace":"db","requirement_level":"recommended","tag":"tech-specific-cassandra","type":"boolean"},{"brief":"The fetch size used for paging, i.e. how many rows will be returned at once.\n","examples":[5000],"name":"db.cassandra.page_size","namespace":"db","requirement_level":"recommended","tag":"tech-specific-cassandra","type":"int"},{"brief":"The number of times a query was speculatively executed. Not set or `0` if the query was not executed speculatively.\n","examples":[0,2],"name":"db.cassandra.speculative_execution_count","namespace":"db","requirement_level":"recommended","tag":"tech-specific-cassandra","type":"int"},{"brief":"The name of the primary Cassandra table that the operation is acting upon, including the keyspace name (if applicable).","examples":"mytable","name":"db.cassandra.table","namespace":"db","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","requirement_level":"recommended","tag":"tech-specific-cassandra","type":"string"},{"brief":"The connection string used to connect to the database. It is recommended to remove embedded credentials.\n","examples":"Server=(localdb)\\v11.0;Integrated Security=true;","name":"db.connection_string","namespace":"db","requirement_level":"recommended","tag":"db-generic","type":"string"},{"brief":"Unique Cosmos client instance id.","examples":"3ba4827d-4422-483f-b59f-85b74211c11d","name":"db.cosmosdb.client_id","namespace":"db","requirement_level":"recommended","tag":"tech-specific-cosmosdb","type":"string"},{"brief":"Cosmos client connection mode.","name":"db.cosmosdb.connection_mode","namespace":"db","requirement_level":"recommended","tag":"tech-specific-cosmosdb","type":{"allow_custom_values":false,"members":[{"brief":"Gateway (HTTP) connections mode","deprecated":null,"id":"gateway","note":null,"stability":null,"value":"gateway"},{"brief":"Direct connection.","deprecated":null,"id":"direct","note":null,"stability":null,"value":"direct"}]}},{"brief":"Cosmos DB container name.","examples":"anystring","name":"db.cosmosdb.container","namespace":"db","requirement_level":"recommended","tag":"tech-specific-cosmosdb","type":"string"},{"brief":"CosmosDB Operation Type.","name":"db.cosmosdb.operation_type","namespace":"db","requirement_level":"recommended","tag":"tech-specific-cosmosdb","type":{"allow_custom_values":true,"members":[{"brief":null,"deprecated":null,"id":"invalid","note":null,"stability":null,"value":"Invalid"},{"brief":null,"deprecated":null,"id":"create","note":null,"stability":null,"value":"Create"},{"brief":null,"deprecated":null,"id":"patch","note":null,"stability":null,"value":"Patch"},{"brief":null,"deprecated":null,"id":"read","note":null,"stability":null,"value":"Read"},{"brief":null,"deprecated":null,"id":"read_feed","note":null,"stability":null,"value":"ReadFeed"},{"brief":null,"deprecated":null,"id":"delete","note":null,"stability":null,"value":"Delete"},{"brief":null,"deprecated":null,"id":"replace","note":null,"stability":null,"value":"Replace"},{"brief":null,"deprecated":null,"id":"execute","note":null,"stability":null,"value":"Execute"},{"brief":null,"deprecated":null,"id":"query","note":null,"stability":null,"value":"Query"},{"brief":null,"deprecated":null,"id":"head","note":null,"stability":null,"value":"Head"},{"brief":null,"deprecated":null,"id":"head_feed","note":null,"stability":null,"value":"HeadFeed"},{"brief":null,"deprecated":null,"id":"upsert","note":null,"stability":null,"value":"Upsert"},{"brief":null,"deprecated":null,"id":"batch","note":null,"stability":null,"value":"Batch"},{"brief":null,"deprecated":null,"id":"query_plan","note":null,"stability":null,"value":"QueryPlan"},{"brief":null,"deprecated":null,"id":"execute_javascript","note":null,"stability":null,"value":"ExecuteJavaScript"}]}},{"brief":"RU consumed for that operation","examples":[46.18,1.0],"name":"db.cosmosdb.request_charge","namespace":"db","requirement_level":"recommended","tag":"tech-specific-cosmosdb","type":"double"},{"brief":"Request payload size in bytes","name":"db.cosmosdb.request_content_length","namespace":"db","requirement_level":"recommended","tag":"tech-specific-cosmosdb","type":"int"},{"brief":"Cosmos DB status code.","examples":[200,201],"name":"db.cosmosdb.status_code","namespace":"db","requirement_level":"recommended","tag":"tech-specific-cosmosdb","type":"int"},{"brief":"Cosmos DB sub status code.","examples":[1000,1002],"name":"db.cosmosdb.sub_status_code","namespace":"db","requirement_level":"recommended","tag":"tech-specific-cosmosdb","type":"int"},{"brief":"Represents the identifier of an Elasticsearch cluster.\n","examples":["e9106fc68e3044f0b1475b04bf4ffd5f"],"name":"db.elasticsearch.cluster.name","namespace":"db","requirement_level":"recommended","tag":"tech-specific-elasticsearch","type":"string"},{"brief":"Represents the human-readable identifier of the node/instance to which a request was routed.\n","examples":["instance-0000000001"],"name":"db.elasticsearch.node.name","namespace":"db","requirement_level":"recommended","tag":"tech-specific-elasticsearch","type":"string"},{"brief":"A dynamic value in the url path.\n","examples":["db.elasticsearch.path_parts.index=test-index","db.elasticsearch.path_parts.doc_id=123"],"name":"db.elasticsearch.path_parts","namespace":"db","note":"Many Elasticsearch url paths allow dynamic values. These SHOULD be recorded in span attributes in the format `db.elasticsearch.path_parts.\u003ckey\u003e`, where `\u003ckey\u003e` 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","requirement_level":"recommended","tag":"tech-specific-elasticsearch","type":"template[string]"},{"brief":"An identifier (address, unique name, or any other identifier) of the database instance that is executing queries or mutations on the current connection. This is useful in cases where the database is running in a clustered environment and the instrumentation is able to record the node executing the query. The client may obtain this value in databases like MySQL using queries like `select @@hostname`.\n","examples":"mysql-e26b99z.example.com","name":"db.instance.id","namespace":"db","requirement_level":"recommended","tag":"db-generic","type":"string"},{"brief":"The fully-qualified class name of the [Java Database Connectivity (JDBC)](https://docs.oracle.com/javase/8/docs/technotes/guides/jdbc/) driver used to connect.\n","examples":["org.postgresql.Driver","com.microsoft.sqlserver.jdbc.SQLServerDriver"],"name":"db.jdbc.driver_classname","namespace":"db","requirement_level":"recommended","tag":"tech-specific-jdbc","type":"string"},{"brief":"The MongoDB collection being accessed within the database stated in `db.name`.\n","examples":["customers","products"],"name":"db.mongodb.collection","namespace":"db","requirement_level":"recommended","tag":"tech-specific-mongodb","type":"string"},{"brief":"The Microsoft SQL Server [instance name](https://docs.microsoft.com/sql/connect/jdbc/building-the-connection-url?view=sql-server-ver15) connecting to. This name is used to determine the port of a named instance.\n","examples":"MSSQLSERVER","name":"db.mssql.instance_name","namespace":"db","note":"If setting a `db.mssql.instance_name`, `server.port` is no longer required (but still recommended if non-standard).\n","requirement_level":"recommended","tag":"tech-specific-mssql","type":"string"},{"brief":"This attribute is used to report the name of the database being accessed. For commands that switch the database, this should be set to the target database (even if the command fails).\n","examples":["customers","main"],"name":"db.name","namespace":"db","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","requirement_level":"recommended","tag":"db-generic","type":"string"},{"brief":"The name of the operation being executed, e.g. the [MongoDB command name](https://docs.mongodb.com/manual/reference/command/#database-operations) such as `findAndModify`, or the SQL keyword.\n","examples":["findAndModify","HMSET","SELECT"],"name":"db.operation","namespace":"db","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","requirement_level":"recommended","tag":"db-generic","type":"string"},{"brief":"The index of the database being accessed as used in the [`SELECT` command](https://redis.io/commands/select), provided as an integer. To be used instead of the generic `db.name` attribute.\n","examples":[0,1,15],"name":"db.redis.database_index","namespace":"db","requirement_level":"recommended","tag":"tech-specific-redis","type":"int"},{"brief":"The name of the primary table that the operation is acting upon, including the database name (if applicable).","examples":["public.users","customers"],"name":"db.sql.table","namespace":"db","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","requirement_level":"recommended","tag":"tech-specific-sql","type":"string"},{"brief":"The database statement being executed.\n","examples":["SELECT * FROM wuser_table","SET mykey \"WuValue\""],"name":"db.statement","namespace":"db","requirement_level":"recommended","tag":"db-generic","type":"string"},{"brief":"An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers.","name":"db.system","namespace":"db","requirement_level":"recommended","tag":"db-generic","type":{"allow_custom_values":true,"members":[{"brief":"Some other SQL database. Fallback only. See notes.","deprecated":null,"id":"other_sql","note":null,"stability":null,"value":"other_sql"},{"brief":"Microsoft SQL Server","deprecated":null,"id":"mssql","note":null,"stability":null,"value":"mssql"},{"brief":"Microsoft SQL Server Compact","deprecated":null,"id":"mssqlcompact","note":null,"stability":null,"value":"mssqlcompact"},{"brief":"MySQL","deprecated":null,"id":"mysql","note":null,"stability":null,"value":"mysql"},{"brief":"Oracle Database","deprecated":null,"id":"oracle","note":null,"stability":null,"value":"oracle"},{"brief":"IBM Db2","deprecated":null,"id":"db2","note":null,"stability":null,"value":"db2"},{"brief":"PostgreSQL","deprecated":null,"id":"postgresql","note":null,"stability":null,"value":"postgresql"},{"brief":"Amazon Redshift","deprecated":null,"id":"redshift","note":null,"stability":null,"value":"redshift"},{"brief":"Apache Hive","deprecated":null,"id":"hive","note":null,"stability":null,"value":"hive"},{"brief":"Cloudscape","deprecated":null,"id":"cloudscape","note":null,"stability":null,"value":"cloudscape"},{"brief":"HyperSQL DataBase","deprecated":null,"id":"hsqldb","note":null,"stability":null,"value":"hsqldb"},{"brief":"Progress Database","deprecated":null,"id":"progress","note":null,"stability":null,"value":"progress"},{"brief":"SAP MaxDB","deprecated":null,"id":"maxdb","note":null,"stability":null,"value":"maxdb"},{"brief":"SAP HANA","deprecated":null,"id":"hanadb","note":null,"stability":null,"value":"hanadb"},{"brief":"Ingres","deprecated":null,"id":"ingres","note":null,"stability":null,"value":"ingres"},{"brief":"FirstSQL","deprecated":null,"id":"firstsql","note":null,"stability":null,"value":"firstsql"},{"brief":"EnterpriseDB","deprecated":null,"id":"edb","note":null,"stability":null,"value":"edb"},{"brief":"InterSystems Caché","deprecated":null,"id":"cache","note":null,"stability":null,"value":"cache"},{"brief":"Adabas (Adaptable Database System)","deprecated":null,"id":"adabas","note":null,"stability":null,"value":"adabas"},{"brief":"Firebird","deprecated":null,"id":"firebird","note":null,"stability":null,"value":"firebird"},{"brief":"Apache Derby","deprecated":null,"id":"derby","note":null,"stability":null,"value":"derby"},{"brief":"FileMaker","deprecated":null,"id":"filemaker","note":null,"stability":null,"value":"filemaker"},{"brief":"Informix","deprecated":null,"id":"informix","note":null,"stability":null,"value":"informix"},{"brief":"InstantDB","deprecated":null,"id":"instantdb","note":null,"stability":null,"value":"instantdb"},{"brief":"InterBase","deprecated":null,"id":"interbase","note":null,"stability":null,"value":"interbase"},{"brief":"MariaDB","deprecated":null,"id":"mariadb","note":null,"stability":null,"value":"mariadb"},{"brief":"Netezza","deprecated":null,"id":"netezza","note":null,"stability":null,"value":"netezza"},{"brief":"Pervasive PSQL","deprecated":null,"id":"pervasive","note":null,"stability":null,"value":"pervasive"},{"brief":"PointBase","deprecated":null,"id":"pointbase","note":null,"stability":null,"value":"pointbase"},{"brief":"SQLite","deprecated":null,"id":"sqlite","note":null,"stability":null,"value":"sqlite"},{"brief":"Sybase","deprecated":null,"id":"sybase","note":null,"stability":null,"value":"sybase"},{"brief":"Teradata","deprecated":null,"id":"teradata","note":null,"stability":null,"value":"teradata"},{"brief":"Vertica","deprecated":null,"id":"vertica","note":null,"stability":null,"value":"vertica"},{"brief":"H2","deprecated":null,"id":"h2","note":null,"stability":null,"value":"h2"},{"brief":"ColdFusion IMQ","deprecated":null,"id":"coldfusion","note":null,"stability":null,"value":"coldfusion"},{"brief":"Apache Cassandra","deprecated":null,"id":"cassandra","note":null,"stability":null,"value":"cassandra"},{"brief":"Apache HBase","deprecated":null,"id":"hbase","note":null,"stability":null,"value":"hbase"},{"brief":"MongoDB","deprecated":null,"id":"mongodb","note":null,"stability":null,"value":"mongodb"},{"brief":"Redis","deprecated":null,"id":"redis","note":null,"stability":null,"value":"redis"},{"brief":"Couchbase","deprecated":null,"id":"couchbase","note":null,"stability":null,"value":"couchbase"},{"brief":"CouchDB","deprecated":null,"id":"couchdb","note":null,"stability":null,"value":"couchdb"},{"brief":"Microsoft Azure Cosmos DB","deprecated":null,"id":"cosmosdb","note":null,"stability":null,"value":"cosmosdb"},{"brief":"Amazon DynamoDB","deprecated":null,"id":"dynamodb","note":null,"stability":null,"value":"dynamodb"},{"brief":"Neo4j","deprecated":null,"id":"neo4j","note":null,"stability":null,"value":"neo4j"},{"brief":"Apache Geode","deprecated":null,"id":"geode","note":null,"stability":null,"value":"geode"},{"brief":"Elasticsearch","deprecated":null,"id":"elasticsearch","note":null,"stability":null,"value":"elasticsearch"},{"brief":"Memcached","deprecated":null,"id":"memcached","note":null,"stability":null,"value":"memcached"},{"brief":"CockroachDB","deprecated":null,"id":"cockroachdb","note":null,"stability":null,"value":"cockroachdb"},{"brief":"OpenSearch","deprecated":null,"id":"opensearch","note":null,"stability":null,"value":"opensearch"},{"brief":"ClickHouse","deprecated":null,"id":"clickhouse","note":null,"stability":null,"value":"clickhouse"},{"brief":"Cloud Spanner","deprecated":null,"id":"spanner","note":null,"stability":null,"value":"spanner"},{"brief":"Trino","deprecated":null,"id":"trino","note":null,"stability":null,"value":"trino"}]}},{"brief":"Username for accessing the database.\n","examples":["readonly_user","reporting_user"],"name":"db.user","namespace":"db","requirement_level":"recommended","tag":"db-generic","type":"string"}],"namespace":"db"},{"attributes":[{"brief":"HTTP request headers, `\u003ckey\u003e` being the normalized HTTP Header name (lowercase), the value being the header values.\n","examples":["http.request.header.content-type=[\"application/json\"]","http.request.header.x-forwarded-for=[\"1.2.3.4\", \"1.2.3.5\"]"],"name":"http.request.header","namespace":"http","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","requirement_level":"recommended","stability":"stable","type":"template[string[]]"},{"brief":"HTTP request method.","examples":["GET","POST","HEAD"],"name":"http.request.method","namespace":"http","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","requirement_level":"recommended","stability":"stable","type":{"allow_custom_values":true,"members":[{"brief":"CONNECT method.","deprecated":null,"id":"connect","note":null,"stability":null,"value":"CONNECT"},{"brief":"DELETE method.","deprecated":null,"id":"delete","note":null,"stability":null,"value":"DELETE"},{"brief":"GET method.","deprecated":null,"id":"get","note":null,"stability":null,"value":"GET"},{"brief":"HEAD method.","deprecated":null,"id":"head","note":null,"stability":null,"value":"HEAD"},{"brief":"OPTIONS method.","deprecated":null,"id":"options","note":null,"stability":null,"value":"OPTIONS"},{"brief":"PATCH method.","deprecated":null,"id":"patch","note":null,"stability":null,"value":"PATCH"},{"brief":"POST method.","deprecated":null,"id":"post","note":null,"stability":null,"value":"POST"},{"brief":"PUT method.","deprecated":null,"id":"put","note":null,"stability":null,"value":"PUT"},{"brief":"TRACE method.","deprecated":null,"id":"trace","note":null,"stability":null,"value":"TRACE"},{"brief":"Any HTTP method that the instrumentation has no prior knowledge of.","deprecated":null,"id":"other","note":null,"stability":null,"value":"_OTHER"}]}},{"brief":"Original HTTP method sent by the client in the request line.","examples":["GeT","ACL","foo"],"name":"http.request.method_original","namespace":"http","requirement_level":"recommended","stability":"stable","type":"string"},{"brief":"The ordinal number of request resending attempt (for any reason, including redirects).\n","examples":3,"name":"http.request.resend_count","namespace":"http","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","requirement_level":"recommended","stability":"stable","type":"int"},{"brief":"HTTP response headers, `\u003ckey\u003e` being the normalized HTTP Header name (lowercase), the value being the header values.\n","examples":["http.response.header.content-type=[\"application/json\"]","http.response.header.my-custom-header=[\"abc\", \"def\"]"],"name":"http.response.header","namespace":"http","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","requirement_level":"recommended","stability":"stable","type":"template[string[]]"},{"brief":"[HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6).","examples":[200],"name":"http.response.status_code","namespace":"http","requirement_level":"recommended","stability":"stable","type":"int"},{"brief":"The matched route, that is, the path template in the format used by the respective server framework.\n","examples":["/users/:userID?","{controller}/{action}/{id?}"],"name":"http.route","namespace":"http","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.","requirement_level":"recommended","stability":"stable","type":"string"}],"namespace":"http"},{"attributes":[{"brief":"Value of the [HTTP User-Agent](https://www.rfc-editor.org/rfc/rfc9110.html#field.user-agent) header sent by the client.\n","examples":["CERN-LineMode/2.15 libwww/2.17b3","Mozilla/5.0 (iPhone; CPU iPhone OS 14_7_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.2 Mobile/15E148 Safari/604.1"],"name":"user_agent.original","namespace":"user_agent","requirement_level":"recommended","stability":"stable","type":"string"}],"namespace":"user_agent"}] \ No newline at end of file +[{"attributes":[{"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","name":"db.cassandra.consistency_level","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-cassandra","type":{"allow_custom_values":true,"members":[{"brief":null,"deprecated":null,"id":"all","note":null,"stability":null,"value":"all"},{"brief":null,"deprecated":null,"id":"each_quorum","note":null,"stability":null,"value":"each_quorum"},{"brief":null,"deprecated":null,"id":"quorum","note":null,"stability":null,"value":"quorum"},{"brief":null,"deprecated":null,"id":"local_quorum","note":null,"stability":null,"value":"local_quorum"},{"brief":null,"deprecated":null,"id":"one","note":null,"stability":null,"value":"one"},{"brief":null,"deprecated":null,"id":"two","note":null,"stability":null,"value":"two"},{"brief":null,"deprecated":null,"id":"three","note":null,"stability":null,"value":"three"},{"brief":null,"deprecated":null,"id":"local_one","note":null,"stability":null,"value":"local_one"},{"brief":null,"deprecated":null,"id":"any","note":null,"stability":null,"value":"any"},{"brief":null,"deprecated":null,"id":"serial","note":null,"stability":null,"value":"serial"},{"brief":null,"deprecated":null,"id":"local_serial","note":null,"stability":null,"value":"local_serial"}]}},{"brief":"The data center of the coordinating node for a query.\n","examples":"us-west-2","name":"db.cassandra.coordinator.dc","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-cassandra","type":"string"},{"brief":"The ID of the coordinating node for a query.\n","examples":"be13faa2-8574-4d71-926d-27f16cf8a7af","name":"db.cassandra.coordinator.id","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-cassandra","type":"string"},{"brief":"Whether or not the query is idempotent.\n","name":"db.cassandra.idempotence","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-cassandra","type":"boolean"},{"brief":"The fetch size used for paging, i.e. how many rows will be returned at once.\n","examples":[5000],"name":"db.cassandra.page_size","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-cassandra","type":"int"},{"brief":"The number of times a query was speculatively executed. Not set or `0` if the query was not executed speculatively.\n","examples":[0,2],"name":"db.cassandra.speculative_execution_count","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-cassandra","type":"int"},{"brief":"The name of the primary Cassandra table that the operation is acting upon, including the keyspace name (if applicable).","examples":"mytable","name":"db.cassandra.table","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","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-cassandra","type":"string"},{"brief":"The connection string used to connect to the database. It is recommended to remove embedded credentials.\n","examples":"Server=(localdb)\\v11.0;Integrated Security=true;","name":"db.connection_string","requirement_level":"recommended","root_namespace":"db","tag":"db-generic","type":"string"},{"brief":"Unique Cosmos client instance id.","examples":"3ba4827d-4422-483f-b59f-85b74211c11d","name":"db.cosmosdb.client_id","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-cosmosdb","type":"string"},{"brief":"Cosmos client connection mode.","name":"db.cosmosdb.connection_mode","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-cosmosdb","type":{"allow_custom_values":false,"members":[{"brief":"Gateway (HTTP) connections mode","deprecated":null,"id":"gateway","note":null,"stability":null,"value":"gateway"},{"brief":"Direct connection.","deprecated":null,"id":"direct","note":null,"stability":null,"value":"direct"}]}},{"brief":"Cosmos DB container name.","examples":"anystring","name":"db.cosmosdb.container","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-cosmosdb","type":"string"},{"brief":"CosmosDB Operation Type.","name":"db.cosmosdb.operation_type","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-cosmosdb","type":{"allow_custom_values":true,"members":[{"brief":null,"deprecated":null,"id":"invalid","note":null,"stability":null,"value":"Invalid"},{"brief":null,"deprecated":null,"id":"create","note":null,"stability":null,"value":"Create"},{"brief":null,"deprecated":null,"id":"patch","note":null,"stability":null,"value":"Patch"},{"brief":null,"deprecated":null,"id":"read","note":null,"stability":null,"value":"Read"},{"brief":null,"deprecated":null,"id":"read_feed","note":null,"stability":null,"value":"ReadFeed"},{"brief":null,"deprecated":null,"id":"delete","note":null,"stability":null,"value":"Delete"},{"brief":null,"deprecated":null,"id":"replace","note":null,"stability":null,"value":"Replace"},{"brief":null,"deprecated":null,"id":"execute","note":null,"stability":null,"value":"Execute"},{"brief":null,"deprecated":null,"id":"query","note":null,"stability":null,"value":"Query"},{"brief":null,"deprecated":null,"id":"head","note":null,"stability":null,"value":"Head"},{"brief":null,"deprecated":null,"id":"head_feed","note":null,"stability":null,"value":"HeadFeed"},{"brief":null,"deprecated":null,"id":"upsert","note":null,"stability":null,"value":"Upsert"},{"brief":null,"deprecated":null,"id":"batch","note":null,"stability":null,"value":"Batch"},{"brief":null,"deprecated":null,"id":"query_plan","note":null,"stability":null,"value":"QueryPlan"},{"brief":null,"deprecated":null,"id":"execute_javascript","note":null,"stability":null,"value":"ExecuteJavaScript"}]}},{"brief":"RU consumed for that operation","examples":[46.18,1.0],"name":"db.cosmosdb.request_charge","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-cosmosdb","type":"double"},{"brief":"Request payload size in bytes","name":"db.cosmosdb.request_content_length","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-cosmosdb","type":"int"},{"brief":"Cosmos DB status code.","examples":[200,201],"name":"db.cosmosdb.status_code","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-cosmosdb","type":"int"},{"brief":"Cosmos DB sub status code.","examples":[1000,1002],"name":"db.cosmosdb.sub_status_code","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-cosmosdb","type":"int"},{"brief":"Represents the identifier of an Elasticsearch cluster.\n","examples":["e9106fc68e3044f0b1475b04bf4ffd5f"],"name":"db.elasticsearch.cluster.name","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-elasticsearch","type":"string"},{"brief":"Represents the human-readable identifier of the node/instance to which a request was routed.\n","examples":["instance-0000000001"],"name":"db.elasticsearch.node.name","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-elasticsearch","type":"string"},{"brief":"A dynamic value in the url path.\n","examples":["db.elasticsearch.path_parts.index=test-index","db.elasticsearch.path_parts.doc_id=123"],"name":"db.elasticsearch.path_parts","note":"Many Elasticsearch url paths allow dynamic values. These SHOULD be recorded in span attributes in the format `db.elasticsearch.path_parts.\u003ckey\u003e`, where `\u003ckey\u003e` 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","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-elasticsearch","type":"template[string]"},{"brief":"An identifier (address, unique name, or any other identifier) of the database instance that is executing queries or mutations on the current connection. This is useful in cases where the database is running in a clustered environment and the instrumentation is able to record the node executing the query. The client may obtain this value in databases like MySQL using queries like `select @@hostname`.\n","examples":"mysql-e26b99z.example.com","name":"db.instance.id","requirement_level":"recommended","root_namespace":"db","tag":"db-generic","type":"string"},{"brief":"The fully-qualified class name of the [Java Database Connectivity (JDBC)](https://docs.oracle.com/javase/8/docs/technotes/guides/jdbc/) driver used to connect.\n","examples":["org.postgresql.Driver","com.microsoft.sqlserver.jdbc.SQLServerDriver"],"name":"db.jdbc.driver_classname","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-jdbc","type":"string"},{"brief":"The MongoDB collection being accessed within the database stated in `db.name`.\n","examples":["customers","products"],"name":"db.mongodb.collection","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-mongodb","type":"string"},{"brief":"The Microsoft SQL Server [instance name](https://docs.microsoft.com/sql/connect/jdbc/building-the-connection-url?view=sql-server-ver15) connecting to. This name is used to determine the port of a named instance.\n","examples":"MSSQLSERVER","name":"db.mssql.instance_name","note":"If setting a `db.mssql.instance_name`, `server.port` is no longer required (but still recommended if non-standard).\n","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-mssql","type":"string"},{"brief":"This attribute is used to report the name of the database being accessed. For commands that switch the database, this should be set to the target database (even if the command fails).\n","examples":["customers","main"],"name":"db.name","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","requirement_level":"recommended","root_namespace":"db","tag":"db-generic","type":"string"},{"brief":"The name of the operation being executed, e.g. the [MongoDB command name](https://docs.mongodb.com/manual/reference/command/#database-operations) such as `findAndModify`, or the SQL keyword.\n","examples":["findAndModify","HMSET","SELECT"],"name":"db.operation","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","requirement_level":"recommended","root_namespace":"db","tag":"db-generic","type":"string"},{"brief":"The index of the database being accessed as used in the [`SELECT` command](https://redis.io/commands/select), provided as an integer. To be used instead of the generic `db.name` attribute.\n","examples":[0,1,15],"name":"db.redis.database_index","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-redis","type":"int"},{"brief":"The name of the primary table that the operation is acting upon, including the database name (if applicable).","examples":["public.users","customers"],"name":"db.sql.table","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","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-sql","type":"string"},{"brief":"The database statement being executed.\n","examples":["SELECT * FROM wuser_table","SET mykey \"WuValue\""],"name":"db.statement","requirement_level":"recommended","root_namespace":"db","tag":"db-generic","type":"string"},{"brief":"An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers.","name":"db.system","requirement_level":"recommended","root_namespace":"db","tag":"db-generic","type":{"allow_custom_values":true,"members":[{"brief":"Some other SQL database. Fallback only. See notes.","deprecated":null,"id":"other_sql","note":null,"stability":null,"value":"other_sql"},{"brief":"Microsoft SQL Server","deprecated":null,"id":"mssql","note":null,"stability":null,"value":"mssql"},{"brief":"Microsoft SQL Server Compact","deprecated":null,"id":"mssqlcompact","note":null,"stability":null,"value":"mssqlcompact"},{"brief":"MySQL","deprecated":null,"id":"mysql","note":null,"stability":null,"value":"mysql"},{"brief":"Oracle Database","deprecated":null,"id":"oracle","note":null,"stability":null,"value":"oracle"},{"brief":"IBM Db2","deprecated":null,"id":"db2","note":null,"stability":null,"value":"db2"},{"brief":"PostgreSQL","deprecated":null,"id":"postgresql","note":null,"stability":null,"value":"postgresql"},{"brief":"Amazon Redshift","deprecated":null,"id":"redshift","note":null,"stability":null,"value":"redshift"},{"brief":"Apache Hive","deprecated":null,"id":"hive","note":null,"stability":null,"value":"hive"},{"brief":"Cloudscape","deprecated":null,"id":"cloudscape","note":null,"stability":null,"value":"cloudscape"},{"brief":"HyperSQL DataBase","deprecated":null,"id":"hsqldb","note":null,"stability":null,"value":"hsqldb"},{"brief":"Progress Database","deprecated":null,"id":"progress","note":null,"stability":null,"value":"progress"},{"brief":"SAP MaxDB","deprecated":null,"id":"maxdb","note":null,"stability":null,"value":"maxdb"},{"brief":"SAP HANA","deprecated":null,"id":"hanadb","note":null,"stability":null,"value":"hanadb"},{"brief":"Ingres","deprecated":null,"id":"ingres","note":null,"stability":null,"value":"ingres"},{"brief":"FirstSQL","deprecated":null,"id":"firstsql","note":null,"stability":null,"value":"firstsql"},{"brief":"EnterpriseDB","deprecated":null,"id":"edb","note":null,"stability":null,"value":"edb"},{"brief":"InterSystems Caché","deprecated":null,"id":"cache","note":null,"stability":null,"value":"cache"},{"brief":"Adabas (Adaptable Database System)","deprecated":null,"id":"adabas","note":null,"stability":null,"value":"adabas"},{"brief":"Firebird","deprecated":null,"id":"firebird","note":null,"stability":null,"value":"firebird"},{"brief":"Apache Derby","deprecated":null,"id":"derby","note":null,"stability":null,"value":"derby"},{"brief":"FileMaker","deprecated":null,"id":"filemaker","note":null,"stability":null,"value":"filemaker"},{"brief":"Informix","deprecated":null,"id":"informix","note":null,"stability":null,"value":"informix"},{"brief":"InstantDB","deprecated":null,"id":"instantdb","note":null,"stability":null,"value":"instantdb"},{"brief":"InterBase","deprecated":null,"id":"interbase","note":null,"stability":null,"value":"interbase"},{"brief":"MariaDB","deprecated":null,"id":"mariadb","note":null,"stability":null,"value":"mariadb"},{"brief":"Netezza","deprecated":null,"id":"netezza","note":null,"stability":null,"value":"netezza"},{"brief":"Pervasive PSQL","deprecated":null,"id":"pervasive","note":null,"stability":null,"value":"pervasive"},{"brief":"PointBase","deprecated":null,"id":"pointbase","note":null,"stability":null,"value":"pointbase"},{"brief":"SQLite","deprecated":null,"id":"sqlite","note":null,"stability":null,"value":"sqlite"},{"brief":"Sybase","deprecated":null,"id":"sybase","note":null,"stability":null,"value":"sybase"},{"brief":"Teradata","deprecated":null,"id":"teradata","note":null,"stability":null,"value":"teradata"},{"brief":"Vertica","deprecated":null,"id":"vertica","note":null,"stability":null,"value":"vertica"},{"brief":"H2","deprecated":null,"id":"h2","note":null,"stability":null,"value":"h2"},{"brief":"ColdFusion IMQ","deprecated":null,"id":"coldfusion","note":null,"stability":null,"value":"coldfusion"},{"brief":"Apache Cassandra","deprecated":null,"id":"cassandra","note":null,"stability":null,"value":"cassandra"},{"brief":"Apache HBase","deprecated":null,"id":"hbase","note":null,"stability":null,"value":"hbase"},{"brief":"MongoDB","deprecated":null,"id":"mongodb","note":null,"stability":null,"value":"mongodb"},{"brief":"Redis","deprecated":null,"id":"redis","note":null,"stability":null,"value":"redis"},{"brief":"Couchbase","deprecated":null,"id":"couchbase","note":null,"stability":null,"value":"couchbase"},{"brief":"CouchDB","deprecated":null,"id":"couchdb","note":null,"stability":null,"value":"couchdb"},{"brief":"Microsoft Azure Cosmos DB","deprecated":null,"id":"cosmosdb","note":null,"stability":null,"value":"cosmosdb"},{"brief":"Amazon DynamoDB","deprecated":null,"id":"dynamodb","note":null,"stability":null,"value":"dynamodb"},{"brief":"Neo4j","deprecated":null,"id":"neo4j","note":null,"stability":null,"value":"neo4j"},{"brief":"Apache Geode","deprecated":null,"id":"geode","note":null,"stability":null,"value":"geode"},{"brief":"Elasticsearch","deprecated":null,"id":"elasticsearch","note":null,"stability":null,"value":"elasticsearch"},{"brief":"Memcached","deprecated":null,"id":"memcached","note":null,"stability":null,"value":"memcached"},{"brief":"CockroachDB","deprecated":null,"id":"cockroachdb","note":null,"stability":null,"value":"cockroachdb"},{"brief":"OpenSearch","deprecated":null,"id":"opensearch","note":null,"stability":null,"value":"opensearch"},{"brief":"ClickHouse","deprecated":null,"id":"clickhouse","note":null,"stability":null,"value":"clickhouse"},{"brief":"Cloud Spanner","deprecated":null,"id":"spanner","note":null,"stability":null,"value":"spanner"},{"brief":"Trino","deprecated":null,"id":"trino","note":null,"stability":null,"value":"trino"}]}},{"brief":"Username for accessing the database.\n","examples":["readonly_user","reporting_user"],"name":"db.user","requirement_level":"recommended","root_namespace":"db","tag":"db-generic","type":"string"}],"root_namespace":"db"},{"attributes":[{"brief":"HTTP request headers, `\u003ckey\u003e` being the normalized HTTP Header name (lowercase), the value being the header values.\n","examples":["http.request.header.content-type=[\"application/json\"]","http.request.header.x-forwarded-for=[\"1.2.3.4\", \"1.2.3.5\"]"],"name":"http.request.header","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","requirement_level":"recommended","root_namespace":"http","stability":"stable","type":"template[string[]]"},{"brief":"HTTP request method.","examples":["GET","POST","HEAD"],"name":"http.request.method","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","requirement_level":"recommended","root_namespace":"http","stability":"stable","type":{"allow_custom_values":true,"members":[{"brief":"CONNECT method.","deprecated":null,"id":"connect","note":null,"stability":null,"value":"CONNECT"},{"brief":"DELETE method.","deprecated":null,"id":"delete","note":null,"stability":null,"value":"DELETE"},{"brief":"GET method.","deprecated":null,"id":"get","note":null,"stability":null,"value":"GET"},{"brief":"HEAD method.","deprecated":null,"id":"head","note":null,"stability":null,"value":"HEAD"},{"brief":"OPTIONS method.","deprecated":null,"id":"options","note":null,"stability":null,"value":"OPTIONS"},{"brief":"PATCH method.","deprecated":null,"id":"patch","note":null,"stability":null,"value":"PATCH"},{"brief":"POST method.","deprecated":null,"id":"post","note":null,"stability":null,"value":"POST"},{"brief":"PUT method.","deprecated":null,"id":"put","note":null,"stability":null,"value":"PUT"},{"brief":"TRACE method.","deprecated":null,"id":"trace","note":null,"stability":null,"value":"TRACE"},{"brief":"Any HTTP method that the instrumentation has no prior knowledge of.","deprecated":null,"id":"other","note":null,"stability":null,"value":"_OTHER"}]}},{"brief":"Original HTTP method sent by the client in the request line.","examples":["GeT","ACL","foo"],"name":"http.request.method_original","requirement_level":"recommended","root_namespace":"http","stability":"stable","type":"string"},{"brief":"The ordinal number of request resending attempt (for any reason, including redirects).\n","examples":3,"name":"http.request.resend_count","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","requirement_level":"recommended","root_namespace":"http","stability":"stable","type":"int"},{"brief":"HTTP response headers, `\u003ckey\u003e` being the normalized HTTP Header name (lowercase), the value being the header values.\n","examples":["http.response.header.content-type=[\"application/json\"]","http.response.header.my-custom-header=[\"abc\", \"def\"]"],"name":"http.response.header","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","requirement_level":"recommended","root_namespace":"http","stability":"stable","type":"template[string[]]"},{"brief":"[HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6).","examples":[200],"name":"http.response.status_code","requirement_level":"recommended","root_namespace":"http","stability":"stable","type":"int"},{"brief":"The matched route, that is, the path template in the format used by the respective server framework.\n","examples":["/users/:userID?","{controller}/{action}/{id?}"],"name":"http.route","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.","requirement_level":"recommended","root_namespace":"http","stability":"stable","type":"string"}],"root_namespace":"http"},{"attributes":[{"brief":"The ISO 3166-1 alpha-2 2-character country code associated with the mobile carrier network.","examples":"DE","name":"network.carrier.icc","requirement_level":"recommended","root_namespace":"network","type":"string"},{"brief":"The mobile carrier country code.","examples":"310","name":"network.carrier.mcc","requirement_level":"recommended","root_namespace":"network","type":"string"},{"brief":"The mobile carrier network code.","examples":"001","name":"network.carrier.mnc","requirement_level":"recommended","root_namespace":"network","type":"string"},{"brief":"The name of the mobile carrier.","examples":"sprint","name":"network.carrier.name","requirement_level":"recommended","root_namespace":"network","type":"string"},{"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","name":"network.connection.subtype","requirement_level":"recommended","root_namespace":"network","type":{"allow_custom_values":true,"members":[{"brief":"GPRS","deprecated":null,"id":"gprs","note":null,"stability":null,"value":"gprs"},{"brief":"EDGE","deprecated":null,"id":"edge","note":null,"stability":null,"value":"edge"},{"brief":"UMTS","deprecated":null,"id":"umts","note":null,"stability":null,"value":"umts"},{"brief":"CDMA","deprecated":null,"id":"cdma","note":null,"stability":null,"value":"cdma"},{"brief":"EVDO Rel. 0","deprecated":null,"id":"evdo_0","note":null,"stability":null,"value":"evdo_0"},{"brief":"EVDO Rev. A","deprecated":null,"id":"evdo_a","note":null,"stability":null,"value":"evdo_a"},{"brief":"CDMA2000 1XRTT","deprecated":null,"id":"cdma2000_1xrtt","note":null,"stability":null,"value":"cdma2000_1xrtt"},{"brief":"HSDPA","deprecated":null,"id":"hsdpa","note":null,"stability":null,"value":"hsdpa"},{"brief":"HSUPA","deprecated":null,"id":"hsupa","note":null,"stability":null,"value":"hsupa"},{"brief":"HSPA","deprecated":null,"id":"hspa","note":null,"stability":null,"value":"hspa"},{"brief":"IDEN","deprecated":null,"id":"iden","note":null,"stability":null,"value":"iden"},{"brief":"EVDO Rev. B","deprecated":null,"id":"evdo_b","note":null,"stability":null,"value":"evdo_b"},{"brief":"LTE","deprecated":null,"id":"lte","note":null,"stability":null,"value":"lte"},{"brief":"EHRPD","deprecated":null,"id":"ehrpd","note":null,"stability":null,"value":"ehrpd"},{"brief":"HSPAP","deprecated":null,"id":"hspap","note":null,"stability":null,"value":"hspap"},{"brief":"GSM","deprecated":null,"id":"gsm","note":null,"stability":null,"value":"gsm"},{"brief":"TD-SCDMA","deprecated":null,"id":"td_scdma","note":null,"stability":null,"value":"td_scdma"},{"brief":"IWLAN","deprecated":null,"id":"iwlan","note":null,"stability":null,"value":"iwlan"},{"brief":"5G NR (New Radio)","deprecated":null,"id":"nr","note":null,"stability":null,"value":"nr"},{"brief":"5G NRNSA (New Radio Non-Standalone)","deprecated":null,"id":"nrnsa","note":null,"stability":null,"value":"nrnsa"},{"brief":"LTE CA","deprecated":null,"id":"lte_ca","note":null,"stability":null,"value":"lte_ca"}]}},{"brief":"The internet connection type.","examples":"wifi","name":"network.connection.type","requirement_level":"recommended","root_namespace":"network","type":{"allow_custom_values":true,"members":[{"brief":null,"deprecated":null,"id":"wifi","note":null,"stability":null,"value":"wifi"},{"brief":null,"deprecated":null,"id":"wired","note":null,"stability":null,"value":"wired"},{"brief":null,"deprecated":null,"id":"cell","note":null,"stability":null,"value":"cell"},{"brief":null,"deprecated":null,"id":"unavailable","note":null,"stability":null,"value":"unavailable"},{"brief":null,"deprecated":null,"id":"unknown","note":null,"stability":null,"value":"unknown"}]}},{"brief":"The network IO operation direction.","examples":["transmit"],"name":"network.io.direction","requirement_level":"recommended","root_namespace":"network","type":{"allow_custom_values":false,"members":[{"brief":null,"deprecated":null,"id":"transmit","note":null,"stability":null,"value":"transmit"},{"brief":null,"deprecated":null,"id":"receive","note":null,"stability":null,"value":"receive"}]}},{"brief":"Local address of the network connection - IP address or Unix domain socket name.","examples":["10.1.2.80","/tmp/my.sock"],"name":"network.local.address","requirement_level":"recommended","root_namespace":"network","stability":"stable","type":"string"},{"brief":"Local port number of the network connection.","examples":[65123],"name":"network.local.port","requirement_level":"recommended","root_namespace":"network","stability":"stable","type":"int"},{"brief":"Peer address of the network connection - IP address or Unix domain socket name.","examples":["10.1.2.80","/tmp/my.sock"],"name":"network.peer.address","requirement_level":"recommended","root_namespace":"network","stability":"stable","type":"string"},{"brief":"Peer port number of the network connection.","examples":[65123],"name":"network.peer.port","requirement_level":"recommended","root_namespace":"network","stability":"stable","type":"int"},{"brief":"[OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent.","examples":["amqp","http","mqtt"],"name":"network.protocol.name","note":"The value SHOULD be normalized to lowercase.","requirement_level":"recommended","root_namespace":"network","stability":"stable","type":"string"},{"brief":"Version of the protocol specified in `network.protocol.name`.","examples":"3.1.1","name":"network.protocol.version","note":"`network.protocol.version` refers to the version of the protocol used and might be different from the protocol client\u0027s 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","requirement_level":"recommended","root_namespace":"network","stability":"stable","type":"string"},{"brief":"[OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication).\n","examples":["tcp","udp"],"name":"network.transport","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","requirement_level":"recommended","root_namespace":"network","stability":"stable","type":{"allow_custom_values":true,"members":[{"brief":"TCP","deprecated":null,"id":"tcp","note":null,"stability":null,"value":"tcp"},{"brief":"UDP","deprecated":null,"id":"udp","note":null,"stability":null,"value":"udp"},{"brief":"Named or anonymous pipe.","deprecated":null,"id":"pipe","note":null,"stability":null,"value":"pipe"},{"brief":"Unix domain socket","deprecated":null,"id":"unix","note":null,"stability":null,"value":"unix"}]}},{"brief":"[OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent.","examples":["ipv4","ipv6"],"name":"network.type","note":"The value SHOULD be normalized to lowercase.","requirement_level":"recommended","root_namespace":"network","stability":"stable","type":{"allow_custom_values":true,"members":[{"brief":"IPv4","deprecated":null,"id":"ipv4","note":null,"stability":null,"value":"ipv4"},{"brief":"IPv6","deprecated":null,"id":"ipv6","note":null,"stability":null,"value":"ipv6"}]}}],"root_namespace":"network"},{"attributes":[{"brief":"The [URI fragment](https://www.rfc-editor.org/rfc/rfc3986#section-3.5) component","examples":["SemConv"],"name":"url.fragment","requirement_level":"recommended","root_namespace":"url","stability":"stable","type":"string"},{"brief":"Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986)","examples":["https://www.foo.bar/search?q=OpenTelemetry#SemConv","//localhost"],"name":"url.full","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\u0027s 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","requirement_level":"recommended","root_namespace":"url","stability":"stable","type":"string"},{"brief":"The [URI path](https://www.rfc-editor.org/rfc/rfc3986#section-3.3) component","examples":["/search"],"name":"url.path","requirement_level":"recommended","root_namespace":"url","stability":"stable","type":"string"},{"brief":"The [URI query](https://www.rfc-editor.org/rfc/rfc3986#section-3.4) component","examples":["q=OpenTelemetry"],"name":"url.query","note":"Sensitive content provided in query string SHOULD be scrubbed when instrumentations can identify it.","requirement_level":"recommended","root_namespace":"url","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"],"name":"url.scheme","requirement_level":"recommended","root_namespace":"url","stability":"stable","type":"string"}],"root_namespace":"url"},{"attributes":[{"brief":"Value of the [HTTP User-Agent](https://www.rfc-editor.org/rfc/rfc9110.html#field.user-agent) header sent by the client.\n","examples":["CERN-LineMode/2.15 libwww/2.17b3","Mozilla/5.0 (iPhone; CPU iPhone OS 14_7_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.2 Mobile/15E148 Safari/604.1"],"name":"user_agent.original","requirement_level":"recommended","root_namespace":"user_agent","stability":"stable","type":"string"}],"root_namespace":"user_agent"}] \ No newline at end of file diff --git a/crates/weaver_forge/expected_output/semconv_jq_fn/semconv_metrics.json b/crates/weaver_forge/expected_output/semconv_jq_fn/semconv_metrics.json index db3f0f3b..0ecb7806 100644 --- a/crates/weaver_forge/expected_output/semconv_jq_fn/semconv_metrics.json +++ b/crates/weaver_forge/expected_output/semconv_jq_fn/semconv_metrics.json @@ -1 +1 @@ -[{"metrics":[{"attributes":[{"brief":"The type of memory.","examples":["heap","non_heap"],"name":"jvm.memory.type","requirement_level":"recommended","stability":"stable","type":{"allow_custom_values":false,"members":[{"brief":"Heap memory.","deprecated":null,"id":"heap","note":null,"stability":null,"value":"heap"},{"brief":"Non-heap memory","deprecated":null,"id":"non_heap","note":null,"stability":null,"value":"non_heap"}]}},{"brief":"Name of the memory pool.","examples":["G1 Old Gen","G1 Eden space","G1 Survivor Space"],"name":"jvm.memory.pool.name","note":"Pool names are generally obtained via [MemoryPoolMXBean#getName()](https://docs.oracle.com/en/java/javase/11/docs/api/java.management/java/lang/management/MemoryPoolMXBean.html#getName()).\n","requirement_level":"recommended","stability":"stable","type":"string"}],"brief":"Measure of memory used.","events":[],"id":"metric.jvm.memory.used","instrument":"updowncounter","lineage":{"attributes":{"jvm.memory.pool.name":{"inherited_fields":["brief","examples","note","requirement_level","stability"],"source_group":"attributes.jvm.memory"},"jvm.memory.type":{"inherited_fields":["brief","examples","note","requirement_level","stability"],"source_group":"attributes.jvm.memory"}},"source_file":"data/jvm-metrics.yaml"},"metric_name":"jvm.memory.used","name":null,"namespace":"jvm","span_kind":null,"stability":"stable","type":"metric","unit":"By"},{"attributes":[{"brief":"The type of memory.","examples":["heap","non_heap"],"name":"jvm.memory.type","requirement_level":"recommended","stability":"stable","type":{"allow_custom_values":false,"members":[{"brief":"Heap memory.","deprecated":null,"id":"heap","note":null,"stability":null,"value":"heap"},{"brief":"Non-heap memory","deprecated":null,"id":"non_heap","note":null,"stability":null,"value":"non_heap"}]}},{"brief":"Name of the memory pool.","examples":["G1 Old Gen","G1 Eden space","G1 Survivor Space"],"name":"jvm.memory.pool.name","note":"Pool names are generally obtained via [MemoryPoolMXBean#getName()](https://docs.oracle.com/en/java/javase/11/docs/api/java.management/java/lang/management/MemoryPoolMXBean.html#getName()).\n","requirement_level":"recommended","stability":"stable","type":"string"}],"brief":"Measure of memory committed.","events":[],"id":"metric.jvm.memory.committed","instrument":"updowncounter","lineage":{"attributes":{"jvm.memory.pool.name":{"inherited_fields":["brief","examples","note","requirement_level","stability"],"source_group":"attributes.jvm.memory"},"jvm.memory.type":{"inherited_fields":["brief","examples","note","requirement_level","stability"],"source_group":"attributes.jvm.memory"}},"source_file":"data/jvm-metrics.yaml"},"metric_name":"jvm.memory.committed","name":null,"namespace":"jvm","span_kind":null,"stability":"stable","type":"metric","unit":"By"},{"attributes":[{"brief":"The type of memory.","examples":["heap","non_heap"],"name":"jvm.memory.type","requirement_level":"recommended","stability":"stable","type":{"allow_custom_values":false,"members":[{"brief":"Heap memory.","deprecated":null,"id":"heap","note":null,"stability":null,"value":"heap"},{"brief":"Non-heap memory","deprecated":null,"id":"non_heap","note":null,"stability":null,"value":"non_heap"}]}},{"brief":"Name of the memory pool.","examples":["G1 Old Gen","G1 Eden space","G1 Survivor Space"],"name":"jvm.memory.pool.name","note":"Pool names are generally obtained via [MemoryPoolMXBean#getName()](https://docs.oracle.com/en/java/javase/11/docs/api/java.management/java/lang/management/MemoryPoolMXBean.html#getName()).\n","requirement_level":"recommended","stability":"stable","type":"string"}],"brief":"Measure of max obtainable memory.","events":[],"id":"metric.jvm.memory.limit","instrument":"updowncounter","lineage":{"attributes":{"jvm.memory.pool.name":{"inherited_fields":["brief","examples","note","requirement_level","stability"],"source_group":"attributes.jvm.memory"},"jvm.memory.type":{"inherited_fields":["brief","examples","note","requirement_level","stability"],"source_group":"attributes.jvm.memory"}},"source_file":"data/jvm-metrics.yaml"},"metric_name":"jvm.memory.limit","name":null,"namespace":"jvm","span_kind":null,"stability":"stable","type":"metric","unit":"By"},{"attributes":[{"brief":"The type of memory.","examples":["heap","non_heap"],"name":"jvm.memory.type","requirement_level":"recommended","stability":"stable","type":{"allow_custom_values":false,"members":[{"brief":"Heap memory.","deprecated":null,"id":"heap","note":null,"stability":null,"value":"heap"},{"brief":"Non-heap memory","deprecated":null,"id":"non_heap","note":null,"stability":null,"value":"non_heap"}]}},{"brief":"Name of the memory pool.","examples":["G1 Old Gen","G1 Eden space","G1 Survivor Space"],"name":"jvm.memory.pool.name","note":"Pool names are generally obtained via [MemoryPoolMXBean#getName()](https://docs.oracle.com/en/java/javase/11/docs/api/java.management/java/lang/management/MemoryPoolMXBean.html#getName()).\n","requirement_level":"recommended","stability":"stable","type":"string"}],"brief":"Measure of memory used, as measured after the most recent garbage collection event on this pool.","events":[],"id":"metric.jvm.memory.used_after_last_gc","instrument":"updowncounter","lineage":{"attributes":{"jvm.memory.pool.name":{"inherited_fields":["brief","examples","note","requirement_level","stability"],"source_group":"attributes.jvm.memory"},"jvm.memory.type":{"inherited_fields":["brief","examples","note","requirement_level","stability"],"source_group":"attributes.jvm.memory"}},"source_file":"data/jvm-metrics.yaml"},"metric_name":"jvm.memory.used_after_last_gc","name":null,"namespace":"jvm","span_kind":null,"stability":"stable","type":"metric","unit":"By"},{"attributes":[{"brief":"Name of the garbage collector.","examples":["G1 Young Generation","G1 Old Generation"],"name":"jvm.gc.name","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()).\n","requirement_level":"recommended","stability":"stable","type":"string"},{"brief":"Name of the garbage collector action.","examples":["end of minor GC","end of major GC"],"name":"jvm.gc.action","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()).\n","requirement_level":"recommended","stability":"stable","type":"string"}],"brief":"Duration of JVM garbage collection actions.","events":[],"id":"metric.jvm.gc.duration","instrument":"histogram","lineage":{"source_file":"data/jvm-metrics.yaml"},"metric_name":"jvm.gc.duration","name":null,"namespace":"jvm","prefix":"jvm.gc","span_kind":null,"stability":"stable","type":"metric","unit":"s"},{"attributes":[{"brief":"Whether the thread is daemon or not.","name":"jvm.thread.daemon","requirement_level":"recommended","stability":"stable","type":"boolean"},{"brief":"State of the thread.","examples":["runnable","blocked"],"name":"jvm.thread.state","requirement_level":"recommended","stability":"stable","type":{"allow_custom_values":false,"members":[{"brief":"A thread that has not yet started is in this state.","deprecated":null,"id":"new","note":null,"stability":null,"value":"new"},{"brief":"A thread executing in the Java virtual machine is in this state.","deprecated":null,"id":"runnable","note":null,"stability":null,"value":"runnable"},{"brief":"A thread that is blocked waiting for a monitor lock is in this state.","deprecated":null,"id":"blocked","note":null,"stability":null,"value":"blocked"},{"brief":"A thread that is waiting indefinitely for another thread to perform a particular action is in this state.","deprecated":null,"id":"waiting","note":null,"stability":null,"value":"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.","deprecated":null,"id":"timed_waiting","note":null,"stability":null,"value":"timed_waiting"},{"brief":"A thread that has exited is in this state.","deprecated":null,"id":"terminated","note":null,"stability":null,"value":"terminated"}]}}],"brief":"Number of executing platform threads.","events":[],"id":"metric.jvm.thread.count","instrument":"updowncounter","lineage":{"source_file":"data/jvm-metrics.yaml"},"metric_name":"jvm.thread.count","name":null,"namespace":"jvm","span_kind":null,"stability":"stable","type":"metric","unit":"{thread}"},{"attributes":[],"brief":"Number of classes loaded since JVM start.","events":[],"id":"metric.jvm.class.loaded","instrument":"counter","lineage":{"source_file":"data/jvm-metrics.yaml"},"metric_name":"jvm.class.loaded","name":null,"namespace":"jvm","span_kind":null,"stability":"stable","type":"metric","unit":"{class}"},{"attributes":[],"brief":"Number of classes unloaded since JVM start.","events":[],"id":"metric.jvm.class.unloaded","instrument":"counter","lineage":{"source_file":"data/jvm-metrics.yaml"},"metric_name":"jvm.class.unloaded","name":null,"namespace":"jvm","span_kind":null,"stability":"stable","type":"metric","unit":"{class}"},{"attributes":[],"brief":"Number of classes currently loaded.","events":[],"id":"metric.jvm.class.count","instrument":"updowncounter","lineage":{"source_file":"data/jvm-metrics.yaml"},"metric_name":"jvm.class.count","name":null,"namespace":"jvm","span_kind":null,"stability":"stable","type":"metric","unit":"{class}"},{"attributes":[],"brief":"Number of processors available to the Java virtual machine.","events":[],"id":"metric.jvm.cpu.count","instrument":"updowncounter","lineage":{"source_file":"data/jvm-metrics.yaml"},"metric_name":"jvm.cpu.count","name":null,"namespace":"jvm","span_kind":null,"stability":"stable","type":"metric","unit":"{cpu}"},{"attributes":[],"brief":"CPU time used by the process as reported by the JVM.","events":[],"id":"metric.jvm.cpu.time","instrument":"counter","lineage":{"source_file":"data/jvm-metrics.yaml"},"metric_name":"jvm.cpu.time","name":null,"namespace":"jvm","span_kind":null,"stability":"stable","type":"metric","unit":"s"},{"attributes":[],"brief":"Recent CPU utilization for the process as reported by the JVM.","events":[],"id":"metric.jvm.cpu.recent_utilization","instrument":"gauge","lineage":{"source_file":"data/jvm-metrics.yaml"},"metric_name":"jvm.cpu.recent_utilization","name":null,"namespace":"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()).\n","span_kind":null,"stability":"stable","type":"metric","unit":"1"}],"namespace":"jvm"}] \ No newline at end of file +[{"metrics":[{"attributes":[{"brief":"The type of memory.","examples":["heap","non_heap"],"name":"jvm.memory.type","requirement_level":"recommended","stability":"stable","type":{"allow_custom_values":false,"members":[{"brief":"Heap memory.","deprecated":null,"id":"heap","note":null,"stability":null,"value":"heap"},{"brief":"Non-heap memory","deprecated":null,"id":"non_heap","note":null,"stability":null,"value":"non_heap"}]}},{"brief":"Name of the memory pool.","examples":["G1 Old Gen","G1 Eden space","G1 Survivor Space"],"name":"jvm.memory.pool.name","note":"Pool names are generally obtained via [MemoryPoolMXBean#getName()](https://docs.oracle.com/en/java/javase/11/docs/api/java.management/java/lang/management/MemoryPoolMXBean.html#getName()).\n","requirement_level":"recommended","stability":"stable","type":"string"}],"brief":"Measure of memory used.","events":[],"id":"metric.jvm.memory.used","instrument":"updowncounter","lineage":{"attributes":{"jvm.memory.pool.name":{"inherited_fields":["brief","examples","note","requirement_level","stability"],"source_group":"attributes.jvm.memory"},"jvm.memory.type":{"inherited_fields":["brief","examples","note","requirement_level","stability"],"source_group":"attributes.jvm.memory"}},"source_file":"data/jvm-metrics.yaml"},"metric_name":"jvm.memory.used","name":null,"root_namespace":"jvm","span_kind":null,"stability":"stable","type":"metric","unit":"By"},{"attributes":[{"brief":"The type of memory.","examples":["heap","non_heap"],"name":"jvm.memory.type","requirement_level":"recommended","stability":"stable","type":{"allow_custom_values":false,"members":[{"brief":"Heap memory.","deprecated":null,"id":"heap","note":null,"stability":null,"value":"heap"},{"brief":"Non-heap memory","deprecated":null,"id":"non_heap","note":null,"stability":null,"value":"non_heap"}]}},{"brief":"Name of the memory pool.","examples":["G1 Old Gen","G1 Eden space","G1 Survivor Space"],"name":"jvm.memory.pool.name","note":"Pool names are generally obtained via [MemoryPoolMXBean#getName()](https://docs.oracle.com/en/java/javase/11/docs/api/java.management/java/lang/management/MemoryPoolMXBean.html#getName()).\n","requirement_level":"recommended","stability":"stable","type":"string"}],"brief":"Measure of memory committed.","events":[],"id":"metric.jvm.memory.committed","instrument":"updowncounter","lineage":{"attributes":{"jvm.memory.pool.name":{"inherited_fields":["brief","examples","note","requirement_level","stability"],"source_group":"attributes.jvm.memory"},"jvm.memory.type":{"inherited_fields":["brief","examples","note","requirement_level","stability"],"source_group":"attributes.jvm.memory"}},"source_file":"data/jvm-metrics.yaml"},"metric_name":"jvm.memory.committed","name":null,"root_namespace":"jvm","span_kind":null,"stability":"stable","type":"metric","unit":"By"},{"attributes":[{"brief":"The type of memory.","examples":["heap","non_heap"],"name":"jvm.memory.type","requirement_level":"recommended","stability":"stable","type":{"allow_custom_values":false,"members":[{"brief":"Heap memory.","deprecated":null,"id":"heap","note":null,"stability":null,"value":"heap"},{"brief":"Non-heap memory","deprecated":null,"id":"non_heap","note":null,"stability":null,"value":"non_heap"}]}},{"brief":"Name of the memory pool.","examples":["G1 Old Gen","G1 Eden space","G1 Survivor Space"],"name":"jvm.memory.pool.name","note":"Pool names are generally obtained via [MemoryPoolMXBean#getName()](https://docs.oracle.com/en/java/javase/11/docs/api/java.management/java/lang/management/MemoryPoolMXBean.html#getName()).\n","requirement_level":"recommended","stability":"stable","type":"string"}],"brief":"Measure of max obtainable memory.","events":[],"id":"metric.jvm.memory.limit","instrument":"updowncounter","lineage":{"attributes":{"jvm.memory.pool.name":{"inherited_fields":["brief","examples","note","requirement_level","stability"],"source_group":"attributes.jvm.memory"},"jvm.memory.type":{"inherited_fields":["brief","examples","note","requirement_level","stability"],"source_group":"attributes.jvm.memory"}},"source_file":"data/jvm-metrics.yaml"},"metric_name":"jvm.memory.limit","name":null,"root_namespace":"jvm","span_kind":null,"stability":"stable","type":"metric","unit":"By"},{"attributes":[{"brief":"The type of memory.","examples":["heap","non_heap"],"name":"jvm.memory.type","requirement_level":"recommended","stability":"stable","type":{"allow_custom_values":false,"members":[{"brief":"Heap memory.","deprecated":null,"id":"heap","note":null,"stability":null,"value":"heap"},{"brief":"Non-heap memory","deprecated":null,"id":"non_heap","note":null,"stability":null,"value":"non_heap"}]}},{"brief":"Name of the memory pool.","examples":["G1 Old Gen","G1 Eden space","G1 Survivor Space"],"name":"jvm.memory.pool.name","note":"Pool names are generally obtained via [MemoryPoolMXBean#getName()](https://docs.oracle.com/en/java/javase/11/docs/api/java.management/java/lang/management/MemoryPoolMXBean.html#getName()).\n","requirement_level":"recommended","stability":"stable","type":"string"}],"brief":"Measure of memory used, as measured after the most recent garbage collection event on this pool.","events":[],"id":"metric.jvm.memory.used_after_last_gc","instrument":"updowncounter","lineage":{"attributes":{"jvm.memory.pool.name":{"inherited_fields":["brief","examples","note","requirement_level","stability"],"source_group":"attributes.jvm.memory"},"jvm.memory.type":{"inherited_fields":["brief","examples","note","requirement_level","stability"],"source_group":"attributes.jvm.memory"}},"source_file":"data/jvm-metrics.yaml"},"metric_name":"jvm.memory.used_after_last_gc","name":null,"root_namespace":"jvm","span_kind":null,"stability":"stable","type":"metric","unit":"By"},{"attributes":[{"brief":"Name of the garbage collector.","examples":["G1 Young Generation","G1 Old Generation"],"name":"jvm.gc.name","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()).\n","requirement_level":"recommended","stability":"stable","type":"string"},{"brief":"Name of the garbage collector action.","examples":["end of minor GC","end of major GC"],"name":"jvm.gc.action","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()).\n","requirement_level":"recommended","stability":"stable","type":"string"}],"brief":"Duration of JVM garbage collection actions.","events":[],"id":"metric.jvm.gc.duration","instrument":"histogram","lineage":{"source_file":"data/jvm-metrics.yaml"},"metric_name":"jvm.gc.duration","name":null,"prefix":"jvm.gc","root_namespace":"jvm","span_kind":null,"stability":"stable","type":"metric","unit":"s"},{"attributes":[{"brief":"Whether the thread is daemon or not.","name":"jvm.thread.daemon","requirement_level":"recommended","stability":"stable","type":"boolean"},{"brief":"State of the thread.","examples":["runnable","blocked"],"name":"jvm.thread.state","requirement_level":"recommended","stability":"stable","type":{"allow_custom_values":false,"members":[{"brief":"A thread that has not yet started is in this state.","deprecated":null,"id":"new","note":null,"stability":null,"value":"new"},{"brief":"A thread executing in the Java virtual machine is in this state.","deprecated":null,"id":"runnable","note":null,"stability":null,"value":"runnable"},{"brief":"A thread that is blocked waiting for a monitor lock is in this state.","deprecated":null,"id":"blocked","note":null,"stability":null,"value":"blocked"},{"brief":"A thread that is waiting indefinitely for another thread to perform a particular action is in this state.","deprecated":null,"id":"waiting","note":null,"stability":null,"value":"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.","deprecated":null,"id":"timed_waiting","note":null,"stability":null,"value":"timed_waiting"},{"brief":"A thread that has exited is in this state.","deprecated":null,"id":"terminated","note":null,"stability":null,"value":"terminated"}]}}],"brief":"Number of executing platform threads.","events":[],"id":"metric.jvm.thread.count","instrument":"updowncounter","lineage":{"source_file":"data/jvm-metrics.yaml"},"metric_name":"jvm.thread.count","name":null,"root_namespace":"jvm","span_kind":null,"stability":"stable","type":"metric","unit":"{thread}"},{"attributes":[],"brief":"Number of classes loaded since JVM start.","events":[],"id":"metric.jvm.class.loaded","instrument":"counter","lineage":{"source_file":"data/jvm-metrics.yaml"},"metric_name":"jvm.class.loaded","name":null,"root_namespace":"jvm","span_kind":null,"stability":"stable","type":"metric","unit":"{class}"},{"attributes":[],"brief":"Number of classes unloaded since JVM start.","events":[],"id":"metric.jvm.class.unloaded","instrument":"counter","lineage":{"source_file":"data/jvm-metrics.yaml"},"metric_name":"jvm.class.unloaded","name":null,"root_namespace":"jvm","span_kind":null,"stability":"stable","type":"metric","unit":"{class}"},{"attributes":[],"brief":"Number of classes currently loaded.","events":[],"id":"metric.jvm.class.count","instrument":"updowncounter","lineage":{"source_file":"data/jvm-metrics.yaml"},"metric_name":"jvm.class.count","name":null,"root_namespace":"jvm","span_kind":null,"stability":"stable","type":"metric","unit":"{class}"},{"attributes":[],"brief":"Number of processors available to the Java virtual machine.","events":[],"id":"metric.jvm.cpu.count","instrument":"updowncounter","lineage":{"source_file":"data/jvm-metrics.yaml"},"metric_name":"jvm.cpu.count","name":null,"root_namespace":"jvm","span_kind":null,"stability":"stable","type":"metric","unit":"{cpu}"},{"attributes":[],"brief":"CPU time used by the process as reported by the JVM.","events":[],"id":"metric.jvm.cpu.time","instrument":"counter","lineage":{"source_file":"data/jvm-metrics.yaml"},"metric_name":"jvm.cpu.time","name":null,"root_namespace":"jvm","span_kind":null,"stability":"stable","type":"metric","unit":"s"},{"attributes":[],"brief":"Recent CPU utilization for the process as reported by the JVM.","events":[],"id":"metric.jvm.cpu.recent_utilization","instrument":"gauge","lineage":{"source_file":"data/jvm-metrics.yaml"},"metric_name":"jvm.cpu.recent_utilization","name":null,"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()).\n","root_namespace":"jvm","span_kind":null,"stability":"stable","type":"metric","unit":"1"}],"root_namespace":"jvm"}] \ No newline at end of file diff --git a/crates/weaver_forge/images/artifact-generation-pipeline.svg b/crates/weaver_forge/images/artifact-generation-pipeline.svg index 429f8462..07ce9728 100644 --- a/crates/weaver_forge/images/artifact-generation-pipeline.svg +++ b/crates/weaver_forge/images/artifact-generation-pipeline.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/crates/weaver_forge/templates/test/attribute_group.md b/crates/weaver_forge/templates/test/attribute_group.md index f96f527d..1be6bcc3 100644 --- a/crates/weaver_forge/templates/test/attribute_group.md +++ b/crates/weaver_forge/templates/test/attribute_group.md @@ -1,7 +1,7 @@ -{%- set file_name = ctx.namespace | snake_case -%} +{%- set file_name = ctx.root_namespace | snake_case -%} {{- template.set_file_name("attribute_group/" ~ file_name ~ ".md") -}} -## Namespace `{{ ctx.namespace }}` +## Namespace `{{ ctx.root_namespace }}` ### Attributes diff --git a/crates/weaver_forge/templates/test/attribute_groups.md b/crates/weaver_forge/templates/test/attribute_groups.md index f2d04dad..a5f31c46 100644 --- a/crates/weaver_forge/templates/test/attribute_groups.md +++ b/crates/weaver_forge/templates/test/attribute_groups.md @@ -7,7 +7,7 @@ {%- endfor -%} {% for grouped_attributes in ctx %} -## Namespace `{{ grouped_attributes.namespace }}` +## Namespace `{{ grouped_attributes.root_namespace }}` ### Attributes diff --git a/crates/weaver_forge/templates/test/event.md b/crates/weaver_forge/templates/test/event.md index 17ef1ee8..b15e5680 100644 --- a/crates/weaver_forge/templates/test/event.md +++ b/crates/weaver_forge/templates/test/event.md @@ -1,7 +1,7 @@ -{%- set file_name = ctx.namespace | snake_case -%} +{%- set file_name = ctx.root_namespace | snake_case -%} {{- template.set_file_name("event/" ~ file_name ~ ".md") -}} -## Events Namespace `{{ ctx.namespace }}` +## Events Namespace `{{ ctx.root_namespace }}` {% for event in ctx.events %} ## Event `{{ event.name }}` diff --git a/crates/weaver_forge/templates/test/events.md b/crates/weaver_forge/templates/test/events.md index a4fe860b..d8bba381 100644 --- a/crates/weaver_forge/templates/test/events.md +++ b/crates/weaver_forge/templates/test/events.md @@ -1,5 +1,5 @@ {% for grouped_events in ctx %} -# Events Namespace `{{ grouped_events.namespace }}` +# Events Namespace `{{ grouped_events.root_namespace }}` {% for event in grouped_events.events %} ## Event `{{ event.name }}` diff --git a/crates/weaver_forge/templates/test/metric.md b/crates/weaver_forge/templates/test/metric.md index bcabf034..c89fde7d 100644 --- a/crates/weaver_forge/templates/test/metric.md +++ b/crates/weaver_forge/templates/test/metric.md @@ -1,7 +1,7 @@ -{%- set file_name = ctx.namespace | snake_case -%} +{%- set file_name = ctx.root_namespace | snake_case -%} {{- template.set_file_name("metric/" ~ file_name ~ ".md") -}} -## Metrics Namespace `{{ ctx.namespace }}` +## Metrics Namespace `{{ ctx.root_namespace }}` {% for metric in ctx.metrics %} ## Metric `{{ metric.metric_name }}` diff --git a/crates/weaver_forge/templates/test/metrics.md b/crates/weaver_forge/templates/test/metrics.md index 40feb4c1..bea6f675 100644 --- a/crates/weaver_forge/templates/test/metrics.md +++ b/crates/weaver_forge/templates/test/metrics.md @@ -1,5 +1,5 @@ {% for grouped_metrics in ctx %} -# Metric Namespace `{{ grouped_metrics.namespace }}` +# Metric Namespace `{{ grouped_metrics.root_namespace }}` {% for metric in grouped_metrics.metrics %} ## Metric `{{ metric.metric_name }}` diff --git a/crates/weaver_forge/templates/test/resource.md b/crates/weaver_forge/templates/test/resource.md index 217d387f..de165458 100644 --- a/crates/weaver_forge/templates/test/resource.md +++ b/crates/weaver_forge/templates/test/resource.md @@ -1,7 +1,7 @@ -{%- set file_name = ctx.namespace | snake_case -%} +{%- set file_name = ctx.root_namespace | snake_case -%} {{- template.set_file_name("resource/" ~ file_name ~ ".md") -}} -## Namespace Resource `{{ ctx.namespace }}` +## Namespace Resource `{{ ctx.root_namespace }}` {% for resource in ctx.resources %} diff --git a/crates/weaver_forge/templates/test/resources.md b/crates/weaver_forge/templates/test/resources.md index a2bd9b71..483f5b4f 100644 --- a/crates/weaver_forge/templates/test/resources.md +++ b/crates/weaver_forge/templates/test/resources.md @@ -1,7 +1,7 @@ # Semantic Convention Resource Groups {% for grouped_resources in ctx %} -## Namespace Resource `{{ grouped_resources.namespace }}` +## Namespace Resource `{{ grouped_resources.root_namespace }}` {% for resource in grouped_resources.resources %} diff --git a/crates/weaver_forge/templates/test/span.md b/crates/weaver_forge/templates/test/span.md index f870d87e..ac667659 100644 --- a/crates/weaver_forge/templates/test/span.md +++ b/crates/weaver_forge/templates/test/span.md @@ -1,7 +1,7 @@ -{%- set file_name = ctx.namespace | snake_case -%} +{%- set file_name = ctx.root_namespace | snake_case -%} {{- template.set_file_name("span/" ~ file_name ~ ".md") -}} -## Namespace Span `{{ ctx.namespace }}` +## Namespace Span `{{ ctx.root_namespace }}` {% for span in ctx.spans %} ## Span `{{ span.id }}` diff --git a/crates/weaver_forge/templates/test/spans.md b/crates/weaver_forge/templates/test/spans.md index 8a54d485..8d8a685e 100644 --- a/crates/weaver_forge/templates/test/spans.md +++ b/crates/weaver_forge/templates/test/spans.md @@ -1,7 +1,7 @@ # Semantic Convention Span Groups {% for grouped_spans in ctx %} -## Namespace Spans `{{ grouped_spans.namespace }}` +## Namespace Spans `{{ grouped_spans.root_namespace }}` {% for span in grouped_spans.spans %} ## Span `{{ span.id }}` diff --git a/crates/weaver_forge/templates/test/weaver.yaml b/crates/weaver_forge/templates/test/weaver.yaml index 0b8bd626..a4f9446a 100644 --- a/crates/weaver_forge/templates/test/weaver.yaml +++ b/crates/weaver_forge/templates/test/weaver.yaml @@ -27,10 +27,10 @@ templates: filter: semconv_grouped_attributes application_mode: single - pattern: "**/event.md" - filter: semconv_grouped_events + filter: semconv_signal("event"; {}) | semconv_group_signals_by_root_namespace("events") application_mode: each - pattern: "**/events.md" - filter: semconv_grouped_events + filter: semconv_signal("event"; {}) | semconv_group_signals_by_root_namespace("events") application_mode: single - pattern: "**/metric.md" filter: semconv_grouped_metrics @@ -39,14 +39,14 @@ templates: filter: semconv_grouped_metrics application_mode: single - pattern: "**/resource.md" - filter: semconv_grouped_resources + filter: semconv_signal("resource"; {}) | semconv_group_signals_by_root_namespace("resources") application_mode: each - pattern: "**/resources.md" - filter: semconv_grouped_resources + filter: semconv_signal("resource"; {}) | semconv_group_signals_by_root_namespace("resources") application_mode: single - pattern: "**/span.md" - filter: semconv_grouped_spans + filter: semconv_signal("span"; {}) | semconv_group_signals_by_root_namespace("spans") application_mode: each - pattern: "**/spans.md" - filter: semconv_grouped_spans + filter: semconv_signal("span"; {}) | semconv_group_signals_by_root_namespace("spans") application_mode: single \ No newline at end of file diff --git a/crates/weaver_resolved_schema/Cargo.toml b/crates/weaver_resolved_schema/Cargo.toml index 3922bda5..db0f83dd 100644 --- a/crates/weaver_resolved_schema/Cargo.toml +++ b/crates/weaver_resolved_schema/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "weaver_resolved_schema" -version = "0.6.0" +version = "0.7.0" authors.workspace = true repository.workspace = true license.workspace = true diff --git a/crates/weaver_resolver/Cargo.toml b/crates/weaver_resolver/Cargo.toml index 294a0fd0..bcddb218 100644 --- a/crates/weaver_resolver/Cargo.toml +++ b/crates/weaver_resolver/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "weaver_resolver" -version = "0.6.0" +version = "0.7.0" authors.workspace = true repository.workspace = true license.workspace = true diff --git a/crates/weaver_semconv/Cargo.toml b/crates/weaver_semconv/Cargo.toml index efa0c027..f772f82a 100644 --- a/crates/weaver_semconv/Cargo.toml +++ b/crates/weaver_semconv/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "weaver_semconv" -version = "0.6.0" +version = "0.7.0" authors.workspace = true repository.workspace = true license.workspace = true diff --git a/crates/weaver_semconv_gen/Cargo.toml b/crates/weaver_semconv_gen/Cargo.toml index 6126acf6..88a944e9 100644 --- a/crates/weaver_semconv_gen/Cargo.toml +++ b/crates/weaver_semconv_gen/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "weaver_semconv_gen" -version = "0.6.0" +version = "0.7.0" authors.workspace = true repository.workspace = true license.workspace = true diff --git a/crates/weaver_version/Cargo.toml b/crates/weaver_version/Cargo.toml index f4ce0789..ca6107ca 100644 --- a/crates/weaver_version/Cargo.toml +++ b/crates/weaver_version/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "weaver_version" -version = "0.6.0" +version = "0.7.0" authors.workspace = true repository.workspace = true license.workspace = true diff --git a/defaults/jq/semconv.jq b/defaults/jq/semconv.jq index a6b20905..c4c15716 100644 --- a/defaults/jq/semconv.jq +++ b/defaults/jq/semconv.jq @@ -1,10 +1,17 @@ -def semconv_group_attributes_by_namespace: - group_by(.namespace) - | map({ namespace: .[0].namespace, attributes: . | sort_by(.name) }); +# Groups the attributes by their root namespace and sorts them by name. +def semconv_group_attributes_by_root_namespace: + group_by(.root_namespace) + | map({ root_namespace: .[0].root_namespace, attributes: . | sort_by(.name) }); ##################### # Attribute functions ##################### + +# Extracts and processes semantic convention attributes based on provided options. +# $options is an object that can contain: +# - exclude_stability: a list of stability statuses to exclude. +# - exclude_deprecated: a boolean to exclude deprecated attributes. +# - exclude_root_namespace: a list of root namespaces to exclude. def semconv_attributes($options): .groups | map(select(.type == "attribute_group" and (.id | startswith("registry.")))) @@ -19,27 +26,44 @@ def semconv_attributes($options): else . end - | map(. + {namespace: (if .name | index(".") then .name | split(".")[0] else "other" end)}) - | if ($options | has("exclude_namespace")) then - map(select(.namespace as $st | $options.exclude_namespace | index($st) | not)) + | map(. + {root_namespace: (if .name | index(".") then .name | split(".")[0] else "other" end)}) + | if ($options | has("exclude_root_namespace")) then + map(select(.root_namespace as $st | $options.exclude_root_namespace | index($st) | not)) else . end - | sort_by(.namespace, .name); + | sort_by(.root_namespace, .name); +# Convenience function to extract all attributes without any filtering options. def semconv_attributes: semconv_attributes({}); +# Groups the processed attributes by their root namespace based on provided options. +# $options is an object that can contain: +# - exclude_stability: a list of stability statuses to exclude. +# - exclude_deprecated: a boolean to exclude deprecated attributes. +# - exclude_root_namespace: a list of root namespaces to exclude. def semconv_grouped_attributes($options): semconv_attributes($options) - | semconv_group_attributes_by_namespace; + | semconv_group_attributes_by_root_namespace; +# Convenience function to group all attributes by their root namespace without +# any filtering options. def semconv_grouped_attributes: semconv_grouped_attributes({}); # Generic Signal Functions -def semconv_group_signals_by_namespace($signal): - group_by(.namespace) - | map({ namespace: .[0].namespace, ($signal): . | sort_by(.name) }); +# Groups the signals by their root namespace and sorts them by name. +# $signal is the type of signal to group. +def semconv_group_signals_by_root_namespace($signal): + group_by(.root_namespace) + | map({ root_namespace: .[0].root_namespace, ($signal): . | sort_by(.name) }); + +# Extracts and processes semantic convention signals based on provided options. +# $signal is the type of signal to process. +# $options is an object that can contain: +# - exclude_stability: a list of stability statuses to exclude. +# - exclude_deprecated: a boolean to exclude deprecated signals. +# - exclude_root_namespace: a list of root namespaces to exclude. def semconv_signal($signal; $options): .groups | map(select(.type == $signal)) @@ -53,50 +77,34 @@ def semconv_signal($signal; $options): else . end - | map(. + {namespace: (if .id | index(".") then .id | split(".") | .[1] else "other" end)}) - | if ($options | has("exclude_namespace")) then - map(select(.namespace as $st | $options.exclude_namespace | index($st) | not)) + | map(. + {root_namespace: (if .id | index(".") then .id | split(".") | .[1] else "other" end)}) + | if ($options | has("exclude_root_namespace")) then + map(select(.root_namespace as $st | $options.exclude_root_namespace | index($st) | not)) else . end - | sort_by(.namespace); + | sort_by(.root_namespace); # Metric Functions -def semconv_group_metrics_by_namespace: semconv_group_signals_by_namespace("metrics"); +# Groups the metrics by their root namespace. +def semconv_group_metrics_by_root_namespace: semconv_group_signals_by_root_namespace("metrics"); + +# Extracts and processes semantic convention metrics based on provided options. +# $options is an object that can contain: +# - exclude_stability: a list of stability statuses to exclude. +# - exclude_deprecated: a boolean to exclude deprecated metrics. +# - exclude_root_namespace: a list of root namespaces to exclude. def semconv_metrics($options): semconv_signal("metric"; $options); -def semconv_metrics: semconv_metrics({}); - -def semconv_grouped_metrics($options): semconv_metrics($options) | semconv_group_metrics_by_namespace; -def semconv_grouped_metrics: semconv_grouped_metrics({}); - -# Resource functions -def semconv_group_resources_by_namespace: semconv_group_signals_by_namespace("resources"); -def semconv_resources($options): semconv_signal("resource"; $options); -def semconv_resources: semconv_resources({}); - -def semconv_grouped_resources($options): semconv_resources($options) | semconv_group_resources_by_namespace; -def semconv_grouped_resources: semconv_grouped_resources({}); -# Scope functions -def semconv_group_scopes_by_namespace: semconv_group_signals_by_namespace("scopes"); -def semconv_scopes($options): semconv_signal("scope"; $options); -def semconv_scopes: semconv_scopes({}); - -def semconv_grouped_scopes($options): semconv_scopes($options) | semconv_group_scopes_by_namespace; -def semconv_grouped_scopes: semconv_grouped_scopes({}); - -# Span functions -def semconv_group_spans_by_namespace: semconv_group_signals_by_namespace("spans"); -def semconv_spans($options): semconv_signal("span"; $options); -def semconv_spans: semconv_spans({}); - -def semconv_grouped_spans($options): semconv_spans($options) | semconv_group_spans_by_namespace; -def semconv_grouped_spans: semconv_grouped_spans({}); +# Convenience function to extract all metrics without any filtering options. +def semconv_metrics: semconv_metrics({}); -# Event functions -def semconv_group_events_by_namespace: semconv_group_signals_by_namespace("events"); -def semconv_events($options): semconv_signal("event"; $options); -def semconv_events: semconv_events({}); +# Groups the processed metrics by their root namespace based on provided options. +# $options is an object that can contain: +# - exclude_stability: a list of stability statuses to exclude. +# - exclude_deprecated: a boolean to exclude deprecated metrics. +# - exclude_root_namespace: a list of root namespaces to exclude. +def semconv_grouped_metrics($options): semconv_metrics($options) | semconv_group_metrics_by_root_namespace; -def semconv_grouped_events($options): semconv_events($options) | semconv_group_events_by_namespace; -def semconv_grouped_events: semconv_grouped_events({}); +# Convenience function to group all metrics by their root namespace without any filtering options. +def semconv_grouped_metrics: semconv_grouped_metrics({}); From b8172b1de4faa76c676274546c0fc4ee53549711 Mon Sep 17 00:00:00 2001 From: Laurent Querel Date: Mon, 22 Jul 2024 14:11:40 -0700 Subject: [PATCH 29/29] feat(forge): Fix renaming issue --- .../semconv_grouped_attributes_without_experimental.json | 2 +- crates/weaver_forge/templates/semconv_jq_fn/weaver.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/weaver_forge/expected_output/semconv_jq_fn/semconv_grouped_attributes_without_experimental.json b/crates/weaver_forge/expected_output/semconv_jq_fn/semconv_grouped_attributes_without_experimental.json index 24649758..83d7e2ed 100644 --- a/crates/weaver_forge/expected_output/semconv_jq_fn/semconv_grouped_attributes_without_experimental.json +++ b/crates/weaver_forge/expected_output/semconv_jq_fn/semconv_grouped_attributes_without_experimental.json @@ -1 +1 @@ -[{"attributes":[{"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","name":"db.cassandra.consistency_level","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-cassandra","type":{"allow_custom_values":true,"members":[{"brief":null,"deprecated":null,"id":"all","note":null,"stability":null,"value":"all"},{"brief":null,"deprecated":null,"id":"each_quorum","note":null,"stability":null,"value":"each_quorum"},{"brief":null,"deprecated":null,"id":"quorum","note":null,"stability":null,"value":"quorum"},{"brief":null,"deprecated":null,"id":"local_quorum","note":null,"stability":null,"value":"local_quorum"},{"brief":null,"deprecated":null,"id":"one","note":null,"stability":null,"value":"one"},{"brief":null,"deprecated":null,"id":"two","note":null,"stability":null,"value":"two"},{"brief":null,"deprecated":null,"id":"three","note":null,"stability":null,"value":"three"},{"brief":null,"deprecated":null,"id":"local_one","note":null,"stability":null,"value":"local_one"},{"brief":null,"deprecated":null,"id":"any","note":null,"stability":null,"value":"any"},{"brief":null,"deprecated":null,"id":"serial","note":null,"stability":null,"value":"serial"},{"brief":null,"deprecated":null,"id":"local_serial","note":null,"stability":null,"value":"local_serial"}]}},{"brief":"The data center of the coordinating node for a query.\n","examples":"us-west-2","name":"db.cassandra.coordinator.dc","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-cassandra","type":"string"},{"brief":"The ID of the coordinating node for a query.\n","examples":"be13faa2-8574-4d71-926d-27f16cf8a7af","name":"db.cassandra.coordinator.id","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-cassandra","type":"string"},{"brief":"Whether or not the query is idempotent.\n","name":"db.cassandra.idempotence","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-cassandra","type":"boolean"},{"brief":"The fetch size used for paging, i.e. how many rows will be returned at once.\n","examples":[5000],"name":"db.cassandra.page_size","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-cassandra","type":"int"},{"brief":"The number of times a query was speculatively executed. Not set or `0` if the query was not executed speculatively.\n","examples":[0,2],"name":"db.cassandra.speculative_execution_count","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-cassandra","type":"int"},{"brief":"The name of the primary Cassandra table that the operation is acting upon, including the keyspace name (if applicable).","examples":"mytable","name":"db.cassandra.table","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","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-cassandra","type":"string"},{"brief":"The connection string used to connect to the database. It is recommended to remove embedded credentials.\n","examples":"Server=(localdb)\\v11.0;Integrated Security=true;","name":"db.connection_string","requirement_level":"recommended","root_namespace":"db","tag":"db-generic","type":"string"},{"brief":"Unique Cosmos client instance id.","examples":"3ba4827d-4422-483f-b59f-85b74211c11d","name":"db.cosmosdb.client_id","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-cosmosdb","type":"string"},{"brief":"Cosmos client connection mode.","name":"db.cosmosdb.connection_mode","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-cosmosdb","type":{"allow_custom_values":false,"members":[{"brief":"Gateway (HTTP) connections mode","deprecated":null,"id":"gateway","note":null,"stability":null,"value":"gateway"},{"brief":"Direct connection.","deprecated":null,"id":"direct","note":null,"stability":null,"value":"direct"}]}},{"brief":"Cosmos DB container name.","examples":"anystring","name":"db.cosmosdb.container","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-cosmosdb","type":"string"},{"brief":"CosmosDB Operation Type.","name":"db.cosmosdb.operation_type","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-cosmosdb","type":{"allow_custom_values":true,"members":[{"brief":null,"deprecated":null,"id":"invalid","note":null,"stability":null,"value":"Invalid"},{"brief":null,"deprecated":null,"id":"create","note":null,"stability":null,"value":"Create"},{"brief":null,"deprecated":null,"id":"patch","note":null,"stability":null,"value":"Patch"},{"brief":null,"deprecated":null,"id":"read","note":null,"stability":null,"value":"Read"},{"brief":null,"deprecated":null,"id":"read_feed","note":null,"stability":null,"value":"ReadFeed"},{"brief":null,"deprecated":null,"id":"delete","note":null,"stability":null,"value":"Delete"},{"brief":null,"deprecated":null,"id":"replace","note":null,"stability":null,"value":"Replace"},{"brief":null,"deprecated":null,"id":"execute","note":null,"stability":null,"value":"Execute"},{"brief":null,"deprecated":null,"id":"query","note":null,"stability":null,"value":"Query"},{"brief":null,"deprecated":null,"id":"head","note":null,"stability":null,"value":"Head"},{"brief":null,"deprecated":null,"id":"head_feed","note":null,"stability":null,"value":"HeadFeed"},{"brief":null,"deprecated":null,"id":"upsert","note":null,"stability":null,"value":"Upsert"},{"brief":null,"deprecated":null,"id":"batch","note":null,"stability":null,"value":"Batch"},{"brief":null,"deprecated":null,"id":"query_plan","note":null,"stability":null,"value":"QueryPlan"},{"brief":null,"deprecated":null,"id":"execute_javascript","note":null,"stability":null,"value":"ExecuteJavaScript"}]}},{"brief":"RU consumed for that operation","examples":[46.18,1.0],"name":"db.cosmosdb.request_charge","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-cosmosdb","type":"double"},{"brief":"Request payload size in bytes","name":"db.cosmosdb.request_content_length","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-cosmosdb","type":"int"},{"brief":"Cosmos DB status code.","examples":[200,201],"name":"db.cosmosdb.status_code","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-cosmosdb","type":"int"},{"brief":"Cosmos DB sub status code.","examples":[1000,1002],"name":"db.cosmosdb.sub_status_code","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-cosmosdb","type":"int"},{"brief":"Represents the identifier of an Elasticsearch cluster.\n","examples":["e9106fc68e3044f0b1475b04bf4ffd5f"],"name":"db.elasticsearch.cluster.name","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-elasticsearch","type":"string"},{"brief":"Represents the human-readable identifier of the node/instance to which a request was routed.\n","examples":["instance-0000000001"],"name":"db.elasticsearch.node.name","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-elasticsearch","type":"string"},{"brief":"A dynamic value in the url path.\n","examples":["db.elasticsearch.path_parts.index=test-index","db.elasticsearch.path_parts.doc_id=123"],"name":"db.elasticsearch.path_parts","note":"Many Elasticsearch url paths allow dynamic values. These SHOULD be recorded in span attributes in the format `db.elasticsearch.path_parts.\u003ckey\u003e`, where `\u003ckey\u003e` 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","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-elasticsearch","type":"template[string]"},{"brief":"An identifier (address, unique name, or any other identifier) of the database instance that is executing queries or mutations on the current connection. This is useful in cases where the database is running in a clustered environment and the instrumentation is able to record the node executing the query. The client may obtain this value in databases like MySQL using queries like `select @@hostname`.\n","examples":"mysql-e26b99z.example.com","name":"db.instance.id","requirement_level":"recommended","root_namespace":"db","tag":"db-generic","type":"string"},{"brief":"The fully-qualified class name of the [Java Database Connectivity (JDBC)](https://docs.oracle.com/javase/8/docs/technotes/guides/jdbc/) driver used to connect.\n","examples":["org.postgresql.Driver","com.microsoft.sqlserver.jdbc.SQLServerDriver"],"name":"db.jdbc.driver_classname","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-jdbc","type":"string"},{"brief":"The MongoDB collection being accessed within the database stated in `db.name`.\n","examples":["customers","products"],"name":"db.mongodb.collection","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-mongodb","type":"string"},{"brief":"The Microsoft SQL Server [instance name](https://docs.microsoft.com/sql/connect/jdbc/building-the-connection-url?view=sql-server-ver15) connecting to. This name is used to determine the port of a named instance.\n","examples":"MSSQLSERVER","name":"db.mssql.instance_name","note":"If setting a `db.mssql.instance_name`, `server.port` is no longer required (but still recommended if non-standard).\n","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-mssql","type":"string"},{"brief":"This attribute is used to report the name of the database being accessed. For commands that switch the database, this should be set to the target database (even if the command fails).\n","examples":["customers","main"],"name":"db.name","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","requirement_level":"recommended","root_namespace":"db","tag":"db-generic","type":"string"},{"brief":"The name of the operation being executed, e.g. the [MongoDB command name](https://docs.mongodb.com/manual/reference/command/#database-operations) such as `findAndModify`, or the SQL keyword.\n","examples":["findAndModify","HMSET","SELECT"],"name":"db.operation","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","requirement_level":"recommended","root_namespace":"db","tag":"db-generic","type":"string"},{"brief":"The index of the database being accessed as used in the [`SELECT` command](https://redis.io/commands/select), provided as an integer. To be used instead of the generic `db.name` attribute.\n","examples":[0,1,15],"name":"db.redis.database_index","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-redis","type":"int"},{"brief":"The name of the primary table that the operation is acting upon, including the database name (if applicable).","examples":["public.users","customers"],"name":"db.sql.table","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","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-sql","type":"string"},{"brief":"The database statement being executed.\n","examples":["SELECT * FROM wuser_table","SET mykey \"WuValue\""],"name":"db.statement","requirement_level":"recommended","root_namespace":"db","tag":"db-generic","type":"string"},{"brief":"An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers.","name":"db.system","requirement_level":"recommended","root_namespace":"db","tag":"db-generic","type":{"allow_custom_values":true,"members":[{"brief":"Some other SQL database. Fallback only. See notes.","deprecated":null,"id":"other_sql","note":null,"stability":null,"value":"other_sql"},{"brief":"Microsoft SQL Server","deprecated":null,"id":"mssql","note":null,"stability":null,"value":"mssql"},{"brief":"Microsoft SQL Server Compact","deprecated":null,"id":"mssqlcompact","note":null,"stability":null,"value":"mssqlcompact"},{"brief":"MySQL","deprecated":null,"id":"mysql","note":null,"stability":null,"value":"mysql"},{"brief":"Oracle Database","deprecated":null,"id":"oracle","note":null,"stability":null,"value":"oracle"},{"brief":"IBM Db2","deprecated":null,"id":"db2","note":null,"stability":null,"value":"db2"},{"brief":"PostgreSQL","deprecated":null,"id":"postgresql","note":null,"stability":null,"value":"postgresql"},{"brief":"Amazon Redshift","deprecated":null,"id":"redshift","note":null,"stability":null,"value":"redshift"},{"brief":"Apache Hive","deprecated":null,"id":"hive","note":null,"stability":null,"value":"hive"},{"brief":"Cloudscape","deprecated":null,"id":"cloudscape","note":null,"stability":null,"value":"cloudscape"},{"brief":"HyperSQL DataBase","deprecated":null,"id":"hsqldb","note":null,"stability":null,"value":"hsqldb"},{"brief":"Progress Database","deprecated":null,"id":"progress","note":null,"stability":null,"value":"progress"},{"brief":"SAP MaxDB","deprecated":null,"id":"maxdb","note":null,"stability":null,"value":"maxdb"},{"brief":"SAP HANA","deprecated":null,"id":"hanadb","note":null,"stability":null,"value":"hanadb"},{"brief":"Ingres","deprecated":null,"id":"ingres","note":null,"stability":null,"value":"ingres"},{"brief":"FirstSQL","deprecated":null,"id":"firstsql","note":null,"stability":null,"value":"firstsql"},{"brief":"EnterpriseDB","deprecated":null,"id":"edb","note":null,"stability":null,"value":"edb"},{"brief":"InterSystems Caché","deprecated":null,"id":"cache","note":null,"stability":null,"value":"cache"},{"brief":"Adabas (Adaptable Database System)","deprecated":null,"id":"adabas","note":null,"stability":null,"value":"adabas"},{"brief":"Firebird","deprecated":null,"id":"firebird","note":null,"stability":null,"value":"firebird"},{"brief":"Apache Derby","deprecated":null,"id":"derby","note":null,"stability":null,"value":"derby"},{"brief":"FileMaker","deprecated":null,"id":"filemaker","note":null,"stability":null,"value":"filemaker"},{"brief":"Informix","deprecated":null,"id":"informix","note":null,"stability":null,"value":"informix"},{"brief":"InstantDB","deprecated":null,"id":"instantdb","note":null,"stability":null,"value":"instantdb"},{"brief":"InterBase","deprecated":null,"id":"interbase","note":null,"stability":null,"value":"interbase"},{"brief":"MariaDB","deprecated":null,"id":"mariadb","note":null,"stability":null,"value":"mariadb"},{"brief":"Netezza","deprecated":null,"id":"netezza","note":null,"stability":null,"value":"netezza"},{"brief":"Pervasive PSQL","deprecated":null,"id":"pervasive","note":null,"stability":null,"value":"pervasive"},{"brief":"PointBase","deprecated":null,"id":"pointbase","note":null,"stability":null,"value":"pointbase"},{"brief":"SQLite","deprecated":null,"id":"sqlite","note":null,"stability":null,"value":"sqlite"},{"brief":"Sybase","deprecated":null,"id":"sybase","note":null,"stability":null,"value":"sybase"},{"brief":"Teradata","deprecated":null,"id":"teradata","note":null,"stability":null,"value":"teradata"},{"brief":"Vertica","deprecated":null,"id":"vertica","note":null,"stability":null,"value":"vertica"},{"brief":"H2","deprecated":null,"id":"h2","note":null,"stability":null,"value":"h2"},{"brief":"ColdFusion IMQ","deprecated":null,"id":"coldfusion","note":null,"stability":null,"value":"coldfusion"},{"brief":"Apache Cassandra","deprecated":null,"id":"cassandra","note":null,"stability":null,"value":"cassandra"},{"brief":"Apache HBase","deprecated":null,"id":"hbase","note":null,"stability":null,"value":"hbase"},{"brief":"MongoDB","deprecated":null,"id":"mongodb","note":null,"stability":null,"value":"mongodb"},{"brief":"Redis","deprecated":null,"id":"redis","note":null,"stability":null,"value":"redis"},{"brief":"Couchbase","deprecated":null,"id":"couchbase","note":null,"stability":null,"value":"couchbase"},{"brief":"CouchDB","deprecated":null,"id":"couchdb","note":null,"stability":null,"value":"couchdb"},{"brief":"Microsoft Azure Cosmos DB","deprecated":null,"id":"cosmosdb","note":null,"stability":null,"value":"cosmosdb"},{"brief":"Amazon DynamoDB","deprecated":null,"id":"dynamodb","note":null,"stability":null,"value":"dynamodb"},{"brief":"Neo4j","deprecated":null,"id":"neo4j","note":null,"stability":null,"value":"neo4j"},{"brief":"Apache Geode","deprecated":null,"id":"geode","note":null,"stability":null,"value":"geode"},{"brief":"Elasticsearch","deprecated":null,"id":"elasticsearch","note":null,"stability":null,"value":"elasticsearch"},{"brief":"Memcached","deprecated":null,"id":"memcached","note":null,"stability":null,"value":"memcached"},{"brief":"CockroachDB","deprecated":null,"id":"cockroachdb","note":null,"stability":null,"value":"cockroachdb"},{"brief":"OpenSearch","deprecated":null,"id":"opensearch","note":null,"stability":null,"value":"opensearch"},{"brief":"ClickHouse","deprecated":null,"id":"clickhouse","note":null,"stability":null,"value":"clickhouse"},{"brief":"Cloud Spanner","deprecated":null,"id":"spanner","note":null,"stability":null,"value":"spanner"},{"brief":"Trino","deprecated":null,"id":"trino","note":null,"stability":null,"value":"trino"}]}},{"brief":"Username for accessing the database.\n","examples":["readonly_user","reporting_user"],"name":"db.user","requirement_level":"recommended","root_namespace":"db","tag":"db-generic","type":"string"}],"root_namespace":"db"},{"attributes":[{"brief":"HTTP request headers, `\u003ckey\u003e` being the normalized HTTP Header name (lowercase), the value being the header values.\n","examples":["http.request.header.content-type=[\"application/json\"]","http.request.header.x-forwarded-for=[\"1.2.3.4\", \"1.2.3.5\"]"],"name":"http.request.header","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","requirement_level":"recommended","root_namespace":"http","stability":"stable","type":"template[string[]]"},{"brief":"HTTP request method.","examples":["GET","POST","HEAD"],"name":"http.request.method","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","requirement_level":"recommended","root_namespace":"http","stability":"stable","type":{"allow_custom_values":true,"members":[{"brief":"CONNECT method.","deprecated":null,"id":"connect","note":null,"stability":null,"value":"CONNECT"},{"brief":"DELETE method.","deprecated":null,"id":"delete","note":null,"stability":null,"value":"DELETE"},{"brief":"GET method.","deprecated":null,"id":"get","note":null,"stability":null,"value":"GET"},{"brief":"HEAD method.","deprecated":null,"id":"head","note":null,"stability":null,"value":"HEAD"},{"brief":"OPTIONS method.","deprecated":null,"id":"options","note":null,"stability":null,"value":"OPTIONS"},{"brief":"PATCH method.","deprecated":null,"id":"patch","note":null,"stability":null,"value":"PATCH"},{"brief":"POST method.","deprecated":null,"id":"post","note":null,"stability":null,"value":"POST"},{"brief":"PUT method.","deprecated":null,"id":"put","note":null,"stability":null,"value":"PUT"},{"brief":"TRACE method.","deprecated":null,"id":"trace","note":null,"stability":null,"value":"TRACE"},{"brief":"Any HTTP method that the instrumentation has no prior knowledge of.","deprecated":null,"id":"other","note":null,"stability":null,"value":"_OTHER"}]}},{"brief":"Original HTTP method sent by the client in the request line.","examples":["GeT","ACL","foo"],"name":"http.request.method_original","requirement_level":"recommended","root_namespace":"http","stability":"stable","type":"string"},{"brief":"The ordinal number of request resending attempt (for any reason, including redirects).\n","examples":3,"name":"http.request.resend_count","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","requirement_level":"recommended","root_namespace":"http","stability":"stable","type":"int"},{"brief":"HTTP response headers, `\u003ckey\u003e` being the normalized HTTP Header name (lowercase), the value being the header values.\n","examples":["http.response.header.content-type=[\"application/json\"]","http.response.header.my-custom-header=[\"abc\", \"def\"]"],"name":"http.response.header","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","requirement_level":"recommended","root_namespace":"http","stability":"stable","type":"template[string[]]"},{"brief":"[HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6).","examples":[200],"name":"http.response.status_code","requirement_level":"recommended","root_namespace":"http","stability":"stable","type":"int"},{"brief":"The matched route, that is, the path template in the format used by the respective server framework.\n","examples":["/users/:userID?","{controller}/{action}/{id?}"],"name":"http.route","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.","requirement_level":"recommended","root_namespace":"http","stability":"stable","type":"string"}],"root_namespace":"http"},{"attributes":[{"brief":"The ISO 3166-1 alpha-2 2-character country code associated with the mobile carrier network.","examples":"DE","name":"network.carrier.icc","requirement_level":"recommended","root_namespace":"network","type":"string"},{"brief":"The mobile carrier country code.","examples":"310","name":"network.carrier.mcc","requirement_level":"recommended","root_namespace":"network","type":"string"},{"brief":"The mobile carrier network code.","examples":"001","name":"network.carrier.mnc","requirement_level":"recommended","root_namespace":"network","type":"string"},{"brief":"The name of the mobile carrier.","examples":"sprint","name":"network.carrier.name","requirement_level":"recommended","root_namespace":"network","type":"string"},{"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","name":"network.connection.subtype","requirement_level":"recommended","root_namespace":"network","type":{"allow_custom_values":true,"members":[{"brief":"GPRS","deprecated":null,"id":"gprs","note":null,"stability":null,"value":"gprs"},{"brief":"EDGE","deprecated":null,"id":"edge","note":null,"stability":null,"value":"edge"},{"brief":"UMTS","deprecated":null,"id":"umts","note":null,"stability":null,"value":"umts"},{"brief":"CDMA","deprecated":null,"id":"cdma","note":null,"stability":null,"value":"cdma"},{"brief":"EVDO Rel. 0","deprecated":null,"id":"evdo_0","note":null,"stability":null,"value":"evdo_0"},{"brief":"EVDO Rev. A","deprecated":null,"id":"evdo_a","note":null,"stability":null,"value":"evdo_a"},{"brief":"CDMA2000 1XRTT","deprecated":null,"id":"cdma2000_1xrtt","note":null,"stability":null,"value":"cdma2000_1xrtt"},{"brief":"HSDPA","deprecated":null,"id":"hsdpa","note":null,"stability":null,"value":"hsdpa"},{"brief":"HSUPA","deprecated":null,"id":"hsupa","note":null,"stability":null,"value":"hsupa"},{"brief":"HSPA","deprecated":null,"id":"hspa","note":null,"stability":null,"value":"hspa"},{"brief":"IDEN","deprecated":null,"id":"iden","note":null,"stability":null,"value":"iden"},{"brief":"EVDO Rev. B","deprecated":null,"id":"evdo_b","note":null,"stability":null,"value":"evdo_b"},{"brief":"LTE","deprecated":null,"id":"lte","note":null,"stability":null,"value":"lte"},{"brief":"EHRPD","deprecated":null,"id":"ehrpd","note":null,"stability":null,"value":"ehrpd"},{"brief":"HSPAP","deprecated":null,"id":"hspap","note":null,"stability":null,"value":"hspap"},{"brief":"GSM","deprecated":null,"id":"gsm","note":null,"stability":null,"value":"gsm"},{"brief":"TD-SCDMA","deprecated":null,"id":"td_scdma","note":null,"stability":null,"value":"td_scdma"},{"brief":"IWLAN","deprecated":null,"id":"iwlan","note":null,"stability":null,"value":"iwlan"},{"brief":"5G NR (New Radio)","deprecated":null,"id":"nr","note":null,"stability":null,"value":"nr"},{"brief":"5G NRNSA (New Radio Non-Standalone)","deprecated":null,"id":"nrnsa","note":null,"stability":null,"value":"nrnsa"},{"brief":"LTE CA","deprecated":null,"id":"lte_ca","note":null,"stability":null,"value":"lte_ca"}]}},{"brief":"The internet connection type.","examples":"wifi","name":"network.connection.type","requirement_level":"recommended","root_namespace":"network","type":{"allow_custom_values":true,"members":[{"brief":null,"deprecated":null,"id":"wifi","note":null,"stability":null,"value":"wifi"},{"brief":null,"deprecated":null,"id":"wired","note":null,"stability":null,"value":"wired"},{"brief":null,"deprecated":null,"id":"cell","note":null,"stability":null,"value":"cell"},{"brief":null,"deprecated":null,"id":"unavailable","note":null,"stability":null,"value":"unavailable"},{"brief":null,"deprecated":null,"id":"unknown","note":null,"stability":null,"value":"unknown"}]}},{"brief":"The network IO operation direction.","examples":["transmit"],"name":"network.io.direction","requirement_level":"recommended","root_namespace":"network","type":{"allow_custom_values":false,"members":[{"brief":null,"deprecated":null,"id":"transmit","note":null,"stability":null,"value":"transmit"},{"brief":null,"deprecated":null,"id":"receive","note":null,"stability":null,"value":"receive"}]}},{"brief":"Local address of the network connection - IP address or Unix domain socket name.","examples":["10.1.2.80","/tmp/my.sock"],"name":"network.local.address","requirement_level":"recommended","root_namespace":"network","stability":"stable","type":"string"},{"brief":"Local port number of the network connection.","examples":[65123],"name":"network.local.port","requirement_level":"recommended","root_namespace":"network","stability":"stable","type":"int"},{"brief":"Peer address of the network connection - IP address or Unix domain socket name.","examples":["10.1.2.80","/tmp/my.sock"],"name":"network.peer.address","requirement_level":"recommended","root_namespace":"network","stability":"stable","type":"string"},{"brief":"Peer port number of the network connection.","examples":[65123],"name":"network.peer.port","requirement_level":"recommended","root_namespace":"network","stability":"stable","type":"int"},{"brief":"[OSI application layer](https://osi-model.com/application-layer/) or non-OSI equivalent.","examples":["amqp","http","mqtt"],"name":"network.protocol.name","note":"The value SHOULD be normalized to lowercase.","requirement_level":"recommended","root_namespace":"network","stability":"stable","type":"string"},{"brief":"Version of the protocol specified in `network.protocol.name`.","examples":"3.1.1","name":"network.protocol.version","note":"`network.protocol.version` refers to the version of the protocol used and might be different from the protocol client\u0027s 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","requirement_level":"recommended","root_namespace":"network","stability":"stable","type":"string"},{"brief":"[OSI transport layer](https://osi-model.com/transport-layer/) or [inter-process communication method](https://wikipedia.org/wiki/Inter-process_communication).\n","examples":["tcp","udp"],"name":"network.transport","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","requirement_level":"recommended","root_namespace":"network","stability":"stable","type":{"allow_custom_values":true,"members":[{"brief":"TCP","deprecated":null,"id":"tcp","note":null,"stability":null,"value":"tcp"},{"brief":"UDP","deprecated":null,"id":"udp","note":null,"stability":null,"value":"udp"},{"brief":"Named or anonymous pipe.","deprecated":null,"id":"pipe","note":null,"stability":null,"value":"pipe"},{"brief":"Unix domain socket","deprecated":null,"id":"unix","note":null,"stability":null,"value":"unix"}]}},{"brief":"[OSI network layer](https://osi-model.com/network-layer/) or non-OSI equivalent.","examples":["ipv4","ipv6"],"name":"network.type","note":"The value SHOULD be normalized to lowercase.","requirement_level":"recommended","root_namespace":"network","stability":"stable","type":{"allow_custom_values":true,"members":[{"brief":"IPv4","deprecated":null,"id":"ipv4","note":null,"stability":null,"value":"ipv4"},{"brief":"IPv6","deprecated":null,"id":"ipv6","note":null,"stability":null,"value":"ipv6"}]}}],"root_namespace":"network"},{"attributes":[{"brief":"The [URI fragment](https://www.rfc-editor.org/rfc/rfc3986#section-3.5) component","examples":["SemConv"],"name":"url.fragment","requirement_level":"recommended","root_namespace":"url","stability":"stable","type":"string"},{"brief":"Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986)","examples":["https://www.foo.bar/search?q=OpenTelemetry#SemConv","//localhost"],"name":"url.full","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\u0027s 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","requirement_level":"recommended","root_namespace":"url","stability":"stable","type":"string"},{"brief":"The [URI path](https://www.rfc-editor.org/rfc/rfc3986#section-3.3) component","examples":["/search"],"name":"url.path","requirement_level":"recommended","root_namespace":"url","stability":"stable","type":"string"},{"brief":"The [URI query](https://www.rfc-editor.org/rfc/rfc3986#section-3.4) component","examples":["q=OpenTelemetry"],"name":"url.query","note":"Sensitive content provided in query string SHOULD be scrubbed when instrumentations can identify it.","requirement_level":"recommended","root_namespace":"url","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"],"name":"url.scheme","requirement_level":"recommended","root_namespace":"url","stability":"stable","type":"string"}],"root_namespace":"url"},{"attributes":[{"brief":"Value of the [HTTP User-Agent](https://www.rfc-editor.org/rfc/rfc9110.html#field.user-agent) header sent by the client.\n","examples":["CERN-LineMode/2.15 libwww/2.17b3","Mozilla/5.0 (iPhone; CPU iPhone OS 14_7_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.2 Mobile/15E148 Safari/604.1"],"name":"user_agent.original","requirement_level":"recommended","root_namespace":"user_agent","stability":"stable","type":"string"}],"root_namespace":"user_agent"}] \ No newline at end of file +[{"attributes":[{"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","name":"db.cassandra.consistency_level","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-cassandra","type":{"allow_custom_values":true,"members":[{"brief":null,"deprecated":null,"id":"all","note":null,"stability":null,"value":"all"},{"brief":null,"deprecated":null,"id":"each_quorum","note":null,"stability":null,"value":"each_quorum"},{"brief":null,"deprecated":null,"id":"quorum","note":null,"stability":null,"value":"quorum"},{"brief":null,"deprecated":null,"id":"local_quorum","note":null,"stability":null,"value":"local_quorum"},{"brief":null,"deprecated":null,"id":"one","note":null,"stability":null,"value":"one"},{"brief":null,"deprecated":null,"id":"two","note":null,"stability":null,"value":"two"},{"brief":null,"deprecated":null,"id":"three","note":null,"stability":null,"value":"three"},{"brief":null,"deprecated":null,"id":"local_one","note":null,"stability":null,"value":"local_one"},{"brief":null,"deprecated":null,"id":"any","note":null,"stability":null,"value":"any"},{"brief":null,"deprecated":null,"id":"serial","note":null,"stability":null,"value":"serial"},{"brief":null,"deprecated":null,"id":"local_serial","note":null,"stability":null,"value":"local_serial"}]}},{"brief":"The data center of the coordinating node for a query.\n","examples":"us-west-2","name":"db.cassandra.coordinator.dc","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-cassandra","type":"string"},{"brief":"The ID of the coordinating node for a query.\n","examples":"be13faa2-8574-4d71-926d-27f16cf8a7af","name":"db.cassandra.coordinator.id","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-cassandra","type":"string"},{"brief":"Whether or not the query is idempotent.\n","name":"db.cassandra.idempotence","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-cassandra","type":"boolean"},{"brief":"The fetch size used for paging, i.e. how many rows will be returned at once.\n","examples":[5000],"name":"db.cassandra.page_size","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-cassandra","type":"int"},{"brief":"The number of times a query was speculatively executed. Not set or `0` if the query was not executed speculatively.\n","examples":[0,2],"name":"db.cassandra.speculative_execution_count","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-cassandra","type":"int"},{"brief":"The name of the primary Cassandra table that the operation is acting upon, including the keyspace name (if applicable).","examples":"mytable","name":"db.cassandra.table","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","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-cassandra","type":"string"},{"brief":"The connection string used to connect to the database. It is recommended to remove embedded credentials.\n","examples":"Server=(localdb)\\v11.0;Integrated Security=true;","name":"db.connection_string","requirement_level":"recommended","root_namespace":"db","tag":"db-generic","type":"string"},{"brief":"Unique Cosmos client instance id.","examples":"3ba4827d-4422-483f-b59f-85b74211c11d","name":"db.cosmosdb.client_id","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-cosmosdb","type":"string"},{"brief":"Cosmos client connection mode.","name":"db.cosmosdb.connection_mode","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-cosmosdb","type":{"allow_custom_values":false,"members":[{"brief":"Gateway (HTTP) connections mode","deprecated":null,"id":"gateway","note":null,"stability":null,"value":"gateway"},{"brief":"Direct connection.","deprecated":null,"id":"direct","note":null,"stability":null,"value":"direct"}]}},{"brief":"Cosmos DB container name.","examples":"anystring","name":"db.cosmosdb.container","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-cosmosdb","type":"string"},{"brief":"CosmosDB Operation Type.","name":"db.cosmosdb.operation_type","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-cosmosdb","type":{"allow_custom_values":true,"members":[{"brief":null,"deprecated":null,"id":"invalid","note":null,"stability":null,"value":"Invalid"},{"brief":null,"deprecated":null,"id":"create","note":null,"stability":null,"value":"Create"},{"brief":null,"deprecated":null,"id":"patch","note":null,"stability":null,"value":"Patch"},{"brief":null,"deprecated":null,"id":"read","note":null,"stability":null,"value":"Read"},{"brief":null,"deprecated":null,"id":"read_feed","note":null,"stability":null,"value":"ReadFeed"},{"brief":null,"deprecated":null,"id":"delete","note":null,"stability":null,"value":"Delete"},{"brief":null,"deprecated":null,"id":"replace","note":null,"stability":null,"value":"Replace"},{"brief":null,"deprecated":null,"id":"execute","note":null,"stability":null,"value":"Execute"},{"brief":null,"deprecated":null,"id":"query","note":null,"stability":null,"value":"Query"},{"brief":null,"deprecated":null,"id":"head","note":null,"stability":null,"value":"Head"},{"brief":null,"deprecated":null,"id":"head_feed","note":null,"stability":null,"value":"HeadFeed"},{"brief":null,"deprecated":null,"id":"upsert","note":null,"stability":null,"value":"Upsert"},{"brief":null,"deprecated":null,"id":"batch","note":null,"stability":null,"value":"Batch"},{"brief":null,"deprecated":null,"id":"query_plan","note":null,"stability":null,"value":"QueryPlan"},{"brief":null,"deprecated":null,"id":"execute_javascript","note":null,"stability":null,"value":"ExecuteJavaScript"}]}},{"brief":"RU consumed for that operation","examples":[46.18,1.0],"name":"db.cosmosdb.request_charge","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-cosmosdb","type":"double"},{"brief":"Request payload size in bytes","name":"db.cosmosdb.request_content_length","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-cosmosdb","type":"int"},{"brief":"Cosmos DB status code.","examples":[200,201],"name":"db.cosmosdb.status_code","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-cosmosdb","type":"int"},{"brief":"Cosmos DB sub status code.","examples":[1000,1002],"name":"db.cosmosdb.sub_status_code","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-cosmosdb","type":"int"},{"brief":"Represents the identifier of an Elasticsearch cluster.\n","examples":["e9106fc68e3044f0b1475b04bf4ffd5f"],"name":"db.elasticsearch.cluster.name","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-elasticsearch","type":"string"},{"brief":"Represents the human-readable identifier of the node/instance to which a request was routed.\n","examples":["instance-0000000001"],"name":"db.elasticsearch.node.name","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-elasticsearch","type":"string"},{"brief":"A dynamic value in the url path.\n","examples":["db.elasticsearch.path_parts.index=test-index","db.elasticsearch.path_parts.doc_id=123"],"name":"db.elasticsearch.path_parts","note":"Many Elasticsearch url paths allow dynamic values. These SHOULD be recorded in span attributes in the format `db.elasticsearch.path_parts.\u003ckey\u003e`, where `\u003ckey\u003e` 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","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-elasticsearch","type":"template[string]"},{"brief":"An identifier (address, unique name, or any other identifier) of the database instance that is executing queries or mutations on the current connection. This is useful in cases where the database is running in a clustered environment and the instrumentation is able to record the node executing the query. The client may obtain this value in databases like MySQL using queries like `select @@hostname`.\n","examples":"mysql-e26b99z.example.com","name":"db.instance.id","requirement_level":"recommended","root_namespace":"db","tag":"db-generic","type":"string"},{"brief":"The fully-qualified class name of the [Java Database Connectivity (JDBC)](https://docs.oracle.com/javase/8/docs/technotes/guides/jdbc/) driver used to connect.\n","examples":["org.postgresql.Driver","com.microsoft.sqlserver.jdbc.SQLServerDriver"],"name":"db.jdbc.driver_classname","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-jdbc","type":"string"},{"brief":"The MongoDB collection being accessed within the database stated in `db.name`.\n","examples":["customers","products"],"name":"db.mongodb.collection","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-mongodb","type":"string"},{"brief":"The Microsoft SQL Server [instance name](https://docs.microsoft.com/sql/connect/jdbc/building-the-connection-url?view=sql-server-ver15) connecting to. This name is used to determine the port of a named instance.\n","examples":"MSSQLSERVER","name":"db.mssql.instance_name","note":"If setting a `db.mssql.instance_name`, `server.port` is no longer required (but still recommended if non-standard).\n","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-mssql","type":"string"},{"brief":"This attribute is used to report the name of the database being accessed. For commands that switch the database, this should be set to the target database (even if the command fails).\n","examples":["customers","main"],"name":"db.name","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","requirement_level":"recommended","root_namespace":"db","tag":"db-generic","type":"string"},{"brief":"The name of the operation being executed, e.g. the [MongoDB command name](https://docs.mongodb.com/manual/reference/command/#database-operations) such as `findAndModify`, or the SQL keyword.\n","examples":["findAndModify","HMSET","SELECT"],"name":"db.operation","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","requirement_level":"recommended","root_namespace":"db","tag":"db-generic","type":"string"},{"brief":"The index of the database being accessed as used in the [`SELECT` command](https://redis.io/commands/select), provided as an integer. To be used instead of the generic `db.name` attribute.\n","examples":[0,1,15],"name":"db.redis.database_index","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-redis","type":"int"},{"brief":"The name of the primary table that the operation is acting upon, including the database name (if applicable).","examples":["public.users","customers"],"name":"db.sql.table","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","requirement_level":"recommended","root_namespace":"db","tag":"tech-specific-sql","type":"string"},{"brief":"The database statement being executed.\n","examples":["SELECT * FROM wuser_table","SET mykey \"WuValue\""],"name":"db.statement","requirement_level":"recommended","root_namespace":"db","tag":"db-generic","type":"string"},{"brief":"An identifier for the database management system (DBMS) product being used. See below for a list of well-known identifiers.","name":"db.system","requirement_level":"recommended","root_namespace":"db","tag":"db-generic","type":{"allow_custom_values":true,"members":[{"brief":"Some other SQL database. Fallback only. See notes.","deprecated":null,"id":"other_sql","note":null,"stability":null,"value":"other_sql"},{"brief":"Microsoft SQL Server","deprecated":null,"id":"mssql","note":null,"stability":null,"value":"mssql"},{"brief":"Microsoft SQL Server Compact","deprecated":null,"id":"mssqlcompact","note":null,"stability":null,"value":"mssqlcompact"},{"brief":"MySQL","deprecated":null,"id":"mysql","note":null,"stability":null,"value":"mysql"},{"brief":"Oracle Database","deprecated":null,"id":"oracle","note":null,"stability":null,"value":"oracle"},{"brief":"IBM Db2","deprecated":null,"id":"db2","note":null,"stability":null,"value":"db2"},{"brief":"PostgreSQL","deprecated":null,"id":"postgresql","note":null,"stability":null,"value":"postgresql"},{"brief":"Amazon Redshift","deprecated":null,"id":"redshift","note":null,"stability":null,"value":"redshift"},{"brief":"Apache Hive","deprecated":null,"id":"hive","note":null,"stability":null,"value":"hive"},{"brief":"Cloudscape","deprecated":null,"id":"cloudscape","note":null,"stability":null,"value":"cloudscape"},{"brief":"HyperSQL DataBase","deprecated":null,"id":"hsqldb","note":null,"stability":null,"value":"hsqldb"},{"brief":"Progress Database","deprecated":null,"id":"progress","note":null,"stability":null,"value":"progress"},{"brief":"SAP MaxDB","deprecated":null,"id":"maxdb","note":null,"stability":null,"value":"maxdb"},{"brief":"SAP HANA","deprecated":null,"id":"hanadb","note":null,"stability":null,"value":"hanadb"},{"brief":"Ingres","deprecated":null,"id":"ingres","note":null,"stability":null,"value":"ingres"},{"brief":"FirstSQL","deprecated":null,"id":"firstsql","note":null,"stability":null,"value":"firstsql"},{"brief":"EnterpriseDB","deprecated":null,"id":"edb","note":null,"stability":null,"value":"edb"},{"brief":"InterSystems Caché","deprecated":null,"id":"cache","note":null,"stability":null,"value":"cache"},{"brief":"Adabas (Adaptable Database System)","deprecated":null,"id":"adabas","note":null,"stability":null,"value":"adabas"},{"brief":"Firebird","deprecated":null,"id":"firebird","note":null,"stability":null,"value":"firebird"},{"brief":"Apache Derby","deprecated":null,"id":"derby","note":null,"stability":null,"value":"derby"},{"brief":"FileMaker","deprecated":null,"id":"filemaker","note":null,"stability":null,"value":"filemaker"},{"brief":"Informix","deprecated":null,"id":"informix","note":null,"stability":null,"value":"informix"},{"brief":"InstantDB","deprecated":null,"id":"instantdb","note":null,"stability":null,"value":"instantdb"},{"brief":"InterBase","deprecated":null,"id":"interbase","note":null,"stability":null,"value":"interbase"},{"brief":"MariaDB","deprecated":null,"id":"mariadb","note":null,"stability":null,"value":"mariadb"},{"brief":"Netezza","deprecated":null,"id":"netezza","note":null,"stability":null,"value":"netezza"},{"brief":"Pervasive PSQL","deprecated":null,"id":"pervasive","note":null,"stability":null,"value":"pervasive"},{"brief":"PointBase","deprecated":null,"id":"pointbase","note":null,"stability":null,"value":"pointbase"},{"brief":"SQLite","deprecated":null,"id":"sqlite","note":null,"stability":null,"value":"sqlite"},{"brief":"Sybase","deprecated":null,"id":"sybase","note":null,"stability":null,"value":"sybase"},{"brief":"Teradata","deprecated":null,"id":"teradata","note":null,"stability":null,"value":"teradata"},{"brief":"Vertica","deprecated":null,"id":"vertica","note":null,"stability":null,"value":"vertica"},{"brief":"H2","deprecated":null,"id":"h2","note":null,"stability":null,"value":"h2"},{"brief":"ColdFusion IMQ","deprecated":null,"id":"coldfusion","note":null,"stability":null,"value":"coldfusion"},{"brief":"Apache Cassandra","deprecated":null,"id":"cassandra","note":null,"stability":null,"value":"cassandra"},{"brief":"Apache HBase","deprecated":null,"id":"hbase","note":null,"stability":null,"value":"hbase"},{"brief":"MongoDB","deprecated":null,"id":"mongodb","note":null,"stability":null,"value":"mongodb"},{"brief":"Redis","deprecated":null,"id":"redis","note":null,"stability":null,"value":"redis"},{"brief":"Couchbase","deprecated":null,"id":"couchbase","note":null,"stability":null,"value":"couchbase"},{"brief":"CouchDB","deprecated":null,"id":"couchdb","note":null,"stability":null,"value":"couchdb"},{"brief":"Microsoft Azure Cosmos DB","deprecated":null,"id":"cosmosdb","note":null,"stability":null,"value":"cosmosdb"},{"brief":"Amazon DynamoDB","deprecated":null,"id":"dynamodb","note":null,"stability":null,"value":"dynamodb"},{"brief":"Neo4j","deprecated":null,"id":"neo4j","note":null,"stability":null,"value":"neo4j"},{"brief":"Apache Geode","deprecated":null,"id":"geode","note":null,"stability":null,"value":"geode"},{"brief":"Elasticsearch","deprecated":null,"id":"elasticsearch","note":null,"stability":null,"value":"elasticsearch"},{"brief":"Memcached","deprecated":null,"id":"memcached","note":null,"stability":null,"value":"memcached"},{"brief":"CockroachDB","deprecated":null,"id":"cockroachdb","note":null,"stability":null,"value":"cockroachdb"},{"brief":"OpenSearch","deprecated":null,"id":"opensearch","note":null,"stability":null,"value":"opensearch"},{"brief":"ClickHouse","deprecated":null,"id":"clickhouse","note":null,"stability":null,"value":"clickhouse"},{"brief":"Cloud Spanner","deprecated":null,"id":"spanner","note":null,"stability":null,"value":"spanner"},{"brief":"Trino","deprecated":null,"id":"trino","note":null,"stability":null,"value":"trino"}]}},{"brief":"Username for accessing the database.\n","examples":["readonly_user","reporting_user"],"name":"db.user","requirement_level":"recommended","root_namespace":"db","tag":"db-generic","type":"string"}],"root_namespace":"db"},{"attributes":[{"brief":"HTTP request headers, `\u003ckey\u003e` being the normalized HTTP Header name (lowercase), the value being the header values.\n","examples":["http.request.header.content-type=[\"application/json\"]","http.request.header.x-forwarded-for=[\"1.2.3.4\", \"1.2.3.5\"]"],"name":"http.request.header","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","requirement_level":"recommended","root_namespace":"http","stability":"stable","type":"template[string[]]"},{"brief":"HTTP request method.","examples":["GET","POST","HEAD"],"name":"http.request.method","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","requirement_level":"recommended","root_namespace":"http","stability":"stable","type":{"allow_custom_values":true,"members":[{"brief":"CONNECT method.","deprecated":null,"id":"connect","note":null,"stability":null,"value":"CONNECT"},{"brief":"DELETE method.","deprecated":null,"id":"delete","note":null,"stability":null,"value":"DELETE"},{"brief":"GET method.","deprecated":null,"id":"get","note":null,"stability":null,"value":"GET"},{"brief":"HEAD method.","deprecated":null,"id":"head","note":null,"stability":null,"value":"HEAD"},{"brief":"OPTIONS method.","deprecated":null,"id":"options","note":null,"stability":null,"value":"OPTIONS"},{"brief":"PATCH method.","deprecated":null,"id":"patch","note":null,"stability":null,"value":"PATCH"},{"brief":"POST method.","deprecated":null,"id":"post","note":null,"stability":null,"value":"POST"},{"brief":"PUT method.","deprecated":null,"id":"put","note":null,"stability":null,"value":"PUT"},{"brief":"TRACE method.","deprecated":null,"id":"trace","note":null,"stability":null,"value":"TRACE"},{"brief":"Any HTTP method that the instrumentation has no prior knowledge of.","deprecated":null,"id":"other","note":null,"stability":null,"value":"_OTHER"}]}},{"brief":"Original HTTP method sent by the client in the request line.","examples":["GeT","ACL","foo"],"name":"http.request.method_original","requirement_level":"recommended","root_namespace":"http","stability":"stable","type":"string"},{"brief":"The ordinal number of request resending attempt (for any reason, including redirects).\n","examples":3,"name":"http.request.resend_count","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","requirement_level":"recommended","root_namespace":"http","stability":"stable","type":"int"},{"brief":"HTTP response headers, `\u003ckey\u003e` being the normalized HTTP Header name (lowercase), the value being the header values.\n","examples":["http.response.header.content-type=[\"application/json\"]","http.response.header.my-custom-header=[\"abc\", \"def\"]"],"name":"http.response.header","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","requirement_level":"recommended","root_namespace":"http","stability":"stable","type":"template[string[]]"},{"brief":"[HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6).","examples":[200],"name":"http.response.status_code","requirement_level":"recommended","root_namespace":"http","stability":"stable","type":"int"},{"brief":"The matched route, that is, the path template in the format used by the respective server framework.\n","examples":["/users/:userID?","{controller}/{action}/{id?}"],"name":"http.route","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.","requirement_level":"recommended","root_namespace":"http","stability":"stable","type":"string"}],"root_namespace":"http"},{"attributes":[{"brief":"Value of the [HTTP User-Agent](https://www.rfc-editor.org/rfc/rfc9110.html#field.user-agent) header sent by the client.\n","examples":["CERN-LineMode/2.15 libwww/2.17b3","Mozilla/5.0 (iPhone; CPU iPhone OS 14_7_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.2 Mobile/15E148 Safari/604.1"],"name":"user_agent.original","requirement_level":"recommended","root_namespace":"user_agent","stability":"stable","type":"string"}],"root_namespace":"user_agent"}] \ No newline at end of file diff --git a/crates/weaver_forge/templates/semconv_jq_fn/weaver.yaml b/crates/weaver_forge/templates/semconv_jq_fn/weaver.yaml index 1907f262..36a42d6a 100644 --- a/crates/weaver_forge/templates/semconv_jq_fn/weaver.yaml +++ b/crates/weaver_forge/templates/semconv_jq_fn/weaver.yaml @@ -12,7 +12,7 @@ templates: - pattern: semconv_grouped_attributes_without_experimental.json filter: > semconv_grouped_attributes({ - "exclude_namespace": ["url", "network"], + "exclude_root_namespace": ["url", "network"], "exclude_stability": ["experimental"] }) application_mode: single