style: Optimize stub proxy logging and cleanup nvim-core JSON-RPC response boilerplate
This commit is contained in:
1 parent
6011da95f6
commit
368f28e593
7 files changed
+113
-89
No files matched your search
@@ -17,6 +17,7 @@ tracing-subscriber = "0.3.23"
|
||||
dirs = "7.0.0"
|
||||
serde_json = "1.0.151"
|
||||
mcp-stdio = { version = "0.1.0", path = "../mcp-stdio" }
|
||||
regex = "1.13.1"
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
use std::sync::LazyLock;
|
||||
use regex::Regex;
|
||||
|
||||
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(|m| m.as_str()).unwrap_or("null");
|
||||
|
||||
if is_response {
|
||||
let is_error = ERROR_REGEX.is_match(json_str) || IS_ERROR_REGEX.is_match(json_str);
|
||||
return format!("Response id={} [Error: {}]", id, is_error);
|
||||
}
|
||||
|
||||
let method = METHOD_REGEX.captures(json_str).and_then(|c| c.get(1)).map(|m| m.as_str()).unwrap_or("");
|
||||
|
||||
if method == "tools/call" {
|
||||
let tool = TOOL_REGEX.captures(json_str).and_then(|c| c.get(1)).map(|m| m.as_str()).unwrap_or("unknown");
|
||||
format!("ToolCall[{}] id={}", tool, id)
|
||||
} else if !method.is_empty() {
|
||||
format!("Request[{}] id={}", method, id)
|
||||
} else if id != "null" {
|
||||
format!("Response id={}", id)
|
||||
} else {
|
||||
"Message".to_string()
|
||||
}
|
||||
}
|
||||
+4
-19
@@ -14,6 +14,8 @@ struct Cli {
|
||||
|
||||
|
||||
|
||||
mod logger;
|
||||
|
||||
fn init_logging(app_name: &str) -> Option<tracing_appender::non_blocking::WorkerGuard> {
|
||||
let mut base_dir = dirs::home_dir().unwrap_or_else(|| std::path::PathBuf::from("."));
|
||||
base_dir.push(".gemini/mcp_memory/logs");
|
||||
@@ -87,19 +89,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
match rx.recv().await {
|
||||
Some(msg) => {
|
||||
drop(rx);
|
||||
let mut log_prefix = String::from("Message");
|
||||
if let Ok(v) = serde_json::from_str::<serde_json::Value>(&msg) {
|
||||
let method = v.get("method").and_then(|m| m.as_str()).unwrap_or("");
|
||||
let id = v.get("id").unwrap_or(&serde_json::Value::Null);
|
||||
if method == "tools/call" {
|
||||
let tool = v.get("params").and_then(|p| p.get("name")).and_then(|n| n.as_str()).unwrap_or("unknown");
|
||||
log_prefix = format!("ToolCall[{}] id={}", tool, id);
|
||||
} else if !method.is_empty() {
|
||||
log_prefix = format!("Request[{}] id={}", method, id);
|
||||
} else if let Some(res_id) = v.get("id") {
|
||||
log_prefix = format!("Response id={}", res_id);
|
||||
}
|
||||
}
|
||||
let log_prefix = logger::extract_log_prefix(&msg, false);
|
||||
tracing::info!(">>> [Stub] Forwarding {} to server (length: {}): {}", log_prefix, msg.len(), if msg.len() > 1000 { format!("{}...", &msg[..1000]) } else { msg.clone() });
|
||||
if write.send(tokio_tungstenite::tungstenite::Message::Text(msg)).await.is_err() {
|
||||
|
||||
@@ -115,12 +105,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let mut recv_task = tokio::spawn(async move {
|
||||
while let Some(Ok(msg)) = read.next().await {
|
||||
if let tokio_tungstenite::tungstenite::Message::Text(text) = msg {
|
||||
let mut log_prefix = String::from("Message");
|
||||
if let Ok(v) = serde_json::from_str::<serde_json::Value>(&text) {
|
||||
let id = v.get("id").unwrap_or(&serde_json::Value::Null);
|
||||
let is_error = v.get("error").is_some() || v.get("result").and_then(|res| res.get("isError")).and_then(|e| e.as_bool()).unwrap_or(false);
|
||||
log_prefix = format!("Response id={} [Error: {}]", id, is_error);
|
||||
}
|
||||
let log_prefix = logger::extract_log_prefix(&text, true);
|
||||
tracing::info!("<<< [Stub] Received {} from server (length: {}): {}", log_prefix, text.len(), if text.len() > 1000 { format!("{}...", &text[..1000]) } else { text.clone() });
|
||||
let payload = format!("{}\n", text);
|
||||
use tokio::io::AsyncWriteExt;
|
||||
|
||||
Reference in new issue
Block a user