Skip to content

Commit

Permalink
request stats refactroing (#140)
Browse files Browse the repository at this point in the history
  • Loading branch information
ludeknovy authored Apr 27, 2021
1 parent f827e71 commit 7f2c8a6
Show file tree
Hide file tree
Showing 8 changed files with 403 additions and 216 deletions.
2 changes: 2 additions & 0 deletions src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ import { LabelChartComponent } from './item-detail/label-chart/label-chart.compo
import { AnalyzeChartsComponent } from './item-detail/analyze-charts/analyze-charts.component';
import { AddMetricComponent } from './item-detail/analyze-charts/add-metric/add-metric.component';
import { ScenarioTrendsComponent } from './scenario/scenario-trends/scenario-trends.component';
import { RequestStatsCompareComponent } from './item-detail/request-stats-compare/request-stats-compare.component';

const appRoutes: Routes = [
{ path: 'dashboard', component: DashboardComponent, canActivate: [AuthGuard] },
Expand Down Expand Up @@ -150,6 +151,7 @@ const appRoutes: Routes = [
AnalyzeChartsComponent,
AddMetricComponent,
ScenarioTrendsComponent,
RequestStatsCompareComponent,
],
imports: [
RouterModule.forRoot(
Expand Down
128 changes: 6 additions & 122 deletions src/app/item-detail/item-detail.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -160,11 +160,12 @@ <h2 *ngIf="itemData.overview.avgConnect < 1000 && itemData.overview.avgConnect >
</div>
</div>

<div class="col-sm" *ngIf="itemData.overview.bytesPerSecond && itemData.overview.bytesSentPerSecond && itemData.overview.bytesPerSecond !== 0">
<div class="col-sm"
*ngIf="itemData.overview.bytesPerSecond && itemData.overview.bytesSentPerSecond && itemData.overview.bytesPerSecond !== 0">
<div class="card">
<div class="card-body overview-body">
<h2 class="card-title text-latency">{{convertBytesToMbps(itemData.overview.bytesPerSecond + itemData.overview.bytesSentPerSecond)}} <span
class="unit-desc">Mbps</span>
<h2 class="card-title text-latency">{{convertBytesToMbps(itemData.overview.bytesPerSecond +
itemData.overview.bytesSentPerSecond)}} <span class="unit-desc">Mbps</span>
</h2>
</div>
<div class="card-footer bg-transparent card-footer-overview">Network data</div>
Expand Down Expand Up @@ -346,126 +347,9 @@ <h6 class="card-header bg-transparent">SUT Statistics <span class="compare">
</div>
</div>
</div>

<div class="row">
<div class="row" *ngIf="itemData">
<div class="col">
<div class="card table-stats request-stats">

<h6 class="card-header bg-transparent">Request Statistics <span class="compare">

<span class="comparison-desc" *ngIf="comparedData">Comparing to test: {{comparedMetadata.id}} with
{{comparedMetadata.maxVu}} VU</span>
<button class="remove-comparison btn btn-sm jtl-btn-light" *ngIf="comparedData"
(click)="resetStatsData()"><span class="compare-desc-btn">Remove</span>
</button>

<div *ngIf="!isAnonymous" class="btn-group mr-3">
<div display="dynamic" [placement]="['bottom-right', 'bottom-left']" class="btn-group" ngbDropdown
role="group" aria-label="Button group with nested dropdown">
<button class="btn btn-sm jtl-no-glow jtl-control-menu hamburger-menu" ngbDropdownToggle><i
class="fas fa-bars"></i></button>
<div class="dropdown-menu jtl-dropdown-control-menu" ngbDropdownMenu>
<button class="quick-base-comparison btn btn-sm btn-outline-dark"
*ngIf="(itemData.baseId && itemData.baseId !== itemParams.id)"
(click)="quickBaseComparison(itemData.baseId)" ngbDropdownItem><span class="compare-desc-btn">
Compare to base run</span></button>
<app-stats-compare (itemDetailToCompare)="itemToCompare($event)"></app-stats-compare>
</div>
</div>
</div>

</span></h6>
<div class="card-body card-body-request-stats">
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text" id="basic-addon1"><i class="fas fa-search"></i></span>
</div>
<input class="form-control" id="label-filter" type="search" placeholder="label"
(keyup)='search($event.target.value)'>
</div>
<div class="labels-detail table-responsive">
<table class="table" [mfData]="labelsData" #mf="mfDataTable">
<thead>
<tr>
<th scope="col" class="hd">
<mfDefaultSorter by="label">label</mfDefaultSorter>
</th>
<th scope="col" class="hd">
<mfDefaultSorter by="samples">samples</mfDefaultSorter>
</th>
<th scope="col" class="hd">
<mfDefaultSorter by="avgResponseTime">avg [ms]</mfDefaultSorter>
</th>
<th scope="col" class="hd">
<mfDefaultSorter by="minResponseTime">min [ms]</mfDefaultSorter>
</th>
<th scope="col" class="hd">
<mfDefaultSorter by="maxResponseTime">max [ms]</mfDefaultSorter>
</th>
<th scope="col" class="hd">
<mfDefaultSorter by="n0">P90 [ms]</mfDefaultSorter>
</th>
<th scope="col" class="hd">
<mfDefaultSorter by="n5">P95 [ms]</mfDefaultSorter>
</th>
<th scope="col" class="hd">
<mfDefaultSorter by="n9">P99 [ms]</mfDefaultSorter>
</th>
<th scope="col" class="hd">
<mfDefaultSorter by="throughput">requests/s</mfDefaultSorter>
</th>
<th scope="col" class="hd">
<mfDefaultSorter by="bytes">mbps</mfDefaultSorter>
</th>
<th scope="col" class="hd">
<mfDefaultSorter by="errorRate">error rate</mfDefaultSorter>
</th>
<th scope="col" class="hd">
</th>
<th scope="col" class="hd">
</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let _ of mf.data">
<td>{{_.label}}</td>
<td>{{_.samples}}</td>
<td>{{_.avgResponseTime}} <sup [className]="_.avgDiff > 0 ? 'value-positive' : 'value-negative'"
*ngIf="_.avgDiff">{{_.avgDiff}}</sup></td>
<td>{{_.minResponseTime}} <sup [className]="_.minDiff > 0 ? 'value-positive' : 'value-negative'"
*ngIf="_.minDiff">{{_.minDiff}}</sup></td>
<td>{{_.maxResponseTime}} <sup [className]="_.maxDiff > 0 ? 'value-positive' : 'value-negative'"
*ngIf="_.maxDiff">{{_.maxDiff}}</sup></td>
<td>{{_.n0}} <sup [ngClass]="_.n0Diff > 0 ? 'value-positive' : 'value-negative'"
*ngIf="_.n0Diff">{{_.n0Diff}}</sup></td>
<td>{{_.n5}} <sup [className]="_.n5Diff > 0 ? 'value-positive' : 'value-negative'"
*ngIf="_.n5Diff">{{_.n5Diff}}</sup></td>
<td>{{_.n9}} <sup [className]="_.n9Diff > 0 ? 'value-positive' : 'value-negative'"
*ngIf="_.n9Diff">{{_.n9Diff}}</sup></td>
<td>{{_.throughput || "n/a"}} <sup
[className]="_.throughputDiff < 0 ? 'value-positive' : 'value-negative'"
*ngIf="_.throughputDiff">{{_.throughputDiff}}</sup></td>
<td>{{convertBytesToMbps(_.bytesPerSecond + _.bytesSentPerSecond) || "n/a"}} <sup
[className]="_.bytesDiff < 0 ? 'value-positive' : 'value-negative'"
*ngIf="_.bytesDiff && bytesDiff !== 0">{{_.bytesDiff}}</sup></td>
<td>{{_.errorRate}} % <sup [className]="_.errorRateDiff > 0 ? 'value-positive' : 'value-negative'"
*ngIf="_.errorRateDiff">{{_.errorRateDiff}}</sup>
</td>
<td>
<app-label-error *ngIf="!isAnonymous && _.errorRate > 0 && hasErrorsAttachment"
[labelInput]="{ labelName: _.label, params: itemParams }"></app-label-error>
</td>
<td>
<app-label-trend *ngIf="!isAnonymous"
[trendInput]="{ environment: itemData.environment, labelName: _.label }">
</app-label-trend>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<app-request-stats-compare [itemData]="itemData" [isAnonymous]="isAnonymous" [params]="itemParams"></app-request-stats-compare>
</div>
</div>
</div>
Expand Down
1 change: 0 additions & 1 deletion src/app/item-detail/item-detail.component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ describe('ItemDetailComponent', () => {
DeleteItemComponent,
ControlPanelComponent,
StatsCompareComponent,
LabelTrendComponent,
],
imports: [
DataTableModule,
Expand Down
95 changes: 2 additions & 93 deletions src/app/item-detail/item-detail.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ import { catchError, withLatestFrom } from 'rxjs/operators';
import { of } from 'rxjs';
import { SharedMainBarService } from '../shared-main-bar.service';
import { ToastrService } from 'ngx-toastr';
import { ItemStatusValue } from './item-detail.model';
import { bytesToMbps, roundNumberTwoDecimals } from './calculations';
import { logScaleButton } from '../graphs/log-scale-button';
import { ItemStatusValue } from './item-detail.model';

@Component({
selector: 'app-item-detail',
Expand Down Expand Up @@ -51,11 +51,7 @@ export class ItemDetailComponent implements OnInit {
monitoringChart;
itemParams;
hasErrorsAttachment;
comparedData;
comparedMetadata;
labelsData;
Math: any;
comparisonWarning = [];
token: string;
isAnonymous = false;
toggleThroughputBandFlag = false;
Expand Down Expand Up @@ -102,7 +98,6 @@ export class ItemDetailComponent implements OnInit {
}))
.subscribe((results) => {
this.itemData = results;
this.labelsData = this.itemData.statistics;
this.hasErrorsAttachment = this.itemData.attachements.find((_) => _ === 'error');
this.monitoringAlerts();
this.generateCharts();
Expand Down Expand Up @@ -193,64 +188,6 @@ export class ItemDetailComponent implements OnInit {
this.itemData.hostname = hostname;
}

itemToCompare(data) {
this.comparedMetadata = { id: data.id, maxVu: data.maxVu };
if (data.maxVu !== this.itemData.overview.maxVu) {
this.comparisonWarning.push(`VU do differ ${this.itemData.overview.maxVu} vs. ${data.maxVu}`);
}

this.comparedData = this.labelsData.map((_) => {
const labelToBeCompared = data.statistics.find((__) => __.label === _.label);
if (labelToBeCompared) {
return {
..._,
avgDiff: (_.avgResponseTime - labelToBeCompared.avgResponseTime),
minDiff: (_.minResponseTime - labelToBeCompared.minResponseTime),
maxDiff: (_.maxResponseTime - labelToBeCompared.maxResponseTime),
// @ts-ignore
bytesDiff: ((_.bytes - labelToBeCompared.bytes) / 1024).toFixed(2),
n0Diff: (_.n0 - labelToBeCompared.n0),
n5Diff: (_.n5 - labelToBeCompared.n5),
n9Diff: (_.n9 - labelToBeCompared.n9),
errorRateDiff: roundNumberTwoDecimals((_.errorRate - labelToBeCompared.errorRate)),
throughputDiff: roundNumberTwoDecimals((_.throughput - labelToBeCompared.throughput))
};
} else {
this.comparisonWarning.push(`${_.label} label not found`);
return {
..._,
avgDiff: null,
minDiff: null,
maxDiff: null,
n0Diff: null,
n5Diff: null,
n9Diff: null,
errorRateDiff: null,
throughputDiff: null
};
}
});
if (data.environment !== this.itemData.environment) {
this.comparisonWarning.push('Environments do differ');
}
this.labelsData = this.comparedData;

if (this.comparisonWarning.length) {
this.showComparisonWarnings();
}
}

showComparisonWarnings() {
this.toastr.warning(this.comparisonWarning.join('<br>'), 'Comparison Warning!',
{
closeButton: true,
enableHtml: true,
timeOut: 15000,
positionClass: 'toast-bottom-right'
});
this.comparisonWarning = [];
}

monitoringAlerts() {
const alertMessages = [];
const { maxCpu, maxMem } = this.itemData.monitoringData;
Expand All @@ -269,23 +206,6 @@ export class ItemDetailComponent implements OnInit {
enableHtml: true,
});
}

}

resetStatsData() {
this.comparedData = null;
this.labelsData = this.itemData.statistics;
}

search(term: string) {
const dataToFilter = this.comparedData || this.itemData.statistics;
if (term) {
this.labelsData = dataToFilter.filter(x =>
x.label.trim().toLowerCase().includes(term.trim().toLowerCase())
);
} else {
this.labelsData = dataToFilter;
}
}

getTextStatus(status) {
Expand All @@ -296,18 +216,6 @@ export class ItemDetailComponent implements OnInit {
}
}

quickBaseComparison(id) {
this.itemsService.fetchItemDetail(
this.itemParams.projectName,
this.itemParams.scenarioName,
id).subscribe(_ => this.itemToCompare({
statistics: _.statistics,
maxVu: _.overview.maxVu,
environment: _.environment,
id
}));
}

toggleThroughputBand({ element, perfAnalysis }) {
this.overallChartOptions.series.forEach(serie => {
if (['response time', 'errors'].includes(serie.name)) {
Expand Down Expand Up @@ -344,4 +252,5 @@ export class ItemDetailComponent implements OnInit {
convertBytesToMbps(bytes) {
return bytesToMbps(bytes);
}

}
Empty file.
Loading

0 comments on commit 7f2c8a6

Please sign in to comment.