diff --git a/hive-metric/src/main.rs b/hive-metric/src/main.rs index 48e066eb..0e107031 100644 --- a/hive-metric/src/main.rs +++ b/hive-metric/src/main.rs @@ -12,7 +12,7 @@ //! //! # Usage //! ```text -//! hive-metric [--type counter|gauge] [--labels key=value...] +//! hive-metric [--type counter|gauge] [--temporality delta|cumulative] [--labels key=value...] //! ``` use anyhow::{Context, Result, bail}; @@ -20,6 +20,7 @@ use clap::Parser; use opentelemetry::KeyValue; use opentelemetry::metrics::MeterProvider; use opentelemetry_otlp::{Protocol, WithExportConfig}; +use opentelemetry_sdk::metrics::Temporality; #[derive(Parser)] #[command( @@ -39,10 +40,17 @@ struct Cli { /// negative; counters must be >= 0 (they only increase). value: f64, - /// Metric kind: `counter` (cumulative sum, default) or `gauge` (instantaneous value). + /// Metric kind: `counter` (increasing sum, default) or `gauge` (instantaneous value). #[arg(long = "type", value_name = "TYPE", default_value = "counter")] metric_type: MetricKind, + /// Counter reporting mode: `delta` (this call's own contribution, default — + /// send `1` each time and the collector accumulates) or `cumulative` (this + /// call reports the running total, which a stateless one-shot CLI can't + /// track itself — only meaningful for `--type counter`; ignored for `gauge`). + #[arg(long, value_name = "MODE", default_value = "delta")] + temporality: TemporalityArg, + /// Extra label(s) as `key=value` pairs. May be repeated. /// Resource labels (agent, hive, swarm) come from `OTEL_RESOURCE_ATTRIBUTES` /// automatically — do not re-specify them here. @@ -52,12 +60,29 @@ struct Cli { #[derive(Clone, Debug, clap::ValueEnum)] enum MetricKind { - /// Counter: monotonically increasing cumulative sum (default). + /// Counter: increasing sum (default). Counter, /// Gauge: point-in-time instantaneous value. Gauge, } +#[derive(Clone, Debug, clap::ValueEnum)] +enum TemporalityArg { + /// Report this call's own contribution since the last report (default). + Delta, + /// Report the running total as of this call. + Cumulative, +} + +impl From for Temporality { + fn from(arg: TemporalityArg) -> Self { + match arg { + TemporalityArg::Delta => Temporality::Delta, + TemporalityArg::Cumulative => Temporality::Cumulative, + } + } +} + fn main() -> Result<()> { let cli = Cli::parse(); @@ -86,6 +111,7 @@ fn main() -> Result<()> { let exporter = opentelemetry_otlp::MetricExporter::builder() .with_http() .with_protocol(Protocol::HttpJson) + .with_temporality(cli.temporality.into()) .build() .context("failed to build OTLP metric exporter")?;