Skip to content

Commit 2d10efb

Browse files
committed
Merge branch '2840-advanced-benchmark-reporting-for-web-Console' into 'main'
feat(ui): include graphs for TPS, percentile histogram and most used statements on becnhmark status Closes #2840 See merge request ongresinc/stackgres!1607
2 parents a961e37 + 03e8602 commit 2d10efb

3 files changed

Lines changed: 233 additions & 18 deletions

File tree

stackgres-k8s/src/admin-ui/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
"dotenv": "^8.2.0",
2727
"express": "^4.17.1",
2828
"express-http-proxy": "^1.6.0",
29+
"hdr-histogram-widget": "^1.0.1",
2930
"jquery": "^3.6.0",
3031
"later": "github:RickCarlino/later",
3132
"moment": "^2.29.1",

stackgres-k8s/src/admin-ui/public/assets/css/style.css

Lines changed: 79 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2609,8 +2609,8 @@ fieldset {
26092609
margin: 0;
26102610
} */
26112611

2612-
.form .header {
2613-
border-bottom: 1px solid var(--gray2);
2612+
.form .header, .sectionHeader {
2613+
border-bottom: 1px solid var(--borderColor);
26142614
display: inline-block;
26152615
width: 100%;
26162616
padding-bottom: 5px;
@@ -5287,4 +5287,81 @@ i.length {
52875287
.darkmode i.length {
52885288
border-color: var(--inputBg);
52895289
background: var(--borderColor);
5290+
}
5291+
5292+
/* ApexCharts Styling */
5293+
.apexcharts-menu {
5294+
background: var(--activeBg) !important;
5295+
border-color: var(--borderColor) !important;
5296+
}
5297+
5298+
.apexcharts-theme-light .apexcharts-menu-item:hover {
5299+
background: var(--activeBg) !important;
5300+
}
5301+
5302+
text.apexcharts-text, #hdrHistogram svg text {
5303+
fill: var(--textColor) !important;
5304+
}
5305+
5306+
.apexcharts-tooltip-title {
5307+
background: transparent !important;
5308+
border-bottom-color: var(--borderColor) !important;
5309+
}
5310+
5311+
.apexcharts-tooltip {
5312+
border-color: var(--borderColor) !important;
5313+
}
5314+
5315+
.apexcharts-grid line {
5316+
stroke: var(--borderColor) !important;
5317+
}
5318+
5319+
#benchmark-statements .apexcharts-series path {
5320+
stroke-width: 0 !important;
5321+
}
5322+
5323+
.benchmarkGraph .apexcharts-canvas:not([style$="350px;"]) {
5324+
max-height: 350px;
5325+
overflow: hidden;
5326+
background: url(../img/loader.gif) center center no-repeat;
5327+
background-size: 30px;
5328+
}
5329+
5330+
.benchmarkGraph > div {
5331+
max-height: 365px;
5332+
min-height: auto !important;
5333+
}
5334+
5335+
.benchmarkGraph .apexcharts-canvas > svg:not([height="350"]) {
5336+
display: none;
5337+
}
5338+
5339+
#hdrHistogram {
5340+
margin-bottom: 60px;
5341+
min-height: 365px;
5342+
background: url(../img/loader.gif) center center no-repeat;
5343+
background-size: 30px;
5344+
}
5345+
5346+
#hdrHistogram > div {
5347+
background: var(--bgColor);
5348+
}
5349+
5350+
#hdrHistogram svg {
5351+
margin-top: -60px;
5352+
}
5353+
5354+
#hdrHistogram p {
5355+
margin-top: -40px;
5356+
position: relative;
5357+
z-index: 2;
5358+
}
5359+
5360+
#hdrHistogram rect {
5361+
fill: transparent !important;
5362+
5363+
}
5364+
5365+
#hdrHistogram svg > g:first-of-type {
5366+
display: none !important;
52905367
}

stackgres-k8s/src/admin-ui/src/components/SGDbOps.vue

Lines changed: 153 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -464,6 +464,110 @@
464464
</div>
465465
</template>
466466

