Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@

All notable changes to this project will be documented in this file.

# [Next] - Next

- Support for describing aggregation being done on metrics
([#845](https://github.com/open-telemetry/weaver/pull/822) by @thompson-tomo)

# [0.17.1] - 2025-08-15

- Fix error messages to ignore new version variants ([#880](https://github.com/open-telemetry/weaver/pull/880) by @jsuereth)
Expand Down
9 changes: 9 additions & 0 deletions 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::attribute::Attribute;
use weaver_resolved_schema::catalog::Catalog;
use weaver_resolved_schema::lineage::GroupLineage;
use weaver_resolved_schema::registry::{Group, Registry};
use weaver_semconv::aggregation::AggregationSpec;
use weaver_semconv::any_value::AnyValueSpec;
use weaver_semconv::deprecated::Deprecated;
use weaver_semconv::group::{GroupType, InstrumentSpec, SpanKindSpec};
Expand Down Expand Up @@ -99,6 +100,12 @@ pub struct ResolvedGroup {
/// Note: This field is required if type is metric.
#[serde(skip_serializing_if = "Option::is_none")]
pub unit: Option<String>,
/// The aggregation which should occur on the data points being capture by a meter.
/// Semconv metrics all use the default aggregation type, hence this option is for
/// providing the parameters of the aggregation.
/// For more details: [Metrics SDK - Aggregation](https://opentelemetry.io/docs/specs/otel/metrics/sdk/#aggregation).
#[serde(skip_serializing_if = "Option::is_none")]
pub aggregation: Option<AggregationSpec>,
/// The name of the event. If not specified, the prefix is used.
/// If prefix is empty (or unspecified), name is required.
#[serde(skip_serializing_if = "Option::is_none")]
Expand Down Expand Up @@ -168,6 +175,7 @@ impl ResolvedGroup {
metric_name: group.metric_name.clone(),
instrument: group.instrument.clone(),
unit: group.unit.clone(),
aggregation: group.aggregation.clone(),
name: group.name.clone(),
lineage,
display_name: group.display_name.clone(),
Expand Down Expand Up @@ -229,6 +237,7 @@ impl ResolvedRegistry {
metric_name: group.metric_name.clone(),
instrument: group.instrument.clone(),
unit: group.unit.clone(),
aggregation: group.aggregation.clone(),
name: group.name.clone(),
lineage,
display_name: group.display_name.clone(),
Expand Down
7 changes: 7 additions & 0 deletions crates/weaver_resolved_schema/src/registry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ use crate::registry::GroupStats::{
AttributeGroup, Entity, Event, Metric, MetricGroup, Scope, Span, Undefined,
};
use serde::{Deserialize, Serialize};
use weaver_semconv::aggregation::AggregationSpec;
use weaver_semconv::deprecated::Deprecated;
use weaver_semconv::group::{GroupType, InstrumentSpec, SpanKindSpec};
use weaver_semconv::provenance::Provenance;
Expand Down Expand Up @@ -113,6 +114,12 @@ pub struct Group {
/// Note: This field is required if type is metric.
#[serde(skip_serializing_if = "Option::is_none")]
pub unit: Option<String>,
/// The aggregation which should occur on the data points being capture by a meter.
/// Semconv metrics all use the default aggregation type, hence this option is for
/// providing the parameters of the aggregation.
/// For more details: [Metrics SDK - Aggregation](https://opentelemetry.io/docs/specs/otel/metrics/sdk/#aggregation).
#[serde(skip_serializing_if = "Option::is_none")]
pub aggregation: Option<AggregationSpec>,
/// The name of the event. If not specified, the prefix is used.
/// If prefix is empty (or unspecified), name is required.
#[serde(skip_serializing_if = "Option::is_none")]
Expand Down
1 change: 1 addition & 0 deletions crates/weaver_resolver/src/registry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,7 @@ fn group_from_spec(group: GroupSpecWithProvenance) -> UnresolvedGroup {
metric_name: group.spec.metric_name,
instrument: group.spec.instrument,
unit: group.spec.unit,
aggregation: group.spec.aggregation,
name: group.spec.name,
lineage: Some(GroupLineage::new(group.provenance.clone())),
display_name: group.spec.display_name,
Expand Down
7 changes: 7 additions & 0 deletions crates/weaver_semconv/data/jvm-metrics.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,13 @@ groups:
brief: "Duration of JVM garbage collection actions."
instrument: histogram
unit: "s"
aggregation:
parameters:
boundaries:
- 0
- 5
- 10
recordMinMax: true
attributes:
- id: jvm.gc.name
stability: stable
Expand Down
46 changes: 46 additions & 0 deletions crates/weaver_semconv/src/aggregation.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// SPDX-License-Identifier: Apache-2.0

//! Metric specification.
//!
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use crate::YamlValue;

/// An aggregation specification.
#[derive(Serialize, Deserialize, Clone, Debug, Eq, PartialEq, JsonSchema)]
#[serde(deny_unknown_fields)]
pub struct AggregationSpec {
/// The method of aggregation to be used
#[serde(skip_serializing_if = "Option::is_none")]
pub method: Option<AggregationMethodSpec>,
/// The parameters used in the aggregation
#[serde(skip_serializing_if = "Option::is_none")]
pub parameters: Option<HashMap<String, YamlValue>>,
}

impl AggregationSpec {
/// Returns the parameters of the aggregation.
#[must_use]
pub fn parameters(&self) -> &Option<HashMap<String, YamlValue>> {
&self.parameters
}
}

/// The Aggregation Method
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, Hash, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub enum AggregationMethodSpec {
/// Use the Default Aggregation Method.
Default,
/// Use the Sum Aggregation Method.
Sum,
/// Use the Last Value Aggregation Method.
LastValue,
/// Use the Histogram Aggregation Method.
Histogram,
/// Use the Explicit Histogram Aggregation Method.
ExplicitHistogram,
/// Use the Exponential Histogram Aggregation Method.
ExponentialHistogram,
}
18 changes: 18 additions & 0 deletions crates/weaver_semconv/src/group.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use serde::{Deserialize, Serialize};
use std::collections::{BTreeMap, HashSet};
use std::fmt::{Display, Formatter};

use crate::aggregation::AggregationSpec;
use crate::any_value::AnyValueSpec;
use crate::attribute::{AttributeSpec, AttributeType, PrimitiveOrArrayTypeSpec};
use crate::deprecated::Deprecated;
Expand Down Expand Up @@ -97,6 +98,12 @@ pub struct GroupSpec {
/// Note: This field is required if type is metric.
#[serde(skip_serializing_if = "Option::is_none")]
pub unit: Option<String>,
/// The aggregation which should occur on the data points being capture by a meter.
/// Semconv metrics all use the default aggregation type, hence this option is for
/// providing the parameters of the aggregation.
/// For more details: [Metrics SDK - Aggregation](https://opentelemetry.io/docs/specs/otel/metrics/sdk/#aggregation).
#[serde(skip_serializing_if = "Option::is_none")]
pub aggregation: Option<AggregationSpec>,
/// The name of the event (valid only when the group `type` is `event`).
///
/// Note: If not specified, the prefix is used. If the prefix is empty (or unspecified), the name is required.
Expand Down Expand Up @@ -694,6 +701,7 @@ mod tests {
metric_name: None,
instrument: None,
unit: None,
aggregation: None,
name: None,
display_name: None,
body: None,
Expand Down Expand Up @@ -859,6 +867,7 @@ mod tests {
metric_name: None,
instrument: None,
unit: None,
aggregation: None,
name: None,
display_name: None,
body: None,
Expand Down Expand Up @@ -1145,6 +1154,7 @@ mod tests {
metric_name: None,
instrument: None,
unit: None,
aggregation: None,
display_name: None,
attributes: vec![],
body: Some(AnyValueSpec::String {
Expand Down Expand Up @@ -1360,6 +1370,7 @@ mod tests {
metric_name: None,
instrument: None,
unit: None,
aggregation: None,
display_name: None,
attributes: vec![],
body: Some(AnyValueSpec::String {
Expand Down Expand Up @@ -1515,6 +1526,7 @@ mod tests {
metric_name: None,
instrument: None,
unit: None,
aggregation: None,
name: None,
display_name: None,
body: None,
Expand Down Expand Up @@ -1586,6 +1598,7 @@ mod tests {
group.metric_name = Some("test".to_owned());
group.instrument = Some(Counter);
group.unit = Some("test".to_owned());
group.aggregation = None;
let result = group.validate("<test>").into_result_failing_non_fatal();
assert_eq!(
Err(InvalidGroupStability {
Expand Down Expand Up @@ -1685,6 +1698,7 @@ mod tests {
metric_name: None,
instrument: None,
unit: None,
aggregation: None,
name: None,
display_name: None,
body: None,
Expand Down Expand Up @@ -1776,6 +1790,7 @@ mod tests {
group.metric_name = Some("test".to_owned());
group.instrument = Some(Counter);
group.unit = Some("test".to_owned());
group.aggregation = None;
assert!(group
.validate("<test>")
.into_result_failing_non_fatal()
Expand Down Expand Up @@ -1837,6 +1852,7 @@ mod tests {
metric_name: None,
instrument: None,
unit: None,
aggregation: None,
name: None,
display_name: None,
body: None,
Expand Down Expand Up @@ -1897,6 +1913,7 @@ mod tests {
metric_name: Some("metric".to_owned()),
instrument: Some(Gauge),
unit: Some("{thing}".to_owned()),
aggregation: None,
name: None,
display_name: None,
body: None,
Expand All @@ -1913,6 +1930,7 @@ mod tests {
group.metric_name = None;
group.instrument = None;
group.unit = None;
group.aggregation = None;
group.span_kind = Some(SpanKindSpec::Client);
assert!(group
.validate("<test>")
Expand Down
1 change: 1 addition & 0 deletions crates/weaver_semconv/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use std::path::PathBuf;
use weaver_common::diagnostic::{DiagnosticMessage, DiagnosticMessages};
use weaver_common::error::{format_errors, WeaverError};

pub mod aggregation;
pub mod any_value;
pub mod attribute;
pub mod deprecated;
Expand Down
2 changes: 2 additions & 0 deletions crates/weaver_semconv/src/registry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,7 @@ mod tests {
metric_name: None,
instrument: None,
unit: None,
aggregation: None,
brief: "brief".to_owned(),
note: "note".to_owned(),
extends: None,
Expand Down Expand Up @@ -366,6 +367,7 @@ mod tests {
metric_name: None,
instrument: None,
unit: None,
aggregation: None,
brief: "brief".to_owned(),
note: "note".to_owned(),
extends: None,
Expand Down