feat: add observability api foundation
This commit is contained in:
@@ -14,6 +14,7 @@ use crate::{
|
||||
save_agent_bindings,
|
||||
},
|
||||
auth_profiles::{create_auth_profile, get_auth_profile, list_auth_profiles},
|
||||
observability::{get_agent_usage, get_log, get_operation_usage, get_usage, list_logs},
|
||||
operations::{
|
||||
create_operation, create_version, export_operation, generate_draft, get_operation,
|
||||
get_operation_version, list_grpc_services, list_operations, publish_operation,
|
||||
@@ -98,7 +99,12 @@ pub fn build_app(state: AppState) -> Router {
|
||||
.route(
|
||||
"/platform-api-keys/{key_id}",
|
||||
axum::routing::delete(delete_platform_api_key),
|
||||
);
|
||||
)
|
||||
.route("/logs", get(list_logs))
|
||||
.route("/logs/{log_id}", get(get_log))
|
||||
.route("/usage", get(get_usage))
|
||||
.route("/usage/operations/{operation_id}", get(get_operation_usage))
|
||||
.route("/usage/agents/{agent_id}", get(get_agent_usage));
|
||||
|
||||
let admin_router = Router::new()
|
||||
.route("/workspaces", get(list_workspaces).post(create_workspace))
|
||||
@@ -394,6 +400,86 @@ mod tests {
|
||||
assert_eq!(delete_key_status, reqwest::StatusCode::NO_CONTENT);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn exposes_logs_and_usage_from_real_test_runs() {
|
||||
let registry = test_registry().await;
|
||||
let storage_root = test_storage_root("observability");
|
||||
let upstream_base_url = spawn_upstream_server().await;
|
||||
let base_url = spawn_admin_api(build_test_app(registry, storage_root)).await;
|
||||
let client = reqwest::Client::new();
|
||||
|
||||
let created = client
|
||||
.post(format!("{base_url}/operations"))
|
||||
.json(&test_operation_payload(
|
||||
&upstream_base_url,
|
||||
"crm_observability",
|
||||
))
|
||||
.send()
|
||||
.await
|
||||
.unwrap()
|
||||
.json::<Value>()
|
||||
.await
|
||||
.unwrap();
|
||||
let operation_id = created["operation_id"].as_str().unwrap().to_owned();
|
||||
|
||||
client
|
||||
.post(format!("{base_url}/operations/{operation_id}/test-runs"))
|
||||
.json(&json!({
|
||||
"version": 1,
|
||||
"input": { "email": "user@example.com" }
|
||||
}))
|
||||
.send()
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let logs = client
|
||||
.get(format!("{base_url}/logs?period=7d"))
|
||||
.send()
|
||||
.await
|
||||
.unwrap()
|
||||
.json::<Value>()
|
||||
.await
|
||||
.unwrap();
|
||||
let log_id = logs["items"][0]["log"]["id"].as_str().unwrap().to_owned();
|
||||
let log_detail = client
|
||||
.get(format!("{base_url}/logs/{log_id}"))
|
||||
.send()
|
||||
.await
|
||||
.unwrap()
|
||||
.json::<Value>()
|
||||
.await
|
||||
.unwrap();
|
||||
let usage = client
|
||||
.get(format!("{base_url}/usage?period=7d"))
|
||||
.send()
|
||||
.await
|
||||
.unwrap()
|
||||
.json::<Value>()
|
||||
.await
|
||||
.unwrap();
|
||||
let operation_usage = client
|
||||
.get(format!(
|
||||
"{base_url}/usage/operations/{operation_id}?period=7d"
|
||||
))
|
||||
.send()
|
||||
.await
|
||||
.unwrap()
|
||||
.json::<Value>()
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(logs["items"][0]["log"]["source"], "admin_test_run");
|
||||
assert_eq!(logs["items"][0]["operation_name"], "crm_observability");
|
||||
assert_eq!(log_detail["log"]["status"], "ok");
|
||||
assert_eq!(usage["summary"]["rollup"]["calls_total"], 1);
|
||||
assert_eq!(usage["summary"]["rollup"]["calls_ok"], 1);
|
||||
assert_eq!(
|
||||
usage["operations"][0]["operation_name"],
|
||||
"crm_observability"
|
||||
);
|
||||
assert_eq!(operation_usage["rollup"]["calls_total"], 1);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn creates_publishes_and_tests_graphql_operation() {
|
||||
let registry = test_registry().await;
|
||||
|
||||
Reference in New Issue
Block a user