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
293 changes: 157 additions & 136 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<&str> {
self.attributes
.get(attribute_ref.0 as usize)
.map(|attr| attr.name.as_ref())
}
}
44 changes: 43 additions & 1 deletion 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 @@ -124,7 +125,7 @@ pub enum TypedGroup {
}

/// Allow to define additional requirements on the semantic convention.
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Hash, Eq)]
#[serde(deny_unknown_fields)]
pub struct Constraint {
/// any_of accepts a list of sequences. Each sequence contains a list of
Expand All @@ -137,3 +138,44 @@ 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())
});
}

/// Returns the provenance of the group.
pub fn provenance(&self) -> &str {
match &self.lineage {
Some(lineage) => lineage.provenance(),
None => "unknown",
}
}
}
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
Loading
Loading