btlqql opened a new issue, #4291:
URL: https://github.com/apache/rocketmq-dashboard/issues/4291

   ## 1. Symptom
   
   A native ratio alert whose threshold unit is `%` (for example 
`broker.disk.usage_ratio`) delivers its
   notification body with a raw floating-point artifact for `${value}`: a 
broker disk usage of `0.29` is
   rendered and delivered as `28.999999999999996` instead of `29`.
   
   ## 2. Root cause
   
   
`server/src/main/java/org/apache/rocketmq/studio/ops/alert/AlertNotificationTemplate.java:61-70`
   
   ```java
   if (rule != null && "%".equals(rule.getThresholdUnit())
           && RATIO_METRICS.contains(rule.getMetric() == null ? "" : 
rule.getMetric().trim())) {
       return String.valueOf(alert.getCurrentValue() * 100);
   }
   ```
   
   Ratio metrics are stored as fractions of the whole: 
`ApacheRocketMqClusterMetricsCollector.java:142`
   normalizes every sample with `value > 1D ? value / 100D : value`, and
   `AlertRuleSemanticFingerprint.java:65-66` divides the `%` threshold by 100 
for exactly the same
   metric/unit pairing. The template therefore has to scale the stored fraction 
by 100, but it does so
   with plain `double` arithmetic, and `Double.toString` prints the exact 
binary result of that product.
   
   For whole percents, `n / 100 * 100` does not round-trip for 8 of the 99 
possible values:
   `0.07 -> 7.000000000000001`, `0.14 -> 14.000000000000002`, `0.28 -> 
28.000000000000004`,
   `0.29 -> 28.999999999999996`, `0.55 -> 55.00000000000001`, `0.56 -> 
56.00000000000001`,
   `0.57 -> 56.99999999999999`, `0.58 -> 57.99999999999999`.
   
   ## 3. Impact
   
   - The rendered artifact is persisted into the notification row
     (`NotificationOutboxService.java:191` -> 
`AlertNotificationTemplate.render(...)`) and delivered over
     every configured channel (DingTalk, SMS, email), so an operator reading an 
alert sees a number that
     looks like a broken metric.
   - The same template is used by the alert template preview, so the preview 
shows the artifact too.
   - Nothing rounds or formats the value anywhere else on this path (no 
`BigDecimal`, no
     `DecimalFormat`, no `Math.round`).
   
   ## 4. Reproduction
   
   1. Create a cluster alert rule with metric `broker.disk.usage_ratio`, 
threshold unit `%` and a
      threshold of `29`. The web UI sends `thresholdUnit: '%'` for every ratio 
metric
      (`web/src/pages/ops/alerts.tsx:772`), and 
`AlertRuleRequestDTO.thresholdUnit` is unvalidated.
   2. Let the broker report a commit-log disk ratio of `0.29`, so the rule 
fires.
   3. The delivered notification body contains `28.999999999999996` where 
`${value}` is expanded.
   
   ## 5. Expected behaviour
   
   - `${value}` for a ratio metric with the `%` unit renders the shortest exact 
decimal percent:
     `0.29 -> 29`, `0.07 -> 7`, and the already-correct `0.865 -> 86.5` keeps 
working.
   - Values that are not finite keep the current rendering instead of raising.
   - Non-ratio metrics are untouched: the plain `String.valueOf` path stays as 
it is.


-- 
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