Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Registry manifest and Schema diff #400

Draft
wants to merge 35 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
edab834
feat(semconv): create registry manifest
lquerel Oct 3, 2024
fe7d7b5
feat(schema): Parse OTEL schema 1.1
lquerel Oct 4, 2024
76db2aa
feat(cli): Add registry diff command (WIP)
lquerel Oct 4, 2024
ad77910
Merge branch 'main' into generate-otel-schema
lquerel Oct 4, 2024
6de07ee
feat(schema): Support new deprecated field format
lquerel Oct 17, 2024
5efe6b1
Merge remote-tracking branch 'upstream/main' into generate-otel-schema
lquerel Oct 23, 2024
6cdfbfa
feat(diff): Add registry diff command.
lquerel Oct 23, 2024
880649f
feat(diff): Add diff for metrics
lquerel Oct 24, 2024
a87807b
feat(diff): Add diff for events, spans, and resources
lquerel Oct 24, 2024
8f8bdaf
feat(diff): Add template rendering capability
lquerel Oct 25, 2024
a818f4e
feat(diff): Add diff-format for ansi, ansi-stats, json, and yaml
lquerel Oct 28, 2024
05256ea
feat(diff): Add diff-format for markdown
lquerel Oct 29, 2024
c584f30
chore(diff): Fix unit tests
lquerel Oct 29, 2024
374def2
feat(cli): Prepare registry update-schema command
lquerel Oct 30, 2024
1b7c9c2
Merge branch 'main' into generate-otel-schema
lquerel Oct 30, 2024
2abd024
feat(cli): Prepare registry update-schema command
lquerel Oct 30, 2024
83f45eb
feat(cli): Prepare registry update-schema command
lquerel Oct 31, 2024
6312e42
chore(typo): fix typo in comment
lquerel Dec 2, 2024
6532bf3
Merge remote-tracking branch 'upstream/main' into generate-otel-schema
lquerel Dec 2, 2024
f5efacc
chore(build): Resolve merging with main upstream
lquerel Dec 2, 2024
9bda8cb
chore(build): Clean up code to prepare PR
lquerel Dec 2, 2024
edf85b0
chore(build): Clean up code to prepare PR
lquerel Dec 2, 2024
3b41c58
Merge branch 'main' into generate-otel-schema
lquerel Dec 6, 2024
bde3eef
chore(build): Prepare resolve_telemetry_schema to return WResult
lquerel Dec 6, 2024
904e856
Merge branch 'generate-otel-schema' of https://github.com/lquerel/ote…
lquerel Dec 6, 2024
3c4b6dd
chore(build): Fix `registry diff` to return a diff even when there ar…
lquerel Dec 9, 2024
c0609b5
Merge branch 'open-telemetry:main' into generate-otel-schema
lquerel Dec 17, 2024
6ba427c
chore(merge): Merge with main branch
lquerel Dec 17, 2024
ebcd15f
feat(diff): Test schema diff feature
lquerel Dec 19, 2024
8dcd311
feat(diff): Remove complex logic infering the type of deprecation bas…
lquerel Dec 19, 2024
b58d200
feat(diff): Rename the field Deprecated::Renamed::new_name into Depre…
lquerel Dec 19, 2024
a1ab93a
chore(doc): Fix documentation of the ResolvedTelemetrySchema::groups …
lquerel Dec 19, 2024
396450f
chore(doc): Fix documentation based on @jsuereth feedback
lquerel Dec 19, 2024
12c79c2
Merge remote-tracking branch 'upstream/main' into generate-otel-schema
lquerel Dec 19, 2024
0a63cd8
chore(merge): Merge with upstream main branch
lquerel Dec 19, 2024
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
2 changes: 1 addition & 1 deletion .clippy.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
msrv = "1.76.0" # MSRV
msrv = "1.80.0" # MSRV
warn-on-all-wildcard-imports = true
allow-expect-in-tests = true
allow-unwrap-in-tests = true
Expand Down
15 changes: 15 additions & 0 deletions Cargo.lock

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

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ edition = "2021"
repository = "https://github.com/open-telemetry/weaver"
license = "Apache-2.0"
publish = false
rust-version = "1.76"
rust-version = "1.80"

[workspace.dependencies]
serde = { version = "1.0.210", features = ["derive"] }
Expand Down Expand Up @@ -78,6 +78,7 @@ weaver_semconv_gen = { path = "crates/weaver_semconv_gen" }
weaver_cache = { path = "crates/weaver_cache" }
weaver_forge = { path = "crates/weaver_forge" }
weaver_checker = { path = "crates/weaver_checker" }
weaver_otel_schema = { path = "crates/weaver_otel_schema" }

