forked from open-telemetry/weaver
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcatalog.rs
More file actions
142 lines (131 loc) · 5.27 KB
/
catalog.rs
File metadata and controls
142 lines (131 loc) · 5.27 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
// SPDX-License-Identifier: Apache-2.0
//! 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, AttributeRef};
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use std::collections::{BTreeMap, HashMap};
use std::fmt::Debug;
use weaver_semconv::attribute::{AttributeType, BasicRequirementLevelSpec, RequirementLevel};
use weaver_semconv::stability::Stability;
/// A catalog of indexed attributes shared across semconv groups, or signals.
/// Attribute references are used to refer to attributes in the catalog.
///
/// Note : In the future, this catalog could be extended with other entities.
#[derive(Serialize, Deserialize, Debug, Clone, JsonSchema, Default, PartialEq, Eq)]
#[serde(deny_unknown_fields)]
#[must_use]
pub struct Catalog {
/// Catalog of attributes used in the schema.
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub(crate) attributes: Vec<Attribute>,
}
/// Statistics on a catalog.
#[derive(Debug, Serialize)]
#[must_use]
pub struct Stats {
/// Total number of attributes.
pub attribute_count: usize,
/// Breakdown of attribute types.
pub attribute_type_breakdown: BTreeMap<String, usize>,
/// Breakdown of requirement levels.
pub requirement_level_breakdown: BTreeMap<String, usize>,
/// Breakdown of stability levels.
pub stability_breakdown: HashMap<Stability, usize>,
/// Number of deprecated attributes.
pub deprecated_count: usize,
}
impl Catalog {
/// Creates a catalog from a list of attributes.
pub fn from_attributes(attributes: Vec<Attribute>) -> Self {
Self { attributes }
}
/// Adds attributes to the catalog and returns a list of attribute references.
#[must_use]
pub fn add_attributes<const N: usize>(
&mut self,
attributes: [Attribute; N],
) -> Vec<AttributeRef> {
let start_index = self.attributes.len();
self.attributes.extend(attributes.iter().cloned());
(start_index..self.attributes.len())
.map(|i| AttributeRef(i as u32))
.collect::<Vec<_>>()
}
/// Returns the attribute name from an attribute ref if it exists
/// in the catalog or None if it does not exist.
#[must_use]
pub fn attribute_name(&self, attribute_ref: &AttributeRef) -> Option<&str> {
self.attributes
.get(attribute_ref.0 as usize)
.map(|attr| attr.name.as_ref())
}
/// Counts the number of attributes in the catalog.
#[must_use]
pub fn count_attributes(&self) -> usize {
self.attributes.len()
}
/// Return an iterator over the attributes in the catalog.
pub fn iter(&self) -> impl Iterator<Item = &Attribute> {
self.attributes.iter()
}
/// Returns the attribute from an attribute ref if it exists.
#[must_use]
pub fn attribute(&self, attribute_ref: &AttributeRef) -> Option<&Attribute> {
self.attributes.get(attribute_ref.0 as usize)
}
/// Statistics on the catalog.
pub fn stats(&self) -> Stats {
Stats {
attribute_count: self.attributes.len(),
attribute_type_breakdown: self
.attributes
.iter()
.map(|attr| {
if let AttributeType::Enum { members, .. } = &attr.r#type {
(format!("enum(card:{:03})", members.len()), 1)
} else {
(format!("{:#}", attr.r#type), 1)
}
})
.fold(BTreeMap::new(), |mut acc, (k, v)| {
*acc.entry(k).or_insert(0) += v;
acc
}),
requirement_level_breakdown: self
.attributes
.iter()
.map(|attr| {
let requirement_level = match &attr.requirement_level {
RequirementLevel::Basic(BasicRequirementLevelSpec::Required) => "required",
RequirementLevel::Basic(BasicRequirementLevelSpec::Recommended) => {
"recommended"
}
RequirementLevel::Basic(BasicRequirementLevelSpec::OptIn) => "opt_in",
RequirementLevel::Recommended { .. } => "recommended",
RequirementLevel::ConditionallyRequired { .. } => "conditionally_required",
RequirementLevel::OptIn { .. } => "opt_in",
};
(requirement_level.to_owned(), 1)
})
.fold(BTreeMap::new(), |mut acc, (k, v)| {
*acc.entry(k).or_insert(0) += v;
acc
}),
stability_breakdown: self
.attributes
.iter()
.filter_map(|attr| attr.stability.as_ref())
.map(|stability| (stability.clone(), 1))
.fold(HashMap::new(), |mut acc, (k, v)| {
*acc.entry(k).or_insert(0) += v;
acc
}),
deprecated_count: self
.attributes
.iter()
.filter(|attr| attr.deprecated.is_some())
.count(),
}
}
}