Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
5ce7e02
Change version -> file_format: definition/2.0.0
lmolkova Jan 23, 2026
fe0cdbe
changelog
lmolkova Jan 23, 2026
2379e6c
up
lmolkova Jan 23, 2026
9cad2e0
regenerate v2 json schema
lmolkova Jan 23, 2026
3b3e3c2
definition/2.0.0 -> definition/2, semver does not make sense
lmolkova Feb 9, 2026
b369d9a
support version: 2 as well
lmolkova Feb 13, 2026
9e5e2dd
cleanup
lmolkova Feb 13, 2026
16a4fb6
Merge branch 'main' into definition-file-format
lmolkova Feb 21, 2026
973d80f
add warning for version
lmolkova Feb 21, 2026
b492683
merge deserialization and from file logic
lmolkova Feb 21, 2026
94409f6
Update CHANGELOG.md
lmolkova Feb 22, 2026
081cc59
Merge branch 'main' into definition-file-format
lmolkova Feb 24, 2026
a8f7ddd
make SemConvSpec not deserializeable, refactor
lmolkova Feb 24, 2026
2a09a95
Merge branch 'definition-file-format' of https://github.com/lmolkova/…
lmolkova Feb 24, 2026
b35d598
refactor more: remove SemConvSpec - not needed
lmolkova Feb 24, 2026
86df809
a bit more cleanup
lmolkova Feb 24, 2026
708e716
Merge branch 'main' into definition-file-format
lmolkova Feb 24, 2026
9649a7c
don't escape formatted compound error message
lmolkova Feb 24, 2026
6c6c36b
lint
lmolkova Feb 24, 2026
b14e1e2
Merge branch 'main' into definition-file-format
lmolkova Feb 25, 2026
a778a09
comments and changelog
lmolkova Feb 25, 2026
8626f50
Merge branch 'main' into definition-file-format
jsuereth Feb 25, 2026
df096eb
Merge branch 'main' into definition-file-format
lmolkova Feb 26, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ All notable changes to this project will be documented in this file.
from it. ([#1202](https://github.com/open-telemetry/weaver/pull/1202) by @lmolkova)
- Default to `manifest.yaml` for registry manifest file, deprecate `registry_manifest.yaml` and add warning when it's used. ([#1202](https://github.com/open-telemetry/weaver/pull/1202) by @lmolkova)
- 💥 BREAKING CHANGE 💥 (Fixes [#760](https://github.com/open-telemetry/weaver/issues/760)) - Auto-escaping is now off by default (`none`) for all templates, regardless of file extension. To opt in, set `auto_escape: html` or `auto_escape: json` per template in `weaver.yaml`. Within a template, `{% autoescape false %}` blocks can selectively disable escaping for sections. Use `|tojson` for explicit JSON/YAML value escaping where needed. ([#1239](https://github.com/open-telemetry/weaver/pull/1239) by @jerbly)
- 💥 BREAKING CHANGE 💥 Replace `version: "2"` with `file_format: definition/2` for v2 definition schema ([#1154](https://github.com/open-telemetry/weaver/pull/1154) by @lmolkova)

# [0.21.2] - 2026-02-03

Expand Down
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion crates/weaver_checker/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ pub enum Error {
},

/// A container for multiple errors.
#[error("{:?}", format_errors(.0))]
#[error("{}", format_errors(.0))]
#[diagnostic()]
CompoundError(Vec<Error>),
}
Expand Down
2 changes: 1 addition & 1 deletion crates/weaver_forge/data/registry/http.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
version: "2"
file_format: definition/2
Comment thread
lmolkova marked this conversation as resolved.
attribute_groups:
- id: http.client.server_and_port
visibility: internal
Expand Down
1 change: 1 addition & 0 deletions crates/weaver_resolver/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,4 @@ rand.workspace = true

[dev-dependencies]
glob = "=0.3.3"
tempfile.workspace = true
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
version: "2"
file_format: definition/2
attributes:
- key: test.attr.one
stability: stable
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
version: "2"
file_format: definition/2
attributes:
- key: server.port
stability: stable
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
version: "2"
file_format: definition/2
metrics:
- name: http.server.request.duration
brief: "Duration of HTTP server requests."
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
version: "2"
file_format: definition/2
attributes:
- key: network.protocol.name
stability: stable
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
version: "2"
file_format: definition/2
attributes:
- key: server.port
stability: stable
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
version: "2"
file_format: definition/2
metrics:
- name: http.server.request.duration
brief: "Duration of HTTP server requests."
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
version: "1"
file_format: definition/1
groups:
- id: registry.network
type: attribute_group
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
version: "2"
file_format: definition/2
attributes:
- key: server.port
stability: stable
Expand Down
2 changes: 1 addition & 1 deletion crates/weaver_resolver/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ pub enum Error {
},

/// A container for multiple errors.
#[error("{:?}", format_errors(.0))]
#[error("{}", format_errors(.0))]
CompoundError(#[related] Vec<Error>),
}

Expand Down
26 changes: 16 additions & 10 deletions crates/weaver_resolver/src/loader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ use walkdir::DirEntry;
use weaver_common::result::WResult;
use weaver_resolved_schema::v2::ResolvedTelemetrySchema as V2Schema;
use weaver_resolved_schema::ResolvedTelemetrySchema as V1Schema;
use weaver_semconv::json_schema::JsonSchemaValidator;
use weaver_semconv::registry_repo::{RegistryRepo, LEGACY_REGISTRY_MANIFEST, REGISTRY_MANIFEST};
use weaver_semconv::{group::ImportsWithProvenance, semconv::SemConvSpecWithProvenance};

Expand Down Expand Up @@ -45,21 +44,32 @@ impl LoadedSemconvRegistry {
/// Creates a loaded semconv registry from a single string.
#[cfg(test)]
pub fn create_from_string(spec: &str) -> Result<LoadedSemconvRegistry, Error> {
use std::io::Write;
use weaver_common::vdir::VirtualDirectoryPath;
use weaver_semconv::provenance::Provenance;
let path: VirtualDirectoryPath = "data".try_into().expect("Bad fake path for test");
let repo =
RegistryRepo::try_new(None, &path, &mut vec![]).map_err(|e| Error::InvalidUrl {
url: "test string".to_owned(),
error: format!("{e}"),
})?;
let provenance = Provenance::new("default", "<str>");
let spec_with_provenance = SemConvSpecWithProvenance::from_string(provenance, spec)
.into_result_failing_non_fatal()
let mut temp_file =
tempfile::NamedTempFile::with_suffix(".yaml").map_err(|e| Error::InvalidUrl {
url: "test string".to_owned(),
error: format!("Failed to create temp file: {e}"),
})?;
temp_file
.write_all(spec.as_bytes())
.map_err(|e| Error::InvalidUrl {
url: "test string".to_owned(),
error: format!("{e}"),
error: format!("Failed to write to temp file: {e}"),
})?;
let spec_with_provenance =
SemConvSpecWithProvenance::from_file("default", temp_file.path())
.into_result_failing_non_fatal()
.map_err(|e| Error::InvalidUrl {
url: "test string".to_owned(),
error: format!("{e}"),
})?;
Ok(LoadedSemconvRegistry::Unresolved {
repo,
specs: vec![spec_with_provenance],
Expand Down Expand Up @@ -289,8 +299,6 @@ fn load_definition_repository(
}
let local_path = registry_repo.path().to_path_buf();
let registry_path_repr = registry_repo.registry_path_repr();
let versioned_validator = JsonSchemaValidator::new_versioned();
let unversioned_validator = JsonSchemaValidator::new_unversioned();

// Loads the semantic convention specifications from the git repo.
// All yaml files are recursively loaded and parsed in parallel from
Expand All @@ -311,8 +319,6 @@ fn load_definition_repository(
vec![SemConvRegistry::semconv_spec_from_file(
registry_repo.name(),
entry.path(),
&unversioned_validator,
&versioned_validator,
|path| {
// Replace the local path with the git URL combined with the relative path
// of the semantic convention file.
Expand Down
12 changes: 10 additions & 2 deletions crates/weaver_resolver/src/registry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -947,8 +947,8 @@ mod tests {
matches!(
e,
crate::Error::FailToResolveDefinition(
weaver_semconv::Error::UnstableFileVersion {
version: _,
weaver_semconv::Error::UnstableFileFormat {
file_format: _,
provenance: _,
}
)
Expand All @@ -962,6 +962,14 @@ mod tests {
)
)
})
.ignore(|e| {
matches!(
e,
crate::Error::FailToResolveDefinition(
weaver_semconv::Error::DeprecatedVersionField { provenance: _ }
)
)
})
.into_result_failing_non_fatal()
.expect("Failed to load semconv specs");

Expand Down
1 change: 1 addition & 0 deletions crates/weaver_semconv/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ workspace = true

[dev-dependencies]
serde_json.workspace = true
tempfile.workspace = true
walkdir.workspace = true

[dependencies]
Expand Down
2 changes: 1 addition & 1 deletion crates/weaver_semconv/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ deserialization support for YAML files adhering to the semantic convention regis
serialization and deserialization of the data model making it easy to read and write YAML, JSON, and other formats
supported by the Serde ecosystem.

For more details on the syntax and semantics, see the [semantic convention YAML language](/schemas/semconv-syntax.md)
For more details on the syntax and semantics, see the [semantic convention Definition language](/schemas/semconv-syntax.md)
documentation.

For a formal definition of the allowed syntax, see the [JSON schema](/schemas/semconv.schema.json).
Expand Down
21 changes: 1 addition & 20 deletions crates/weaver_semconv/src/json_schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

//! JSON Schema validator for semantic convention files.

use crate::semconv::{SemConvSpec, SemConvSpecV1, Versioned};
use crate::Error::{CompoundError, InvalidSemConvSpec, InvalidXPath};
use crate::{Error, InvalidSemConvSpecError};
use itertools::Itertools;
Expand Down Expand Up @@ -30,27 +29,9 @@ pub struct JsonSchemaValidator {
}

impl JsonSchemaValidator {
/// Creates a new JSON schema validator.
#[must_use]
pub fn new_all_versions() -> Self {
Self::new_for::<SemConvSpec>()
}

/// Creates a new JSON schema validator that ONLY works when `version` is not specified.
#[must_use]
pub fn new_unversioned() -> Self {
Self::new_for::<SemConvSpecV1>()
}

/// Creates a new JSON schema validator that ONLY works when `version` is specified.
#[must_use]
pub fn new_versioned() -> Self {
Self::new_for::<Versioned>()
}

/// Creates a new JSON schema validator that works for any type T.
#[must_use]
fn new_for<T: JsonSchema>() -> Self {
pub fn new_for<T: JsonSchema>() -> Self {
// Generate the JSON schema for the SemConvSpec struct using Schemars
let root_schema = schemars::schema_for!(T);
let json_schema = serde_json::to_value(&root_schema)
Expand Down
31 changes: 25 additions & 6 deletions crates/weaver_semconv/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -297,16 +297,35 @@ pub enum Error {
error: String,
},

/// This indicates the file version used is not yet stable.
#[error("Version `{version}` schema file format is not yet stable: {provenance}")]
/// This indicates the file format (version) used is not yet stable.
#[error("File format `{file_format}` is not yet stable: {provenance}")]
#[diagnostic(severity(Warning))]
UnstableFileVersion {
/// The version specified.
version: String,
UnstableFileFormat {
/// The file_format specified.
file_format: String,
/// The source using that version.
provenance: String,
},

/// This indicates the deprecated 'version' field is being used instead of 'file_format'.
#[error("The 'version' field is deprecated and will be removed in a future version. Please use 'file_format: definition/2' instead: {provenance}")]
#[diagnostic(severity(Warning))]
DeprecatedVersionField {
/// The source using the deprecated field.
provenance: String,
},

/// This indicates the file format (version) used is not yet stable.
#[error("Invalid file format: `{field_key}: {field_value}`. Expected 'file_format: definition/1' or 'file_format: definition/2'.")]
#[diagnostic(severity(Error))]
InvalidFileFormat {
/// The file_format or version field key.
field_key: String,

/// The version specified.
field_value: String,
},

/// This indicates that deprecated property is invalid
#[error(
"The `deprecated` property in `{id}` is invalid. {error}\nProvenance: {path_or_url:?}"
Expand Down Expand Up @@ -340,7 +359,7 @@ pub enum Error {
},

/// A container for multiple errors.
#[error("{:?}", format_errors(.0))]
#[error("{}", format_errors(.0))]
CompoundError(#[related] Vec<Error>),
}

Expand Down
42 changes: 7 additions & 35 deletions crates/weaver_semconv/src/registry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@

use crate::attribute::AttributeSpecWithProvenance;
use crate::group::{GroupSpecWithProvenance, ImportsWithProvenance};
use crate::json_schema::JsonSchemaValidator;
use crate::manifest::RegistryManifest;
use crate::provenance::Provenance;
use crate::registry_repo::RegistryRepo;
use crate::schema_url::SchemaUrl;
use crate::semconv::{SemConvSpecV1WithProvenance, SemConvSpecWithProvenance};
Expand Down Expand Up @@ -77,8 +75,6 @@ impl SemConvRegistry {
non_fatal_errors: &mut Vec<Error>,
) -> Result<SemConvRegistry, Error> {
let mut registry = SemConvRegistry::new(registry_id);
let versioned_validator = JsonSchemaValidator::new_versioned();
let unversioned_validator = JsonSchemaValidator::new_unversioned();
for sc_entry in
glob::glob(path_pattern).map_err(|e| Error::InvalidRegistryPathPattern {
path_pattern: path_pattern.to_owned(),
Expand All @@ -89,13 +85,9 @@ impl SemConvRegistry {
path_pattern: path_pattern.to_owned(),
error: e.to_string(),
})?;
let (semconv_spec, nfes) = SemConvSpecWithProvenance::from_file(
registry_id,
path_buf.as_path(),
&unversioned_validator,
&versioned_validator,
)
.into_result_with_non_fatal()?;
let (semconv_spec, nfes) =
SemConvSpecWithProvenance::from_file(registry_id, path_buf.as_path())
.into_result_with_non_fatal()?;
registry.add_semconv_spec(semconv_spec);
non_fatal_errors.extend(nfes);
}
Expand Down Expand Up @@ -187,37 +179,17 @@ impl SemConvRegistry {
self.semconv_spec_count += 1;
}

/// Load and add a semantic convention string to the semantic convention registry.
///
/// This should only be used in tests!
pub fn add_semconv_spec_from_string(
&mut self,
provenance: Provenance,
spec: &str,
) -> WResult<(), Error> {
SemConvSpecWithProvenance::from_string(provenance, spec)
.map(|spec| self.add_semconv_spec(spec))
}

/// Loads and returns the semantic convention spec from a file.
pub fn semconv_spec_from_file<P, F>(
registry_id: &str,
semconv_path: P,
unversioned_validator: &JsonSchemaValidator,
versioned_validator: &JsonSchemaValidator,
path_fixer: F,
) -> WResult<SemConvSpecWithProvenance, Error>
where
P: AsRef<Path>,
F: Fn(String) -> String,
{
SemConvSpecWithProvenance::from_file_with_mapped_path(
registry_id,
semconv_path,
unversioned_validator,
versioned_validator,
path_fixer,
)
SemConvSpecWithProvenance::from_file_with_mapped_path(registry_id, semconv_path, path_fixer)
}

/// Returns the number of semantic convention specs added in the semantic
Expand Down Expand Up @@ -282,7 +254,7 @@ mod tests {
use crate::provenance::Provenance;
use crate::registry::SemConvRegistry;
use crate::registry_repo::RegistryRepo;
use crate::semconv::{SemConvSpec, SemConvSpecV1, SemConvSpecWithProvenance};
use crate::semconv::{SemConvSpecV1, SemConvSpecWithProvenance, Versioned};
use crate::Error;

use weaver_common::vdir::VirtualDirectoryPath;
Expand Down Expand Up @@ -311,7 +283,7 @@ mod tests {
let semconv_specs = vec![
SemConvSpecWithProvenance {
provenance: Provenance::new("main", "data/c1.yaml"),
spec: SemConvSpec::NoVersion(SemConvSpecV1 {
spec: Versioned::V1(SemConvSpecV1 {
groups: vec![GroupSpec {
id: "group1".to_owned(),
r#type: GroupType::AttributeGroup,
Expand Down Expand Up @@ -355,7 +327,7 @@ mod tests {
},
SemConvSpecWithProvenance {
provenance: Provenance::new("main", "data/c2.yaml"),
spec: SemConvSpec::NoVersion(SemConvSpecV1 {
spec: Versioned::V1(SemConvSpecV1 {
groups: vec![GroupSpec {
id: "group2".to_owned(),
r#type: GroupType::AttributeGroup,
Expand Down
Loading