clap = { version = "4.5.20", features = ["derive"] }
rayon = "1.10.0"
Expand Down
13 changes: 12 additions & 1 deletion crates/weaver_cache/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ impl From<Error> for DiagnosticMessages {
/// - A simple wrapper around a local directory
/// - Initialized from a Git repository
/// - Initialized from a Git archive
#[derive(Default)]
#[derive(Default, Debug)]
pub struct RegistryRepo {
// A unique identifier for the registry (e.g. main, baseline, etc.)
id: String,
Expand Down Expand Up @@ -509,6 +509,17 @@ impl RegistryRepo {
&self.registry_path
}

/// Returns the path to the `registry_manifest.yaml` file (if any).
#[must_use]
pub fn manifest_path(&self) -> Option<PathBuf> {
let manifest_path = self.path.join("registry_manifest.yaml");
if manifest_path.exists() {
Some(manifest_path)
} else {
None
}
}

/// Creates a temporary directory for the registry repository and returns the path.
/// The temporary directory is created in the `.weaver/semconv_registry_cache`.
fn create_tmp_repo() -> Result<TempDir, Error> {
Expand Down
14 changes: 5 additions & 9 deletions crates/weaver_codegen_test/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ use weaver_semconv::registry::SemConvRegistry;

const SEMCONV_REGISTRY_PATH: &str = "./semconv_registry/";
const TEMPLATES_PATH: &str = "./templates/registry/";
const REGISTRY_ID: &str = "test";
const TARGET: &str = "rust";

fn main() {
Expand All @@ -49,7 +48,8 @@ fn main() {
.ignore(|e| matches!(e.severity(), Some(miette::Severity::Warning)))
.into_result_failing_non_fatal()
.unwrap_or_else(|e| process_error(&logger, e));
let mut registry = SemConvRegistry::from_semconv_specs(REGISTRY_ID, semconv_specs);
let mut registry = SemConvRegistry::from_semconv_specs(&registry_repo, semconv_specs)
.unwrap_or_else(|e| process_error(&logger, e));
let schema = SchemaResolver::resolve_semantic_convention_registry(&mut registry)
.unwrap_or_else(|e| process_error(&logger, e));

Expand All @@ -61,13 +61,9 @@ fn main() {
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)
.expect("Failed to get the registry from the resolved schema"),
schema.catalog(),
)
.unwrap_or_else(|e| process_error(&logger, e));
let template_registry =
ResolvedRegistry::try_from_resolved_registry(&schema.registry, schema.catalog())
.unwrap_or_else(|e| process_error(&logger, e));
let target_dir: PathBuf = target_dir.into();
engine
.generate(
Expand Down
3 changes: 1 addition & 2 deletions crates/weaver_common/src/diagnostic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -180,8 +180,7 @@ impl DiagnosticMessages {
Self(vec![DiagnosticMessage::new(error)])
}

/// Returns true if all the diagnostic messages are explicitly marked as
/// warnings or advices.
/// Returns true if at least one diagnostic message has an error severity.
#[must_use]
pub fn has_error(&self) -> bool {
let non_error_count = self
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ Brief: Span attributes used by non-OTLP exporters to represent OpenTelemetry Sco
- Examples: [
"io.opentelemetry.contrib.mongodb",
]
- Deprecated: use the `otel.scope.name` attribute.
- Deprecated: {"action": "renamed", "new_name": "otel.scope.name", "note": "use the `otel.scope.name` attribute."}


#### Attribute `otel.library.version`
Expand All @@ -36,7 +36,7 @@ Brief: Span attributes used by non-OTLP exporters to represent OpenTelemetry Sco
- Examples: [
"1.0.0",
]
- Deprecated: use the `otel.scope.version` attribute.
- Deprecated: {"action": "renamed", "new_name": "otel.scope.version", "note": "use the `otel.scope.version` attribute."}



4 changes: 2 additions & 2 deletions crates/weaver_forge/expected_output/test/resources.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ Brief: Span attributes used by non-OTLP exporters to represent OpenTelemetry Sco
- Examples: [
"io.opentelemetry.contrib.mongodb",
]
- Deprecated: use the `otel.scope.name` attribute.
- Deprecated: {"action": "renamed", "new_name": "otel.scope.name", "note": "use the `otel.scope.name` attribute."}


#### Attribute `otel.library.version`
Expand All @@ -39,7 +39,7 @@ Brief: Span attributes used by non-OTLP exporters to represent OpenTelemetry Sco
- Examples: [
"1.0.0",
]
- Deprecated: use the `otel.scope.version` attribute.
- Deprecated: {"action": "renamed", "new_name": "otel.scope.version", "note": "use the `otel.scope.version` attribute."}



Expand Down
41 changes: 41 additions & 0 deletions crates/weaver_forge/src/extensions/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ pub(crate) fn add_filters(env: &mut Environment<'_>, target_config: &WeaverConfi
env.add_filter("flatten", flatten);
env.add_filter("split_id", split_id);
env.add_filter("regex_replace", regex_replace);
env.add_filter("toyaml", to_yaml);
}

/// Add utility functions to the environment.
Expand Down Expand Up @@ -86,6 +87,32 @@ fn regex_replace(
.to_string())
}

/// Convert a value to a YAML string.
fn to_yaml(value: Value) -> Result<Value, minijinja::Error> {
serde_yaml::to_string(&value)
.map_err(|e| {
minijinja::Error::new(
ErrorKind::InvalidOperation,
format!("Failed to convert to YAML: {}", e),
)
})
.map(|s| {
// When this filter is used the return value is safe for both HTML and YAML
// Note: this code is a copy of the `tojson` filter with the JSON-specific parts removed
let mut rv = String::with_capacity(s.len());
for c in s.chars() {
match c {
'<' => rv.push_str("\\u003c"),
'>' => rv.push_str("\\u003e"),
'&' => rv.push_str("\\u0026"),
'\'' => rv.push_str("\\u0027"),
_ => rv.push(c),
}
}
Value::from_safe_string(rv)
})
}

/// Create a filter that replaces acronyms in the input string with the full
/// name defined in the `acronyms` list.
///
Expand Down Expand Up @@ -159,4 +186,18 @@ mod tests {
"This A test with multiple A's"
);
}

#[test]
fn test_to_yaml() {
let mut env = Environment::new();
let ctx = serde_json::json!({"ctx": {"key": "value", "nested": {"key": "value"}}});
let config = crate::config::WeaverConfig::default();

add_filters(&mut env, &config);

assert_eq!(
env.render_str("{{ ctx | toyaml }}", &ctx).unwrap(),
"key: value\nnested:\n key: value\n"
);
}
}
41 changes: 18 additions & 23 deletions crates/weaver_forge/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -755,13 +755,12 @@ mod tests {
let registry = SemConvRegistry::try_from_path_pattern(registry_id, "data/*.yaml")
.into_result_failing_non_fatal()
.expect("Failed to load registry");
prepare_test_with_registry(target, cli_params, registry_id, registry)
prepare_test_with_registry(target, cli_params, registry)
}

fn prepare_test_with_registry(
target: &str,
cli_params: Params,
registry_id: &str,
mut registry: SemConvRegistry,
) -> (
TestLogger,
Expand All @@ -779,16 +778,14 @@ mod tests {
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
)
});
let template_registry =
ResolvedRegistry::try_from_resolved_registry(&schema.registry, 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/target directory
// before generating the new files.
Expand Down Expand Up @@ -959,16 +956,14 @@ mod tests {
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
)
});
let template_registry =
ResolvedRegistry::try_from_resolved_registry(&schema.registry, schema.catalog())
.unwrap_or_else(|e| {
panic!(
"Failed to create the context for the template evaluation: {:?}",
e
)
});

engine
.generate(
Expand Down Expand Up @@ -1093,7 +1088,7 @@ mod tests {
.into_result_failing_non_fatal()
.expect("Failed to load registry");
let (logger, engine, template_registry, observed_output, expected_output) =
prepare_test_with_registry("comment_format", Params::default(), registry_id, registry);
prepare_test_with_registry("comment_format", Params::default(), registry);

engine
.generate(
Expand Down
3 changes: 2 additions & 1 deletion crates/weaver_forge/src/registry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use weaver_resolved_schema::catalog::Catalog;
use weaver_resolved_schema::lineage::GroupLineage;
use weaver_resolved_schema::registry::{Constraint, Group, Registry};
use weaver_semconv::any_value::AnyValueSpec;
use weaver_semconv::deprecated::Deprecated;
use weaver_semconv::group::{GroupType, InstrumentSpec, SpanKindSpec};
use weaver_semconv::stability::Stability;

Expand Down Expand Up @@ -63,7 +64,7 @@ pub struct ResolvedGroup {
/// provided as `description` MUST specify why it's deprecated and/or what
/// to use instead. See also stability.
#[serde(skip_serializing_if = "Option::is_none")]
pub deprecated: Option<String>,
pub deprecated: Option<Deprecated>,
/// Additional constraints.
/// Allow to define additional requirements on the semantic convention.
/// It defaults to an empty list.
Expand Down
21 changes: 21 additions & 0 deletions crates/weaver_otel_schema/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
[package]
name = "weaver_otel_schema"
version = "0.10.0"
authors.workspace = true
repository.workspace = true
license.workspace = true
publish.workspace = true
edition.workspace = true
rust-version.workspace = true

[lints]
workspace = true

[dependencies]
weaver_version = { path = "../weaver_version" }
weaver_common = { path = "../weaver_common" }

thiserror.workspace = true
serde.workspace = true
serde_yaml.workspace = true
miette.workspace = true
3 changes: 3 additions & 0 deletions crates/weaver_otel_schema/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# OpenTelemetry Schema Data Model

This crate describes the data model for the OpenTelemetry telemetry schema.
6 changes: 6 additions & 0 deletions crates/weaver_otel_schema/allowed-external-types.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Copyright The OpenTelemetry Authors
# SPDX-License-Identifier: Apache-2.0
# This is used with cargo-check-external-types to reduce the surface area of downstream crates from
# the public API. Ideally this can have a few exceptions as possible.
allowed_external_types = [
]
Loading
Loading