mirror of
https://github.com/openai/codex.git
synced 2026-05-03 02:46:39 +00:00
201 lines
8.3 KiB
Rust
201 lines
8.3 KiB
Rust
use crate::metrics::names::API_CALL_COUNT_METRIC;
|
|
use crate::metrics::names::API_CALL_DURATION_METRIC;
|
|
use crate::metrics::names::RESPONSES_API_ENGINE_IAPI_TBT_DURATION_METRIC;
|
|
use crate::metrics::names::RESPONSES_API_ENGINE_IAPI_TTFT_DURATION_METRIC;
|
|
use crate::metrics::names::RESPONSES_API_ENGINE_SERVICE_TBT_DURATION_METRIC;
|
|
use crate::metrics::names::RESPONSES_API_ENGINE_SERVICE_TTFT_DURATION_METRIC;
|
|
use crate::metrics::names::RESPONSES_API_INFERENCE_TIME_DURATION_METRIC;
|
|
use crate::metrics::names::RESPONSES_API_OVERHEAD_DURATION_METRIC;
|
|
use crate::metrics::names::SSE_EVENT_COUNT_METRIC;
|
|
use crate::metrics::names::SSE_EVENT_DURATION_METRIC;
|
|
use crate::metrics::names::TOOL_CALL_COUNT_METRIC;
|
|
use crate::metrics::names::TOOL_CALL_DURATION_METRIC;
|
|
use crate::metrics::names::WEBSOCKET_EVENT_COUNT_METRIC;
|
|
use crate::metrics::names::WEBSOCKET_EVENT_DURATION_METRIC;
|
|
use crate::metrics::names::WEBSOCKET_REQUEST_COUNT_METRIC;
|
|
use crate::metrics::names::WEBSOCKET_REQUEST_DURATION_METRIC;
|
|
use opentelemetry_sdk::metrics::data::AggregatedMetrics;
|
|
use opentelemetry_sdk::metrics::data::Metric;
|
|
use opentelemetry_sdk::metrics::data::MetricData;
|
|
use opentelemetry_sdk::metrics::data::ResourceMetrics;
|
|
|
|
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
|
|
pub struct RuntimeMetricTotals {
|
|
pub count: u64,
|
|
pub duration_ms: u64,
|
|
}
|
|
|
|
impl RuntimeMetricTotals {
|
|
pub fn is_empty(self) -> bool {
|
|
self.count == 0 && self.duration_ms == 0
|
|
}
|
|
|
|
pub fn merge(&mut self, other: Self) {
|
|
self.count = self.count.saturating_add(other.count);
|
|
self.duration_ms = self.duration_ms.saturating_add(other.duration_ms);
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
|
|
pub struct RuntimeMetricsSummary {
|
|
pub tool_calls: RuntimeMetricTotals,
|
|
pub api_calls: RuntimeMetricTotals,
|
|
pub streaming_events: RuntimeMetricTotals,
|
|
pub websocket_calls: RuntimeMetricTotals,
|
|
pub websocket_events: RuntimeMetricTotals,
|
|
pub responses_api_overhead_ms: u64,
|
|
pub responses_api_inference_time_ms: u64,
|
|
pub responses_api_engine_iapi_ttft_ms: u64,
|
|
pub responses_api_engine_service_ttft_ms: u64,
|
|
pub responses_api_engine_iapi_tbt_ms: u64,
|
|
pub responses_api_engine_service_tbt_ms: u64,
|
|
}
|
|
|
|
impl RuntimeMetricsSummary {
|
|
pub fn is_empty(self) -> bool {
|
|
self.tool_calls.is_empty()
|
|
&& self.api_calls.is_empty()
|
|
&& self.streaming_events.is_empty()
|
|
&& self.websocket_calls.is_empty()
|
|
&& self.websocket_events.is_empty()
|
|
&& self.responses_api_overhead_ms == 0
|
|
&& self.responses_api_inference_time_ms == 0
|
|
&& self.responses_api_engine_iapi_ttft_ms == 0
|
|
&& self.responses_api_engine_service_ttft_ms == 0
|
|
&& self.responses_api_engine_iapi_tbt_ms == 0
|
|
&& self.responses_api_engine_service_tbt_ms == 0
|
|
}
|
|
|
|
pub fn merge(&mut self, other: Self) {
|
|
self.tool_calls.merge(other.tool_calls);
|
|
self.api_calls.merge(other.api_calls);
|
|
self.streaming_events.merge(other.streaming_events);
|
|
self.websocket_calls.merge(other.websocket_calls);
|
|
self.websocket_events.merge(other.websocket_events);
|
|
if other.responses_api_overhead_ms > 0 {
|
|
self.responses_api_overhead_ms = other.responses_api_overhead_ms;
|
|
}
|
|
if other.responses_api_inference_time_ms > 0 {
|
|
self.responses_api_inference_time_ms = other.responses_api_inference_time_ms;
|
|
}
|
|
if other.responses_api_engine_iapi_ttft_ms > 0 {
|
|
self.responses_api_engine_iapi_ttft_ms = other.responses_api_engine_iapi_ttft_ms;
|
|
}
|
|
if other.responses_api_engine_service_ttft_ms > 0 {
|
|
self.responses_api_engine_service_ttft_ms = other.responses_api_engine_service_ttft_ms;
|
|
}
|
|
if other.responses_api_engine_iapi_tbt_ms > 0 {
|
|
self.responses_api_engine_iapi_tbt_ms = other.responses_api_engine_iapi_tbt_ms;
|
|
}
|
|
if other.responses_api_engine_service_tbt_ms > 0 {
|
|
self.responses_api_engine_service_tbt_ms = other.responses_api_engine_service_tbt_ms;
|
|
}
|
|
}
|
|
|
|
pub fn responses_api_summary(&self) -> RuntimeMetricsSummary {
|
|
Self {
|
|
responses_api_overhead_ms: self.responses_api_overhead_ms,
|
|
responses_api_inference_time_ms: self.responses_api_inference_time_ms,
|
|
responses_api_engine_iapi_ttft_ms: self.responses_api_engine_iapi_ttft_ms,
|
|
responses_api_engine_service_ttft_ms: self.responses_api_engine_service_ttft_ms,
|
|
responses_api_engine_iapi_tbt_ms: self.responses_api_engine_iapi_tbt_ms,
|
|
responses_api_engine_service_tbt_ms: self.responses_api_engine_service_tbt_ms,
|
|
..RuntimeMetricsSummary::default()
|
|
}
|
|
}
|
|
|
|
pub(crate) fn from_snapshot(snapshot: &ResourceMetrics) -> Self {
|
|
let tool_calls = RuntimeMetricTotals {
|
|
count: sum_counter(snapshot, TOOL_CALL_COUNT_METRIC),
|
|
duration_ms: sum_histogram_ms(snapshot, TOOL_CALL_DURATION_METRIC),
|
|
};
|
|
let api_calls = RuntimeMetricTotals {
|
|
count: sum_counter(snapshot, API_CALL_COUNT_METRIC),
|
|
duration_ms: sum_histogram_ms(snapshot, API_CALL_DURATION_METRIC),
|
|
};
|
|
let streaming_events = RuntimeMetricTotals {
|
|
count: sum_counter(snapshot, SSE_EVENT_COUNT_METRIC),
|
|
duration_ms: sum_histogram_ms(snapshot, SSE_EVENT_DURATION_METRIC),
|
|
};
|
|
let websocket_calls = RuntimeMetricTotals {
|
|
count: sum_counter(snapshot, WEBSOCKET_REQUEST_COUNT_METRIC),
|
|
duration_ms: sum_histogram_ms(snapshot, WEBSOCKET_REQUEST_DURATION_METRIC),
|
|
};
|
|
let websocket_events = RuntimeMetricTotals {
|
|
count: sum_counter(snapshot, WEBSOCKET_EVENT_COUNT_METRIC),
|
|
duration_ms: sum_histogram_ms(snapshot, WEBSOCKET_EVENT_DURATION_METRIC),
|
|
};
|
|
let responses_api_overhead_ms =
|
|
sum_histogram_ms(snapshot, RESPONSES_API_OVERHEAD_DURATION_METRIC);
|
|
let responses_api_inference_time_ms =
|
|
sum_histogram_ms(snapshot, RESPONSES_API_INFERENCE_TIME_DURATION_METRIC);
|
|
let responses_api_engine_iapi_ttft_ms =
|
|
sum_histogram_ms(snapshot, RESPONSES_API_ENGINE_IAPI_TTFT_DURATION_METRIC);
|
|
let responses_api_engine_service_ttft_ms =
|
|
sum_histogram_ms(snapshot, RESPONSES_API_ENGINE_SERVICE_TTFT_DURATION_METRIC);
|
|
let responses_api_engine_iapi_tbt_ms =
|
|
sum_histogram_ms(snapshot, RESPONSES_API_ENGINE_IAPI_TBT_DURATION_METRIC);
|
|
let responses_api_engine_service_tbt_ms =
|
|
sum_histogram_ms(snapshot, RESPONSES_API_ENGINE_SERVICE_TBT_DURATION_METRIC);
|
|
Self {
|
|
tool_calls,
|
|
api_calls,
|
|
streaming_events,
|
|
websocket_calls,
|
|
websocket_events,
|
|
responses_api_overhead_ms,
|
|
responses_api_inference_time_ms,
|
|
responses_api_engine_iapi_ttft_ms,
|
|
responses_api_engine_service_ttft_ms,
|
|
responses_api_engine_iapi_tbt_ms,
|
|
responses_api_engine_service_tbt_ms,
|
|
}
|
|
}
|
|
}
|
|
|
|
fn sum_counter(snapshot: &ResourceMetrics, name: &str) -> u64 {
|
|
snapshot
|
|
.scope_metrics()
|
|
.flat_map(opentelemetry_sdk::metrics::data::ScopeMetrics::metrics)
|
|
.filter(|metric| metric.name() == name)
|
|
.map(sum_counter_metric)
|
|
.sum()
|
|
}
|
|
|
|
fn sum_counter_metric(metric: &Metric) -> u64 {
|
|
match metric.data() {
|
|
AggregatedMetrics::U64(MetricData::Sum(sum)) => sum
|
|
.data_points()
|
|
.map(opentelemetry_sdk::metrics::data::SumDataPoint::value)
|
|
.sum(),
|
|
_ => 0,
|
|
}
|
|
}
|
|
|
|
fn sum_histogram_ms(snapshot: &ResourceMetrics, name: &str) -> u64 {
|
|
snapshot
|
|
.scope_metrics()
|
|
.flat_map(opentelemetry_sdk::metrics::data::ScopeMetrics::metrics)
|
|
.filter(|metric| metric.name() == name)
|
|
.map(sum_histogram_metric_ms)
|
|
.sum()
|
|
}
|
|
|
|
fn sum_histogram_metric_ms(metric: &Metric) -> u64 {
|
|
match metric.data() {
|
|
AggregatedMetrics::F64(MetricData::Histogram(histogram)) => histogram
|
|
.data_points()
|
|
.map(|point| f64_to_u64(point.sum()))
|
|
.sum(),
|
|
_ => 0,
|
|
}
|
|
}
|
|
|
|
fn f64_to_u64(value: f64) -> u64 {
|
|
if !value.is_finite() || value <= 0.0 {
|
|
return 0;
|
|
}
|
|
let clamped = value.min(u64::MAX as f64);
|
|
clamped.round() as u64
|
|
}
|