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