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

[Feature] Implement any_of and include constraints support #39

Merged
merged 11 commits into from
Feb 28, 2024
260 changes: 130 additions & 130 deletions Cargo.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion crates/weaver_resolved_schema/src/attribute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ pub struct Attribute {
}

/// An unresolved attribute definition.
#[derive(Debug, Clone)]
#[derive(Debug, Deserialize, Clone)]
pub struct UnresolvedAttribute {
/// The attribute specification.
pub spec: AttributeSpec,
Expand Down
12 changes: 11 additions & 1 deletion crates/weaver_resolved_schema/src/catalog.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
//! Defines the catalog of attributes, metrics, and other telemetry items
//! that are shared across multiple signals in the Resolved Telemetry Schema.

use crate::attribute::Attribute;
use crate::attribute::{Attribute, AttributeRef};
use crate::metric::Metric;
use serde::{Deserialize, Serialize};
use std::fmt::Debug;
Expand Down Expand Up @@ -31,3 +31,13 @@ pub enum Stability {
/// A stable definition.
Stable,
}

impl Catalog {
/// Returns the attribute name from an attribute ref if it exists
/// in the catalog or None if it does not exist.
pub fn attribute_name(&self, attribute_ref: &AttributeRef) -> Option<String> {
lquerel marked this conversation as resolved.
Show resolved Hide resolved
self.attributes
.get(attribute_ref.0 as usize)
.map(|attr| attr.name.clone())
}
}
34 changes: 34 additions & 0 deletions crates/weaver_resolved_schema/src/registry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

use crate::attribute::AttributeRef;
use serde::{Deserialize, Serialize};
use std::collections::HashSet;

use crate::catalog::Stability;
use crate::lineage::GroupLineage;
Expand Down Expand Up @@ -137,3 +138,36 @@ pub struct Constraint {
/// not already defined in the current semantic convention.
pub include: Option<String>,
}

impl Group {
/// Returns true if the group contains at least one `include` constraint.
pub fn has_include(&self) -> bool {
self.constraints.iter().any(|c| c.include.is_some())
}

/// Import attributes from the provided slice that do not exist in the
/// current group.
pub fn import_attributes_from(&mut self, attributes: &[AttributeRef]) {
for attr in attributes {
if !self.attributes.contains(attr) {
self.attributes.push(*attr);
}
}
}

/// Update the group constraints according to the provided constraints to
/// add and the `include` constraints to remove.
pub fn update_constraints(
&mut self,
constraints_to_add: Vec<Constraint>,
include_to_remove: HashSet<String>,
) {
// Add the new constraints
self.constraints.extend(constraints_to_add);

// Remove the include constraints
self.constraints.retain(|c| {
c.include.is_none() || !include_to_remove.contains(c.include.as_ref().unwrap())
});
}
}
6 changes: 4 additions & 2 deletions crates/weaver_resolver/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# Telemetry Schema Resolution Process

Status: **Work-In-Progress**
Resolution Process Status:
- Semantic Convention Registry: **Fully Implemented**, **Partially Tested**
- Application Telemetry Schema: **Partially Implemented**

This crate describes the resolution process for the OpenTelemetry telemetry
schema. The resolution process takes a telemetry schema and/or a semantic
Expand Down Expand Up @@ -36,7 +38,7 @@ involves the following steps:
- Resolve iteratively all `extends` parent/child clauses until no more
resolvable `extends` are found. The extended entity inherits prefix,
attributes, and constraints from the parent entity.
- Apply constraints `any_of` and `include` (not yet supported).
- Apply constraints `any_of` and `include`.
- Validate the resolved semantic conventions
- No more unresolved `ref` or `extends` clauses. The unresolved list should
be empty.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2477,29 +2477,44 @@
"events": []
},
"brief": "Semantic convention group for specific technologies",
"constraints": [
{
"any_of": [],
"include": "db.cassandra"
},
{
"any_of": [],
"include": "db.redis"
},
{
"any_of": [],
"include": "db.mongodb"
},
{
"any_of": [],
"include": "db.sql"
},
{
"any_of": [],
"include": "db.cosmosdb"
}
"constraints": [],
"attributes": [
62,
63,
64,
65,
66,
67,
68,
69,
70,
71,
72,
73,
74,
75,
77,
78,
79,
80,
81,
82,
83,
84,
87,
88,
89,
99,
100,
101,
102,
103,
104,
105,
106,
107,
108
],
"attributes": [],
"lineage": {
"provenance": "data/registry-test-7-spans/registry/trace-database.yaml"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ groups:
tag: call-level-tech-specific-cassandra
brief: >
The keyspace name in Cassandra.
examples: ["mykeyspace"]
examples: [ "mykeyspace" ]
note: For Cassandra the `db.name` should be set to the Cassandra keyspace name.
- ref: db.cassandra.page_size
tag: call-level-tech-specific-cassandra
Expand All @@ -97,7 +97,7 @@ groups:
tag: call-level-tech-specific
brief: >
The HBase namespace.
examples: ['mynamespace']
examples: [ 'mynamespace' ]
note: For HBase the `db.name` should be set to the HBase namespace.

- id: db.couchdb
Expand All @@ -110,7 +110,7 @@ groups:
tag: call-level-tech-specific
brief: >
The HTTP method + the target REST route.
examples: ['GET /{db}/{docid}']
examples: [ 'GET /{db}/{docid}' ]
note: >
In **CouchDB**, `db.operation` should be set to the HTTP method +
the target REST route according to the API reference documentation.
Expand All @@ -132,7 +132,7 @@ groups:
tag: call-level-tech-specific
brief: >
The full syntax of the Redis CLI command.
examples: ["HMSET myhash field1 'Hello' field2 'World'"]
examples: [ "HMSET myhash field1 'Hello' field2 'World'" ]
note: >
For **Redis**, the value provided for `db.statement` SHOULD correspond to the syntax of the Redis CLI.
If, for example, the [`HMSET` command](https://redis.io/commands/hmset) is invoked, `"HMSET myhash field1 'Hello' field2 'World'"` would be a suitable value for `db.statement`.
Expand Down Expand Up @@ -227,7 +227,7 @@ groups:
`failover_information` : Generated key to determine if region failover enabled.
Format Reg-{D (Disabled discovery)}-S(application region)|L(List of preferred regions)|N(None, user did not configure it).
Default value is "NS".
examples: ['cosmos-netstandard-sdk/3.23.0\|3.23.1\|1\|X64\|Linux 5.4.0-1098-azure 104 18\|.NET Core 3.1.32\|S\|']
examples: [ 'cosmos-netstandard-sdk/3.23.0\|3.23.1\|1\|X64\|Linux 5.4.0-1098-azure 104 18\|.NET Core 3.1.32\|S\|' ]
tag: call-level-tech-specific
- ref: db.cosmosdb.connection_mode
requirement_level:
Expand Down Expand Up @@ -260,4 +260,5 @@ groups:
- include: 'db.redis'
- include: 'db.mongodb'
- include: 'db.sql'
- include: 'db.cosmosdb'
- include: 'db.cosmosdb'
- any_of: ['db.cassandra.page_size', 'db.cassandra.consistency_level', 'db.cassandra.table', 'db.cassandra.idempotence', 'db.cassandra.speculative_execution_count', 'db.cassandra.coordinator.id', 'db.cassandra.coordinator.dc']
11 changes: 11 additions & 0 deletions crates/weaver_resolver/src/attribute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,17 @@ impl AttributeCatalog {
attributes.into_iter().map(|(attr, _)| attr).collect()
}

/// Returns a list of indexed attribute names ordered by their references.
pub fn attribute_name_index(&self) -> Vec<String> {
let mut attributes: Vec<(&attribute::Attribute, &AttributeRef)> =
self.attribute_refs.iter().collect();
attributes.sort_by_key(|(_, attr_ref)| attr_ref.0);
attributes
.iter()
.map(|(attr, _)| attr.name.clone())
.collect()
}

/// Tries to resolve the given attribute spec (ref or id) from the catalog.
/// Returns `None` if the attribute spec is a ref and it does not exist yet
/// in the catalog.
Expand Down
40 changes: 35 additions & 5 deletions crates/weaver_resolver/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,16 @@ use regex::Regex;
use url::Url;
use walkdir::DirEntry;

use crate::attribute::AttributeCatalog;
use weaver_cache::Cache;
use weaver_logger::Logger;
use weaver_resolved_schema::attribute::AttributeRef;
use weaver_resolved_schema::catalog::Catalog;
use weaver_resolved_schema::ResolvedTelemetrySchema;
use weaver_schema::{SemConvImport, TelemetrySchema};
use weaver_semconv::{ResolverConfig, SemConvRegistry, SemConvSpec, SemConvSpecWithProvenance};
use weaver_version::VersionChanges;

use crate::attribute::AttributeCatalog;
use crate::events::resolve_events;
use crate::metrics::{resolve_metrics, semconv_to_resolved_metric};
use crate::registry::resolve_semconv_registry;
Expand Down Expand Up @@ -67,6 +68,15 @@ pub enum UnresolvedReference {
/// The provenance of the reference (URL or path).
provenance: String,
},
/// An unresolved `include` reference.
IncludeRef {
/// The id of the group containing the `include` reference.
group_id: String,
/// The unresolved `include` reference.
include_ref: String,
/// The provenance of the reference (URL or path).
provenance: String,
},
}

/// An error that can occur while resolving a telemetry schema.
Expand Down Expand Up @@ -136,6 +146,24 @@ pub enum Error {
/// The error that occurred.
message: String,
},

/// The `any_of` constraints are unsatisfied for a group.
#[error("The `any_of` constraints are unsatisfied for the group '{group_id}'.\nGroup attributes: {group_attributes:#?}\n`any_of` constraints: {any_of_constraints:#?}")]
UnsatisfiedAnyOfConstraint {
/// The id of the group containing the unsatisfied `any_of` constraint.
group_id: String,
/// The attributes of the group.
group_attributes: Vec<String>,
/// The `any_of` constraints of the group.
any_of_constraints: Vec<Vec<String>>,
},

/// Attribute ref not found in the catalog.
#[error("Attribute ref `{attribute_ref:?}` not found in the catalog.")]
UnresolvedAttribute {
/// The unresolved attribute reference.
attribute_ref: AttributeRef,
},
}

impl SchemaResolver {
Expand Down Expand Up @@ -380,14 +408,16 @@ impl SchemaResolver {
.map(semconv_to_resolved_metric)
.collect();

let catalog = Catalog {
attributes: attr_catalog.drain_attributes(),
metrics,
};

let resolved_schema = ResolvedTelemetrySchema {
file_format: "1.0.0".to_string(),
schema_url: "".to_string(),
registries: vec![resolved_registry],
catalog: Catalog {
attributes: attr_catalog.drain_attributes(),
metrics,
},
catalog,
resource: None,
instrumentation_library: None,
dependencies: vec![],
Expand Down
Loading
Loading