feat(core,cli): add debug logging infrastructure (M0-M2)

Implement debug logfile foundation for routing internal diagnostics
to a per-session log file instead of polluting the terminal.

Core changes:
- Add DebugLogger interface and createDebugLogger() in debugLogger.ts
- Add Storage.getGlobalDebugDir() and getDebugLogPath() for log paths
- Add Config.getDebugLogger() method with session-scoped logger
- Track write failures via isDebugLoggingDegraded()

CLI changes:
- Add DebugModeNotification component for interactive startup notice
- Add non-interactive debug notice to stderr in gemini.tsx

Log files are written to ~/.qwen/debug/<sessionId>.txt with format:
2026-01-24T10:30:00.000Z [LEVEL] [TAG] message

Debug logging is always-on; debug mode only controls the startup notice.
This commit is contained in:
tanzhenxin 2026-01-25 09:23:18 +08:00
parent 829ba9c431
commit ba2824b0b0
8 changed files with 409 additions and 6 deletions

View file

@ -4,8 +4,13 @@
* SPDX-License-Identifier: Apache-2.0
*/
import type { Config } from '@qwen-code/qwen-code-core';
import { InputFormat, logUserPrompt } from '@qwen-code/qwen-code-core';
import {
InputFormat,
isDebugLoggingDegraded,
logUserPrompt,
Storage,
type Config,
} from '@qwen-code/qwen-code-core';
import { render } from 'ink';
import dns from 'node:dns';
import os from 'node:os';
@ -419,6 +424,19 @@ export async function main() {
return;
}
// Print debug mode notice to stderr for non-interactive mode
if (config.getDebugMode()) {
console.error('Debug mode enabled');
console.error(
`Logging to: ${Storage.getDebugLogPath(config.getSessionId())}`,
);
if (isDebugLoggingDegraded()) {
console.error(
'Warning: Debug logging is degraded (write failures occurred)',
);
}
}
// For non-stream-json mode, initialize config here
if (inputFormat !== InputFormat.STREAM_JSON) {
await config.initialize();