Skip to content

Commit 6b48b5f

Browse files
authored
feat(chat): support for --mcp option in /logdump (#3143)
1 parent eb1c8a8 commit 6b48b5f

File tree

1 file changed

+67
-5
lines changed

1 file changed

+67
-5
lines changed

crates/chat-cli/src/cli/chat/cli/logdump.rs

Lines changed: 67 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,11 @@ use crate::util::directories::logs_dir;
2323

2424
/// Arguments for the logdump command that collects logs for support investigation
2525
#[derive(Debug, PartialEq, Args)]
26-
pub struct LogdumpArgs;
26+
pub struct LogdumpArgs {
27+
/// Include MCP logs
28+
#[arg(long)]
29+
pub mcp: bool,
30+
}
2731

2832
impl LogdumpArgs {
2933
pub async fn execute(self, session: &mut ChatSession) -> Result<ChatState, ChatError> {
@@ -73,9 +77,14 @@ impl LogdumpArgs {
7377
let mut zip = ZipWriter::new(file);
7478
let mut log_count = 0;
7579

76-
// Only collect qchat.log (keeping current implementation logic)
80+
// Collect qchat.log
7781
log_count += Self::collect_qchat_log(&mut zip, &logs_dir)?;
7882

83+
// Collect mcp.log if --mcp flag is set
84+
if self.mcp {
85+
log_count += Self::collect_mcp_log(&mut zip, &logs_dir)?;
86+
}
87+
7988
zip.finish()?;
8089
Ok(log_count)
8190
}
@@ -91,6 +100,17 @@ impl LogdumpArgs {
91100
Ok(0)
92101
}
93102

103+
fn collect_mcp_log(
104+
zip: &mut ZipWriter<std::fs::File>,
105+
logs_dir: &Path,
106+
) -> Result<usize, Box<dyn std::error::Error>> {
107+
let mcp_log_path = logs_dir.join("mcp.log");
108+
if mcp_log_path.exists() {
109+
return Self::add_log_file_to_zip(&mcp_log_path, zip, "logs");
110+
}
111+
Ok(0)
112+
}
113+
94114
fn add_log_file_to_zip(
95115
path: &Path,
96116
zip: &mut ZipWriter<std::fs::File>,
@@ -126,7 +146,7 @@ mod tests {
126146
let logs_dir = temp_dir.path().join("logs");
127147
fs::create_dir_all(&logs_dir).unwrap();
128148

129-
let logdump = LogdumpArgs;
149+
let logdump = LogdumpArgs { mcp: false };
130150

131151
// Create the zip file (even if no logs are found, it should create an empty zip)
132152
let result = logdump.create_log_dump(&zip_path, logs_dir).await;
@@ -144,7 +164,7 @@ mod tests {
144164
}
145165

146166
#[tokio::test]
147-
async fn test_logdump_includes_qchat_log_when_present() {
167+
async fn test_logdump_includes_qchat_log() {
148168
let temp_dir = TempDir::new().unwrap();
149169
let zip_path = temp_dir.path().join("test-logs.zip");
150170
let logs_dir = temp_dir.path().join("logs");
@@ -154,7 +174,7 @@ mod tests {
154174
let qchat_log_path = logs_dir.join("qchat.log");
155175
fs::write(&qchat_log_path, "test log content").unwrap();
156176

157-
let logdump = LogdumpArgs;
177+
let logdump = LogdumpArgs { mcp: false };
158178

159179
let result = logdump.create_log_dump(&zip_path, logs_dir).await;
160180

@@ -173,4 +193,46 @@ mod tests {
173193
std::io::Read::read_to_string(&mut log_file, &mut contents).unwrap();
174194
assert_eq!(contents, "test log content");
175195
}
196+
197+
#[tokio::test]
198+
async fn test_logdump_includes_qchat_log_with_mcp_log() {
199+
let temp_dir = TempDir::new().unwrap();
200+
let zip_path = temp_dir.path().join("test-logs.zip");
201+
let logs_dir = temp_dir.path().join("logs");
202+
fs::create_dir_all(&logs_dir).unwrap();
203+
204+
// Create test log files
205+
let qchat_log_path = logs_dir.join("qchat.log");
206+
fs::write(&qchat_log_path, "qchat log content").unwrap();
207+
let mcp_log_path = logs_dir.join("mcp.log");
208+
fs::write(&mcp_log_path, "mcp log content").unwrap();
209+
210+
let logdump = LogdumpArgs { mcp: true };
211+
212+
let result = logdump.create_log_dump(&zip_path, logs_dir).await;
213+
214+
// The function should succeed and include 2 log files
215+
assert!(result.is_ok());
216+
assert_eq!(result.unwrap(), 2);
217+
assert!(zip_path.exists());
218+
219+
// Verify the zip contains both log files
220+
let file = fs::File::open(&zip_path).unwrap();
221+
let mut archive = zip::ZipArchive::new(file).unwrap();
222+
assert_eq!(archive.len(), 2);
223+
224+
{
225+
let mut qchat_file = archive.by_name("logs/qchat.log").unwrap();
226+
let mut qchat_contents = String::new();
227+
std::io::Read::read_to_string(&mut qchat_file, &mut qchat_contents).unwrap();
228+
assert_eq!(qchat_contents, "qchat log content");
229+
}
230+
231+
{
232+
let mut mcp_file = archive.by_name("logs/mcp.log").unwrap();
233+
let mut mcp_contents = String::new();
234+
std::io::Read::read_to_string(&mut mcp_file, &mut mcp_contents).unwrap();
235+
assert_eq!(mcp_contents, "mcp log content");
236+
}
237+
}
176238
}

0 commit comments

Comments
 (0)