blob: 7bdcfcca6734ad2e8c663dec3d99e87fdb835679 [file] [log] [blame]
Alexb2129542021-11-23 15:49:42 -06001<!DOCTYPE html>
2<html lang="en">
3<head>
4 <meta charset="UTF-8">
Alex30380a42021-12-20 16:11:20 -06005 <title>Ceph cluster benchmark</title>
Alexb2129542021-11-23 15:49:42 -06006 {% include 'common_styles.j2' %}
7 {% include 'common_scripts.j2' %}
8 {% include 'bar_chart.j2' %}
9 <style>
10 table.cluster_nodes {
11 width: 100%;
12 margin-left: 1%;
13 margin-right: 1%;
14 }
15 .barcontent {
16 margin: auto;
17 width: 1350px;
18 padding: 10px;
19 }
20 .bar-centered {
21 float: none;
22 transform: translate(25%);
23 }
Alex30380a42021-12-20 16:11:20 -060024 .inlineheader {
25 background-color: lightgray;
26 padding-left: 40px;
27 margin-bottom: 10px;
28 }
Alexb2129542021-11-23 15:49:42 -060029 /* Node rows*/
30 .node {
31 font-family: "LaoSangamMN", Monaco, monospace;
32 font-size: 0.8em;
33 display: flex;
34 background-color: white;
35 align-items: center;
36 }
Alex30380a42021-12-20 16:11:20 -060037 .node:hover, .node:active {
38 background-color: #eda;
39 }
Alexb2129542021-11-23 15:49:42 -060040 .collapsable {
41 font-family: "LaoSangamMN", Monaco, monospace;
42 font-size: 0.8em;
43 display: none;
44 background-color: white;
45 visibility: hidden;
Alexbdc72742021-12-23 13:26:05 -060046 width: 100%;
47 border-style: dashed;
48 border-width: 1px;
Alexb2129542021-11-23 15:49:42 -060049 }
50 .collapsable.in {
51 visibility: visible;
52 display: inline-block;
53 }
54
55 .row_button {
56 background-color: #468;
57 color: #fff;
58 cursor: pointer;
59 padding: 5px;
60 width: 100%;
61 border: none;
62 text-align: left;
63 outline: none;
64 font-size: 13px;
65 }
66 .row_button:after {
67 content: '\02795'; /* Unicode character for "plus" sign (+) */
68 font-size: 13px;
69 color: white;
70 float: left;
71 margin-left: 5px;
72 }
73
74 .row_active:after {
75 content: "\2796"; /* Unicode character for "minus" sign (-) */
76 color: white
77 }
78
79 .row_active, .row_button:hover {
80 background-color: #68a;
81 color: white
82 }
83
84 .cell_button {
85 color: darkgreen;
86 cursor: pointer;
87 padding: 5px;
88 width: 100%;
89 border: none;
90 text-align: center;
91 outline: none;
92 }
93 .cell_button:hover {
94 background-color: gray;
95 }
96
97 .row_content {
98 padding: 0 18px;
99 background-color: white;
100 max-height: 0;
101 overflow: hidden;
102 transition: max-height 0.2s ease-out;
103 border-width: 1px;
104 border-color: #68a;
105 border-style: solid;
106 }
107
108 div.services > .collapsable.in {
109 display: table-row;
110 }
Alex30380a42021-12-20 16:11:20 -0600111 .agents:nth-child(even) {
Alexb2129542021-11-23 15:49:42 -0600112 background-color: #eee;
113 }
Alex30380a42021-12-20 16:11:20 -0600114 .agents:nth-child(odd) {
Alexb2129542021-11-23 15:49:42 -0600115 background-color: #fff;
116 }
117
118 tr.node > td, tr.collapsable > td {
119 display: block;
120 float: left;
121 padding: 1px;
122 margin: 2px;
123 }
124 td > .osd_group {
125 display: grid;
126 grid-template-columns: 40px 25px 25px 70px;
127 padding-left: 0px;
128 padding-right: 0px;
129 margin: 1px;
130 }
131 td > .props_group {
132 display: grid;
133 grid-template-columns: 60px 60px 80px 35px 45px 95px 50px 60px 45px;
134 padding-left: 0px;
135 padding-right: 0px;
136 margin: 1px;
137 }
Alex30380a42021-12-20 16:11:20 -0600138 td > .osd_props_group {
139 display: grid;
140 grid-template-columns: 50px 50px 50px 50px;
141 padding-left: 0px;
142 padding-right: 0px;
143 margin: 1px;
144 }
145 td > .osd_stats_group {
146 display: grid;
147 grid-template-columns: 80px 110px 110px 110px 100px 100px 110px 140px;
148 padding-left: 0px;
149 padding-right: 0px;
150 margin: 1px;
151
152 }
Alexb2129542021-11-23 15:49:42 -0600153 td > .pg_group {
154 display: grid;
155 grid-template-columns: 50px 40px 60px 65px 60px 65px 65px;;
156 padding-left: 0px;
157 padding-right: 0px;
158 margin: 1px;
159 }
160 td > .bench_run_group {
161 display: grid;
162 grid-template-columns: 80px 80px 80px 80px 75px 75px;
163 padding-left: 0px;
164 padding-right: 0px;
165 margin: 1px;
166 }
167 td > .bench_group {
168 display: grid;
169 grid-template-columns: 80px 80px 75px 75px;
170 padding-left: 0px;
171 padding-right: 0px;
172 margin: 1px;
173 }
174 td > .meta_group {
175 display: inline-block;
176 grid-template-columns: repeat(4, auto);
177 padding-left: 0px;
178 padding-right: 0px;
179 margin: 1px;
180 }
181 .item {
Alexb2129542021-11-23 15:49:42 -0600182 border-width: 1px;
183 border-style: solid;
184 margin: 1px 1px 1px 1px;
185 padding: 0px 1px 0px 1px;
186 }
187
Alexbdc72742021-12-23 13:26:05 -0600188 .details-wrap { margin-left: 20px;}
Alexb2129542021-11-23 15:49:42 -0600189 .spacer { border-radius: 2px; width: 20px;}
Alexbdc72742021-12-23 13:26:05 -0600190 .bench_id { border-radius: 10px; width: 50px; text-align: center;}
191 .time { border-radius: 10px; width: 160px; text-align: center;}
Alexb2129542021-11-23 15:49:42 -0600192 .status { border-radius: 10px; width: 120px; text-align: center;}
193 .health_ok { background-color: #393; color: white;}
194 .health_error { background-color: #933; color: white;}
195 .health_warn { background-color: #eb3; color: #333;}
196 .checks_code { border-radius: 2px; width: 20%; background-color: transparent; color: darkred;}
197
198 .head { height: 18px; background-color: transparent; border-color: transparent; border: 0px;}
199 .centered { text-align: center;}
200 .right { text-align: right;}
201 .col_shortmessage { min-width: 300px; }
202 .col_longmessage { width: auto; }
Alexbdc72742021-12-23 13:26:05 -0600203 .col_properties { width: auto; border-radius: 10px;}
204 .col_bench { width: auto; border-radius: 10px;}
Alexb2129542021-11-23 15:49:42 -0600205
206 .srv_name { width: 300px }
207 .srv_path { width: 250px }
208 .srv_timestamp { width: 250px }
209 .srv_addr { width: 450px }
210
211 .id { width: 30px }
212 .bucket_name { width: 365px }
213 .bucket_type { width: 50px }
214 .bucket_params { width: 200px }
215 .bucket_items { width: 630px }
216
217 .df_name { width: 300px }
218 .df_total { width: 150px }
219 .df_avail { width: 150px }
220 .df_used { width: 150px }
221 .df_used_raw { width: 150px }
222 .df_used_raw_rate { width: 150px }
223
224 .rdf_name { width: 200px; }
225 .rdf_obj { width: 75px; }
226 .rdf_total { width: 100px; }
227 .rdf_used { width: 100px; }
228 .rdf_bench { width: 100px; }
229
230 .dev_name { width: 300px; }
231 .dev_param { width: 100px; }
232
233 .mon_name { width: 100px }
234 .mon_url { width: 500px }
235
236 .meters {
237 display: inline-block;
238 margin: 1px;
239 }
240 .meters > .meter {
241 display: block;
242 float: left;
243 border-width: 1px;
244 border-style: solid;
245 margin: 0px 1px 0px 1px;
246 padding: 0px 1px 0px 1px;
247
248 }
249 .meters > .warn {
250 border-color: #d3a200;
251 background-color: rgb(255, 216, 133);
252 }
253 .meters > .fail {
254 border-color: #bb0000;
255 background-color: rgb(250, 135, 135);
256 }
257 .osd { border-color: #a0c0a0; background-color: rgb(252, 248, 248); text-align: center;}
258 .prop { border-color: #74c28b; background-color: rgb(252, 248, 248); text-align: center;}
259 .pg { border-color: #c0c0a0; background-color: rgb(255, 255, 251); text-align: right; }
260 .bench { border-color: #a0c0c0; background-color: rgb(255, 250, 250); text-align: right; }
261 .lat_commit { border-color: #a0c0c0; background-color: rgb(255, 250, 250); text-align: right; width: 45px}
262 .lat_apply { border-color: #a0c0c0; background-color: rgb(255, 250, 250); text-align: left; width: 35px}
263 .meta_name { border-color: #c4b890; background-color: #e7dbb6; text-align: left; width: 150px;}
264 .meta_value { border-color: #c6c3ba;background-color: #d4d4d4; text-align: left; width: 480px;}
265
266 .map_grid {
267 display: grid;
268 grid-template-columns: auto auto auto auto auto auto auto auto auto auto;
269 grid-column-gap: 20px;
270 padding-left: 0px;
271 padding-right: 0px;
272 margin: 1px;
273 margin-left: 20px;
274
275 }
276 .map_item {
277 display: inline-grid;
278 border-width: 0px;
279 border-style: solid;
280 margin: 1px 1px 1px 1px;
281 padding: 0px 1px 0px 1px;
282 }
283
284 .map_grid > .ok {
285 color: #80a080;
286 }
287 .map_grid > .warn {
288 color: #d3a200;
289 }
290 .map_grid > .fail {
291 color: #bb0000;
292 }
293
294 .modules {
295 font-family: "LaoSangamMN", Monaco, monospace;
296 font-size: 0.8em;
297 background-color: white;
298 }
299 .module_node {
300 margin-bottom: 2px;
301 display: flex;
302 }
303 .module_name, .node_name {
304 text-align: center;
305 border-width: 0px;
306 border-style: solid;
307 margin: 1px 1px 1px 1px;
308 padding: 0px 1px 0px 1px;
309 min-width: 250px;
310 border-radius: 10px;
311 }
312 .node_name {
313 background-color: #ddd;
314 }
315 .module_grid {
316 display: grid;
317 grid-template-columns: repeat(8, 100px);
318 grid-template-rows: repeat(6, auto);
319 grid-auto-flow: column;
320 grid-column-gap: 10px;
321 padding-left: 0px;
322 padding-right: 0px;
323 margin: 1px;
324 margin-left: 20px;
325 }
326 .module {
327 display: inline-grid;
328 text-align: center;
329 border-width: 0px;
330 border-style: solid;
331 margin: 1px 1px 1px 1px;
332 padding: 0px 1px 0px 1px;
333 min-width: 100px;
334 border-radius: 10px;
335 }
336
337 .module_grid > .on, .service_node > .ok {
338 background-color: #8c8;
339 }
340 .module_grid > .off, .service_node > .off{
341 background-color: #9aa;
342 }
343 .module_grid > .fail, .service_node > .fail {
344 background-color: #a33;
345 }
346 .module_grid > .always, .service_node > .fail {
347 background-color: #282;
348 }
349
Alexbdc72742021-12-23 13:26:05 -0600350 .tooltip { border-bottom: 0px dotted black;}
351 .tooltip .tooltiptext {
352 font-size: 0.9em;
353 width: 200px;
354
355 }
Alexb2129542021-11-23 15:49:42 -0600356 .tooltiptext {
Alexbdc72742021-12-23 13:26:05 -0600357 transform: translate(0px, 2px);
Alexb2129542021-11-23 15:49:42 -0600358 }
359
360 .console {
361 background-color: black;
362 font-family: "Lucida Console", Monaco, monospace;
363 font-size: 0.5em;
364 width: auto;
365 color: #fff;
366 border-radius: 6px;
367 padding: 5px 5px;
368 }
369
370 </style>
371</head>
Alex30380a42021-12-20 16:11:20 -0600372
373{% macro put_osd_prop(prop, b, a, p) %}
374 {% if prop in p %}
375 <div class="item bench">{{ a[prop] | to_mb }} ({{ "%0.4f" | format(p[prop]|float) }})</div>
376 {% else %}
377 <div class="item bench">{{ a[prop] | to_mb }}</div>
378 {% endif %}
379{% endmacro %}
380
381{% macro put_osd_perc(prop, b, a, p) %}
382 {% if prop in p %}
383 <div class="item bench">{{ "%0.4f"|format(a[prop]|float) }} ({{ "%0.4f" | format(p[prop]|float) }})</div>
384 {% else %}
385 <div class="item bench">{{ "%0.4f"|format(a[prop]|float) }}</div>
386 {% endif %}
387{% endmacro %}
388
389{% macro summary_value(prop, s) %}
390 {% if prop in s %}
391 <div class="item bench">{{ s[prop] }} nodes</div>
392 {% else %}
393 <div class="item bench">0</div>
394 {% endif %}
395{% endmacro %}
396
397
398
Alexb2129542021-11-23 15:49:42 -0600399<body onload="init()">
400
401<div class="header">
402 <div class="label">Ceph version:</div>
403 <div class="text">{{ ceph_version }}</div>
404 <div class="label">Image:</div>
405 <div class="text">{{ cluster.image }}</div>
406 <div class="label date">generated on: {{ gen_date }}</div>
407</div>
408
409<div class="bar">
410 <div class="bar-centered">
411 <button class="bar-item" onclick="openBar(event, 'bench')">Benchmark Results</button>
Alex30380a42021-12-20 16:11:20 -0600412 <button class="bar-item" onclick="openBar(event, 'osdstats')">OSD Stats</button>
Alexb2129542021-11-23 15:49:42 -0600413 <button class="bar-item" onclick="openBar(event, 'status')">Status</button>
414 <!-- <button class="bar-item" onclick="openBar(event, 'latency')">Latency</button> -->
415 </div>
416</div>
417
418<!-- Benchmarks -->
419{% macro bench_page(results, id_label) %}
420<div id="{{ id_label }}" class="barcontent">
421 <h5>{{ caller() }}</h5>
Alexbdc72742021-12-23 13:26:05 -0600422 <div class="note">Graphs in detailed section shows value measured by internal Ceph profiler</div>
423 <div class="note">'All agents' value shows theoretical load calculated client-side</div>
Alexb2129542021-11-23 15:49:42 -0600424 <hr>
425 <table class="ceph_status">
426 <tr class="node">
Alexbdc72742021-12-23 13:26:05 -0600427 <td class="bench_id">N</td>
428 <td class="time">Time started</td>
Alexb2129542021-11-23 15:49:42 -0600429 <td class="status">Data point</td>
430 <td class="col_properties">
431 <div class="props_group">
432 <div class="item prop">Warmup</div>
433 <div class="item prop">Run Time</div>
434 <div class="item prop">Storage class</div>
435 <div class="item pg">PGs</div>
436 <div class="item prop">Engine</div>
437 <div class="item prop">Mode</div>
438 <div class="item prop">BS</div>
439 <div class="item prop">IOdepth</div>
440 <div class="item prop">Size</div>
441 </div>
442 </td>
443 <td class="col_bench">
444 <div class="bench_run_group">
445 <div class="item bench">Read, MB/s</div>
446 <div class="item bench">Avg lat, usec</div>
447 <div class="item bench">Read, op/s</div>
448 <div class="item bench">Write, MB/s</div>
449 <div class="item bench">Avg lat, usec</div>
450 <div class="item bench">Write, op/s</div>
451 </div>
452 </td>
453 </tr>
454 {% for time,dt in results.items() %}
455 {% set t = dt["totals"] %}
456 {% set o = dt["input_options"] %}
457 {% set tstripped = time | tstrip %}
458 <tr class="node" onclick="toggleClassByID('timing_{{ tstripped }}_data')" id="timing_{{ tstripped }}_button">
Alexbdc72742021-12-23 13:26:05 -0600459 <td class="bench_id">{{ dt["id"] }}</td>
460 <td class="time">{{ time }}</td>
Alexb2129542021-11-23 15:49:42 -0600461 <td class="status">All agents</td>
462 <td class="col_properties">
463 <div class="props_group">
464 <div class="item prop">{{ o["ramp_time"] }}</div>
465 <div class="item prop">{{ o["runtime"] }}</div>
466 <div class="item prop">{{ t["storage_class"] }}</div>
467 <div class="item pg">{{ t["storage_class_stats"]["num_pg"] }}</div>
468 <div class="item prop">{{ o["ioengine"] }}</div>
Alex30380a42021-12-20 16:11:20 -0600469 <div class="item prop">{{ o["readwrite"] }} ({{ o["rwmixread"] }}/{{ 100 - (o["rwmixread"]|int) }})</div>
Alexb2129542021-11-23 15:49:42 -0600470 <div class="item prop">{{ o["bs"] }}</div>
471 <div class="item prop">{{ o["iodepth"] }}</div>
472 <div class="item prop">{{ o["size"] }}</div>
473 </div>
474 </td>
475 <td class="col_bench">
476 <div class="bench_run_group">
477 <div class="item bench">{{ t["read_bw_bytes"] | to_mb }}</div>
478 <div class="item bench">{{ "%0.2f" | format(t["read_avg_lat_us"]|float) }}</div>
479 <div class="item bench">{{ "%0.2f" | format(t["read_iops"]|float) }}</div>
480 <div class="item bench">{{ t["write_bw_bytes"] | to_mb }}</div>
481 <div class="item bench">{{ "%0.2f" | format(t["write_avg_lat_us"]|float) }}</div>
482 <div class="item bench">{{ "%0.2f" | format(t["write_iops"]|float) }}</div>
483 </div>
484 </td>
485 </tr>
Alex30380a42021-12-20 16:11:20 -0600486 {% set c = dt["ceph"] %}
Alexb2129542021-11-23 15:49:42 -0600487 <tr class="collapsable" id="timing_{{ tstripped }}_data"><td colspan=3>
Alexbdc72742021-12-23 13:26:05 -0600488 <div class="details-wrap">
Alex30380a42021-12-20 16:11:20 -0600489 <div class="inlineheader">Global READ stats, MB/s vs seconds. Measured maximum is <b>{{ c["max_rbl"][0] | to_mb }}</b> MB/sec</div>
Alexb2129542021-11-23 15:49:42 -0600490 <div class="bc-wrap">
491 <div class="bctimecol">
Alex30380a42021-12-20 16:11:20 -0600492 <div class="bctime"><span class="bctimetext">{{ c["max_rbl"][1] | to_mb }}</span></div>
493 <div class="bctime"><span class="bctimetext">{{ c["max_rbl"][2] | to_mb }}</span></div>
494 <div class="bctime"><span class="bctimetext">{{ c["max_rbl"][3] | to_mb }}</span></div>
495 <div class="bctime"><span class="bctimetext">{{ c["max_rbl"][4] | to_mb }}</span></div>
Alexb2129542021-11-23 15:49:42 -0600496 </div>
497
498 <div class="bc-container">
499 <div class="bc">
Alex30380a42021-12-20 16:11:20 -0600500 {% for sec, c_data in c["stats"].items() %}
501 {% set elapsed = sec | float %}
502 <div class="bccol">
503 {% if sec == c["max_rbl_time"] %}
504 <div class="bcheader">{{ c_data["read_bytes_sec"] | to_mb }}</div>
505 <div class="bcbar green-bar" style="height: {{ c_data["read_bytes_sec_perc"] }};"></div>
506 {% else %}
507 <div class="bcbar" style="height: {{ c_data["read_bytes_sec_perc"] }};"></div>
508 {% endif%}
509 <div class="bcfooter">{{ "%0.1f" | format(elapsed) }}</div>
510 </div>
511 {% endfor %}
Alexb2129542021-11-23 15:49:42 -0600512 </div>
513 </div>
514 </div>
Alex30380a42021-12-20 16:11:20 -0600515 <div class="inlineheader">Global READ stats, IOPS vs seconds. Measured maximum is <b>{{ c["max_ril"][0] }}</b> op/sec</div>
516 <div class="bc-wrap">
517 <div class="bctimecol">
518 <div class="bctime"><span class="bctimetext">{{ c["max_ril"][1] }}</span></div>
519 <div class="bctime"><span class="bctimetext">{{ c["max_ril"][2] }}</span></div>
520 <div class="bctime"><span class="bctimetext">{{ c["max_ril"][3] }}</span></div>
521 <div class="bctime"><span class="bctimetext">{{ c["max_ril"][4] }}</span></div>
522 </div>
523
524 <div class="bc-container">
525 <div class="bc">
526 {% for sec, c_data in c["stats"].items() %}
527 {% set elapsed = sec | float %}
528 <div class="bccol">
529 {% if sec == c["max_ril_time"] %}
530 <div class="bcheader">{{ c_data["read_op_per_sec"] }}</div>
531 <div class="bcbar green-bar" style="height: {{ c_data["read_op_per_sec_perc"] }};"></div>
532 {% else %}
533 <div class="bcbar" style="height: {{ c_data["read_op_per_sec_perc"] }};"></div>
534 {% endif%}
535 <div class="bcfooter">{{ "%0.1f" | format(elapsed) }}</div>
536 </div>
537 {% endfor %}
538 </div>
539 </div>
540 </div>
541 <div class="inlineheader">Global WRITE stats, MB/s vs seconds. Measured maximum is <b>{{ c["max_wbl"][0] | to_mb }}</b> MB/sec</div>
542 <div class="bc-wrap">
543 <div class="bctimecol">
544 <div class="bctime"><span class="bctimetext">{{ c["max_wbl"][1] | to_mb }}</span></div>
545 <div class="bctime"><span class="bctimetext">{{ c["max_wbl"][2] | to_mb }}</span></div>
546 <div class="bctime"><span class="bctimetext">{{ c["max_wbl"][3] | to_mb }}</span></div>
547 <div class="bctime"><span class="bctimetext">{{ c["max_wbl"][4] | to_mb }}</span></div>
548 </div>
549
550 <div class="bc-container">
551 <div class="bc">
552 {% for sec, c_data in c["stats"].items() %}
553 {% set elapsed = sec | float %}
554 <div class="bccol">
555 {% if sec == c["max_wbl_time"] %}
556 <div class="bcheader">{{ c_data["write_bytes_sec"] | to_mb }}</div>
557 <div class="bcbar green-bar" style="height: {{ c_data["write_bytes_sec_perc"] }};"></div>
558 {% else %}
559 <div class="bcbar" style="height: {{ c_data["write_bytes_sec_perc"] }};"></div>
560 {% endif%}
561 <div class="bcfooter">{{ "%0.1f" | format(elapsed) }}</div>
562 </div>
563 {% endfor %}
564 </div>
565 </div>
566 </div>
567
568 <div class="inlineheader">Global WRITE stats, IOPS vs seconds. Measured maximum is <b>{{ c["max_wil"][0] }}</b> op/sec</div>
569 <div class="bc-wrap">
570 <div class="bctimecol">
571 <div class="bctime"><span class="bctimetext">{{ c["max_wil"][1] }}</span></div>
572 <div class="bctime"><span class="bctimetext">{{ c["max_wil"][2] }}</span></div>
573 <div class="bctime"><span class="bctimetext">{{ c["max_wil"][3] }}</span></div>
574 <div class="bctime"><span class="bctimetext">{{ c["max_wil"][4] }}</span></div>
575 </div>
576
577 <div class="bc-container">
578 <div class="bc">
579 {% for sec, c_data in c["stats"].items() %}
580 {% set elapsed = sec | float %}
581 <div class="bccol">
582 {% if sec == c["max_wil_time"] %}
583 <div class="bcheader">{{ c_data["write_op_per_sec"] }}</div>
584 <div class="bcbar green-bar" style="height: {{ c_data["write_op_per_sec_perc"] }};"></div>
585 {% else %}
586 <div class="bcbar" style="height: {{ c_data["write_op_per_sec_perc"] }};"></div>
587 {% endif%}
588 <div class="bcfooter">{{ "%0.1f" | format(elapsed) }}</div>
589 </div>
590 {% endfor %}
591 </div>
592 </div>
593 </div>
594 <div class="inlineheader">Per Agent stats</div>
Alexb2129542021-11-23 15:49:42 -0600595 <table style="table-layout: auto;"><tbody>
596 {% for agent,ag_result in dt["agents"].items() %}
Alex90ac1532021-12-09 11:13:14 -0600597 {% set j = ag_result["jobs"][0] %}
Alex30380a42021-12-20 16:11:20 -0600598 <tr class="agents">
Alexbdc72742021-12-23 13:26:05 -0600599 <td class="time">{{ time }}</td>
Alexb2129542021-11-23 15:49:42 -0600600 <td class="status">{{ agent }}</td>
601 <td class="col_properties">
602 <div class="props_group">
603 <div class="item prop">{{ j["job options"]["ramp_time"] }}</div>
604 <div class="item prop">{{ j["job options"]["runtime"] }}</div>
605 <div class="item prop">{{ t["storage_class"] }}</div>
606 <div class="item pg">{{ t["storage_class_stats"]["num_pg"] }}</div>
607 <div class="item prop">{{ o["ioengine"] }}</div>
Alex30380a42021-12-20 16:11:20 -0600608 <div class="item prop">{{ o["readwrite"] }} ({{ o["rwmixread"] }}/{{ 100 - (o["rwmixread"]|int) }})</div>
Alexb2129542021-11-23 15:49:42 -0600609 <div class="item prop">{{ j["job options"]["bs"] }}</div>
610 <div class="item prop">{{ o["iodepth"] }}</div>
611 <div class="item prop">{{ j["job options"]["size"] }}</div>
612 </div>
613 </td>
614 <td class="col_bench">
615 <div class="bench_run_group">
616 <div class="item bench">{{ j["read"]["bw_bytes"] | to_mb }}</div>
617 <div class="item bench">{{ "%0.2f" | format(j["read"]["lat_ns"]["mean"]|float / 1000) }}</div>
618 <div class="item bench">{{ "%0.2f" | format(j["read"]["iops"]|float) }}</div>
619 <div class="item bench">{{ j["write"]["bw_bytes"] | to_mb }}</div>
620 <div class="item bench">{{ "%0.2f" | format(j["write"]["lat_ns"]["mean"]|float / 1000) }}</div>
621 <div class="item bench">{{ "%0.2f" | format(j["write"]["iops"]|float) }}</div>
622 </div>
623 </td>
624 </tr>
625 </tr>
626 {% endfor %}
627 </tbody></table>
Alexbdc72742021-12-23 13:26:05 -0600628 </div>
Alexb2129542021-11-23 15:49:42 -0600629 </td></tr>
630 {% endfor %}
631 </table>
632</div>
633{% endmacro %}
634
Alex30380a42021-12-20 16:11:20 -0600635<!-- OSD stats -->
636{% macro osds_page(results, id_label) %}
637<div id="{{ id_label }}" class="barcontent">
638 <h5>{{ caller() }}</h5>
Alexbdc72742021-12-23 13:26:05 -0600639 <div class="note">Node counts is the number of nodes with parameter changed at the end of the testrun comparing to start of the testrun</div>
640 <div class="note">Hover over column title for description</div>
Alex30380a42021-12-20 16:11:20 -0600641 <hr>
642 <table class="ceph_status">
643 <tr class="node">
Alexbdc72742021-12-23 13:26:05 -0600644 <td class="bench_id">N</td>
645 <td class="time">Time started</td>
Alex30380a42021-12-20 16:11:20 -0600646 <td class="status">Data point</td>
647 <td class="col_properties">
648 <div class="osd_props_group">
Alexbdc72742021-12-23 13:26:05 -0600649 <div class="tooltip">
650 <div class="item prop">Status</div>
651 <div class="tooltiptext">OSD nodes with 'up' status</div>
652 </div>
653 <div class="tooltip">
654 <div class="item prop">Class</div>
655 <div class="tooltiptext">OSD device class: 'hdd', 'ssd', 'nvme', etc</div>
656 </div>
657 <div class="tooltip">
658 <div class="item prop">Weight</div>
659 <div class="tooltiptext">The weight of the OSD in the CRUSH map</div>
660 </div>
661 <div class="tooltip">
662 <div class="item pg">PGs</div>
663 <div class="tooltiptext">The number of placement groups in the OSD</div>
664 </div>
Alex30380a42021-12-20 16:11:20 -0600665 </div>
666 </td>
667 <td class="col_bench">
668 <div class="osd_stats_group">
Alexbdc72742021-12-23 13:26:05 -0600669 <div class="tooltip">
670 <div class="item bench">Total, GB</div>
671 <div class="tooltiptext">The total storage capacity of the OSD</div>
672 </div>
673 <div class="tooltip">
674 <div class="item bench">Avail., GB</div>
675 <div class="tooltiptext">The amount of free space available on the OSD.</div>
676 </div>
677 <div class="tooltip">
678 <div class="item bench">Used, GB</div>
679 <div class="tooltiptext">The OSD capacity used</div>
680 </div>
681 <div class="tooltip">
682 <div class="item bench">Data, GB</div>
683 <div class="tooltiptext">The amount of OSD capacity that is used by user data</div>
684 </div>
685 <div class="tooltip">
686 <div class="item bench">OMAP, GB</div>
687 <div class="tooltiptext">An estimate value of the bluefs storage that is being used to store object map (omap) data (key value pairs stored in rocksdb)</div>
688 </div>
689 <div class="tooltip">
690 <div class="item bench">Meta, GB</div>
691 <div class="tooltiptext">The bluefs space allocated, or the value set in the bluestore_bluefs_min parameter, whichever is larger, for internal metadata which is calculated as the total space allocated in bluefs minus the estimated omap data size</div>
692 </div>
693 <div class="tooltip">
694 <div class="item bench">Utilized, %</div>
695 <div class="tooltiptext">The notional percentage of storage used by the OSD</div>
696 </div>
697 <div class="tooltip">
698 <div class="item bench">Variance, %</div>
699 <div class="tooltiptext">The variation above or below average utilization</div>
700 </div>
Alex30380a42021-12-20 16:11:20 -0600701 </div>
702 </td>
703 </tr>
704 {% for time,dt in results.items() %}
705 {% set b = dt["osd_summary"]["before"] %}
706 {% set a = dt["osd_summary"]["after"] %}
707 {% set s = dt["osd_summary"]["active"] %}
708 {% set tstripped = time | tstrip %}
709 <tr class="node" onclick="toggleClassByID('timing_{{ tstripped }}_osds')" id="timing_{{ tstripped }}_button">
Alexbdc72742021-12-23 13:26:05 -0600710 <td class="bench_id">{{ dt["id"] }}</td>
711 <td class="time">{{ time }}</td>
Alex30380a42021-12-20 16:11:20 -0600712 <td class="status">Active nodes</td>
713 <td class="col_properties">
714 <div class="osd_props_group">
715 <div class="item prop">{{ s["status"] }}</div>
716 <div class="item prop">{{ s["device_class"] }}</div>
717 <div class="item prop">&minus;</div>
718 <div class="item pg">{{ s["pgs"] }}</div>
719 </div>
720 </td>
721 <td class="col_bench">
722 <div class="osd_stats_group">
723 <div class="item bench">{{ a["total_kb"] | to_mb }}</div>
724 {{ summary_value("kb_avail", s) }}
725 {{ summary_value("kb_used", s) }}
726 {{ summary_value("kb_used_data", s) }}
727 {{ summary_value("kb_used_omap", s) }}
728 {{ summary_value("kb_used_meta", s) }}
729 {{ summary_value("utilization", s) }}
730 <div class="item bench">{{ s["var_down"] }}&darr; / {{ s["var_up"] }}&uarr;</div>
731 </div>
732 </td>
733 </tr>
734 <tr class="collapsable" id="timing_{{ tstripped }}_osds"><td colspan=3>
735 <table style="table-layout: auto;"><tbody>
736 {% for osd in dt["osds"].keys() | sort %}
737 {% set n = dt["osds"][osd] %}
738 {% set b = n["before"] %}
739 {% set a = n["after"] %}
740 {% set p = n["percent"] %}
741 <tr class="agents">
Alexbdc72742021-12-23 13:26:05 -0600742 <td class="time">{{ time }}</td>
Alex30380a42021-12-20 16:11:20 -0600743 <td class="status">{{ osd }}</td>
744 <td class="col_properties">
745 <div class="osd_props_group">
746 <div class="item prop">{{ a["status"] }}</div>
747 <div class="item prop">{{ a["device_class"] }}</div>
748 <div class="item prop">{{ "%0.4f" | format(a["crush_weight"]|float) }}</div>
749 <div class="item pg">{{ a["pgs"] }}</div>
750 </div>
751 </td>
752 <td class="col_bench">
753 <div class="osd_stats_group">
754 <div class="item bench">{{ a["kb"] | to_mb }}</div>
755 {{ put_osd_prop("kb_avail", b, a, p) }}
756 {{ put_osd_prop("kb_used", b, a, p) }}
757 {{ put_osd_prop("kb_used_data", b, a, p) }}
758 {{ put_osd_prop("kb_used_omap", b, a, p) }}
759 {{ put_osd_prop("kb_used_meta", b, a, p) }}
760 {{ put_osd_perc("utilization", b, a, p) }}
761 {{ put_osd_perc("var", b, a, p) }}
762 </div>
763 </td>
764 </tr>
765 {% endfor %}
766 </tbody></table>
767 </td></tr>
768 {% endfor %}
769 </table>
770</div>
771{% endmacro %}
772
773
Alexb2129542021-11-23 15:49:42 -0600774<!-- Status page -->
775{% macro status_page(info, id_label) %}
776<div id="{{ id_label }}" class="barcontent">
777 <h5>{{ caller() }}</h5>
778 <hr>
779 <table class="ceph_status">
780 <tr class="node">
781 <td class="status">Cluster status</td>
782 <td class="col_shortmessage">Status summary</td>
783 <td class="col_osd">
784 <div class="osd_group">
785 <div class="item osd">OSDs</div>
786 <div class="item osd">Up</div>
787 <div class="item osd">In</div>
788 <div class="item osd">Remap PGs</div>
789 </div>
790 </td>
791 <td class="col_pgs">
792 <div class="pg_group">
793 <div class="item pg">PGs</div>
794 <div class="item pg">Pools</div>
795 <div class="item pg">Objects</div>
796 <div class="item pg">Data, GB</div>
797 <div class="item pg">Used, GB</div>
798 <div class="item pg">Avail, GB</div>
799 <div class="item pg">Total, GB</div>
800 </div>
801 </td>
802 <td class="col_bench">
803 <div class="bench_group">
804 <div class="item bench">Read, MB/sec</div>
805 <div class="item bench">Write, MB/sec</div>
806 <div class="item bench">Read, op/sec</div>
807 <div class="item bench">Write, op/sec</div>
808 </div>
809 </td>
810 </tr>
811 {% set cs = idle_status %}
812 {% set osdmap = cs | get_osdmap %}
813 <tr class="node" onclick="toggleClassByID('health_data')" id="health_data_button">
814 <td class="status {{ health_detail["status"] | lower }}">{{ health_detail["status"] }}</td>
815 <td class="col_shortmessage">
816 {% for code,dt in health_detail["checks"].items() %}
817 {{ dt["summary"]["message"] }}<br>
818 {% endfor %}
819 </td>
820 <!-- background: linear-gradient(to right, gray 0% 20%, transparent 20% 100%); -->
821 <td class="col_osd">
822 <div class="osd_group">
823 <div class="item osd">{{ osdmap["num_osds"] }}</div>
824 <div class="item osd">{{ osdmap["num_up_osds"] }}</div>
825 <div class="item osd">{{ osdmap["num_in_osds"] }}</div>
826 <div class="item osd">{{ osdmap["num_remapped_pgs"] }}</div>
827 </div>
828 </td>
829 {% set pgmap = cs["pgmap"] %}
830 <td class="col_pgs">
831 <div class="pg_group">
832 <div class="item pg">{{ pgmap["num_pgs"] }}</div>
833 <div class="item pg">{{ pgmap["num_pools"] }}</div>
834 <div class="item pg">{{ pgmap["num_objects"] }}</div>
835 <div class="item pg">{{ pgmap["data_bytes"] | to_gb }}</div>
836 <div class="item pg">{{ pgmap["bytes_used"] | to_gb }}</div>
837 <div class="item pg">{{ pgmap["bytes_avail"] | to_gb }}</div>
838 <div class="item pg">{{ pgmap["bytes_total"] | to_gb }}</div>
839 </div>
840 </td>
841 <td class="col_bench">
842 <div class="bench_group">
843 {% if "read_bytes_sec" in pgmap %}
844 <div class="item bench">{{ pgmap["read_bytes_sec"] | to_mb }}</div>
845 {% else %}
846 <div class="item bench">0</div>
847 {% endif %}
848 {% if "write_bytes_sec" in pgmap %}
849 <div class="item bench">{{ pgmap["write_bytes_sec"] | to_mb }}</div>
850 {% else %}
851 <div class="item bench">0</div>
852 {% endif %}
853 {% if "read_op_per_sec" in pgmap %}
854 <div class="item bench">{{ pgmap["read_op_per_sec"] }}</div>
855 {% else %}
856 <div class="item bench">0</div>
857 {% endif %}
858 {% if "write_op_per_sec" in pgmap %}
859 <div class="item bench">{{ pgmap["write_op_per_sec"] }}</div>
860 {% else %}
861 <div class="item bench">0</div>
862 {% endif %}
863 </div>
864 </td>
865 </tr>
866 <tr class="collapsable in" id="health_data"><td colspan=3>
867 <table><tbody>
868 {% for code,dt in health_detail["checks"].items() %}
869 <tr>
870 <td class="spacer"></td>
871 <td class="status {{ dt["severity"] | lower }}">{{ dt["severity"] }}</td>
872 <td class="checks_code">{{ code }}</td>
873 <td class="col_longmessage">
874 <table><tbody>
875 {% for detail in dt["detail"] %}
876 <tr><td>{{ detail["message"] }}</td></tr>
877 {% endfor %}
878 </tbody></table>
879 </td>
880 </tr>
881 {% endfor %}
882 </tbody></table>
883 </td></tr>
884 </table>
885 <hr>
886 <!-- Services -->
887 {% set sm = idle_status["servicemap"] %}
888 <h5>Services: {{ sm["services"] | count }} running. Last modification: {{ sm["modified"] }}</h5>
889 <table class="ceph_status">
890 <tr class="node">
891 <td class="srv_name">Name</td>
892 <td class="srv_path">Subpath</td>
893 <td class="srv_timestamp">Start time</td>
894 <td class="srv_addr">Address</td>
895 </tr>
896 {% for name, d1 in sm["services"].items() %}
897 {% if "daemons" in d1 %}
898 {% set d2 = d1["daemons"] %}
899 {% for key, d3 in d2.items() %}
900 {% if key.startswith("rgw.store") %}
901 <tr class="node" onclick="toggleClassByID('{{ name }}_service_data')" id="{{ name }}_service_data_button">
902 <td class="srv_name">{{ name }} ({{ d3["gid"] }})</td>
903 <td class="srv_path">daemons:{{ key }}</td>
904 <td class="srv_timestamp">{{ d3["start_stamp"] }}</td>
905 <td class="srv_addr">{{ d3["addr"] }}</td>
906 </tr>
907 <tr class="collapsable in" id="{{ name}}_service_data"><td colspan=4>
908 <table><tbody>
909 <tr><td class="metadata">
910 {% for mname, mvalue in d3["metadata"].items() %}
911 <div class="meta_group">
912 <div class="item meta_name">{{ mname }}</div>
913 <div class="item meta_value">{{ mvalue }}</div>
914 </div>
915 {% endfor %}
916 </td></tr>
917 </tbody></table>
918 </td></tr>
919 {% endif %}
920 {% endfor %}
921 {% endif %}
922 {% endfor %}
923 </table>
924 <hr>
925 <!-- Modules -->
926 {% set mgrmap = idle_status["mgrmap"] %}
927 {% set mods = mgrmap["modules"] %}
928 {% set avail = mgrmap["available_modules"] %}
929 {% if "always_on_modules" in mgrmap %}
930 {% set always_on = mgrmap["always_on_modules"].values() | list %}
931 {% set always_on = always_on[0] %}
932 {% else %}
933 {% set always_on = [] %}
934 {% endif %}
935 <h5>Modules: {{ mods | count}} active. {{ always_on | count }} always on. {{ avail | count }} available.</h5>
936 <div class="modules">
937 <div class="module_grid">
938 {% for mod in avail %}
939 {% if mod["name"] in always_on %}
940 <div class="module always">{{ mod["name"] }}</div>
941 {% elif mod["name"] in mods %}
942 <div class="module on">{{ mod["name"] }}</div>
943 {% elif not mod["can_run"] %}
944 <div class="module fail tooltip">
945 <div class="module fail">{{ mod["name"] }}</div>
946 <pre class="tooltiptext">{{ mod["error_string"] | linebreaks }}</pre>
947 </div>
948 {% else %}
949 <div class="module">{{ mod["name"] }}</div>
950 {% endif %}
951 {% endfor %}
952 </div>
953 </div>
954 <hr>
955</div>
956{% endmacro %}
957
958<!-- ================================= -->
959<!-- Cluster nodes page -->
960{% call bench_page(results, "bench") %}
961 Benchmark results
962{% endcall %}
963
Alex30380a42021-12-20 16:11:20 -0600964{% call osds_page(results, "osdstats") %}
965 OSD nodes stats collected before and after each step
966{% endcall %}
967
Alexb2129542021-11-23 15:49:42 -0600968{% call status_page(info, "status") %}
969 Cluster status
970{% endcall %}
971
972</body>
973</html>