tju-yxq opened a new issue, #6193:
URL: https://github.com/apache/rocketmq-dashboard/issues/6193

   ### Describe the bug
   
   `GET /api/system-alerts` performs an unbounded read: 
`AlertService.listAlerts(level, domain, instanceId, transition)` loads 
**every** alert matching the level filter into memory (`alertMapper.selectList` 
with no limit) and then filters `domain` / `instanceId` / `transition` **in 
Java** on the loaded list.
   
   Two properties make this worse than a usual missing LIMIT:
   
   1. **`rmq_system_alert` has no retention sweep** — rows are only removed by 
the manual "clear acknowledged" action, so the table grows monotonically in a 
running deployment. The unbounded read's memory footprint and latency grow 
linearly with the table, forever.
   2. **The endpoint's filters never reach the database.** A caller asking for 
`instanceId=X` still pays for the full table scan into memory first; the SQL 
`WHERE` only knows about `level`.
   
   Notably, the paginated endpoint `GET /api/system-alerts/page` already builds 
every filter (`level`, `domain`, `instance_id`, `transition`, labels, time 
range) into its SQL `WHERE` with `ORDER BY time DESC, id DESC` and an enforced 
`pageSize <= 100` — the console's own alert page and CSV export both use it. 
The unbounded listing is the odd one out; in the web app it is referenced only 
by the mock-mode service and its tests.
   
   ### To reproduce
   
   ```
   # with N rows in rmq_system_alert (any instance):
   curl 'http://host/api/system-alerts?instanceId=instance-a'
   # -> server loads all N rows into memory, filters in Java, returns the full 
match
   #    (compare 
/api/system-alerts/page?instanceId=instance-a&page=1&pageSize=20,
   #     which pushes the filter into SQL and bounds the result)
   ```
   
   ### Expected behavior
   
   The listing endpoint should not read more rows than it can return, and its 
filters should run in the database. Reusing the existing paginated query with 
the first page at the pagination ceiling bounds the response to the newest 100 
matching alerts while keeping the response shape and every filter semantics 
unchanged; `GET /api/system-alerts/page` remains the complete view.
   
   ### Additional context
   
   The unbounded repository read (`AlertRepository.findAlerts(String level)`) 
and its single-arg service entry point have no remaining production callers 
once the listing delegates, so they can be removed together with the in-memory 
filtering; their stored-level normalization coverage (including the 
Turkish-locale case) moves to the paginated query's tests. A fix is submitted 
referencing this issue.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to