From bb54e601798f4aa97835599ee57100b68193fa2a Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Sat, 3 Jan 2026 12:32:14 +0000 Subject: [PATCH] fix(logging): decouple file logs from console verbose --- CHANGELOG.md | 1 + docs/logging.md | 15 +++++++++++++- src/auto-reply/transcription.ts | 6 +++--- src/discord/monitor.ts | 12 +++++------ src/gateway/server.ts | 35 ++++++++++++++++++--------------- src/globals.ts | 16 ++++++++++++--- src/imessage/monitor.ts | 4 ++-- src/infra/ports.ts | 10 ++++++++-- src/infra/tailscale.ts | 10 ++++++++-- src/logger.ts | 11 ++--------- src/logging.ts | 7 ++++++- src/process/exec.ts | 6 +++--- src/signal/monitor.ts | 4 ++-- src/telegram/bot.ts | 6 +++--- src/utils.ts | 4 ++-- src/web/auto-reply.ts | 12 +++++------ src/web/inbound.ts | 9 +++++---- src/web/media.ts | 4 ++-- 18 files changed, 105 insertions(+), 67 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 913ded0c3..8f11fa627 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ - Agent tools: scope the Discord tool to Discord surface runs. - Agent tools: format verbose tool summaries without brackets, with unique emojis and `tool: detail` style. - Thinking: default to low for reasoning-capable models when no /think or config default is set. +- Logging: decouple file log levels from console verbosity; verbose-only details are captured when `logging.level` is debug/trace. ### Docs - Skills: add Sheets/Docs examples to gog skill (#128) — thanks @mbelinky. diff --git a/docs/logging.md b/docs/logging.md index c8fc987e7..7adca5eb7 100644 --- a/docs/logging.md +++ b/docs/logging.md @@ -23,12 +23,25 @@ Clawdis uses a file logger backed by `tslog` (`src/logging.ts`). The file format is one JSON object per line. +**Verbose vs. log levels** + +- **File logs** are controlled exclusively by `logging.level`. +- `--verbose` only affects **console verbosity** (and WS log style); it does **not** + raise the file log level. +- To capture verbose-only details in file logs, set `logging.level` to `debug` or + `trace`. + ## Console capture The CLI entrypoint enables console capture (`src/index.ts` calls `enableConsoleCapture()`). That means every `console.log/info/warn/error/debug/trace` is also written into the file logs, while still behaving normally on stdout/stderr. +You can tune console verbosity independently via: + +- `logging.consoleLevel` (default `info`) +- `logging.consoleStyle` (`pretty` | `compact` | `json`) + ## Gateway WebSocket logs The gateway prints WebSocket protocol logs in two modes: @@ -80,7 +93,7 @@ Behavior: - **Sub-loggers by subsystem** (auto prefix + structured field `{ subsystem }`) - **`logRaw()`** for QR/UX output (no prefix, no formatting) - **Console styles** (e.g. `pretty | compact | json`) -- **Console log level** separate from file log level (file keeps full detail) +- **Console log level** separate from file log level (file keeps full detail when `logging.level` is set to `debug`/`trace`) - **WhatsApp message bodies** are logged at `debug` (use `--verbose` to see them) This keeps existing file logs stable while making interactive output scannable. diff --git a/src/auto-reply/transcription.ts b/src/auto-reply/transcription.ts index 598c871f3..4e4ba6615 100644 --- a/src/auto-reply/transcription.ts +++ b/src/auto-reply/transcription.ts @@ -4,7 +4,7 @@ import os from "node:os"; import path from "node:path"; import type { ClawdisConfig } from "../config/config.js"; -import { isVerbose, logVerbose } from "../globals.js"; +import { logVerbose, shouldLogVerbose } from "../globals.js"; import { runExec } from "../process/exec.js"; import type { RuntimeEnv } from "../runtime.js"; import { applyTemplate, type MsgContext } from "./templating.js"; @@ -36,7 +36,7 @@ export async function transcribeInboundAudio( ); await fs.writeFile(tmpPath, buffer); mediaPath = tmpPath; - if (isVerbose()) { + if (shouldLogVerbose()) { logVerbose( `Downloaded audio for transcription (${(buffer.length / (1024 * 1024)).toFixed(2)}MB) -> ${tmpPath}`, ); @@ -48,7 +48,7 @@ export async function transcribeInboundAudio( const argv = transcriber.command.map((part) => applyTemplate(part, templCtx), ); - if (isVerbose()) { + if (shouldLogVerbose()) { logVerbose(`Transcribing audio via command: ${argv.join(" ")}`); } const { stdout } = await runExec(argv[0], argv.slice(1), { diff --git a/src/discord/monitor.ts b/src/discord/monitor.ts index 4cc98a169..5f3f0f64a 100644 --- a/src/discord/monitor.ts +++ b/src/discord/monitor.ts @@ -20,7 +20,7 @@ import type { } from "../config/config.js"; import { loadConfig } from "../config/config.js"; import { resolveStorePath, updateLastRoute } from "../config/sessions.js"; -import { danger, isVerbose, logVerbose, warn } from "../globals.js"; +import { danger, logVerbose, shouldLogVerbose, warn } from "../globals.js"; import { getChildLogger } from "../logging.js"; import { detectMime } from "../media/mime.js"; import { saveMediaBuffer } from "../media/store.js"; @@ -139,7 +139,7 @@ export async function monitorDiscordProvider(opts: MonitorDiscordOpts = {}) { const groupDmEnabled = dmConfig?.groupEnabled ?? false; const groupDmChannels = dmConfig?.groupChannels; - if (isVerbose()) { + if (shouldLogVerbose()) { logVerbose( `discord: config dm=${dmEnabled ? "on" : "off"} allowFrom=${summarizeAllowList(allowFrom)} groupDm=${groupDmEnabled ? "on" : "off"} groupDmChannels=${summarizeAllowList(groupDmChannels)} guilds=${summarizeGuilds(guildEntries)} historyLimit=${historyLimit} mediaMaxMb=${Math.round(mediaMaxBytes / (1024 * 1024))}`, ); @@ -191,7 +191,7 @@ export async function monitorDiscordProvider(opts: MonitorDiscordOpts = {}) { const wasMentioned = !isDirectMessage && Boolean(botId && message.mentions.has(botId)); const baseText = resolveDiscordMessageText(message); - if (isVerbose()) { + if (shouldLogVerbose()) { logVerbose( `discord: inbound id=${message.id} guild=${message.guild?.id ?? "dm"} channel=${message.channelId} mention=${wasMentioned ? "yes" : "no"} type=${isDirectMessage ? "dm" : isGroupDm ? "group-dm" : "guild"} content=${baseText ? "yes" : "no"}`, ); @@ -414,7 +414,7 @@ export async function monitorDiscordProvider(opts: MonitorDiscordOpts = {}) { }); } - if (isVerbose()) { + if (shouldLogVerbose()) { const preview = combinedBody.slice(0, 200).replace(/\n/g, "\\n"); logVerbose( `discord inbound: channel=${message.channelId} from=${ctxPayload.From} preview="${preview}"`, @@ -485,7 +485,7 @@ export async function monitorDiscordProvider(opts: MonitorDiscordOpts = {}) { textLimit, }); didSendReply = true; - if (isVerbose()) { + if (shouldLogVerbose()) { logVerbose( `discord: delivered ${replies.length} reply${replies.length === 1 ? "" : "ies"} to ${replyTarget}`, ); @@ -524,7 +524,7 @@ export async function monitorDiscordProvider(opts: MonitorDiscordOpts = {}) { logVerbose("discord: drop slash (dms disabled)"); return; } - if (isVerbose()) { + if (shouldLogVerbose()) { logVerbose( `discord: slash inbound guild=${interaction.guildId ?? "dm"} channel=${interaction.channelId} type=${isDirectMessage ? "dm" : isGroupDm ? "group-dm" : "guild"}`, ); diff --git a/src/gateway/server.ts b/src/gateway/server.ts index 119b0e9b1..8cacfd33b 100644 --- a/src/gateway/server.ts +++ b/src/gateway/server.ts @@ -83,7 +83,7 @@ import { sendMessageDiscord, } from "../discord/index.js"; import { type DiscordProbe, probeDiscord } from "../discord/probe.js"; -import { isVerbose } from "../globals.js"; +import { isVerbose, shouldLogVerbose } from "../globals.js"; import { startGmailWatcher, stopGmailWatcher } from "../hooks/gmail-watcher.js"; import { monitorIMessageProvider, @@ -2084,7 +2084,7 @@ export async function startGatewayServer( lastError: null, }; const task = monitorWebProvider( - isVerbose(), + shouldLogVerbose(), undefined, true, undefined, @@ -2137,7 +2137,7 @@ export async function startGatewayServer( running: false, lastError: "disabled", }; - if (isVerbose()) { + if (shouldLogVerbose()) { logTelegram.debug( "telegram provider disabled (telegram.enabled=false)", ); @@ -2154,7 +2154,7 @@ export async function startGatewayServer( lastError: "not configured", }; // keep quiet by default; this is a normal state - if (isVerbose()) { + if (shouldLogVerbose()) { logTelegram.debug( "telegram provider not configured (no TELEGRAM_BOT_TOKEN)", ); @@ -2171,7 +2171,7 @@ export async function startGatewayServer( const username = probe.ok ? probe.bot?.username?.trim() : null; if (username) telegramBotLabel = ` (@${username})`; } catch (err) { - if (isVerbose()) { + if (shouldLogVerbose()) { logTelegram.debug(`bot probe failed: ${String(err)}`); } } @@ -2240,7 +2240,7 @@ export async function startGatewayServer( running: false, lastError: "disabled", }; - if (isVerbose()) { + if (shouldLogVerbose()) { logDiscord.debug("discord provider disabled (discord.enabled=false)"); } return; @@ -2254,7 +2254,7 @@ export async function startGatewayServer( lastError: "not configured", }; // keep quiet by default; this is a normal state - if (isVerbose()) { + if (shouldLogVerbose()) { logDiscord.debug( "discord provider not configured (no DISCORD_BOT_TOKEN)", ); @@ -2267,7 +2267,7 @@ export async function startGatewayServer( const username = probe.ok ? probe.bot?.username?.trim() : null; if (username) discordBotLabel = ` (@${username})`; } catch (err) { - if (isVerbose()) { + if (shouldLogVerbose()) { logDiscord.debug(`bot probe failed: ${String(err)}`); } } @@ -2335,7 +2335,7 @@ export async function startGatewayServer( lastError: "not configured", }; // keep quiet by default; this is a normal state - if (isVerbose()) { + if (shouldLogVerbose()) { logSignal.debug("signal provider not configured (no signal config)"); } return; @@ -2346,7 +2346,7 @@ export async function startGatewayServer( running: false, lastError: "disabled", }; - if (isVerbose()) { + if (shouldLogVerbose()) { logSignal.debug("signal provider disabled (signal.enabled=false)"); } return; @@ -2367,7 +2367,7 @@ export async function startGatewayServer( lastError: "not configured", }; // keep quiet by default; this is a normal state - if (isVerbose()) { + if (shouldLogVerbose()) { logSignal.debug( "signal provider not configured (signal config present but missing required fields)", ); @@ -2448,7 +2448,7 @@ export async function startGatewayServer( lastError: "not configured", }; // keep quiet by default; this is a normal state - if (isVerbose()) { + if (shouldLogVerbose()) { logIMessage.debug( "imessage provider not configured (no imessage config)", ); @@ -2461,7 +2461,7 @@ export async function startGatewayServer( running: false, lastError: "disabled", }; - if (isVerbose()) { + if (shouldLogVerbose()) { logIMessage.debug( "imessage provider disabled (imessage.enabled=false)", ); @@ -4725,7 +4725,10 @@ export async function startGatewayServer( if (configured) { thinkingLevel = configured; } else { - const { provider, model } = resolveSessionModelRef(cfg, entry); + const { provider, model } = resolveSessionModelRef( + cfg, + entry, + ); const catalog = await loadGatewayModelCatalog(); thinkingLevel = resolveThinkingDefault({ cfg, @@ -6629,7 +6632,7 @@ export async function startGatewayServer( const { token } = resolveTelegramToken(cfg); const result = await sendMessageTelegram(to, message, { mediaUrl: params.mediaUrl, - verbose: isVerbose(), + verbose: shouldLogVerbose(), token: token || undefined, }); const payload = { @@ -6707,7 +6710,7 @@ export async function startGatewayServer( } else { const result = await sendMessageWhatsApp(to, message, { mediaUrl: params.mediaUrl, - verbose: isVerbose(), + verbose: shouldLogVerbose(), }); const payload = { runId: idem, diff --git a/src/globals.ts b/src/globals.ts index a1e2dbf57..3f8655a02 100644 --- a/src/globals.ts +++ b/src/globals.ts @@ -1,5 +1,5 @@ import chalk from "chalk"; -import { getLogger } from "./logging.js"; +import { getLogger, isFileLogLevelEnabled } from "./logging.js"; let globalVerbose = false; let globalYes = false; @@ -12,14 +12,24 @@ export function isVerbose() { return globalVerbose; } +export function shouldLogVerbose() { + return globalVerbose || isFileLogLevelEnabled("debug"); +} + export function logVerbose(message: string) { - if (!globalVerbose) return; - console.log(chalk.gray(message)); + if (!shouldLogVerbose()) return; try { getLogger().debug({ message }, "verbose"); } catch { // ignore logger failures to avoid breaking verbose printing } + if (!globalVerbose) return; + console.log(chalk.gray(message)); +} + +export function logVerboseConsole(message: string) { + if (!globalVerbose) return; + console.log(chalk.gray(message)); } export function setYes(v: boolean) { diff --git a/src/imessage/monitor.ts b/src/imessage/monitor.ts index 281c62830..241642663 100644 --- a/src/imessage/monitor.ts +++ b/src/imessage/monitor.ts @@ -4,7 +4,7 @@ import { getReplyFromConfig } from "../auto-reply/reply.js"; import type { ReplyPayload } from "../auto-reply/types.js"; import { loadConfig } from "../config/config.js"; import { resolveStorePath, updateLastRoute } from "../config/sessions.js"; -import { danger, isVerbose, logVerbose } from "../globals.js"; +import { danger, logVerbose, shouldLogVerbose } from "../globals.js"; import { mediaKindFromMime } from "../media/constants.js"; import type { RuntimeEnv } from "../runtime.js"; import { createIMessageRpcClient } from "./client.js"; @@ -252,7 +252,7 @@ export async function monitorIMessageProvider( } } - if (isVerbose()) { + if (shouldLogVerbose()) { const preview = body.slice(0, 200).replace(/\n/g, "\\n"); logVerbose( `imessage inbound: chatId=${chatId ?? "unknown"} from=${ctxPayload.From} len=${body.length} preview="${preview}"`, diff --git a/src/infra/ports.ts b/src/infra/ports.ts index 93a1d8b58..72f901ed0 100644 --- a/src/infra/ports.ts +++ b/src/infra/ports.ts @@ -1,5 +1,11 @@ import net from "node:net"; -import { danger, info, isVerbose, logVerbose, warn } from "../globals.js"; +import { + danger, + info, + logVerbose, + shouldLogVerbose, + warn, +} from "../globals.js"; import { logDebug } from "../logger.js"; import { runExec } from "../process/exec.js"; import { defaultRuntime, type RuntimeEnv } from "../runtime.js"; @@ -95,7 +101,7 @@ export async function handlePortError( runtime.exit(1); } runtime.error(danger(`${context} failed: ${String(err)}`)); - if (isVerbose()) { + if (shouldLogVerbose()) { const stdout = (err as { stdout?: string })?.stdout; const stderr = (err as { stderr?: string })?.stderr; if (stdout?.trim()) logDebug(`stdout: ${stdout.trim()}`); diff --git a/src/infra/tailscale.ts b/src/infra/tailscale.ts index 6dfb2f695..84df0da74 100644 --- a/src/infra/tailscale.ts +++ b/src/infra/tailscale.ts @@ -1,7 +1,13 @@ import { existsSync } from "node:fs"; import chalk from "chalk"; import { promptYesNo } from "../cli/prompt.js"; -import { danger, info, isVerbose, logVerbose, warn } from "../globals.js"; +import { + danger, + info, + logVerbose, + shouldLogVerbose, + warn, +} from "../globals.js"; import { runExec } from "../process/exec.js"; import { defaultRuntime, type RuntimeEnv } from "../runtime.js"; import { ensureBinary } from "./binaries.js"; @@ -173,7 +179,7 @@ export async function ensureFunnel( "Tip: Funnel is optional for CLAWDIS. You can keep running the web gateway without it: `pnpm clawdis gateway`", ), ); - if (isVerbose()) { + if (shouldLogVerbose()) { if (stdout.trim()) runtime.error(chalk.gray(`stdout: ${stdout.trim()}`)); if (stderr.trim()) runtime.error(chalk.gray(`stderr: ${stderr.trim()}`)); runtime.error(err as Error); diff --git a/src/logger.ts b/src/logger.ts index 7f63b2fa7..5bb69552e 100644 --- a/src/logger.ts +++ b/src/logger.ts @@ -1,11 +1,4 @@ -import { - danger, - info, - isVerbose, - logVerbose, - success, - warn, -} from "./globals.js"; +import { danger, info, logVerboseConsole, success, warn } from "./globals.js"; import { createSubsystemLogger, getLogger } from "./logging.js"; import { defaultRuntime, type RuntimeEnv } from "./runtime.js"; @@ -67,5 +60,5 @@ export function logError( export function logDebug(message: string) { // Always emit to file logger (level-filtered); console only when verbose. getLogger().debug(message); - if (isVerbose()) logVerbose(message); + logVerboseConsole(message); } diff --git a/src/logging.ts b/src/logging.ts index a4b4362dc..e97990c2f 100644 --- a/src/logging.ts +++ b/src/logging.ts @@ -65,7 +65,6 @@ let rawConsole: { } | null = null; function normalizeLevel(level?: string): Level { - if (isVerbose()) return "trace"; const candidate = level ?? "info"; return ALLOWED_LEVELS.includes(candidate as Level) ? (candidate as Level) @@ -112,6 +111,12 @@ function levelToMinLevel(level: Level): number { return map[level]; } +export function isFileLogLevelEnabled(level: LogLevel): boolean { + const settings = cachedSettings ?? resolveSettings(); + if (!cachedSettings) cachedSettings = settings; + return levelToMinLevel(level) <= levelToMinLevel(settings.level); +} + function normalizeConsoleLevel(level?: string): Level { if (isVerbose()) return "debug"; const candidate = level ?? "info"; diff --git a/src/process/exec.ts b/src/process/exec.ts index 914f3bfe5..f0ea1c5a4 100644 --- a/src/process/exec.ts +++ b/src/process/exec.ts @@ -1,7 +1,7 @@ import { execFile, spawn } from "node:child_process"; import { promisify } from "node:util"; -import { danger, isVerbose } from "../globals.js"; +import { danger, shouldLogVerbose } from "../globals.js"; import { logDebug, logError } from "../logger.js"; const execFileAsync = promisify(execFile); @@ -22,13 +22,13 @@ export async function runExec( }; try { const { stdout, stderr } = await execFileAsync(command, args, options); - if (isVerbose()) { + if (shouldLogVerbose()) { if (stdout.trim()) logDebug(stdout.trim()); if (stderr.trim()) logError(stderr.trim()); } return { stdout, stderr }; } catch (err) { - if (isVerbose()) { + if (shouldLogVerbose()) { logError(danger(`Command failed: ${command} ${args.join(" ")}`)); } throw err; diff --git a/src/signal/monitor.ts b/src/signal/monitor.ts index d7917d49b..eb04f87f6 100644 --- a/src/signal/monitor.ts +++ b/src/signal/monitor.ts @@ -4,7 +4,7 @@ import { getReplyFromConfig } from "../auto-reply/reply.js"; import type { ReplyPayload } from "../auto-reply/types.js"; import { loadConfig } from "../config/config.js"; import { resolveStorePath, updateLastRoute } from "../config/sessions.js"; -import { danger, isVerbose, logVerbose } from "../globals.js"; +import { danger, logVerbose, shouldLogVerbose } from "../globals.js"; import { mediaKindFromMime } from "../media/constants.js"; import { saveMediaBuffer } from "../media/store.js"; import type { RuntimeEnv } from "../runtime.js"; @@ -369,7 +369,7 @@ export async function monitorSignalProvider( }); } - if (isVerbose()) { + if (shouldLogVerbose()) { const preview = body.slice(0, 200).replace(/\n/g, "\\n"); logVerbose( `signal inbound: from=${ctxPayload.From} len=${body.length} preview="${preview}"`, diff --git a/src/telegram/bot.ts b/src/telegram/bot.ts index 38e598ef8..aa5d7aa10 100644 --- a/src/telegram/bot.ts +++ b/src/telegram/bot.ts @@ -12,7 +12,7 @@ import type { ReplyPayload } from "../auto-reply/types.js"; import type { ReplyToMode } from "../config/config.js"; import { loadConfig } from "../config/config.js"; import { resolveStorePath, updateLastRoute } from "../config/sessions.js"; -import { danger, isVerbose, logVerbose } from "../globals.js"; +import { danger, logVerbose, shouldLogVerbose } from "../globals.js"; import { formatErrorMessage } from "../infra/errors.js"; import { getChildLogger } from "../logging.js"; import { mediaKindFromMime } from "../media/constants.js"; @@ -173,7 +173,7 @@ export function createTelegramBot(opts: TelegramBotOptions) { MediaUrl: media?.path, }; - if (replyTarget && isVerbose()) { + if (replyTarget && shouldLogVerbose()) { const preview = replyTarget.body.replace(/\s+/g, " ").slice(0, 120); logVerbose( `telegram reply-context: replyToId=${replyTarget.id} replyToSender=${replyTarget.sender} replyToBody="${preview}"`, @@ -192,7 +192,7 @@ export function createTelegramBot(opts: TelegramBotOptions) { }); } - if (isVerbose()) { + if (shouldLogVerbose()) { const preview = body.slice(0, 200).replace(/\n/g, "\\n"); logVerbose( `telegram inbound: chatId=${chatId} from=${ctxPayload.From} len=${body.length} preview="${preview}"`, diff --git a/src/utils.ts b/src/utils.ts index 25287c4d6..801784fa6 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,7 +1,7 @@ import fs from "node:fs"; import os from "node:os"; import path from "node:path"; -import { isVerbose, logVerbose } from "./globals.js"; +import { logVerbose, shouldLogVerbose } from "./globals.js"; export async function ensureDir(dir: string) { await fs.promises.mkdir(dir, { recursive: true }); @@ -79,7 +79,7 @@ export function jidToE164(jid: string): string | null { const phone = JSON.parse(data); if (phone) return `+${phone}`; } catch { - if (isVerbose()) { + if (shouldLogVerbose()) { logVerbose( `LID mapping not found for ${lid}; skipping inbound message`, ); diff --git a/src/web/auto-reply.ts b/src/web/auto-reply.ts index 3d4879a99..ce587e089 100644 --- a/src/web/auto-reply.ts +++ b/src/web/auto-reply.ts @@ -21,7 +21,7 @@ import { saveSessionStore, updateLastRoute, } from "../config/sessions.js"; -import { isVerbose, logVerbose } from "../globals.js"; +import { logVerbose, shouldLogVerbose } from "../globals.js"; import { emitHeartbeatEvent } from "../infra/heartbeat-events.js"; import { enqueueSystemEvent } from "../infra/system-events.js"; import { createSubsystemLogger, getChildLogger } from "../logging.js"; @@ -325,7 +325,7 @@ export async function runWebHeartbeatOnce(opts: { }, "heartbeat skipped", ); - if (isVerbose()) { + if (shouldLogVerbose()) { whatsappHeartbeatLog.debug("heartbeat ok (empty reply)"); } emitHeartbeatEvent({ status: "ok-empty", to }); @@ -352,7 +352,7 @@ export async function runWebHeartbeatOnce(opts: { { to, reason: "heartbeat-token", rawLength: replyPayload.text?.length }, "heartbeat skipped", ); - if (isVerbose()) { + if (shouldLogVerbose()) { whatsappHeartbeatLog.debug("heartbeat ok (HEARTBEAT_OK)"); } emitHeartbeatEvent({ status: "ok-token", to }); @@ -593,7 +593,7 @@ async function deliverWebReply(params: { index === 0 ? remainingText.shift() || undefined : undefined; try { const media = await loadWebMedia(mediaUrl, maxMediaBytes); - if (isVerbose()) { + if (shouldLogVerbose()) { logVerbose( `Web auto-reply media size: ${(media.buffer.length / (1024 * 1024)).toFixed(2)}MB`, ); @@ -1015,7 +1015,7 @@ export async function monitorWebProvider( whatsappInboundLog.info( `Inbound message ${fromDisplay} -> ${msg.to} (${msg.chatType}${kindLabel}, ${combinedBody.length} chars)`, ); - if (isVerbose()) { + if (shouldLogVerbose()) { whatsappInboundLog.debug(`Inbound body: ${elide(combinedBody, 400)}`); } @@ -1268,7 +1268,7 @@ export async function monitorWebProvider( whatsappOutboundLog.info( `Auto-replied to ${fromDisplay}${hasMedia ? " (media)" : ""}`, ); - if (isVerbose()) { + if (shouldLogVerbose()) { const preview = replyPayload.text != null ? elide(replyPayload.text, 400) diff --git a/src/web/inbound.ts b/src/web/inbound.ts index ba2c4e6ba..cc3b463bf 100644 --- a/src/web/inbound.ts +++ b/src/web/inbound.ts @@ -13,7 +13,7 @@ import { } from "@whiskeysockets/baileys"; import { loadConfig } from "../config/config.js"; -import { isVerbose, logVerbose } from "../globals.js"; +import { logVerbose, shouldLogVerbose } from "../globals.js"; import { createSubsystemLogger, getChildLogger } from "../logging.js"; import { saveMediaBuffer } from "../media/store.js"; import { @@ -87,7 +87,8 @@ export async function monitorWebInbox(options: { try { // Advertise that the gateway is online right after connecting. await sock.sendPresenceUpdate("available"); - if (isVerbose()) logVerbose("Sent global 'available' presence on connect"); + if (shouldLogVerbose()) + logVerbose("Sent global 'available' presence on connect"); } catch (err) { logVerbose( `Failed to send 'available' presence on connect: ${String(err)}`, @@ -189,7 +190,7 @@ export async function monitorWebInbox(options: { await sock.readMessages([ { remoteJid, id, participant, fromMe: false }, ]); - if (isVerbose()) { + if (shouldLogVerbose()) { const suffix = participant ? ` (participant ${participant})` : ""; logVerbose( `Marked message ${id} as read for ${remoteJid}${suffix}`, @@ -198,7 +199,7 @@ export async function monitorWebInbox(options: { } catch (err) { logVerbose(`Failed to mark message ${id} read: ${String(err)}`); } - } else if (id && isSelfChat && isVerbose()) { + } else if (id && isSelfChat && shouldLogVerbose()) { // Self-chat mode: never auto-send read receipts (blue ticks) on behalf of the owner. logVerbose(`Self-chat mode: skipping read receipt for ${id}`); } diff --git a/src/web/media.ts b/src/web/media.ts index 091406f9b..c973e0c09 100644 --- a/src/web/media.ts +++ b/src/web/media.ts @@ -1,7 +1,7 @@ import fs from "node:fs/promises"; import path from "node:path"; -import { isVerbose, logVerbose } from "../globals.js"; +import { logVerbose, shouldLogVerbose } from "../globals.js"; import { type MediaKind, maxBytesForKind, @@ -26,7 +26,7 @@ export async function loadWebMedia( const optimizeAndClampImage = async (buffer: Buffer, cap: number) => { const originalSize = buffer.length; const optimized = await optimizeImageToJpeg(buffer, cap); - if (optimized.optimizedSize < originalSize && isVerbose()) { + if (optimized.optimizedSize < originalSize && shouldLogVerbose()) { logVerbose( `Optimized media from ${(originalSize / (1024 * 1024)).toFixed(2)}MB to ${(optimized.optimizedSize / (1024 * 1024)).toFixed(2)}MB (side≤${optimized.resizeSide}px, q=${optimized.quality})`, );