Skip to content

fix(collector): correct jsonpath alias parsing for rows missing path - #4265

Open
orangeCatDeveloper wants to merge 4 commits into
apache:masterfrom
orangeCatDeveloper:fix/issue-3307-jsonpath-row-alias
Open

fix(collector): correct jsonpath alias parsing for rows missing path#4265
orangeCatDeveloper wants to merge 4 commits into
apache:masterfrom
orangeCatDeveloper:fix/issue-3307-jsonpath-row-alias

Conversation

@orangeCatDeveloper

@orangeCatDeveloper orangeCatDeveloper commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

What's changed?

Fixes #3307.

A custom alias field $.status.containerStatuses[0].restartCount (monitor pod restart count, jsonPath parsing) returns an empty or wrong column. Example response, parseScript: $.items.*:

{"items": [
  {"metadata": {"name": "pod-a"}, "status": {"containerStatuses": [{"restartCount": 5}]}},
  {"metadata": {"name": "pod-b"}, "status": {"phase": "Pending"}},
  {"metadata": {"name": "pod-c"}, "status": {"containerStatuses": [{"restartCount": 2}]}}
]}

Two independent bugs. Both hit this user.

Bug 1: rows receive each other's values (HttpCollectImpl)

Problem. The alias column was filled by one global query, then distributed by row index:

query  $.items.*.status.containerStatuses[0].restartCount  →  [5, 2]

pod-b has no containerStatuses, and jayway skips it without a placeholder. Distributing [5, 2] by row index:

row pod gets should be
0 pod-a 5 5
1 pod-b 2 (pod-c's value) null
2 pod-c nothing 2

Fix. Ask each row's own object instead of the whole response: new JsonPathParser.parseRowWithJsonPath(rowObject, alias). A row that lacks the path returns an empty list → NULL cell. No cross-row indexing, nothing to misalign.

Bug 2: the calculates step silently eats the value (MetricsCollect)

Problem. calculates: rc=$.status.containerStatuses[0].restartCount must be classified: is the right side a column reference or a formula? The old rule was "if it compiles as JEXL, it's a formula". This path does compile — JEXL reads [0] as array access on a variable named $.status.containerStatuses. That variable doesn't exist, so it evaluates to null with no log. The column stays empty even when Bug 1 is fixed.

Fix. Before compiling, check: right side exactly equals one of the metric's aliasFields? Then it is by definition a column reference → map it directly, skip JEXL. Real formulas keep working — docker's cpu_delta=$.cpu_stats... - $.precpu_stats... doesn't equal any single aliasField.

Test plan

  • Unit tests reproduce both bugs (red before the fix, green after): HttpCollectImplTest, MetricsCollectTest, JsonPathParserTest. Full collector suites pass.
  • End-to-end on a local instance with a mocked pods API, same monitor, only collector jars swapped: before → rc all null; after → 5 / null / 2.
  • Regression: official spring_gateway (profile=$.activeProfiles[0]) and docker (name=$.Names[0]) monitors return identical values before and after.

Checklist

  • I have read the Contributing Guide
  • I have written the necessary doc or comment.
  • I have added the necessary unit tests and all cases have passed.

Add or update API

  • I have added the necessary e2e tests and all cases have passed.

Http jsonPath collection resolved alias paths with a global
"parseScript + alias" query indexed by row number, so rows missing the
path (e.g. pending pods without containerStatuses) misaligned every
following row. Calculates like rc=$.status.containerStatuses[0].restartCount
also compiled as JEXL array access and silently evaluated to null.
Alias paths are now evaluated per row, and calculates equal to an
aliasField skip JEXL entirely. Fixes apache#3307.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] <title>jsonpath parse data error

1 participant