Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / ceph / src / pybind / mgr / dashboard / health.html
1
2 {% extends "base.html" %}
3
4 {% block content %}
5
6         <script>
7         $(document).ready(function(){
8             // Pre-populated initial data at page load
9             var content_data = {{ content_data }};
10
11             rivets.formatters.mon_summary = function(mon_status) {
12                 var result = mon_status.monmap.mons.length.toString() + " (quorum ";
13                 result += mon_status.quorum.join(", ");
14                 result += ")";
15
16                 return result;
17             };
18
19             rivets.formatters.mds_summary = function(fs_map) {
20                 var standbys = 0;
21                 var active = 0;
22                 var standby_replay = 0;
23                 $.each(fs_map.standbys, function(i, s) {
24                     standbys += 1;
25                 });
26
27                 if (fs_map.standbys && !fs_map.filesystems) {
28                     return standbys + ", no filesystems"
29                 } else if (fs_map.filesystems.length == 0) {
30                     return "no filesystems";
31                 } else {
32                     $.each(fs_map.filesystems, function(i, fs) {
33                         $.each(fs.mdsmap.info, function(j, mds) {
34                             if (mds.state == "up:standby-replay") {
35                                 standby_replay += 1;
36                             } else {
37                                 active += 1;
38                             }
39                         });
40                     });
41
42                     return active + " active, " + (standbys + standby_replay) + " standby";
43                 }
44             };
45
46             rivets.formatters.mgr_summary = function(mgr_map) {
47                 var result = "";
48                 result += "active: " + mgr_map.active_name;
49                 if (mgr_map.standbys.length) {
50                     result += ", " + mgr_map.standbys.length + " standbys";
51                 }
52
53                 return result;
54             };
55
56             rivets.formatters.log_color = function(log_line) {
57                 if (log_line.priority == "[INF]") {
58                     return "";  // Inherit
59                 } else if (log_line.priority == "[WRN]") {
60                     return "color: #FFC200";
61                 } else if (log_line.priority == "[ERR]") {
62                     return "color: #FF2222";
63                 } else {
64                     return "";
65                 }
66             };
67
68             rivets.formatters.osd_summary = function(osd_map) {
69                 var in_count = 0;
70                 var up_count = 0;
71                 $.each(osd_map.osds, function(i, osd) {
72                     if (osd.in) {
73                         in_count++;
74                     }
75                     if (osd.up) {
76                         up_count++;
77                     }
78                 });
79
80                 return osd_map.osds.length + " (" + up_count + " up, " + in_count + " in)";
81             };
82
83             rivets.formatters.pg_status_style = function(pg_status) {
84                 $.each(pg_status, function(state, count) {
85                     if (state == "active+clean"
86                      || state == "active+clean+scrubbing"
87                      || state == "active+clean+scrubbing+deep") {
88                         return "color: #00bb00";
89                     } else {
90                         return "color: #FFC200";
91                     }
92                 });
93             };
94
95             rivets.formatters.pg_status = function(pg_status) {
96                 var strings = [];
97                 $.each(pg_status, function(state, count) {
98                     strings.push(count + " " + state);
99                 });
100
101                 return strings.join(", ");
102             };
103
104             // An extension to Chart.js to enable rendering some
105             // text in the middle of a doughnut
106             Chart.pluginService.register({
107               beforeDraw: function(chart) {
108                 if (!chart.options.center_text) {
109                     return;
110                 }
111                 var width = chart.chart.width,
112                     height = chart.chart.height,
113                     ctx = chart.chart.ctx;
114
115                 ctx.restore();
116                 var fontSize = (height / 114).toFixed(2);
117                 ctx.font = fontSize + "em sans-serif";
118                 ctx.fillStyle = "#ddd";
119                 ctx.textBaseline = "middle";
120
121
122                 var text = chart.options.center_text,
123                     textX = Math.round((width - ctx.measureText(text).width) / 2),
124                     textY = height / 2;
125
126                 ctx.fillText(text, textX, textY);
127                 ctx.save();
128               }
129             });
130
131             var draw_usage_charts = function() {
132                 var raw_usage_text = Math.round(100*(
133                     content_data.df.stats.total_used_bytes
134                     / content_data.df.stats.total_bytes)) + "%";
135                 var raw_usage_canvas = $("#raw_usage_chart").get(0).getContext("2d");
136                 var raw_usage_chart = new Chart(raw_usage_canvas, {
137                     type: 'doughnut',
138                     data: {
139                         labels:[
140                             "Raw Used",
141                             "Raw Available"
142                         ],
143                         datasets: [
144                             {
145                             'label': null,
146                             borderWidth: 0,
147                             data:[
148                                 content_data.df.stats.total_used_bytes,
149                                 content_data.df.stats.total_avail_bytes
150                             ],
151                             backgroundColor: ["#424d52", "#222d32"]
152                             }
153                         ]
154                     },
155                     options: {
156                         center_text: raw_usage_text,
157                         responsive: true,
158                         legend: {display: false},
159                         animation: {duration: 0}
160                     }
161                 });
162
163                 var colors = ['#3366CC','#DC3912','#FF9900','#109618','#990099',
164                     '#3B3EAC','#0099C6','#DD4477','#66AA00','#B82E2E','#316395',
165                     '#994499','#22AA99','#AAAA11','#6633CC','#E67300','#8B0707',
166                     '#329262','#5574A6','#3B3EAC'];
167
168                 var pool_usage_canvas = $("#pool_usage_chart").get(0).getContext("2d");
169                 var pool_labels = [];
170                 var pool_data = [];
171
172                 $.each(content_data.df.pools, function(i, pool) {
173                     pool_labels.push(pool['name']);
174                     pool_data.push(pool['stats']['bytes_used']);
175                 });
176
177                 var pool_usage_chart = new Chart(pool_usage_canvas, {
178                     type: 'doughnut',
179                     data: {
180                         labels:pool_labels,
181                         datasets: [
182                             {
183                             'label': null,
184                             borderWidth: 0,
185                             data:pool_data,
186                             backgroundColor: colors
187                             }
188                         ]
189                     },
190                     options: {
191                         responsive: true,
192                         legend: {display: false},
193                         animation: {duration: 0}
194                     }
195                 });
196             }
197
198             draw_usage_charts();
199             rivets.bind($("#content"), content_data);
200
201             var refresh = function() {
202                 $.get("{{ url_prefix }}/health_data", function(data) {
203                     _.extend(content_data, data);
204                     draw_usage_charts();
205                     setTimeout(refresh, 5000);
206                 });
207             };
208             setTimeout(refresh, 5000);
209         });
210     </script>
211
212     <!-- Main content -->
213     <section class="content">
214         <div class="row">
215             <div class="col-sm-6">
216                 <div class="box">
217                     <div class="box-header">
218                         Health
219                     </div>
220                     <div class="box-body">
221                         Overall status: <span
222                             rv-style="health.status | health_color">{health.status}</span>
223
224                         <ul>
225                             <li rv-each-check="health.checks">
226                                 <span rv-style="check.severity | health_color">{check.type}</span>:
227                                 {check.summary.message}
228                             </li>
229                         </ul>
230                     </div>
231                 </div>
232             </div>
233             <div class="col-sm-3">
234                 <div class="info-box">
235                     <span class="info-box-icon bg-grey"><i
236                             class="fa fa-database"></i></span>
237
238                     <div class="info-box-content">
239                         <span class="info-box-text">Monitors</span>
240                         <span class="info-box-number">{mon_status | mon_summary}</span>
241                     </div>
242                 </div>
243                 <div class="info-box">
244                     <span class="info-box-icon bg-grey"><i
245                             class="fa fa-hdd-o"></i></span>
246
247                     <div class="info-box-content">
248                         <span class="info-box-text">OSDs</span>
249                         <span class="info-box-number">{osd_map | osd_summary}</span>
250                     </div>
251                 </div>
252             </div>
253
254             <div class="col-sm-3">
255                 <div class="info-box">
256                     <span class="info-box-icon bg-grey"><i
257                             class="fa fa-folder"></i></span>
258
259                     <div class="info-box-content">
260                         <span class="info-box-text">Metadata servers</span>
261                         <span class="info-box-number">{fs_map | mds_summary}</span>
262                     </div>
263                 </div>
264                 <div class="info-box">
265                     <span class="info-box-icon bg-grey"><i
266                             class="fa fa-cog"></i></span>
267
268                     <div class="info-box-content">
269                         <span class="info-box-text">Manager daemons</span>
270                         <span class="info-box-number">{mgr_map | mgr_summary}</span>
271                     </div>
272                 </div>
273             </div>
274
275         </div>
276
277         <div class="row">
278             <div class="col-sm-6">
279                 <div class="box">
280                     <div class="box-header">
281                         Usage
282                     </div>
283                     <div class="box-body" style="text-align:center;">
284                         <table class="ceph-chartbox">
285                             <tr>
286                                 <td>
287                                     <span style="font-size: 45px;">{df.stats.total_objects | dimless}</span>
288                                 </td>
289                                 <td >
290                                     <div style="height:120px; width: 120px;">
291                                         <canvas id="raw_usage_chart"></canvas>
292                                     </div>
293                                 </td>
294                                 <td>
295                                     <div style="height:120px; width: 120px;">
296                                         <canvas id="pool_usage_chart"></canvas>
297                                     </div>
298                                 </td>
299                             </tr>
300                             <tr>
301                                 <td>Objects</td>
302                                 <td>Raw capacity<br>({df.stats.total_used_bytes | dimless_binary} used)</td>
303                                 <td>Usage by pool</td>
304                             </tr>
305                         </table>
306
307                     </div>
308                 </div>
309             </div>
310
311             <div class="col-sm-6">
312                 <div class="box">
313                     <div class="box-header">
314                         Pools
315                     </div>
316                     <div class="box-body">
317                         <table class="table table-condensed">
318                             <thead>
319                             <th>Name</th>
320                             <th>PG status</th>
321                             <th>Usage</th>
322                             <th>Activity</th>
323                             </thead>
324                             <tbody>
325                             <tr rv-each-pool="pools">
326                                 <td style="text-align: right;">
327                                     {pool.pool_name}
328                                 </td>
329                                 <td rv-style="pool.pg_status | pg_status_style">
330                                     {pool.pg_status | pg_status}
331                                 </td>
332                                 <td>
333                                     {pool.stats.bytes_used.latest | dimless} /
334                                     {pool.stats.max_avail.latest | dimless }
335                                 </td>
336                                 <td>
337                                     {pool.stats.rd_bytes.rate | dimless } rd, {
338                                     pool.stats.wr_bytes.rate | dimless } wr
339                                 </td>
340                             </tr>
341                             </tbody>
342                         </table>
343                     </div>
344                 </div>
345             </div>
346         </div>
347
348         <div class="box">
349             <div class="box-body">
350                 <ul class="nav nav-tabs">
351                   <li class="active"><a data-toggle="tab" href="#clog">Cluster log</a></li>
352                   <li><a data-toggle="tab" href="#audit_log">Audit log</a></li>
353                 </ul>
354                 <div class="tab-content ceph-log">
355                     <div id="clog" class="tab-pane fade in active">
356                         <span>
357                             <span rv-each-line="clog">
358                                 { line.stamp }&nbsp;{line.priority}&nbsp;
359                                 <span  rv-style="line | log_color">
360                                         { line.message }
361                                     <br>
362                                 </span>
363                             </span>
364                         </span>
365                     </div>
366                     <div id="audit_log" class="tab-pane fade in">
367                         <span>
368                             <span rv-each-line="audit_log">
369                                 { line.stamp }&nbsp;{line.priority}&nbsp;
370                                 <span  rv-style="line | log_color">
371                                     <span style="font-weight: bold;">
372                                         { line.message }
373                                     </span><br>
374                                 </span>
375                             </span>
376                         </span>
377
378                     </div>
379                 </div>
380
381             </div>
382
383         </div>
384     </section>
385
386 {% endblock %}