Wei-Chiu Chuang created HDDS-13133:
--------------------------------------

             Summary: Display Ratis state machine event timeline in OM web UI
                 Key: HDDS-13133
                 URL: https://issues.apache.org/jira/browse/HDDS-13133
             Project: Apache Ozone
          Issue Type: Improvement
          Components: Ozone Manager
    Affects Versions: 2.1.0
            Reporter: Wei-Chiu Chuang
         Attachments: ChatGPT Image May 27, 2025, 01_56_15 PM.png, ChatGPT 
Image May 27, 2025, 12_52_42 PM.png

I would like to see Ratis state machine events displayed in a chronological 
order. Having such a visualization helps troubleshoot OM problems such as 
leader election, snapshot installation.

Please see a few mockups below: both of them adds a new tab "Ratis event 
timeline". The first one is a simple table, and the second one outputs a chart, 
for example, it can be rendered using d3.js 

 !ChatGPT Image May 27, 2025, 12_52_42 PM.png! 

!ChatGPT Image May 27, 2025, 01_56_15 PM.png!

How this can be built:

(1) Backend/data source: 
The OM state machine implementation OzoneManagerStateMachine has several Ratis 
EventApi, LeaderEventApi, FollowerEventApi interface callbacks : 
notifyLeaderReady(), notifyLeaderChanged().

In each callbacks, it can append a string description of the event to an array 
list inside OMMetrics.

Note: \@Metric annotation can both annotate a method or a variable. You may 
want to expose a method instead of a simple variable to create a more complex 
output.

(2) Front end:
Visualize the data source. The data source is exposed as JMX servlet end point. 
(check out ozoneManager.js for details). As a first step, expose the data as a 
simple table. 

Once the events are shown, use d3.js or other javascript libraries to create a 
timeline chart.

Example:

{code}
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Ozone Manager - Ratis Event Timeline</title>
  <script src="https://d3js.org/d3.v7.min.js";></script>
  <link 
href="https://ccycloud-2.nightly7310-xt.root.comops.site:9875/static/bootstrap-3.4.1/css/bootstrap.min.css";
 rel="stylesheet">
  <link 
href="https://ccycloud-2.nightly7310-xt.root.comops.site:9875/static/hadoop.css";
 rel="stylesheet">
  <link 
href="https://ccycloud-2.nightly7310-xt.root.comops.site:9875/static/ozone.css"; 
rel="stylesheet">
  <style>
    .timeline {
      margin: 50px;
      position: relative;
      background-color: white;
      padding: 20px;
      border-radius: 8px;
      box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
    }
    .event-line {
      stroke: #4CAF50;
      stroke-width: 2px;
    }
    .circle {
      fill: #4CAF50;
      r: 6;
    }
    .label {
      font-size: 14px;
      margin-left: 20px;
    }
  </style>
</head>
<body>
  <!-- Include the existing Ozone Manager layout -->
  <div class="container-fluid">
    <div class="row">
      <div class="col-md-12">
        <h2>Ratis Event Timeline</h2>
        <svg width="500" height="600"></svg>
      </div>
    </div>
  </div>
  <script>
    const data = [
      { description: "Install snapshot completed", timestamp: "May 27 2025 
13:01:55PM" },
      { description: "Install snapshot initiated", timestamp: "May 27 2025 
13:09:55PM" },
      { description: "New peer om2 added", timestamp: "May 27 2025 12:49:55PM" 
},
      { description: "Term index updated to (1, 1)", timestamp: "May 27 2025 
12:48:53PM" },
      { description: "leader om1 ready", timestamp: "May 27 2025 12:48:51PM" },
      { description: "leader changed to om1", timestamp: "May 27 2025 
12:48:50PM" }
    ];
    const svg = d3.select("svg");
    const timeline = svg.append("g").attr("class", 
"timeline").attr("transform", "translate(100,50)");
    timeline.append("line")
      .attr("x1", 0)
      .attr("y1", 0)
      .attr("x2", 0)
      .attr("y2", data.length * 100)
      .attr("class", "event-line");
    data.forEach((d, i) => {
      const y = i * 100;
      timeline.append("circle")
        .attr("cx", 0)
        .attr("cy", y)
        .attr("r", 6)
        .attr("class", "circle");
      timeline.append("text")
        .attr("x", 20)
        .attr("y", y + 5)
        .attr("class", "label")
        .text(`${d.description} (${d.timestamp})`);
    });
  </script>
</body>
</html>

{code}



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to