fix(usage): record health checks and non-generated events
This commit is contained in:
1 parent
f9b09a31d9
commit
8885ffd50b
2 files changed
+67
-29
No files matched your search
+65
-29
@@ -732,7 +732,6 @@ fn persist_queue_items(
|
||||
let records = items
|
||||
.into_iter()
|
||||
.filter(Value::is_object)
|
||||
.filter(is_generated_usage_event)
|
||||
.map(|item| normalize_usage_record(item, config))
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
if records.is_empty() {
|
||||
@@ -823,34 +822,6 @@ fn insert_usage_records_in_transaction(
|
||||
Ok(inserted)
|
||||
}
|
||||
|
||||
fn is_generated_usage_event(value: &Value) -> bool {
|
||||
if value.get("generate").and_then(Value::as_bool) == Some(false) {
|
||||
return false;
|
||||
}
|
||||
let legacy_websocket_prewarm = value
|
||||
.get("executor_type")
|
||||
.and_then(Value::as_str)
|
||||
.is_some_and(|value| value.trim() == "CodexWebsocketsExecutor")
|
||||
&& value
|
||||
.get("tokens")
|
||||
.and_then(Value::as_object)
|
||||
.is_some_and(|tokens| {
|
||||
[
|
||||
"input_tokens",
|
||||
"output_tokens",
|
||||
"reasoning_tokens",
|
||||
"cached_tokens",
|
||||
"cache_tokens",
|
||||
"cache_read_tokens",
|
||||
"cache_creation_tokens",
|
||||
"total_tokens",
|
||||
]
|
||||
.into_iter()
|
||||
.all(|key| u64_field(tokens, key) == 0)
|
||||
});
|
||||
!legacy_websocket_prewarm
|
||||
}
|
||||
|
||||
fn normalize_usage_record(value: Value, config: &GuiConfigFile) -> Result<UsageRecord, String> {
|
||||
let object = value
|
||||
.as_object()
|
||||
@@ -2263,6 +2234,71 @@ mod tests {
|
||||
assert!(!record.api_key_hash.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn persists_successful_health_checks_and_zero_token_websocket_events() {
|
||||
let root = test_root("queue-events-without-generation");
|
||||
initialize_usage_storage_at(&root).unwrap();
|
||||
let config = GuiConfigFile::default();
|
||||
let inserted = persist_queue_items(
|
||||
&root,
|
||||
vec![
|
||||
serde_json::json!({
|
||||
"timestamp": "2026-07-29T10:00:00+08:00",
|
||||
"request_id": "cherry-health-check",
|
||||
"generate": false,
|
||||
"failed": false,
|
||||
"provider": "openai",
|
||||
"model": "gpt-test",
|
||||
"endpoint": "POST /v1/chat/completions",
|
||||
"tokens": {
|
||||
"input_tokens": 1,
|
||||
"output_tokens": 1,
|
||||
"total_tokens": 2
|
||||
}
|
||||
}),
|
||||
serde_json::json!({
|
||||
"timestamp": "2026-07-29T10:00:01+08:00",
|
||||
"request_id": "websocket-zero-token",
|
||||
"failed": false,
|
||||
"provider": "codex",
|
||||
"model": "gpt-test",
|
||||
"executor_type": "CodexWebsocketsExecutor",
|
||||
"tokens": {
|
||||
"input_tokens": 0,
|
||||
"output_tokens": 0,
|
||||
"total_tokens": 0
|
||||
}
|
||||
}),
|
||||
],
|
||||
&config,
|
||||
)
|
||||
.unwrap();
|
||||
let connection = open_usage_database_at(&root).unwrap();
|
||||
let events = load_usage_events(
|
||||
&connection,
|
||||
&UsageQuery {
|
||||
failed: Some(false),
|
||||
..UsageQuery::default()
|
||||
},
|
||||
&config,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(inserted, 2);
|
||||
assert_eq!(events.total, 2);
|
||||
assert!(events.items.iter().all(|event| !event.failed));
|
||||
assert!(events
|
||||
.items
|
||||
.iter()
|
||||
.any(|event| event.request_id == "cherry-health-check"));
|
||||
assert!(events
|
||||
.items
|
||||
.iter()
|
||||
.any(|event| event.request_id == "websocket-zero-token"));
|
||||
drop(connection);
|
||||
fs::remove_dir_all(root).unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sqlite_storage_uses_wal_and_reference_busy_timeout() {
|
||||
let root = test_root("sqlite-pragmas");
|
||||
|
||||
@@ -5782,6 +5782,8 @@ input:focus-visible {
|
||||
padding-right: 2px;
|
||||
}
|
||||
|
||||
.usage-events-table th:nth-child(3),
|
||||
.usage-events-table td:nth-child(3),
|
||||
.usage-events-table th:nth-child(4),
|
||||
.usage-events-table td:nth-child(4) {
|
||||
overflow: hidden;
|
||||
|
||||
Reference in new issue
Block a user