Skip to content

Commit

Permalink
apdex feature (#293)
Browse files Browse the repository at this point in the history
  • Loading branch information
ludeknovy authored Jan 13, 2023
1 parent 30e1fb8 commit d44a324
Show file tree
Hide file tree
Showing 7 changed files with 190 additions and 38 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,9 @@ <h6 class="card-header bg-transparent">Request Statistics <span class="compare">
<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" *ngIf="displayColumn(itemData.userSettings?.requestStats.apdex) && shouldApdexColumnBeDisplayed()">
<mfDefaultSorter [by]="sortByApdex">apdex</mfDefaultSorter>
</th>
<th scope="col" class="hd jtl-head-color" data-html2canvas-ignore="true">
</th>
<th scope="col" class="hd jtl-head-color" data-html2canvas-ignore="true">
Expand Down Expand Up @@ -125,6 +128,11 @@ <h6 class="card-header bg-transparent">Request Statistics <span class="compare">
<span
[className]="comparedData ? _.errorRate > 0 ? 'value-positive' : 'value-negative' : ''">{{_.errorRate | number: '1.0-2'}}</span>
</td>
<td *ngIf="displayColumn(itemData.userSettings?.requestStats.apdex) && shouldApdexColumnBeDisplayed()">
<span>
{{ calculateApdex(_.apdex?.satisfaction,_.apdex?.toleration, _.samples)}}
</span>
</td>
<td>
<app-label-health *ngIf="_.statusCodes && _.statusCodes.length > 0" [statusCodes]="_.statusCodes" [responseFailures]="_.responseMessageFailures" [labelName]="_.label" [errorRate]="_.errorRate" data-html2canvas-ignore="true">
</app-label-health>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ describe("RequestStatsCompareComponent", () => {
errorRate: true,
min: true,
p95: true,
apdex: true,
}
},
baseId: "",
Expand All @@ -96,6 +97,10 @@ describe("RequestStatsCompareComponent", () => {
responseMessageFailures: [
{ responseMessage: "error", count: 1 }
],
apdex: {
toleration: 100,
satisfaction: 400,
}
}, {
avgResponseTime: 10,
bytes: 758,
Expand All @@ -111,6 +116,10 @@ describe("RequestStatsCompareComponent", () => {
responseMessageFailures: [
{ responseMessage: "error", count: 1 }
],
apdex: {
toleration: 20,
satisfaction: 4,
}
},
{
avgResponseTime: 10,
Expand All @@ -127,6 +136,10 @@ describe("RequestStatsCompareComponent", () => {
responseMessageFailures: [
{ responseMessage: "error", count: 1 }
],
apdex: {
toleration: 10,
satisfaction: 40,
}
}, ]
};
fixture.detectChanges();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export class RequestStatsCompareComponent implements OnInit, OnDestroy {
comparedMetadata;
defaultUnit = true;
externalSearchTerm = "";
displayApdexColumn = false;

constructor(
private itemsService: ItemsApiService,
Expand All @@ -51,6 +52,7 @@ export class RequestStatsCompareComponent implements OnInit, OnDestroy {
this.externalSearchTerm = data.label;
}
});
this.displayApdexColumn = !!this.itemData.statistics.find(stats => stats.apdex.satisfaction && stats.apdex.toleration)
}

ngOnDestroy() {
Expand Down Expand Up @@ -307,4 +309,28 @@ export class RequestStatsCompareComponent implements OnInit, OnDestroy {
}
return value;
}

calculateApdex(satisfaction, toleration, samples) {
const apdexValue = roundNumberTwoDecimals((satisfaction + (toleration * 0.5)) / samples)
return this.apdexScore(apdexValue)
}

public sortByApdex(item) {
return roundNumberTwoDecimals(((item.apdex.satisfaction + ( item.apdex.toleration * 0.5)) / item.samples))
}

private apdexScore(apdexValue: number): string {
const score = [
{ rangeFrom: 0.94, rangeTo: 1, name: "Excellent" },
{ rangeTo: 0.93, rangeFrom: 0.85, name: "Good" },
{ rangeFrom: 0.7, rangeTo: 0.83, name: "Fair", },
{ rangeFrom: 0.5, rangeTo: 0.69, name: "Poor", },
{ rangeFrom: 0, rangeTo: 0.49, name: "Unacceptable" }
]
return score.find(sc => apdexValue >= sc.rangeFrom && apdexValue <= sc.rangeTo)?.name
}

shouldApdexColumnBeDisplayed(): boolean {
return this.displayApdexColumn
}
}
4 changes: 4 additions & 0 deletions src/app/items.service.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,10 @@ export interface ItemStatistics {
samples: number;
throughput: number;
responseMessageFailures?: ResponseMessageFailure[];
apdex: {
satisfaction?: number
toleration?: number
}
}

interface ResponseMessageFailure {
Expand Down
1 change: 1 addition & 0 deletions src/app/scenario.service.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,5 @@ export interface RequestStats {
p99: boolean
samples: boolean
throughput: boolean
apdex: boolean
}
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,11 @@ <h6>Generate extra chart aggregations <i class="fas fa-flask"></i></h6>
formControlName="errorRate">
<label class="custom-control-label" for="rs-error-rate">Error Rate</label>
</div>
<div class="custom-control custom-switch">
<input type="checkbox" class="custom-control-input" id="rs-apdex"
formControlName="apdex">
<label class="custom-control-label" for="rs-apdex">APDEX</label>
</div>

</div>

Expand All @@ -366,6 +371,48 @@ <h6>Generate extra chart aggregations <i class="fas fa-flask"></i></h6>
</ng-template>
</li>

<li ngbNavItem="apdex-config">
<a ngbNavLink class="jtl-nav-link">APDEX configuration</a>
<ng-template ngbNavContent>
<form [formGroup]="apdexSettingsForm" (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> </small></div>-->

<div class="form-group">
<div class="custom-control custom-switch">
<input type="checkbox" class="custom-control-input" id="apdexEnabled"
formControlName="apdexEnabled">
<label class="custom-control-label" for="apdexEnabled">Enabled</label>
</div>
</div>

<div class="form-group">
<label for="satisfying-threshold">Satisfying threshold [ms]</label>
<input type="input" id="satisfying-threshold" class="form-control" formControlName="satisfyingThreshold">
<div class="form-control-feedback"
*ngIf="apdexFormControls.satisfyingThreshold.errors">
<p class="form-validation-error" *ngIf="apdexFormControls.satisfyingThreshold.errors.minIsGreaterThanMax">The number cannot be greater then tolerating threshold</p>
</div>
</div>
<div class="form-group">
<label for="tolerating-threshold">Tolerating threshold [ms]</label>
<input type="text" id="tolerating-threshold" class="form-control"
formControlName="toleratingThreshold">
<div class="form-control-feedback"
*ngIf="apdexFormControls.toleratingThreshold.errors">
<p class="form-validation-error" *ngIf="apdexFormControls.toleratingThreshold.errors.maxIsLowerThenMin">The number cannot be lower then satisfying threshold</p>
</div>
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-primary">Submit</button>
</div>
</div>
</form>

</ng-template>
</li>


</ul>
<div [ngbNavOutlet]="nav" class="ms-2 ml-10 w-100" ></div>
Expand Down
Loading

0 comments on commit d44a324

Please sign in to comment.