Skip to content

Commit

Permalink
scenario configure request stats table (#282)
Browse files Browse the repository at this point in the history
  • Loading branch information
ludeknovy authored Dec 16, 2022
1 parent fdc631e commit ea8b829
Show file tree
Hide file tree
Showing 8 changed files with 218 additions and 49 deletions.
7 changes: 4 additions & 3 deletions src/app/item-detail/item-detail.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import { ItemChartService } from "../_services/item-chart.service";
providers: [DecimalPipe]
})
export class ItemDetailComponent implements OnInit, OnDestroy {

Highcharts: typeof Highcharts = Highcharts;
itemData: ItemDetail = {
overview: null,
Expand All @@ -48,7 +48,8 @@ export class ItemDetailComponent implements OnInit, OnDestroy {
},
analysisEnabled: null,
zeroErrorToleranceEnabled: null,
topMetricsSettings: null
topMetricsSettings: null,
userSettings: null,
};
overallChartOptions;
updateChartFlag = false;
Expand Down Expand Up @@ -126,7 +127,7 @@ export class ItemDetailComponent implements OnInit, OnDestroy {
if (this.chartLines) {
const oveallChartSeries = Array.from(this.chartLines?.overall?.values());
this.overallChartOptions.series = JSON.parse(JSON.stringify(oveallChartSeries))

}

this.updateChartFlag = true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,34 +56,34 @@ <h6 class="card-header bg-transparent">Request Statistics <span class="compare">
<th scope="col" class="hd jtl-head-color">
<mfDefaultSorter by="label">label</mfDefaultSorter>
</th>
<th scope="col" class="hd jtl-head-color">
<th scope="col" class="hd jtl-head-color" *ngIf="displayColumn(itemData.userSettings?.requestStats?.samples)">
<mfDefaultSorter by="samples">samples {{defaultUnit ? "" : "[%]" }}</mfDefaultSorter>
</th>
<th scope="col" class="hd jtl-head-color">
<th scope="col" class="hd jtl-head-color" *ngIf="displayColumn(itemData.userSettings?.requestStats?.avg)">
<mfDefaultSorter by="avgResponseTime">avg [{{ defaultUnit ? "ms" : "%" }}]</mfDefaultSorter>
</th>
<th scope="col" class="hd jtl-head-color">
<th scope="col" class="hd jtl-head-color" *ngIf="displayColumn(itemData.userSettings?.requestStats?.min)">
<mfDefaultSorter by="minResponseTime">min [{{ defaultUnit ? "ms" : "%" }}]</mfDefaultSorter>
</th>
<th scope="col" class="hd jtl-head-color">
<th scope="col" class="hd jtl-head-color" *ngIf="displayColumn(itemData.userSettings?.requestStats?.max)">
<mfDefaultSorter by="maxResponseTime">max [{{ defaultUnit ? "ms" : "%" }}]</mfDefaultSorter>
</th>
<th scope="col" class="hd jtl-head-color">
<th scope="col" class="hd jtl-head-color" *ngIf="displayColumn(itemData.userSettings?.requestStats?.p90)">
<mfDefaultSorter by="n0">P90 [{{ defaultUnit ? "ms" : "%" }}]</mfDefaultSorter>
</th>
<th scope="col" class="hd jtl-head-color">
<th scope="col" class="hd jtl-head-color" *ngIf="displayColumn(itemData.userSettings?.requestStats?.p95)">
<mfDefaultSorter by="n5">P95 [{{ defaultUnit ? "ms" : "%" }}]</mfDefaultSorter>
</th>
<th scope="col" class="hd jtl-head-color">
<th scope="col" class="hd jtl-head-color" *ngIf="displayColumn(itemData.userSettings?.requestStats?.p99)">
<mfDefaultSorter by="n9">P99 [{{ defaultUnit ? "ms" : "%" }}]</mfDefaultSorter>
</th>
<th scope="col" class="hd jtl-head-color">
<th scope="col" class="hd jtl-head-color" *ngIf="displayColumn(itemData.userSettings?.requestStats?.throughput)">
<mfDefaultSorter by="throughput">reqs/s {{defaultUnit ? "" : "[%]" }}</mfDefaultSorter>
</th>
<th scope="col" class="hd jtl-head-color">
<th scope="col" class="hd jtl-head-color" *ngIf="displayColumn(itemData.userSettings?.requestStats?.network)">
<mfDefaultSorter by="bytes">network [{{ defaultUnit ? "mbps" : "%" }}]</mfDefaultSorter>
</th>
<th scope="col" class="hd jtl-head-color">
<th scope="col" class="hd jtl-head-color" *ngIf="displayColumn(itemData.userSettings?.requestStats?.errorRate)">
<mfDefaultSorter by="errorRate">error rate [%]</mfDefaultSorter>
</th>
<th scope="col" class="hd jtl-head-color" data-html2canvas-ignore="true">
Expand All @@ -95,33 +95,33 @@ <h6 class="card-header bg-transparent">Request Statistics <span class="compare">
<tbody>
<tr *ngFor="let _ of mf.data">
<td>{{_.label}} </td>
<td><span
<td *ngIf="displayColumn(itemData.userSettings?.requestStats?.samples)"><span
[className]="comparedData ? _.avgResponseTime > 0 ? 'value-positive' : 'value-negative' : ''">{{_.samples | number }}</span> </td>
<td><span
<td *ngIf="displayColumn(itemData.userSettings?.requestStats?.avg)"><span
[className]="comparedData ? _.avgResponseTime > 0 ? 'value-positive' : 'value-negative' : ''">{{_.avgResponseTime | number: '1.0-2'}}</span>
</td>
<td><span
<td *ngIf="displayColumn(itemData.userSettings?.requestStats?.min)"><span
[className]="comparedData ? _.minResponseTime > 0 ? 'value-positive' : 'value-negative' : ''">{{_.minResponseTime | number: '1.0-2'}}</span>
</td>
<td><span
<td *ngIf="displayColumn(itemData.userSettings?.requestStats?.max)"><span
[className]="comparedData ? _.maxResponseTime > 0 ? 'value-positive' : 'value-negative' : ''">{{_.maxResponseTime | number: '1.0-2'}}</span>
</td>
<td><span [className]="comparedData ? _.n0 > 0 ? 'value-positive' : 'value-negative' : ''">{{_.n0 | number: '1.0-2'}}</span>
<td *ngIf="displayColumn(itemData.userSettings?.requestStats?.p90)"><span [className]="comparedData ? _.n0 > 0 ? 'value-positive' : 'value-negative' : ''">{{_.n0 | number: '1.0-2'}}</span>
</td>
<td><span [className]="comparedData ? _.n5 > 0 ? 'value-positive' : 'value-negative' : ''">{{_.n5 | number: '1.0-2'}}</span>
<td *ngIf="displayColumn(itemData.userSettings?.requestStats?.p95)"><span [className]="comparedData ? _.n5 > 0 ? 'value-positive' : 'value-negative' : ''">{{_.n5 | number: '1.0-2'}}</span>
</td>
<td><span [className]="comparedData ? _.n9 > 0 ? 'value-positive' : 'value-negative' : ''">{{_.n9 | number: '1.0-2'}}</span>
<td *ngIf="displayColumn(itemData.userSettings?.requestStats?.p99)"><span [className]="comparedData ? _.n9 > 0 ? 'value-positive' : 'value-negative' : ''">{{_.n9 | number: '1.0-2'}}</span>
</td>
<td>
<td *ngIf="displayColumn(itemData.userSettings?.requestStats?.throughput)">
<span
[className]="comparedData ? _.throughput > 0 ? 'value-negative' : 'value-positive' : ''">{{_.throughput | number: '1.0-2'}}</span>
</td>
<td>
<td *ngIf="displayColumn(itemData.userSettings?.requestStats?.network)">
<span
[className]="comparedData ? convertBytesToMbps(_.bytesPerSecond + _.bytesSentPerSecond) > 0 ? 'value-positive' : 'value-negative' : ''">{{convertBytesToMbps(_.bytesPerSecond
+ _.bytesSentPerSecond) || 0 | number: '1.0-2' }}</span>
</td>
<td>
<td *ngIf="displayColumn(itemData.userSettings?.requestStats?.errorRate)">
<span
[className]="comparedData ? _.errorRate > 0 ? 'value-positive' : 'value-negative' : ''">{{_.errorRate | number: '1.0-2'}}</span>
</td>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,46 @@ describe("RequestStatsCompareComponent", () => {
fixture = TestBed.createComponent(RequestStatsCompareComponent);
component = fixture.componentInstance;
component.itemData = {
environment: "",
extraPlotData: [],
hostname: "",
monitoring: { cpu: { data: [] } },
name: "",
note: "",
plot: undefined,
reportStatus: undefined,
topMetricsSettings: undefined,
zeroErrorToleranceEnabled: false,
overview: {
maxVu: 100
maxVu: 100,
avgConnect: 100,
avgLatency: 10,
avgResponseTime: 99,
duration: 100,
endDate: "",
startDate: "",
errorCount: 0,
percentil: 10,
errorRate: 0,
throughput: 100
},
analysisEnabled: false,
userSettings: {
requestStats: {
avg: true,
samples: true,
max: true,
p99: true,
p90: true,
throughput: true,
network: true,
errorRate: true,
min: true,
p95: true,
}
},
baseId: "",

statistics: [{
avgResponseTime: 10,
bytes: 758,
Expand All @@ -59,9 +96,6 @@ describe("RequestStatsCompareComponent", () => {
responseMessageFailures: [
{ responseMessage: "error", count: 1 }
],
statusCodes: [{
statusCode: 200, count: 1
}],
}, {
avgResponseTime: 10,
bytes: 758,
Expand All @@ -77,9 +111,6 @@ describe("RequestStatsCompareComponent", () => {
responseMessageFailures: [
{ responseMessage: "error", count: 1 }
],
statusCodes: [{
statusCode: 200, count: 1
}],
},
{
avgResponseTime: 10,
Expand All @@ -96,9 +127,6 @@ describe("RequestStatsCompareComponent", () => {
responseMessageFailures: [
{ responseMessage: "error", count: 1 }
],
statusCodes: [{
statusCode: 200, count: 1
}],
}, ]
};
fixture.detectChanges();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { ToastrService } from "ngx-toastr";
import { NgbModal } from "@ng-bootstrap/ng-bootstrap";
import html2canvas from "html2canvas";
import { ExcelService } from "src/app/_services/excel.service";
import { ItemDetail } from "../../items.service.model";



Expand All @@ -17,7 +18,7 @@ import { ExcelService } from "src/app/_services/excel.service";
})
export class RequestStatsCompareComponent implements OnInit, OnDestroy {

@Input() itemData;
@Input() itemData: ItemDetail;
@Input() isAnonymous: boolean;
@Input() params: ItemParams;

Expand Down Expand Up @@ -135,7 +136,7 @@ export class RequestStatsCompareComponent implements OnInit, OnDestroy {
maxResponseTime: (_.maxResponseTime - labelToBeCompared.maxResponseTime),
bytes: ((_.bytes - labelToBeCompared.bytes) / 1024).toFixed(2),
bytesPerSecond: (_.bytesPerSecond - labelToBeCompared.bytesPerSecond),
bytesSentPerSecond:(_.bytesSentPerSecond - labelToBeCompared.bytesSentPerSecond),
bytesSentPerSecond:(_.bytesSentPerSecond - labelToBeCompared.bytesSentPerSecond),
n0: (_.n0 - labelToBeCompared.n0),
n5: (_.n5 - labelToBeCompared.n5),
n9: (_.n9 - labelToBeCompared.n9),
Expand Down Expand Up @@ -212,7 +213,7 @@ export class RequestStatsCompareComponent implements OnInit, OnDestroy {
n5: this.calculatePercDifference(_.n5, labelToBeCompared.n5),
n9: this.calculatePercDifference(_.n9, labelToBeCompared.n9),
bytesPerSecond: this.calculatePercDifference(_.bytesPerSecond, labelToBeCompared.bytesPerSecond),
bytesSentPerSecond:this.calculatePercDifference(_.bytesSentPerSecond, labelToBeCompared.bytesSentPerSecond),
bytesSentPerSecond:this.calculatePercDifference(_.bytesSentPerSecond, labelToBeCompared.bytesSentPerSecond),
errorRate: this.calculatePercDifference(_.errorRate, labelToBeCompared.errorRate),
throughput: this.calculatePercDifference(_.throughput, labelToBeCompared.throughput)
};
Expand Down Expand Up @@ -276,11 +277,18 @@ export class RequestStatsCompareComponent implements OnInit, OnDestroy {
}

downloadAsXLXS() {
const dataToBeSaved = this.labelsData.map((label) =>
const dataToBeSaved = this.labelsData.map((label) =>
({ label: label.label, samples: label.samples, "avg [ms]": label.avgResponseTime, "min [ms]": label.minResponseTime,
"max [ms]": label.maxResponseTime, "P90 [ms]": label.n0, "P95 [ms]": label.n5, "P99 [ms]": label.n9,
"reqs/s": label.throughput, "network [mbps]": roundNumberTwoDecimals(this.convertBytesToMbps(label.bytesPerSecond + label.bytesSentPerSecond)), "error rate [%]": label.errorRate
}))
this.excelService.exportAsExcelFile(dataToBeSaved, `request-stats-${this.params.id}`)
}

displayColumn(value) {
if (typeof value === "undefined" || value === null) {
return true
}
return value
}
}
5 changes: 5 additions & 0 deletions src/app/items.service.model.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { RequestStats } from "./scenario.service.model";

export interface ItemsListing {
id: string;
name: string;
Expand Down Expand Up @@ -47,6 +49,9 @@ export interface ItemDetail {
}
};
topMetricsSettings: TopMetricsSettings;
userSettings: {
requestStats: RequestStats
}
}

interface TopMetricsSettings {
Expand Down
21 changes: 19 additions & 2 deletions src/app/scenario.service.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,24 @@ export interface Scenario {
enabled: boolean;
percentile: number;
throughput: number;
erroRate: number;
errorRate: number;
};
labelFilterSettings: [{ operator: string, labelTerm: string }]
labelFilterSettings: [{ operator: string, labelTerm: string }];
userSettings: {
requestStats?: RequestStats
};
}


export interface RequestStats {
avg: boolean
errorRate: boolean
max: boolean
min: boolean
network: boolean
p90: boolean
p95: boolean
p99: boolean
samples: boolean
throughput: boolean
}
Original file line number Diff line number Diff line change
Expand Up @@ -135,16 +135,16 @@ <h6>Generate extra chart aggregations <i class="fas fa-flask"></i></h6>
</div>

<div class="form-group">
<label for="exampleInputEmail1">90% percentil</label>
<input type="input" class="form-control" formControlName="thresholdPercentile">
<label for="scen-settings-p90">90% percentil</label>
<input type="input" id="scen-settings-p90" class="form-control" formControlName="thresholdPercentile">
</div>
<div class="form-group">
<label for="exampleInputEmail1">Throughput</label>
<input type="text" class="form-control" formControlName="thresholdThroughput">
<label for="scen-settings-throughput">Throughput</label>
<input type="text" id="scen-settings-throughput" class="form-control" formControlName="thresholdThroughput">
</div>
<div class="form-group">
<label for="exampleInputEmail1">Error rate</label>
<input type="text" class="form-control" formControlName="thresholdErrorRate">
<label for="scen-settings-error-rate">Error rate</label>
<input type="text" id="scen-settings-error-rate" class="form-control" formControlName="thresholdErrorRate">
</div>
</div>

Expand Down Expand Up @@ -277,6 +277,77 @@ <h6>Generate extra chart aggregations <i class="fas fa-flask"></i></h6>

</ng-template>
</li>

<li ngbNavItem>
<a ngbNavLink>Request statistics configuration</a>
<ng-template ngbNavContent>
<form [formGroup]="requestStatsSettingsForm" (ngSubmit)="onSubmit()" class="pl-3">
<div class="form-group form-settings pt-3">
<div class="desc text-secondary"><i class="fas fa-info-circle"> </i>
<small> The selected metrics will get pre-set in request stats table. Please not that this settings is user specific.</small></div>
<div class="custom-control custom-switch">
<input type="checkbox" class="custom-control-input" id="rs-samples"
formControlName="samples">
<label class="custom-control-label" for="rs-samples">Samples</label>
</div>
<div class="custom-control custom-switch">
<input type="checkbox" class="custom-control-input" id="rs-avg"
formControlName="avg">
<label class="custom-control-label" for="rs-avg">Response Time [avg]</label>
</div>
<div class="custom-control custom-switch">
<input type="checkbox" class="custom-control-input" id="rs-p90"
formControlName="p90">
<label class="custom-control-label" for="rs-p90">Response Time [P90]</label>
</div>
<div class="custom-control custom-switch">
<input type="checkbox" class="custom-control-input" id="rs-p95"
formControlName="p95">
<label class="custom-control-label" for="rs-p95">Response Time [P95]</label>
</div>
<div class="custom-control custom-switch">
<input type="checkbox" class="custom-control-input" id="rs-p99"
formControlName="p99">
<label class="custom-control-label" for="rs-p99">Response Time [P99]</label>
</div>
<div class="custom-control custom-switch">
<input type="checkbox" class="custom-control-input" id="rs-throughput"
formControlName="throughput">
<label class="custom-control-label" for="rs-throughput">Throughput</label>
</div>
<div class="custom-control custom-switch">
<input type="checkbox" class="custom-control-input" id="rs-min"
formControlName="min">
<label class="custom-control-label" for="rs-min">Response Time [min]</label>
</div>
<div class="custom-control custom-switch">
<input type="checkbox" class="custom-control-input" id="rs-max"
formControlName="max">
<label class="custom-control-label" for="rs-max">Response Time [max]</label>
</div>
<div class="custom-control custom-switch">
<input type="checkbox" class="custom-control-input" id="rs-network"
formControlName="network">
<label class="custom-control-label" for="rs-network">Network</label>
</div>
<div class="custom-control custom-switch">
<input type="checkbox" class="custom-control-input" id="rs-error-rate"
formControlName="errorRate">
<label class="custom-control-label" for="rs-error-rate">Error Rate</label>
</div>

</div>


<div class="modal-footer">
<button type="submit" class="btn btn-primary">Submit</button>
</div>
</form>

</ng-template>
</li>


</ul>
<div [ngbNavOutlet]="nav"></div>

Expand Down
Loading

0 comments on commit ea8b829

Please sign in to comment.