This is an automated email from the ASF dual-hosted git repository.
rzo1 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/storm.git
The following commit(s) were added to refs/heads/master by this push:
new 136025bca Fix scientific notation display for large numbers in Storm
UI tables (#8456) (#8457)
136025bca is described below
commit 136025bcac6d63997a597a349fb827de3bad239a
Author: Richard Zowalla <[email protected]>
AuthorDate: Wed Apr 1 19:36:35 2026 +0200
Fix scientific notation display for large numbers in Storm UI tables
(#8456) (#8457)
- Replace DataTables' built-in render.number() with a custom formatter that
uses toLocaleString() to reliably format large integers with comma separators.
- Add Cypress E2E tests with large fixture values to prevent regression.
---
storm-webapp/cypress/e2e/component-page.cy.js | 28 ++++++++++++++++++++++
storm-webapp/cypress/e2e/index-page.cy.js | 8 +++++++
storm-webapp/cypress/e2e/topology-page.cy.js | 28 ++++++++++++++++++++++
.../cypress/fixtures/component-detail.json | 8 +++----
storm-webapp/cypress/fixtures/topology-detail.json | 22 ++++++++---------
.../apache/storm/daemon/ui/WEB-INF/component.html | 14 +++++------
.../org/apache/storm/daemon/ui/WEB-INF/index.html | 4 ++--
.../org/apache/storm/daemon/ui/WEB-INF/owner.html | 4 ++--
.../apache/storm/daemon/ui/WEB-INF/supervisor.html | 4 ++--
.../apache/storm/daemon/ui/WEB-INF/topology.html | 10 ++++----
storm-webapp/src/main/webapp/js/script.js | 12 ++++++++++
11 files changed, 109 insertions(+), 33 deletions(-)
diff --git a/storm-webapp/cypress/e2e/component-page.cy.js
b/storm-webapp/cypress/e2e/component-page.cy.js
index 367bee03e..4a128db1b 100644
--- a/storm-webapp/cypress/e2e/component-page.cy.js
+++ b/storm-webapp/cypress/e2e/component-page.cy.js
@@ -39,4 +39,32 @@ describe('Storm UI - Component Detail Page', () => {
expect(win.moment).to.exist;
});
});
+
+ it('formats large numbers with commas in bolt stats table', () => {
+ cy.get('#bolt-stats-table').within(() => {
+ cy.contains('td', '600,000,000,000').should('exist');
+ cy.contains('td', '200,000,000,000').should('exist');
+ cy.get('td').each(($td) => {
+ expect($td.text()).not.to.match(/\de[+]\d/i);
+ });
+ });
+ });
+
+ it('formats large numbers with commas in output stats table', () => {
+ cy.get('#bolt-output-stats-table').within(() => {
+ cy.contains('td', '600,000,000,000').should('exist');
+ cy.get('td').each(($td) => {
+ expect($td.text()).not.to.match(/\de[+]\d/i);
+ });
+ });
+ });
+
+ it('formats large numbers with commas in input stats table', () => {
+ cy.get('#bolt-input-stats-table').within(() => {
+ cy.contains('td', '200,000,000,000').should('exist');
+ cy.get('td').each(($td) => {
+ expect($td.text()).not.to.match(/\de[+]\d/i);
+ });
+ });
+ });
});
diff --git a/storm-webapp/cypress/e2e/index-page.cy.js
b/storm-webapp/cypress/e2e/index-page.cy.js
index f460cde49..221ad48ea 100644
--- a/storm-webapp/cypress/e2e/index-page.cy.js
+++ b/storm-webapp/cypress/e2e/index-page.cy.js
@@ -79,4 +79,12 @@ describe('Storm UI - Index Page', () => {
it('shows the page rendered timestamp', () => {
cy.get('#page-rendered-at-timestamp').should('contain', 'Page rendered
at:');
});
+
+ it('does not display scientific notation in topology summary table', () => {
+ cy.get('#topology-summary-table').within(() => {
+ cy.get('td').each(($td) => {
+ expect($td.text()).not.to.match(/\de[+]\d/i);
+ });
+ });
+ });
});
diff --git a/storm-webapp/cypress/e2e/topology-page.cy.js
b/storm-webapp/cypress/e2e/topology-page.cy.js
index 22f5dd13a..010c2241c 100644
--- a/storm-webapp/cypress/e2e/topology-page.cy.js
+++ b/storm-webapp/cypress/e2e/topology-page.cy.js
@@ -46,4 +46,32 @@ describe('Storm UI - Topology Detail Page', () => {
it('renders topology action buttons', () => {
cy.get('input[type="button"]').should('have.length.greaterThan', 0);
});
+
+ it('formats large numbers with commas, not scientific notation', () => {
+ cy.get('#topology-stats-table').within(() => {
+ cy.contains('td', '200,000,000,000').should('exist');
+ cy.contains('td', '100,000,000,000').should('exist');
+ cy.get('td').each(($td) => {
+ expect($td.text()).not.to.match(/\de[+]\d/i);
+ });
+ });
+ });
+
+ it('formats large spout numbers with commas, not scientific notation', () =>
{
+ cy.get('#spout-stats-table').within(() => {
+ cy.contains('td', '200,000,000,000').should('exist');
+ cy.get('td').each(($td) => {
+ expect($td.text()).not.to.match(/\de[+]\d/i);
+ });
+ });
+ });
+
+ it('formats large bolt numbers with commas, not scientific notation', () => {
+ cy.get('#bolt-stats-table').within(() => {
+ cy.contains('td', '600,000,000,000').should('exist');
+ cy.get('td').each(($td) => {
+ expect($td.text()).not.to.match(/\de[+]\d/i);
+ });
+ });
+ });
});
diff --git a/storm-webapp/cypress/fixtures/component-detail.json
b/storm-webapp/cypress/fixtures/component-detail.json
index 5bed16804..5313969a3 100644
--- a/storm-webapp/cypress/fixtures/component-detail.json
+++ b/storm-webapp/cypress/fixtures/component-detail.json
@@ -17,16 +17,16 @@
"profilerActive": [],
"schedulerDisplayResource": false,
"boltStats": [
- {"windowPretty": "All time", "window": ":all-time", "emitted": 7200000,
"transferred": 7200000, "executeLatency": "0.020", "executed": 2400000,
"processLatency": "0.015", "acked": 2400000, "failed": 0, "capacity": "0.150"}
+ {"windowPretty": "All time", "window": ":all-time", "emitted":
600000000000, "transferred": 600000000000, "executeLatency": "0.020",
"executed": 200000000000, "processLatency": "0.015", "acked": 200000000000,
"failed": 0, "capacity": "0.150"}
],
"inputStats": [
- {"component": "spout", "encodedComponent": "spout", "stream": "default",
"executeLatency": "0.020", "processLatency": "0.015", "executed": 2400000,
"acked": 2400000, "failed": 0}
+ {"component": "spout", "encodedComponent": "spout", "stream": "default",
"executeLatency": "0.020", "processLatency": "0.015", "executed": 200000000000,
"acked": 200000000000, "failed": 0}
],
"outputStats": [
- {"stream": "default", "emitted": 7200000, "transferred": 7200000}
+ {"stream": "default", "emitted": 600000000000, "transferred": 600000000000}
],
"executorStats": [
- {"id": "[2, 2]", "encodedId": "%5B2%2C+2%5D", "uptime": "1d 5h 30m 10s",
"uptimeSeconds": 106210, "host": "supervisor-host-1", "port": 6700, "emitted":
1200000, "transferred": 1200000, "capacity": "0.150", "executeLatency":
"0.020", "executed": 400000, "processLatency": "0.015", "acked": 400000,
"failed": 0, "workerLogLink":
"http://supervisor-host-1:8000/log?file=worker.log"}
+ {"id": "[2, 2]", "encodedId": "%5B2%2C+2%5D", "uptime": "1d 5h 30m 10s",
"uptimeSeconds": 106210, "host": "supervisor-host-1", "port": 6700, "emitted":
100000000000, "transferred": 100000000000, "capacity": "0.150",
"executeLatency": "0.020", "executed": 33000000000, "processLatency": "0.015",
"acked": 33000000000, "failed": 0, "workerLogLink":
"http://supervisor-host-1:8000/log?file=worker.log"}
],
"componentErrors": []
}
diff --git a/storm-webapp/cypress/fixtures/topology-detail.json
b/storm-webapp/cypress/fixtures/topology-detail.json
index aeb0da4d3..e3a8fed5c 100644
--- a/storm-webapp/cypress/fixtures/topology-detail.json
+++ b/storm-webapp/cypress/fixtures/topology-detail.json
@@ -22,7 +22,7 @@
{"windowPretty": "10m 0s", "window": "600", "emitted": 12000,
"transferred": 12000, "completeLatency": "5.123", "acked": 6000, "failed": 0},
{"windowPretty": "3h 0m 0s", "window": "10800", "emitted": 180000,
"transferred": 180000, "completeLatency": "4.567", "acked": 90000, "failed": 0},
{"windowPretty": "1d 0h 0m 0s", "window": "86400", "emitted": 1200000,
"transferred": 1200000, "completeLatency": "4.890", "acked": 600000, "failed":
0},
- {"windowPretty": "All time", "window": ":all-time", "emitted": 2400000,
"transferred": 2400000, "completeLatency": "4.800", "acked": 1200000, "failed":
0}
+ {"windowPretty": "All time", "window": ":all-time", "emitted":
200000000000, "transferred": 200000000000, "completeLatency": "4.800", "acked":
100000000000, "failed": 5000000000}
],
"spouts": [
{
@@ -30,10 +30,10 @@
"encodedSpoutId": "spout",
"executors": 3,
"tasks": 3,
- "emitted": 2400000,
- "transferred": 2400000,
+ "emitted": 200000000000,
+ "transferred": 200000000000,
"completeLatency": "4.800",
- "acked": 1200000,
+ "acked": 100000000000,
"failed": 0,
"errorHost": "",
"errorPort": "",
@@ -48,13 +48,13 @@
"encodedBoltId": "split",
"executors": 6,
"tasks": 6,
- "emitted": 7200000,
- "transferred": 7200000,
+ "emitted": 600000000000,
+ "transferred": 600000000000,
"capacity": "0.150",
"executeLatency": "0.020",
- "executed": 2400000,
+ "executed": 200000000000,
"processLatency": "0.015",
- "acked": 2400000,
+ "acked": 200000000000,
"failed": 0,
"errorHost": "",
"errorPort": "",
@@ -67,13 +67,13 @@
"encodedBoltId": "count",
"executors": 6,
"tasks": 6,
- "emitted": 7200000,
+ "emitted": 600000000000,
"transferred": 0,
"capacity": "0.200",
"executeLatency": "0.010",
- "executed": 7200000,
+ "executed": 600000000000,
"processLatency": "0.008",
- "acked": 7200000,
+ "acked": 600000000000,
"failed": 0,
"errorHost": "",
"errorPort": "",
diff --git
a/storm-webapp/src/main/java/org/apache/storm/daemon/ui/WEB-INF/component.html
b/storm-webapp/src/main/java/org/apache/storm/daemon/ui/WEB-INF/component.html
index 4aacd9744..3d1000c0d 100644
---
a/storm-webapp/src/main/java/org/apache/storm/daemon/ui/WEB-INF/component.html
+++
b/storm-webapp/src/main/java/org/apache/storm/daemon/ui/WEB-INF/component.html
@@ -253,7 +253,7 @@ $(document).ready(function() {
info: false,
searching: false,
columnDefs: [
- {type: "num", targets: [1, 2, 4, 5], render:
$.fn.dataTable.render.number(',', '.', 0)},
+ {type: "num", targets: [1, 2, 4, 5], render:
renderIntegerWithCommas},
{type: "num", targets: [3]},
{type: "time-str", targets: [0]}
]
@@ -265,7 +265,7 @@ $(document).ready(function() {
//stream, emitted, transferred, compltete latency, acked,
failed
dtAutoPage("#output-stats-table", {
columnDefs: [
- {type: "num", targets: [1, 2, 4, 5], render:
$.fn.dataTable.render.number(',', '.', 0)},
+ {type: "num", targets: [1, 2, 4, 5], render:
renderIntegerWithCommas},
{type: "num", targets: [3]}
]
});
@@ -278,7 +278,7 @@ $(document).ready(function() {
columnDefs: [
{render: renderSupervisorPageLink, searchable: true,
targets: [2]},
{render: renderActionCheckbox, searchable: false,
targets: [4]},
- {type: "num", targets: [5, 6, 8, 9], render:
$.fn.dataTable.render.number(',', '.', 0)},
+ {type: "num", targets: [5, 6, 8, 9], render:
renderIntegerWithCommas},
{type: "num", targets: [7]},
{type: "time-str", targets: [1]},
]
@@ -290,7 +290,7 @@ $(document).ready(function() {
//window, emitted, transferred, execute latency, executed,
process latency, acked, failed
dtAutoPage("#bolt-stats-table", {
columnDefs: [
- {type: "num", targets: [1, 2, 4, 6, 7], render:
$.fn.dataTable.render.number(',', '.', 0)},
+ {type: "num", targets: [1, 2, 4, 6, 7], render:
renderIntegerWithCommas},
{type: "num", targets: [3, 5]},
{type: "time-str", targets: [0]}
]
@@ -303,7 +303,7 @@ $(document).ready(function() {
dtAutoPage("#bolt-input-stats-table", {
columnDefs: [
{type: "num", targets: [2, 4]},
- {type: "num", targets: [3, 5, 6], render:
$.fn.dataTable.render.number(',', '.', 0)}
+ {type: "num", targets: [3, 5, 6], render:
renderIntegerWithCommas}
]
});
});
@@ -313,7 +313,7 @@ $(document).ready(function() {
//stream, emitted, transferred
dtAutoPage("#bolt-output-stats-table", {
columnDefs: [
- {type: "num", targets: [1, 2], render:
$.fn.dataTable.render.number(',', '.', 0)}
+ {type: "num", targets: [1, 2], render:
renderIntegerWithCommas}
]
});
});
@@ -325,7 +325,7 @@ $(document).ready(function() {
columnDefs: [
{render: renderSupervisorPageLink, searchable: true,
targets: [2]},
{render: renderActionCheckbox, searchable: false,
targets: [4]},
- {type: "num", targets: [5, 6, 9, 11, 12], render:
$.fn.dataTable.render.number(',', '.', 0)},
+ {type: "num", targets: [5, 6, 9, 11, 12], render:
renderIntegerWithCommas},
{type: "num", targets: [7, 8, 10]},
{type: "time-str", targets: [1]},
]
diff --git
a/storm-webapp/src/main/java/org/apache/storm/daemon/ui/WEB-INF/index.html
b/storm-webapp/src/main/java/org/apache/storm/daemon/ui/WEB-INF/index.html
index a18220dd9..2afc415e0 100644
--- a/storm-webapp/src/main/java/org/apache/storm/daemon/ui/WEB-INF/index.html
+++ b/storm-webapp/src/main/java/org/apache/storm/daemon/ui/WEB-INF/index.html
@@ -189,7 +189,7 @@ $(document).ready(function() {
//name, owner, status, uptime, num workers, num executors,
num tasks, replication count, assigned total mem, assigned total cpu, scheduler
info
dtAutoPage("#topology-summary-table", {
columnDefs: [
- {type: "num", targets: [4, 5, 6, 7, 8, 9], render:
$.fn.dataTable.render.number(',', '.', 0)},
+ {type: "num", targets: [4, 5, 6, 7, 8, 9], render:
renderIntegerWithCommas},
{type: "time-str", targets: [3]}
]
});
@@ -204,7 +204,7 @@ $(document).ready(function() {
dtAutoPage("#supervisor-summary-table", {
columnDefs: [
{type: "num", targets: [3, 4]},
- {type: "num", targets: [6], render:
$.fn.dataTable.render.number(',', '.', 0)},
+ {type: "num", targets: [6], render:
renderIntegerWithCommas},
{type: "time-str", targets: [2]}
]
});
diff --git
a/storm-webapp/src/main/java/org/apache/storm/daemon/ui/WEB-INF/owner.html
b/storm-webapp/src/main/java/org/apache/storm/daemon/ui/WEB-INF/owner.html
index 0b039deb7..da7d0663c 100644
--- a/storm-webapp/src/main/java/org/apache/storm/daemon/ui/WEB-INF/owner.html
+++ b/storm-webapp/src/main/java/org/apache/storm/daemon/ui/WEB-INF/owner.html
@@ -186,7 +186,7 @@
columnDefs: [{
type: "num", targets: [4, 5, 6]
}, {
- type: "num", targets: [7, 8], render:
$.fn.dataTable.render.number(',', '.', 0)
+ type: "num", targets: [7, 8], render:
renderIntegerWithCommas
}, {
type: "time-str", targets: [3]
}]
@@ -198,7 +198,7 @@
columnDefs: [{
type: "num", targets: [4, 5, 6]
}, {
- type: "num", targets: [7], render:
$.fn.dataTable.render.number(',', '.', 0)
+ type: "num", targets: [7], render:
renderIntegerWithCommas
}, {
type: "time-str", targets: [3]
}]
diff --git
a/storm-webapp/src/main/java/org/apache/storm/daemon/ui/WEB-INF/supervisor.html
b/storm-webapp/src/main/java/org/apache/storm/daemon/ui/WEB-INF/supervisor.html
index dabd21e48..022cd748e 100644
---
a/storm-webapp/src/main/java/org/apache/storm/daemon/ui/WEB-INF/supervisor.html
+++
b/storm-webapp/src/main/java/org/apache/storm/daemon/ui/WEB-INF/supervisor.html
@@ -119,7 +119,7 @@ $(document).ready(function() {
dtAutoPage("#supervisor-summary-table", {
columnDefs: [
{type: "num", targets: [3, 4]},
- {type: "num", targets: [5, 6, 7, 8, 9, 10, 11, 12, 13],
render: $.fn.dataTable.render.number(',', '.', 0)},
+ {type: "num", targets: [5, 6, 7, 8, 9, 10, 11, 12, 13],
render: renderIntegerWithCommas},
{type: "time-str", targets: [2]}
]
});
@@ -128,7 +128,7 @@ $(document).ready(function() {
dtAutoPage("#supervisor-summary-table", {
columnDefs: [
{type: "num", targets: [3, 4]},
- {type: "num", targets: [5], render:
$.fn.dataTable.render.number(',', '.', 0)},
+ {type: "num", targets: [5], render:
renderIntegerWithCommas},
{type: "time-str", targets: [2]}
]
});
diff --git
a/storm-webapp/src/main/java/org/apache/storm/daemon/ui/WEB-INF/topology.html
b/storm-webapp/src/main/java/org/apache/storm/daemon/ui/WEB-INF/topology.html
index a17cd638a..082007830 100644
---
a/storm-webapp/src/main/java/org/apache/storm/daemon/ui/WEB-INF/topology.html
+++
b/storm-webapp/src/main/java/org/apache/storm/daemon/ui/WEB-INF/topology.html
@@ -319,7 +319,7 @@ $(document).ready(function() {
info: false,
searching: false,
columnDefs: [
- {type: "num", targets: [1, 2, 4, 5], render:
$.fn.dataTable.render.number(',', '.', 0)},
+ {type: "num", targets: [1, 2, 4, 5], render:
renderIntegerWithCommas},
{type: "num", targets: [3]},
{type: "time-str", targets: [0]}
]
@@ -333,7 +333,7 @@ $(document).ready(function() {
dtAutoPage("#spout-stats-table", {
columnDefs: [
{type: "num", targets: [1, 6, 9]},
- {type: "num", targets: [2, 3, 4, 5, 7, 8, 10, 11], render:
$.fn.dataTable.render.number(',', '.', 0)}
+ {type: "num", targets: [2, 3, 4, 5, 7, 8, 10, 11], render:
renderIntegerWithCommas}
]
});
} else {
@@ -342,7 +342,7 @@ $(document).ready(function() {
dtAutoPage("#spout-stats-table", {
columnDefs: [
{type: "num", targets: [1, 2, 5]},
- {type: "num", targets: [3, 4, 6, 7], render:
$.fn.dataTable.render.number(',', '.', 0)}
+ {type: "num", targets: [3, 4, 6, 7], render:
renderIntegerWithCommas}
]
});
}
@@ -356,7 +356,7 @@ $(document).ready(function() {
dtAutoPage("#bolt-stats-table", {
columnDefs: [
{type: "num", targets: [1, 2, 9, 10, 12, 16]},
- {type: "num", targets: [3, 4, 5, 6, 7, 8, 11, 13, 14],
render: $.fn.dataTable.render.number(',', '.', 0)}
+ {type: "num", targets: [3, 4, 5, 6, 7, 8, 11, 13, 14],
render: renderIntegerWithCommas}
]
});
} else {
@@ -366,7 +366,7 @@ $(document).ready(function() {
dtAutoPage("#bolt-stats-table", {
columnDefs: [
{type: "num", targets: [1, 2, 5, 6, 8, 12]},
- {type: "num", targets: [3, 4, 7, 9, 10], render:
$.fn.dataTable.render.number(',', '.', 0)}
+ {type: "num", targets: [3, 4, 7, 9, 10], render:
renderIntegerWithCommas}
]
});
}
diff --git a/storm-webapp/src/main/webapp/js/script.js
b/storm-webapp/src/main/webapp/js/script.js
index cea402a67..f684b3ff9 100644
--- a/storm-webapp/src/main/webapp/js/script.js
+++ b/storm-webapp/src/main/webapp/js/script.js
@@ -125,6 +125,17 @@ function dtAutoPage(selector, conf) {
return $(selector).DataTable(conf);
}
+function renderIntegerWithCommas(data, type) {
+ if (type !== 'display' && type !== 'filter') {
+ return data;
+ }
+ var n = Number(data);
+ if (isNaN(n)) {
+ return data;
+ }
+ return n.toLocaleString('en-US', {maximumFractionDigits: 0});
+}
+
function toggleSys() {
var sys = $.cookies.get('sys') || false;
sys = !sys;
@@ -682,6 +693,7 @@ function setStormUITitle(uiTitle, clusterConfig) {
// --- Expose functions to window for use by inline <script> blocks in HTML
pages ---
if (typeof window !== 'undefined') {
+ window.renderIntegerWithCommas = renderIntegerWithCommas;
window.dtAutoPage = dtAutoPage;
window.toggleSys = toggleSys;
window.ensureInt = ensureInt;