Skip to content
This repository was archived by the owner on Sep 23, 2025. It is now read-only.

Commit b3204a5

Browse files
committed
Add development logging with PID tracking
- Add --dev-log flag to MCP server for file logging to /tmp/dialectic-mcp-server.log - Include PID in all log messages for multi-instance debugging - Improve request ID logging at debug level for IPC troubleshooting - Update setup tool to register MCP server with RUST_LOG=dialectic_mcp_server=debug in dev mode - Add tracing-appender dependency for non-blocking file logging This enables detailed debugging of IPC connection lifecycle and reconnection behavior, particularly useful for investigating reader task 'parting gift' reconnection attempts.
1 parent 34e5857 commit b3204a5

File tree

4 files changed

+68
-20
lines changed

4 files changed

+68
-20
lines changed

server/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ thiserror = { workspace = true }
4141
# Logging
4242
tracing = { workspace = true }
4343
tracing-subscriber = { workspace = true }
44+
tracing-appender = "0.2"
4445

4546
# Command line argument parsing
4647
clap = { version = "4.0", features = ["derive"] }

server/src/ipc.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -296,9 +296,10 @@ impl IPCCommunicator {
296296
/// for the background reader task to deliver the matching response.
297297
/// Uses the underlying `write_message` primitive to send the data.
298298
async fn send_message_with_reply(&self, message: IPCMessage) -> Result<IPCResponse> {
299-
trace!(
300-
"send_message_with_reply called with message ID: {}",
301-
message.id
299+
debug!(
300+
"Sending IPC message with ID: {} (PID: {})",
301+
message.id,
302+
std::process::id()
302303
);
303304

304305
let (tx, rx) = oneshot::channel();
@@ -566,7 +567,7 @@ impl IPCCommunicator {
566567
/// Processes incoming response messages from VSCode extension
567568
/// Matches responses to pending requests by ID and sends results back to callers
568569
async fn handle_response_message(inner: &Arc<Mutex<IPCCommunicatorInner>>, message_str: &str) {
569-
debug!("Received IPC response: {}", message_str);
570+
debug!("Received IPC response (PID: {}): {}", std::process::id(), message_str);
570571

571572
// Parse the response message
572573
let response: IPCResponse = match serde_json::from_str(message_str) {
@@ -587,7 +588,7 @@ impl IPCCommunicator {
587588
warn!("Failed to send response to caller - receiver dropped");
588589
}
589590
} else {
590-
warn!("Received response for unknown request ID: {}", response.id);
591+
warn!("Received response for unknown request ID: {} (PID: {})", response.id, std::process::id());
591592
}
592593
}
593594
}

server/src/main.rs

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,18 +20,47 @@ struct Args {
2020
/// Run PID discovery probe and exit (for testing)
2121
#[arg(long)]
2222
probe: bool,
23+
24+
/// Enable development logging to /tmp/dialectic-mcp-server.log
25+
#[arg(long)]
26+
dev_log: bool,
2327
}
2428

2529
#[tokio::main]
2630
async fn main() -> Result<()> {
2731
let args = Args::parse();
32+
let mut flush_guard = None;
2833

2934
// Initialize logging to stderr (MCP uses stdout for protocol)
30-
tracing_subscriber::fmt()
31-
.with_env_filter(EnvFilter::from_default_env())
32-
.with_writer(std::io::stderr)
33-
.with_ansi(true)
34-
.init();
35+
// In dev mode, also log to file for debugging
36+
if args.dev_log {
37+
use std::fs::OpenOptions;
38+
use tracing_appender::non_blocking;
39+
40+
let file = OpenOptions::new()
41+
.create(true)
42+
.append(true)
43+
.open("/tmp/dialectic-mcp-server.log")
44+
.expect("Failed to open log file");
45+
46+
let (file_writer, _guard) = non_blocking(file);
47+
flush_guard = Some(_guard);
48+
49+
tracing_subscriber::fmt()
50+
.with_env_filter(EnvFilter::from_default_env())
51+
.with_writer(file_writer)
52+
.with_ansi(false) // No ANSI codes in file
53+
.init();
54+
55+
// Also log to stderr for immediate feedback
56+
eprintln!("Development logging enabled - writing to /tmp/dialectic-mcp-server.log (PID: {})", std::process::id());
57+
} else {
58+
tracing_subscriber::fmt()
59+
.with_env_filter(EnvFilter::from_default_env())
60+
.with_writer(std::io::stderr)
61+
.with_ansi(true)
62+
.init();
63+
}
3564

3665
if args.probe {
3766
info!("🔍 PROBE MODE DETECTED - Running PID discovery probe...");
@@ -56,6 +85,7 @@ async fn main() -> Result<()> {
5685
service.waiting().await?;
5786

5887
info!("Dialectic MCP Server shutting down");
88+
std::mem::drop(flush_guard);
5989
Ok(())
6090
}
6191

setup/src/main.rs

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -122,13 +122,13 @@ fn main() -> Result<()> {
122122
if !args.skip_mcp {
123123
match tool {
124124
CLITool::QCli => {
125-
success = setup_q_cli_mcp(&binary_path)?;
125+
success = setup_q_cli_mcp(&binary_path, args.dev)?;
126126
}
127127
CLITool::ClaudeCode => {
128128
success = setup_claude_code_mcp(&binary_path, &args.claude_scope)?;
129129
}
130130
CLITool::Both => {
131-
success = setup_q_cli_mcp(&binary_path)?
131+
success = setup_q_cli_mcp(&binary_path, args.dev)?
132132
&& setup_claude_code_mcp(&binary_path, &args.claude_scope)?;
133133
}
134134
CLITool::Auto => unreachable!("Auto should have been resolved earlier"),
@@ -385,18 +385,34 @@ fn build_and_install_extension(dev_mode: bool) -> Result<()> {
385385
Ok(())
386386
}
387387

388-
fn setup_q_cli_mcp(binary_path: &Path) -> Result<bool> {
389-
// Build the command arguments for the binary
388+
fn setup_q_cli_mcp(binary_path: &Path, dev_mode: bool) -> Result<bool> {
390389
let mut cmd = Command::new("q");
391-
cmd.args([
392-
"mcp", "add",
393-
"--name", "dialectic",
394-
"--command", &binary_path.to_string_lossy(),
395-
"--force", // Always overwrite existing configuration
396-
]);
390+
391+
if dev_mode {
392+
// In dev mode, register with --dev-log argument and debug logging
393+
cmd.args([
394+
"mcp", "add",
395+
"--name", "dialectic",
396+
"--command", &binary_path.to_string_lossy(),
397+
"--args", "--dev-log",
398+
"--env", "RUST_LOG=dialectic_mcp_server=debug",
399+
"--force", // Always overwrite existing configuration
400+
]);
401+
} else {
402+
// In production mode, register without arguments
403+
cmd.args([
404+
"mcp", "add",
405+
"--name", "dialectic",
406+
"--command", &binary_path.to_string_lossy(),
407+
"--force", // Always overwrite existing configuration
408+
]);
409+
}
397410

398411
println!("🔧 Registering Dialectic MCP server with Q CLI...");
399412
println!(" Binary path: {}", binary_path.display());
413+
if dev_mode {
414+
println!(" Development mode: logging to /tmp/dialectic-mcp-server.log with RUST_LOG=dialectic_mcp_server=debug");
415+
}
400416

401417
let output = cmd.output().context("Failed to execute q mcp add")?;
402418

0 commit comments

Comments
 (0)