Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b699ca8857 | ||
|
|
34b5fc72fe | ||
|
|
1e9a00ba46 |
2 changed files with 47 additions and 7 deletions
|
|
@ -327,13 +327,18 @@ Agents can push arbitrary labeled metrics to the same OTEL collector via the
|
||||||
### Usage
|
### Usage
|
||||||
|
|
||||||
```text
|
```text
|
||||||
hive-metric <name> <value> [--type counter|gauge] [--labels key=value...]
|
hive-metric <name> <value> [--type counter|gauge] [--temporality delta|cumulative] [--labels key=value...]
|
||||||
```
|
```
|
||||||
|
|
||||||
- `<name>` — metric name (e.g. `tasks_completed`, `latency_ms`).
|
- `<name>` — metric name (e.g. `tasks_completed`, `latency_ms`).
|
||||||
- `<value>` — numeric value (f64; integers and floats both accepted).
|
- `<value>` — numeric value (f64; integers and floats both accepted).
|
||||||
- `--type counter|gauge` — metric kind: `counter` (cumulative sum, default) or
|
- `--type counter|gauge` — metric kind: `counter` (increasing sum, default) or
|
||||||
`gauge` (instantaneous point-in-time value).
|
`gauge` (instantaneous point-in-time value).
|
||||||
|
- `--temporality delta|cumulative` — counter reporting mode (`counter` only,
|
||||||
|
ignored for `gauge`): `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).
|
||||||
- `--labels key=value` — extra per-data-point labels. May be repeated.
|
- `--labels key=value` — extra per-data-point labels. May be repeated.
|
||||||
The resource labels (agent, hive, swarm, service.name) are inherited
|
The resource labels (agent, hive, swarm, service.name) are inherited
|
||||||
automatically from `OTEL_RESOURCE_ATTRIBUTES` — do not re-specify them.
|
automatically from `OTEL_RESOURCE_ATTRIBUTES` — do not re-specify them.
|
||||||
|
|
@ -341,7 +346,7 @@ hive-metric <name> <value> [--type counter|gauge] [--labels key=value...]
|
||||||
### Examples
|
### Examples
|
||||||
|
|
||||||
```text
|
```text
|
||||||
# Counter: cumulative tasks finished (default type — no --type flag needed)
|
# Counter: one more task finished (delta is the default — no flag needed)
|
||||||
hive-metric tasks_completed 1 --labels phase=scan
|
hive-metric tasks_completed 1 --labels phase=scan
|
||||||
|
|
||||||
# Gauge: current queue depth (absolute value — must use --type gauge)
|
# Gauge: current queue depth (absolute value — must use --type gauge)
|
||||||
|
|
@ -366,8 +371,17 @@ with an informative error message. No silently-dropped metrics.
|
||||||
|
|
||||||
## Metrics temporality
|
## Metrics temporality
|
||||||
|
|
||||||
OTEL export is always configured with **cumulative** temporality
|
OTEL export is configured with **cumulative** temporality by default
|
||||||
(`OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE=cumulative`),
|
(`OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE=cumulative`),
|
||||||
overriding Claude Code's default of DELTA. This avoids silent metric drops in
|
overriding Claude Code's default of DELTA. This avoids silent metric drops in
|
||||||
Prometheus-family backends (including Grafana LGTM / Mimir) that don't ship a
|
Prometheus-family backends (including Grafana LGTM / Mimir) that don't ship a
|
||||||
delta-to-cumulative processor.
|
delta-to-cumulative processor.
|
||||||
|
|
||||||
|
**`hive-metric` counters are the one exception**, reporting delta by default
|
||||||
|
(see above) — programmatically set on the exporter, which overrides this
|
||||||
|
container-wide env var for that tool specifically. `--type gauge` is
|
||||||
|
unaffected either way; gauges have no temporality. The hive-tier collector
|
||||||
|
runs a `deltatocumulative` processor ahead of export, so a delta
|
||||||
|
`hive-metric` counter still lands in VictoriaMetrics as a cumulative
|
||||||
|
series — the standard `rate()`/`increase()` idioms work on it exactly like
|
||||||
|
any other counter in this system, no special query needed.
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@
|
||||||
//!
|
//!
|
||||||
//! # Usage
|
//! # Usage
|
||||||
//! ```text
|
//! ```text
|
||||||
//! hive-metric <name> <value> [--type counter|gauge] [--labels key=value...]
|
//! hive-metric <name> <value> [--type counter|gauge] [--temporality delta|cumulative] [--labels key=value...]
|
||||||
//! ```
|
//! ```
|
||||||
|
|
||||||
use anyhow::{Context, Result, bail};
|
use anyhow::{Context, Result, bail};
|
||||||
|
|
@ -20,6 +20,7 @@ use clap::Parser;
|
||||||
use opentelemetry::KeyValue;
|
use opentelemetry::KeyValue;
|
||||||
use opentelemetry::metrics::MeterProvider;
|
use opentelemetry::metrics::MeterProvider;
|
||||||
use opentelemetry_otlp::{Protocol, WithExportConfig};
|
use opentelemetry_otlp::{Protocol, WithExportConfig};
|
||||||
|
use opentelemetry_sdk::metrics::Temporality;
|
||||||
|
|
||||||
#[derive(Parser)]
|
#[derive(Parser)]
|
||||||
#[command(
|
#[command(
|
||||||
|
|
@ -39,10 +40,17 @@ struct Cli {
|
||||||
/// negative; counters must be >= 0 (they only increase).
|
/// negative; counters must be >= 0 (they only increase).
|
||||||
value: f64,
|
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")]
|
#[arg(long = "type", value_name = "TYPE", default_value = "counter")]
|
||||||
metric_type: MetricKind,
|
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.
|
/// Extra label(s) as `key=value` pairs. May be repeated.
|
||||||
/// Resource labels (agent, hive, swarm) come from `OTEL_RESOURCE_ATTRIBUTES`
|
/// Resource labels (agent, hive, swarm) come from `OTEL_RESOURCE_ATTRIBUTES`
|
||||||
/// automatically — do not re-specify them here.
|
/// automatically — do not re-specify them here.
|
||||||
|
|
@ -52,12 +60,29 @@ struct Cli {
|
||||||
|
|
||||||
#[derive(Clone, Debug, clap::ValueEnum)]
|
#[derive(Clone, Debug, clap::ValueEnum)]
|
||||||
enum MetricKind {
|
enum MetricKind {
|
||||||
/// Counter: monotonically increasing cumulative sum (default).
|
/// Counter: increasing sum (default).
|
||||||
Counter,
|
Counter,
|
||||||
/// Gauge: point-in-time instantaneous value.
|
/// Gauge: point-in-time instantaneous value.
|
||||||
Gauge,
|
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<TemporalityArg> for Temporality {
|
||||||
|
fn from(arg: TemporalityArg) -> Self {
|
||||||
|
match arg {
|
||||||
|
TemporalityArg::Delta => Temporality::Delta,
|
||||||
|
TemporalityArg::Cumulative => Temporality::Cumulative,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn main() -> Result<()> {
|
fn main() -> Result<()> {
|
||||||
let cli = Cli::parse();
|
let cli = Cli::parse();
|
||||||
|
|
||||||
|
|
@ -86,6 +111,7 @@ fn main() -> Result<()> {
|
||||||
let exporter = opentelemetry_otlp::MetricExporter::builder()
|
let exporter = opentelemetry_otlp::MetricExporter::builder()
|
||||||
.with_http()
|
.with_http()
|
||||||
.with_protocol(Protocol::HttpJson)
|
.with_protocol(Protocol::HttpJson)
|
||||||
|
.with_temporality(cli.temporality.into())
|
||||||
.build()
|
.build()
|
||||||
.context("failed to build OTLP metric exporter")?;
|
.context("failed to build OTLP metric exporter")?;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue