1use anyhow::Result;
2use serde::Serialize;
3
4#[derive(Serialize, Debug, clickhouse::Row)]
5pub struct LlmUsageEventRow {
6 pub time: i64,
7 pub user_id: i32,
8 pub is_staff: bool,
9 pub plan: String,
10 pub model: String,
11 pub provider: String,
12 pub input_token_count: u64,
13 pub output_token_count: u64,
14 pub requests_this_minute: u64,
15 pub tokens_this_minute: u64,
16 pub tokens_this_day: u64,
17 pub input_tokens_this_month: u64,
18 pub output_tokens_this_month: u64,
19 pub spending_this_month: u64,
20 pub lifetime_spending: u64,
21}
22
23#[derive(Serialize, Debug, clickhouse::Row)]
24pub struct LlmRateLimitEventRow {
25 pub time: i64,
26 pub user_id: i32,
27 pub is_staff: bool,
28 pub plan: String,
29 pub model: String,
30 pub provider: String,
31 pub usage_measure: String,
32 pub requests_this_minute: u64,
33 pub tokens_this_minute: u64,
34 pub tokens_this_day: u64,
35 pub users_in_recent_minutes: u64,
36 pub users_in_recent_days: u64,
37 pub max_requests_per_minute: u64,
38 pub max_tokens_per_minute: u64,
39 pub max_tokens_per_day: u64,
40}
41
42pub async fn report_llm_usage(client: &clickhouse::Client, row: LlmUsageEventRow) -> Result<()> {
43 let mut insert = client.insert("llm_usage_events")?;
44 insert.write(&row).await?;
45 insert.end().await?;
46 Ok(())
47}
48
49pub async fn report_llm_rate_limit(
50 client: &clickhouse::Client,
51 row: LlmRateLimitEventRow,
52) -> Result<()> {
53 let mut insert = client.insert("llm_rate_limits")?;
54 insert.write(&row).await?;
55 insert.end().await?;
56 Ok(())
57}