104 lines
3.3 KiB
Rust
104 lines
3.3 KiB
Rust
use regex::Regex;
|
|
use std::sync::LazyLock;
|
|
|
|
static ID_REGEX: LazyLock<Regex> = LazyLock::new(|| Regex::new(r#""id"\s*:\s*([^,}]+)"#).unwrap());
|
|
static METHOD_REGEX: LazyLock<Regex> =
|
|
LazyLock::new(|| Regex::new(r#""method"\s*:\s*"([^"]+)""#).unwrap());
|
|
static TOOL_REGEX: LazyLock<Regex> =
|
|
LazyLock::new(|| Regex::new(r#""name"\s*:\s*"([^"]+)""#).unwrap());
|
|
static ERROR_REGEX: LazyLock<Regex> = LazyLock::new(|| Regex::new(r#""error"\s*:\s*\{"#).unwrap());
|
|
static IS_ERROR_REGEX: LazyLock<Regex> =
|
|
LazyLock::new(|| Regex::new(r#""isError"\s*:\s*true"#).unwrap());
|
|
|
|
pub fn extract_log_prefix(json_str: &str, is_response: bool) -> String {
|
|
let id = ID_REGEX
|
|
.captures(json_str)
|
|
.and_then(|c| c.get(1))
|
|
.map_or("null", |m| m.as_str());
|
|
|
|
if is_response {
|
|
let is_error = ERROR_REGEX.is_match(json_str) || IS_ERROR_REGEX.is_match(json_str);
|
|
return format!("Response id={id} [Error: {is_error}]");
|
|
}
|
|
|
|
let method = METHOD_REGEX
|
|
.captures(json_str)
|
|
.and_then(|c| c.get(1))
|
|
.map_or("", |m| m.as_str());
|
|
|
|
if method == "tools/call" {
|
|
let tool = TOOL_REGEX
|
|
.captures(json_str)
|
|
.and_then(|c| c.get(1))
|
|
.map_or("unknown", |m| m.as_str());
|
|
format!("ToolCall[{tool}] id={id}")
|
|
} else if !method.is_empty() {
|
|
format!("Request[{method}] id={id}")
|
|
} else if id != "null" {
|
|
format!("Response id={id}")
|
|
} else {
|
|
"Message".to_string()
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn test_extract_log_prefix_response() {
|
|
let json_str = r#"{"jsonrpc":"2.0","id":123,"result":{}}"#;
|
|
assert_eq!(
|
|
extract_log_prefix(json_str, true),
|
|
"Response id=123 [Error: false]"
|
|
);
|
|
|
|
let err_json =
|
|
r#"{"jsonrpc":"2.0","id":456,"error":{"code":-32600,"message":"Invalid Request"}}"#;
|
|
assert_eq!(
|
|
extract_log_prefix(err_json, true),
|
|
"Response id=456 [Error: true]"
|
|
);
|
|
|
|
let is_err_json = r#"{"jsonrpc":"2.0","id":789,"result":{"isError":true}}"#;
|
|
assert_eq!(
|
|
extract_log_prefix(is_err_json, true),
|
|
"Response id=789 [Error: true]"
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn test_extract_log_prefix_tool_call() {
|
|
let json_str =
|
|
r#"{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"search"}}"#;
|
|
assert_eq!(extract_log_prefix(json_str, false), "ToolCall[search] id=1");
|
|
|
|
let unknown_tool = r#"{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{}}"#;
|
|
assert_eq!(
|
|
extract_log_prefix(unknown_tool, false),
|
|
"ToolCall[unknown] id=2"
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn test_extract_log_prefix_request() {
|
|
let json_str = r#"{"jsonrpc":"2.0","id":10,"method":"initialize"}"#;
|
|
assert_eq!(
|
|
extract_log_prefix(json_str, false),
|
|
"Request[initialize] id=10"
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn test_extract_log_prefix_response_as_request() {
|
|
let json_str = r#"{"jsonrpc":"2.0","id":99,"result":true}"#;
|
|
assert_eq!(extract_log_prefix(json_str, false), "Response id=99");
|
|
}
|
|
|
|
#[test]
|
|
fn test_extract_log_prefix_generic_message() {
|
|
let json_str = r#"{"foo":"bar"}"#;
|
|
assert_eq!(extract_log_prefix(json_str, false), "Message");
|
|
}
|
|
}
|