添加qiming-rcoder模块

This commit is contained in:
Codex
2026-06-01 13:54:52 +08:00
parent 8092c4b1f8
commit 4b1a580132
539 changed files with 151650 additions and 0 deletions

View File

@@ -0,0 +1,239 @@
//! Prometheus 指标模块
//!
//! 提供 Prometheus 指标的定义、记录和导出功能。
//! 使用 `metrics` crate 作为 facade`metrics-exporter-prometheus` 作为后端。
use metrics::{
counter, describe_counter, describe_gauge, describe_histogram, gauge, histogram, Unit,
};
use metrics_exporter_prometheus::{PrometheusBuilder, PrometheusHandle};
use std::time::Duration;
use tracing::info;
// ============= 指标名称常量 =============
/// HTTP 请求总数
pub const HTTP_REQUESTS_TOTAL: &str = "http_requests_total";
/// HTTP 请求耗时
pub const HTTP_REQUEST_DURATION_SECONDS: &str = "http_request_duration_seconds";
/// gRPC 请求总数
pub const GRPC_REQUESTS_TOTAL: &str = "grpc_requests_total";
/// gRPC 请求耗时
pub const GRPC_REQUEST_DURATION_SECONDS: &str = "grpc_request_duration_seconds";
/// Agent 任务总数
pub const AGENT_TASKS_TOTAL: &str = "agent_tasks_total";
/// Agent 任务耗时
pub const AGENT_TASK_DURATION_SECONDS: &str = "agent_task_duration_seconds";
/// 活跃任务数
pub const AGENT_ACTIVE_TASKS: &str = "agent_active_tasks";
// ============= 初始化 =============
/// Initializing Prometheus 指标系统
///
/// 安装 Prometheus recorder 并返回 handle用于渲染指标。
///
/// # Returns
///
/// 返回 `PrometheusHandle`,可通过 `render()` 方法获取 Prometheus 格式的指标文本。
///
/// # Example
///
/// ```no_run
/// use rcoder_telemetry::prometheus::init_prometheus;
///
/// fn main() {
/// let handle = init_prometheus().expect("Failed to init prometheus");
/// let metrics_text = handle.render();
/// println!("{}", metrics_text);
/// }
/// ```
pub fn init_prometheus() -> anyhow::Result<PrometheusHandle> {
let handle = PrometheusBuilder::new()
.install_recorder()
.map_err(|e| anyhow::anyhow!("Failed to install Prometheus recorder: {}", e))?;
// 注册指标描述
register_metric_descriptions();
info!("[Prometheus] Metrics system initialization completed");
Ok(handle)
}
/// 注册指标描述(元数据)
fn register_metric_descriptions() {
// HTTP 指标
describe_counter!(
HTTP_REQUESTS_TOTAL,
Unit::Count,
"Total number of HTTP requests"
);
describe_histogram!(
HTTP_REQUEST_DURATION_SECONDS,
Unit::Seconds,
"HTTP request duration in seconds"
);
// gRPC 指标
describe_counter!(
GRPC_REQUESTS_TOTAL,
Unit::Count,
"Total number of gRPC requests"
);
describe_histogram!(
GRPC_REQUEST_DURATION_SECONDS,
Unit::Seconds,
"gRPC request duration in seconds"
);
// Agent 指标
describe_counter!(
AGENT_TASKS_TOTAL,
Unit::Count,
"Total number of agent tasks"
);
describe_histogram!(
AGENT_TASK_DURATION_SECONDS,
Unit::Seconds,
"Agent task duration in seconds"
);
describe_gauge!(
AGENT_ACTIVE_TASKS,
Unit::Count,
"Current number of active agent tasks"
);
}
// ============= HTTP 指标 =============
/// 记录 HTTP 请求
///
/// # Arguments
///
/// * `method` - HTTP 方法GET, POST 等)
/// * `path` - 请求路径
/// * `status` - 响应状态码
pub fn record_http_request(method: &str, path: &str, status: u16) {
counter!(
HTTP_REQUESTS_TOTAL,
"method" => method.to_string(),
"path" => path.to_string(),
"status" => status.to_string()
)
.increment(1);
}
/// 记录 HTTP 请求耗时
///
/// # Arguments
///
/// * `method` - HTTP 方法
/// * `path` - 请求路径
/// * `duration` - 请求耗时
pub fn record_http_duration(method: &str, path: &str, duration: Duration) {
histogram!(
HTTP_REQUEST_DURATION_SECONDS,
"method" => method.to_string(),
"path" => path.to_string()
)
.record(duration.as_secs_f64());
}
// ============= gRPC 指标 =============
/// 记录 gRPC 请求
///
/// # Arguments
///
/// * `method` - gRPC 方法名(如 "Chat", "SubscribeProgress"
/// * `status` - 状态("ok", "error"
pub fn record_grpc_request(method: &str, status: &str) {
counter!(
GRPC_REQUESTS_TOTAL,
"method" => method.to_string(),
"status" => status.to_string()
)
.increment(1);
}
/// 记录 gRPC 请求耗时
///
/// # Arguments
///
/// * `method` - gRPC 方法名
/// * `duration` - 请求耗时
pub fn record_grpc_duration(method: &str, duration: Duration) {
histogram!(
GRPC_REQUEST_DURATION_SECONDS,
"method" => method.to_string()
)
.record(duration.as_secs_f64());
}
// ============= Agent 指标 =============
/// 记录 Agent 任务
///
/// # Arguments
///
/// * `project_id` - 项目 ID
/// * `status` - 任务状态("success", "error", "timeout"
pub fn record_agent_task(project_id: &str, status: &str) {
counter!(
AGENT_TASKS_TOTAL,
"project_id" => project_id.to_string(),
"status" => status.to_string()
)
.increment(1);
}
/// 记录 Agent 任务耗时
///
/// # Arguments
///
/// * `project_id` - 项目 ID
/// * `duration` - 任务耗时
pub fn record_agent_task_duration(project_id: &str, duration: Duration) {
histogram!(
AGENT_TASK_DURATION_SECONDS,
"project_id" => project_id.to_string()
)
.record(duration.as_secs_f64());
}
/// 设置活跃任务数
///
/// # Arguments
///
/// * `count` - 当前活跃任务数
pub fn set_active_tasks(count: u64) {
gauge!(AGENT_ACTIVE_TASKS).set(count as f64);
}
/// 增加活跃任务数
pub fn inc_active_tasks() {
gauge!(AGENT_ACTIVE_TASKS).increment(1.0);
}
/// 减少活跃任务数
pub fn dec_active_tasks() {
gauge!(AGENT_ACTIVE_TASKS).decrement(1.0);
}
#[cfg(test)]
mod tests {
use super::*;
// 注意:这些测试需要先初始化 metrics recorder
// 在实际测试中,可能需要使用 mock recorder
#[test]
fn test_metric_names() {
assert_eq!(HTTP_REQUESTS_TOTAL, "http_requests_total");
assert_eq!(GRPC_REQUESTS_TOTAL, "grpc_requests_total");
assert_eq!(AGENT_ACTIVE_TASKS, "agent_active_tasks");
}
}