#[aggregate]Expand description
Generates aggregation support for metrics structs.
This macro enables combining multiple observations of the same metric into a single aggregated
entry. It must be placed before #[metrics] and generates:
- An
Aggregated{StructName}struct with aggregated field types - An
AggregateEntrytrait implementation for merging observations
For renaming fields and adding unit, #[aggregate] relies on the #[metrics] macro.
§Container Attributes
| Attribute | Type | Description | Example |
|---|---|---|---|
direct | Flag | Aggregates on the struct itself instead of the closed entry (default: aggregates on closed entry) | #[aggregate(direct)] |
§Field Attributes
| Attribute | Type | Description | Example |
|---|---|---|---|
strategy | Path | Specifies the aggregation strategy (required for non-key fields) | #[aggregate(strategy = Histogram<Duration>)] |
key | Flag | Marks a field as part of the aggregation key - observations with different keys are aggregated separately | #[aggregate(key)] |
ignore | Flag | Ignore a field during aggregation. The field will still be part of the non-aggregated metric entry unless also marked #[metrics(ignore)] |
§Aggregation Modes
§Entry Mode (Default)
By default, #[aggregate] implements aggregation on the closed metric entry. This means
aggregation happens after CloseValue has been applied to all fields:
use metrique::unit_of_work::metrics;
use metrique_aggregation::{aggregate, histogram::Histogram, value::Sum};
use std::time::Duration;
#[aggregate]
#[metrics]
struct ApiCall {
#[aggregate(strategy = Histogram<Duration>)]
#[metrics(unit = metrique::writer::unit::Millisecond)]
latency: Duration, // Aggregates Duration values
#[aggregate(strategy = Sum)]
response_size: usize,
}§Direct Mode
Use #[aggregate(direct)] to aggregate on the struct iteslf. In direct mode:
- Aggregation strategies receive the raw field type before
CloseValueis applied - Use this if the base struct is not also a metric
§Aggregation Keys
Fields marked with #[aggregate(key)] define the aggregation key. Observations with different
keys are aggregated into separate entries:
use metrique::unit_of_work::metrics;
use metrique_aggregation::{aggregate, histogram::Histogram};
use std::time::Duration;
#[aggregate]
#[metrics]
struct ApiCall {
#[aggregate(key)]
endpoint: String, // Separate aggregation per endpoint
#[aggregate(strategy = Histogram<Duration>)]
latency: Duration,
}Key behavior:
- Key fields are cloned into the aggregated struct unchanged
- Multiple key fields create a tuple key:
(Field1, Field2, ...) - Without key fields, all observations aggregate into a single entry
- Key fields must implement
Clone
§Aggregation Strategies
Each non-key field must specify an aggregation strategy that implements AggregateValue<T>:
§Built-in Strategies
Sum- Sums numeric values togetherHistogram<T>- Collects values into a distribution. Histogram has a second generic that can control how values are stored. See theHistogramdocs for more info.KeepLast- Keeps the most recent value
use metrique::unit_of_work::metrics;
use metrique_aggregation::{aggregate, histogram::Histogram, value::Sum};
use std::time::Duration;
#[aggregate]
#[metrics]
struct ApiCall {
#[aggregate(strategy = Histogram<Duration>)]
latency: Duration,
#[aggregate(strategy = Sum)]
bytes_sent: usize,
}§Generated Types
For a struct with #[aggregate], the macro generates:
AggregatedMyMetrics: The aggregated struct where each field is replaced with its aggregated typeimpl AggregateEntry for MyMetrics: Trait implementation for merging observations
For more details on the aggregation trait system, see the traits module documentation.
The aggregated struct can be used with Aggregate<T> or MutexSink<T>:
use metrique::unit_of_work::metrics;
use metrique_aggregation::{aggregate, histogram::Histogram, aggregator::Aggregate};
use std::time::Duration;
#[aggregate]
#[metrics]
struct ApiCall {
#[aggregate(strategy = Histogram<Duration>)]
latency: Duration,
}
#[metrics]
struct RequestMetrics {
request_id: String,
#[metrics(flatten)]
api_calls: Aggregate<ApiCall>,
}For more examples, see the examples directory in metrique-aggregation