fix(collector): keep partial telnet metrics, surface raw reply - #4311
Merged
Aias00 merged 3 commits intoAug 17, 2026
Merged
Conversation
orangeCatDeveloper
force-pushed
the
fix/1693-zookeeper-telnet-partial
branch
from
August 12, 2026 05:07
6bdfc2b to
44ec8e3
Compare
orangeCatDeveloper
force-pushed
the
fix/1693-zookeeper-telnet-partial
branch
from
August 13, 2026 19:42
44ec8e3 to
fa102fd
Compare
Aias00
approved these changes
Aug 17, 2026
Aias00
left a comment
Contributor
There was a problem hiding this comment.
Review: fix(collector): keep partial telnet metrics, surface raw reply — APPROVED
Fixes #1693 (zookeeper 4lw command refused → whole collection failed). Clean, well-tested improvement.
What's correct
execCmdAndParseResultnow returns aCmdResult(values, rawResponse)record, decoupling the parsed map from the raw bytes.- Partial metrics preserved: the old guard was
resultMap.size() < aliasFields.size()→ FAIL if any field was missing. New logic only FAILs when none of the expected non-responseTimefields were returned (expectsCmdMetrics && !hasExpectedMetric), and missing fields are padded withNULL_VALUE(confirmed bytestCollectPadsMissingMetrics:a=1present,b/c→ NULL). This is the right "keep what we got" semantics. - Raw reply surfaced: on total failure the FAIL message now includes
sanitizeReply(cmdResult.rawResponse()), andsanitizeReplystrips control chars and abbreviates to 300 chars — good for diagnosing whitelist refusals without log injection. TesttestCollectFailsWithRawReplyWhenNothingParsedasserts the reply text propagates. - Robustness fixes in the parser:
if (lines.length > 0 && ...)guardslines[0]access when the response is empty.if (lines.length == 0) return new CmdResult(new HashMap<>(16), result);handles empty responses (still exposes raw for the error message).Collectors.toMap(..., (first, second) -> first, HashMap::new)adds a merge function so duplicate keys no longer throwIllegalStateException.separatorderived fromlines[0]once — functionally same as before but cleaner.
Non-blocking suggestions
- The separator is still keyed off
lines[0]: if a data line uses a different separator than the header, it would misparse. Same limitation as before, just noting it. - A test for the duplicate-key merge path (two lines with same key) would lock that fix in, but the existing tests already cover the main cases.
Verdict: APPROVED. Good partial-success semantics, safer logging, and solid tests.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What's changed?
Fixes #1693: zookeeper monitors fail with "The cmd execution results do not match the expected number of metrics". One blunt check caused two different failures reported in the issue:
Case 1: valid partial reply thrown away (reporter ZachariahHu)
confon standalone zookeeper 3.4.14 returns 8 keys; the template defines 10 (dataDirSize/dataLogSizeonly exist in newer versions). Nothing is misconfigured, yet the whole group is discarded every cycle.Fix: fail only when the reply contains none of the expected fields. A partial reply keeps its parsed values; missing fields fall through to the pre-existing null-padding path.
Before — 9 parsed entries thrown away,
confshows no data:After — same server, collected without errors:
{"clientPort": "2181", "dataDir": "/data/version-2", "dataDirSize": null, "dataLogDir": "/datalog/version-2", "dataLogSize": null, "tickTime": "2000", "maxClientCnxns": "60", "minSessionTimeout": "4000", "maxSessionTimeout": "40000", "serverId": "0"}Case 2: whitelist refusal reason swallowed (reporter leim)
When the 4lw whitelist blocks
conf(bitnami image default), zookeeper replies with an explanation instead of data — but parsing dropped the raw reply, so the user only saw the generic message above.Fix: parsing returns the raw reply alongside the parsed map (
CmdResultrecord); the failure message now carries it, in logs and in the UI popup.Before — the refusal reason is nowhere:
After — zookeeper's own explanation reaches the user:
Failure is judged by "no expected field present", not "map is empty", so refusal text that parses as key/value (
error=conf disabled) still fails.Parsing hardening
Values split at the first separator only (
split(sep, 2)) sodataDir=/data/zk=asurvives; duplicate keys keep the first value; header-only/newline-only replies no longer throw onlines[0]. Tradeoff: a truncated reply with some expected fields present now yields visible null cells instead of a hard failure. zookeeper 3.9 with an open whitelist still collects all 10 columns.UI popup before/after (case 2):


Checklist
Add or update API