467+
<!-- Benchmark graphs -->
468+
<template v-if="( (op.data.spec.op == 'benchmark') && hasProp(op, 'data.status.benchmark.pgbench') )">
469+
<div id="benchmarkStats">
470+
<template v-if="hasProp(op, 'data.status.benchmark.pgbench.transactionsPerSecond.overTime')">
471+
<div id="benchmark-tpsOverTime" class="benchmarkGraph">
472+
<h3 class="sectionHeader">
473+
TPS over-time
474+
</h3>
475+
476+
<apexchart
477+
type="line"
478+
:options="{
479+
chart: {
480+
type: 'bar',
481+
id: '-tpsOverTimeGraph',
482+
height: '350px',
483+
animations: {
484+
enabled: false
485+
}
486+
},
487+
tooltip: {
488+
enabled: true
489+
},
490+
stroke: {
491+
width: 1
492+
},
493+
yaxis: {
494+
title: {
495+
text: 'TPS'
496+
},
497+
},
498+
xaxis: {
499+
show: false,
500+
labels: {
501+
show: false
502+
},
503+
axisBorder: {
504+
show: false
505+
},
506+
axisTicks: {
507+
show: false
508+
}
509+
},
510+
tooltip: {
511+
shared: false,
512+
}
513+
}"
514+
:series="[{
515+
name: 'TPS',
516+
data: op.data.status.benchmark.pgbench.transactionsPerSecond.overTime.values
517+
}]">
518+
</apexchart>
519+
</div>
520+
</template>
521+
522+
<template v-if="hasProp(op, 'data.status.benchmark.pgbench.hdrHistogram')">
523+
<div id="benchmark-histogram">
524+
<h3 class="sectionHeader">
525+
Time Percentiles
526+
</h3>
527+
528+
<div id="hdrHistogram">
529+
{{ getHdrHistogram(op.data.status.benchmark.pgbench.hdrHistogram) }}
530+
</div>
531+
</div>
532+
</template>
533+
534+
<template v-if="hasProp(op, 'data.status.benchmark.pgbench.statements')">
535+
<div id="benchmark-statements" class="benchmarkGraph">
536+
<h3 class="sectionHeader">
537+
Statements
538+
</h3>
539+
540+
<apexchart
541+
type="bar"
542+
:options="{
543+
chart: {
544+
id: '-statements',
545+
height: '350px',
546+
animations: {
547+
enabled: false
548+
}
549+
},
550+
plotOptions: {
551+
bar: {
552+
horizontal: true,
553+
}
554+
},
555+
dataLabels: {
556+
enabled: false
557+
},
558+
xaxis: {
559+
categories: op.data.status.benchmark.pgbench.statements.map((s) => (s.command))
560+
},
561+
}"
562+
:series="[{
563+
data: op.data.status.benchmark.pgbench.statements.map((s) => (s.latency))
564+
}]">
565+
</apexchart>
566+
</div>
567+
</template>
568+
</div>
569+
</template>
570+
467571
<!--Events-->
468572
<template v-if="op.data.hasOwnProperty('status')">
469573
<div>
@@ -493,7 +597,14 @@
493597
</th>
494598
</thead>
495599
<tbody>
496-
<template v-if="!events.length">
600+
<template v-if="(events === null)">
601+
<tr class="no-results">
602+
<td colspan="999">
603+
Loading events info...
604+
</td>
605+
</tr>
606+
</template>
607+
<template v-else-if="!events.length">
497608
<tr class="no-results">
498609
<td colspan="999">
499610
No recent events have been recorded for this operation.
@@ -700,11 +811,12 @@
700811
</template>
701812

702813
<script>
703-
import { mixin } from './mixins/mixin'
704-
import store from '../store'
705-
import moment from 'moment'
706-
import sgApi from '../api/sgApi'
707-
import CRDSummary from './forms/summary/CRDSummary.vue'
814+
import { mixin } from './mixins/mixin';
815+
import store from '../store';
816+
import moment from 'moment';
817+
import sgApi from '../api/sgApi';
818+
import CRDSummary from './forms/summary/CRDSummary.vue';
819+
import HdrHistogramWidget from "hdr-histogram-widget";
708820
709821
export default {
710822
name: 'SGDbOps',
@@ -736,18 +848,20 @@
736848
},
737849
podConnections: {},
738850
pollClusterStats: 0,
739-
events: [],
851+
events: null,
740852
eventsPooling: null
741853
}
742854
},
743855
744856
mounted: function() {
745857
const vc = this;
746858
747-
vc.getOpEvents();
748-
vc.eventsPooling = setInterval( function() {
749-
vc.getOpEvents()
750-
}, 10000);
859+
if(vc.$route.params.hasOwnProperty('name')) {
860+
vc.getOpEvents();
861+
vc.eventsPooling = setInterval( function() {
862+
vc.getOpEvents()
863+
}, 10000);
864+
}
751865
},
752866
753867
methods: {
@@ -852,14 +966,13 @@
852966
853967
getOpEvents() {
854968
const vc = this;
855-
856-
sgApi
969+
970+
sgApi
857971
.getResourceDetails('sgdbops', vc.$route.params.namespace, vc.$route.params.name, 'events')
858972
.then( function(response) {
859973
vc.events = [...response.data]
860974
861975
vc.events.sort((a,b) => {
862-
863976
if(moment(a.firstTimestamp).isValid && moment(b.firstTimestamp).isValid) {
864977
865978
if(moment(a.firstTimestamp).isBefore(moment(b.firstTimestamp)))
@@ -870,11 +983,35 @@
870983
871984
}
872985
});
986+
873987
}).catch(function(err) {
874988
console.log(err);
875989
vc.checkAuthError(err);
876990
});
877991
},
992+
993+
getStatementsYAxis(statements) {
994+
return statements.map( (s) => (s.command) );
995+
},
996+
997+
getStatementsXAxis(statements) {
998+
return statements.map( (s) => (s.latency) );
999+
},
1000+
1001+
getHdrHistogram(histogramData) {
1002+
/* const opHistogram = hdr.decodeFromCompressedBase64(histogramData);
1003+
console.log(histogramData);
1004+
console.log(opHistogram); */
1005+
1006+
const opHistogram = {
1007+
percentiles: histogramData
1008+
}
1009+
HdrHistogramWidget.display(
1010+
opHistogram,
1011+
'milliseconds', // default is milliseconds
1012+
document.getElementById("hdrHistogram") // default is document.body
1013+
);
1014+
}
8781015
},
8791016
8801017
computed: {
@@ -974,12 +1111,12 @@
9741111
? store.state.sgdbops.find(o => (o.data.metadata.namespace == this.$route.params.namespace) && (o.data.metadata.name == this.$route.params.name))
9751112
: null
9761113
)
977-
}
1114+
},
9781115
},
9791116
9801117
beforeDestroy: function() {
9811118
clearInterval(this.pollClusterStats);
982-
clearInterval(this.eventsPooling)
1119+
clearInterval(this.eventsPooling);
9831120
}
9841121
}
9851122
</script>

0 commit comments

Comments
 (0)