telemetry.rs

 1use anyhow::{Context, Result};
 2use serde::Serialize;
 3
 4use crate::clickhouse::write_to_table;
 5
 6#[derive(Serialize, Debug, clickhouse::Row)]
 7pub struct LlmUsageEventRow {
 8    pub time: i64,
 9    pub user_id: i32,
10    pub is_staff: bool,
11    pub plan: String,
12    pub model: String,
13    pub provider: String,
14    pub input_token_count: u64,
15    pub cache_creation_input_token_count: u64,
16    pub cache_read_input_token_count: u64,
17    pub output_token_count: u64,
18    pub requests_this_minute: u64,
19    pub tokens_this_minute: u64,
20    pub tokens_this_day: u64,
21    pub input_tokens_this_month: u64,
22    pub cache_creation_input_tokens_this_month: u64,
23    pub cache_read_input_tokens_this_month: u64,
24    pub output_tokens_this_month: u64,
25    pub spending_this_month: u64,
26    pub lifetime_spending: u64,
27}
28
29#[derive(Serialize, Debug, clickhouse::Row)]
30pub struct LlmRateLimitEventRow {
31    pub time: i64,
32    pub user_id: i32,
33    pub is_staff: bool,
34    pub plan: String,
35    pub model: String,
36    pub provider: String,
37    pub usage_measure: String,
38    pub requests_this_minute: u64,
39    pub tokens_this_minute: u64,
40    pub tokens_this_day: u64,
41    pub users_in_recent_minutes: u64,
42    pub users_in_recent_days: u64,
43    pub max_requests_per_minute: u64,
44    pub max_tokens_per_minute: u64,
45    pub max_tokens_per_day: u64,
46}
47
48pub async fn report_llm_usage(client: &clickhouse::Client, row: LlmUsageEventRow) -> Result<()> {
49    const LLM_USAGE_EVENTS_TABLE: &str = "llm_usage_events";
50    write_to_table(LLM_USAGE_EVENTS_TABLE, &[row], client)
51        .await
52        .with_context(|| format!("failed to upload to table '{LLM_USAGE_EVENTS_TABLE}'"))?;
53    Ok(())
54}
55
56pub async fn report_llm_rate_limit(
57    client: &clickhouse::Client,
58    row: LlmRateLimitEventRow,
59) -> Result<()> {
60    const LLM_RATE_LIMIT_EVENTS_TABLE: &str = "llm_rate_limit_events";
61    write_to_table(LLM_RATE_LIMIT_EVENTS_TABLE, &[row], client)
62        .await
63        .with_context(|| format!("failed to upload to table '{LLM_RATE_LIMIT_EVENTS_TABLE}'"))?;
64    Ok(())
65}