Files
codex/codex-rs/otel/src/metrics/config.rs
T
Anton Panasenko 8660ad6c64 feat: show runtime metrics in console (#10278)
Summary of changes:

- Adds a new feature flag: runtime_metrics
  - Declared in core/src/features.rs
  - Added to core/config.schema.json
  - Wired into OTEL init in core/src/otel_init.rs

- Enables on-demand runtime metric snapshots in OTEL
  - Adds runtime_metrics: bool to otel/src/config.rs
  - Enables experimental custom reader features in otel/Cargo.toml
  - Adds snapshot/reset/summary APIs in:
    - otel/src/lib.rs
    - otel/src/metrics/client.rs
    - otel/src/metrics/config.rs
    - otel/src/metrics/error.rs

- Defines metric names and a runtime summary builder
  - New files:
    - otel/src/metrics/names.rs
    - otel/src/metrics/runtime_metrics.rs
  - Summarizes totals for:
    - Tool calls
    - API requests
    - SSE/streaming events

- Instruments metrics collection in OTEL manager
  - otel/src/traces/otel_manager.rs now records:
    - API call counts + durations
    - SSE event counts + durations (success/failure)
    - Tool call metrics now use shared constants

- Surfaces runtime metrics in the TUI
  - Resets runtime metrics at turn start in tui/src/chatwidget.rs
- Displays metrics in the final separator line in
tui/src/history_cell.rs

- Adds tests
  - New OTEL tests:
    - otel/tests/suite/snapshot.rs
    - otel/tests/suite/runtime_summary.rs
  - New TUI test:
- final_message_separator_includes_runtime_metrics in
tui/src/history_cell.rs

Scope:
- 19 files changed
- ~652 insertions, 38 deletions


<img width="922" height="169" alt="Screenshot 2026-01-30 at 4 11 34 PM"
src="https://github.com/user-attachments/assets/1efd754d-a16d-4564-83a5-f4442fd2f998"
/>
2026-01-30 22:20:02 -08:00

84 lines
2.6 KiB
Rust

use crate::config::OtelExporter;
use crate::metrics::Result;
use crate::metrics::validation::validate_tag_key;
use crate::metrics::validation::validate_tag_value;
use opentelemetry_sdk::metrics::InMemoryMetricExporter;
use std::collections::BTreeMap;
use std::time::Duration;
#[derive(Clone, Debug)]
pub enum MetricsExporter {
Otlp(OtelExporter),
InMemory(InMemoryMetricExporter),
}
#[derive(Clone, Debug)]
pub struct MetricsConfig {
pub(crate) environment: String,
pub(crate) service_name: String,
pub(crate) service_version: String,
pub(crate) exporter: MetricsExporter,
pub(crate) export_interval: Option<Duration>,
pub(crate) runtime_reader: bool,
pub(crate) default_tags: BTreeMap<String, String>,
}
impl MetricsConfig {
pub fn otlp(
environment: impl Into<String>,
service_name: impl Into<String>,
service_version: impl Into<String>,
exporter: OtelExporter,
) -> Self {
Self {
environment: environment.into(),
service_name: service_name.into(),
service_version: service_version.into(),
exporter: MetricsExporter::Otlp(exporter),
export_interval: None,
runtime_reader: false,
default_tags: BTreeMap::new(),
}
}
/// Create an in-memory config (used in tests).
pub fn in_memory(
environment: impl Into<String>,
service_name: impl Into<String>,
service_version: impl Into<String>,
exporter: InMemoryMetricExporter,
) -> Self {
Self {
environment: environment.into(),
service_name: service_name.into(),
service_version: service_version.into(),
exporter: MetricsExporter::InMemory(exporter),
export_interval: None,
runtime_reader: false,
default_tags: BTreeMap::new(),
}
}
/// Override the interval between periodic metric exports.
pub fn with_export_interval(mut self, interval: Duration) -> Self {
self.export_interval = Some(interval);
self
}
/// Enable a manual reader for on-demand runtime snapshots.
pub fn with_runtime_reader(mut self) -> Self {
self.runtime_reader = true;
self
}
/// Add a default tag that will be sent with every metric.
pub fn with_tag(mut self, key: impl Into<String>, value: impl Into<String>) -> Result<Self> {
let key = key.into();
let value = value.into();
validate_tag_key(&key)?;
validate_tag_value(&value)?;
self.default_tags.insert(key, value);
Ok(self)
}
}