Skip to content

fix(#82957): route Telegram polling [diag] lines through info channel, not error#83047

Closed
YonganZhang wants to merge 1 commit into
openclaw:mainfrom
YonganZhang:yongan/fix-82957-telegram-polling-diag-log-level
Closed

fix(#82957): route Telegram polling [diag] lines through info channel, not error#83047
YonganZhang wants to merge 1 commit into
openclaw:mainfrom
YonganZhang:yongan/fix-82957-telegram-polling-diag-log-level

Conversation

@YonganZhang

Copy link
Copy Markdown
Contributor

Summary

Fixes #82957.

extensions/telegram/src/monitor.ts:111 previously hard-coded:

const log = opts.runtime?.error ?? console.error;

so every line emitted by the monitor and every line bubbled from TelegramPollingSession.opts.log ended up on the runtime's error channel. Normal lifecycle diagnostics ("polling cycle started", "rebuilding transport for next polling cycle", "waited for previous polling session", etc.) were therefore styled as gateway errors in the console, breaking the visual distinction between expected lifecycle output and actual failures.

Why [telegram][diag] is the right discriminator

[telegram][diag] is the established info-level marker in this extension. polling-session.ts:260 itself wraps incoming info: ... messages into \[telegram][diag] ${msg} before forwarding — confirming the intent. Other extensions are consistent:

Extension info / log path error path
twitch/src/monitor.ts:193,195 info: (msg) => runtime.log?.(msg) error: (msg) => runtime.error?.(msg)
nextcloud-talk/src/room-info.ts:105 runtime?.log?.(...)
zalo/src/monitor.webhook.ts:146 log: runtime?.log
signal/src/daemon.ts:96 opts.runtime?.log ?? (() => {})
feishu/src/card-action.ts:155, 298 runtime?.log ?? console.log

Telegram is the outlier — fixing it brings it in line.

Fix

const logInfo = opts.runtime?.log ?? console.log;
const logError = opts.runtime?.error ?? console.error;
const log = (line: string) =>
  (line.includes("[telegram][diag]") ? logInfo : logError)(line);

The single-log API exposed downstream (notably PollingSessionOpts.log) is unchanged — callers still call log("anything"), but now [diag] lines route to info.

Real behavior proof

info channel (4 lines):
  ✓ [telegram][diag] polling cycle started lastUpdate=42
  ✓ [telegram][diag] rebuilding transport for next polling cycle
  ✓ [telegram][diag] waited for previous polling session for bot token X
  ✓ [telegram][diag] marking transport dirty after polling network failure

error channel (2 lines):
  🔴 [telegram] Restarting polling after polling-network-failure: ECONNRESET
  🔴 [telegram] reconnect delivery drain failed: Timeout after 30s

Diagnostics now land on the info channel; only true failures stay on error — matching the issue's expected behavior verbatim.

Diff size

7 lines (3 changed, 4 added comment+dispatch). Single file. No new dependencies.

… channel, not error

`extensions/telegram/src/monitor.ts:111` previously hard-coded:

    const log = opts.runtime?.error ?? console.error;

so every line emitted by the monitor and every line bubbled from
`TelegramPollingSession.opts.log` ended up on the runtime's error
channel. Normal lifecycle diagnostics ("polling cycle started",
"rebuilding transport for next polling cycle", "waited for previous
polling session", etc.) were therefore styled as gateway errors in the
console, breaking the visual distinction between expected lifecycle
output and actual failures.

`[telegram][diag]` is the established info-level marker in this
extension. polling-session.ts:260 itself wraps incoming `info: ...`
messages into `[telegram][diag] ${msg}` before forwarding, confirming
the intent. Other extensions (twitch monitor.ts:193,
nextcloud-talk room-info.ts:105, zalo monitor.webhook.ts:146,
signal daemon.ts:96, feishu card-action.ts:155/298) consistently use
`runtime?.log` for info and `runtime?.error` for error.

Fix: split the single `log` into a dispatch that picks the channel
based on the `[telegram][diag]` prefix:

    const logInfo = opts.runtime?.log ?? console.log;
    const logError = opts.runtime?.error ?? console.error;
    const log = (line: string) =>
      (line.includes("[telegram][diag]") ? logInfo : logError)(line);

After this change, lines like "polling cycle started ..." land on the
info channel; only true failures ("Restarting polling after ...",
"reconnect delivery drain failed: ...") stay on error.
@openclaw-barnacle openclaw-barnacle Bot added channel: telegram Channel integration: telegram size: XS triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup. labels May 17, 2026
@clawsweeper

clawsweeper Bot commented May 17, 2026

Copy link
Copy Markdown
Contributor

Thanks for the context here. I swept through the related work, and this is now duplicate or superseded.

Close as duplicate/superseded: an earlier open maintainer-labeled PR for the same Telegram log-level bug already changes the same monitor boundary and adds regression coverage, so this parallel branch does not carry unique work that should remain open.

Canonical path: Use #82958 as the canonical path to finish and land the Telegram logger fix, then let it close the linked issue.

So I’m closing this here and keeping the remaining discussion on #82958 and #82957.

Review details

Best possible solution:

Use #82958 as the canonical path to finish and land the Telegram logger fix, then let it close the linked issue.

Do we have a high-confidence way to reproduce the issue?

Yes. Source inspection shows current main binds the Telegram monitor logger to runtime.error, passes it into TelegramPollingSession, and the session emits [telegram][diag] polling cycle started through that callback; I did not run a live Telegram poller in this read-only review.

Is this the best way to solve the issue?

No, not as a separate PR. The log-channel direction is sound, but the earlier open canonical PR covers the same bug and adds regression coverage, so this duplicate branch is not the best landing path.

Security review:

Security review cleared: The diff only changes local Telegram log dispatch in one source file and does not touch dependencies, CI, secrets, permissions, or code execution paths.

What I checked:

Likely related people:

  • steipete: Introduced or heavily refactored the Telegram polling/session boundary, including the split of Telegram polling and SDK surfaces where monitor-to-session logging is central. (role: feature-history owner; confidence: high; commits: 0c0f1e34cba0, 6a2c5b2b54a7, 60fea81cf19f; files: extensions/telegram/src/monitor.ts, extensions/telegram/src/polling-session.ts, extensions/telegram/src/polling-transport-state.ts)
  • vincentkoc: Recently split Telegram monitor runtime types and lazy-loaded Telegram monitor runtime graphs, touching the same monitor boundary after the plugin move. (role: recent area contributor; confidence: medium; commits: ae4fdaea8207, 4309dc6d5ee9, 5b952836e3d9; files: extensions/telegram/src/monitor.ts, extensions/telegram/src/monitor.types.ts, extensions/telegram/src/monitor-polling.runtime.ts)
  • scoootscooob: Moved the Telegram channel implementation into extensions/telegram, carrying the monitor and polling-session logging boundary into the plugin package. (role: migration carrier; confidence: medium; commits: e5bca0832fbd; files: src/telegram/monitor.ts, src/telegram/polling-session.ts, extensions/telegram/src/monitor.ts)
  • sinogello: Worked on Telegram stalled-polling restart behavior in the same monitor and polling-session files that emit these diagnostics. (role: adjacent polling reliability contributor; confidence: medium; commits: e035a0d98c91; files: extensions/telegram/src/monitor.ts, extensions/telegram/src/polling-session.ts)

Codex review notes: model gpt-5.5, reasoning high; reviewed against 2ab76240d308.

@clawsweeper clawsweeper Bot added the P2 Normal backlog priority with limited blast radius. label May 17, 2026
@clawsweeper clawsweeper Bot closed this May 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

channel: telegram Channel integration: telegram P2 Normal backlog priority with limited blast radius. size: XS triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Telegram polling startup diagnostic is logged at error level

1 participant