|
1 | | -import { type Logger, logger as rootLogger } from "../logger"; |
| 1 | +import pino from "pino"; |
| 2 | + |
| 3 | +import type { Logger } from "../logger"; |
| 4 | +import { errSerializer, REDACT_PATHS, resolveLogLevel } from "./log-redaction"; |
| 5 | + |
| 6 | +// Config-free default logger (issue #184). Importing retry.ts must not pull in |
| 7 | +// src/logger.ts -> src/config, so the stdio MCP servers that use retry (e.g. |
| 8 | +// resolve-review-thread) stay config-free. `import type { Logger }` above is |
| 9 | +// erased at emit, so it adds no runtime coupling. Same REDACT_PATHS + |
| 10 | +// errSerializer as the root logger keeps redaction parity. The level reads |
| 11 | +// LOG_LEVEL directly (config is intentionally not imported) via resolveLogLevel, |
| 12 | +// which falls back to `info` on an invalid value so pino can't throw at import. |
| 13 | +// Level visibility matches the root logger because both derive from LOG_LEVEL. |
| 14 | +// |
| 15 | +// Writes to stderr (like createMcpLogger), NOT pino's default stdout: a stdio |
| 16 | +// MCP server speaks JSON-RPC over stdout, so a default-path retry warning on |
| 17 | +// stdout would corrupt the protocol. stderr is safe in every context (k8s |
| 18 | +// ships both streams; warn/error on stderr is conventional). |
| 19 | +const defaultLog: Logger = pino( |
| 20 | + { |
| 21 | + level: resolveLogLevel(process.env["LOG_LEVEL"]), |
| 22 | + redact: { paths: [...REDACT_PATHS] }, |
| 23 | + serializers: { err: errSerializer }, |
| 24 | + }, |
| 25 | + process.stderr, |
| 26 | +); |
2 | 27 |
|
3 | 28 | /** |
4 | 29 | * Retry configuration options. |
@@ -60,7 +85,7 @@ export async function retryWithBackoff<T>( |
60 | 85 | initialDelayMs = 5000, |
61 | 86 | maxDelayMs = 20000, |
62 | 87 | backoffFactor = 2, |
63 | | - log = rootLogger, |
| 88 | + log = defaultLog, |
64 | 89 | } = options; |
65 | 90 |
|
66 | 91 | // Fail fast on invalid input. Each check names the offending option and |
|
0 commit comments