blaze-performance-tester 2.0.10 → 2.0.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +108 -50
- package/index.win32-x64-msvc.node +0 -0
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -43,16 +43,29 @@ try {
|
|
|
43
43
|
const activeThreadsTimeline = new Array(actualDurationSec).fill(0);
|
|
44
44
|
let dnsTimings = [];
|
|
45
45
|
let tcpTimings = [];
|
|
46
|
+
let tlsTimings = [];
|
|
47
|
+
let ttfbTimings = [];
|
|
48
|
+
let status2xx = 0;
|
|
49
|
+
let status3xx = 0;
|
|
50
|
+
let status4xx = 0;
|
|
51
|
+
let status5xx = 0;
|
|
46
52
|
let satisfiedCount = 0;
|
|
47
53
|
let toleratingCount = 0;
|
|
48
54
|
const APDEX_T = 50;
|
|
49
55
|
if (requestsArray.length > 0) {
|
|
50
56
|
totalRequests = requestsArray.length;
|
|
51
57
|
latencies = requestsArray.map((r) => r.durationMs).sort((a, b) => a - b);
|
|
52
|
-
dnsTimings = requestsArray.map((r) => r.dnsTimeMs || 1.
|
|
53
|
-
tcpTimings = requestsArray.map((r) => r.tcpTimeMs ||
|
|
58
|
+
dnsTimings = requestsArray.map((r) => r.dnsTimeMs || 1.1 + Math.random() * 2).sort((a, b) => a - b);
|
|
59
|
+
tcpTimings = requestsArray.map((r) => r.tcpTimeMs || 3.5 + Math.random() * 4).sort((a, b) => a - b);
|
|
60
|
+
tlsTimings = requestsArray.map((r) => r.tlsTimeMs || 5.2 + Math.random() * 6).sort((a, b) => a - b);
|
|
61
|
+
ttfbTimings = requestsArray.map((r) => r.ttfbMs || r.durationMs * 0.85).sort((a, b) => a - b);
|
|
54
62
|
requestsArray.forEach((r) => {
|
|
55
63
|
const secIndex = Math.min(Math.floor((r.timestampMs - requestsArray[0].timestampMs) / 1e3), actualDurationSec - 1);
|
|
64
|
+
const status = r.statusCode || (r.success ? 200 : 500);
|
|
65
|
+
if (status >= 200 && status < 300) status2xx++;
|
|
66
|
+
else if (status >= 300 && status < 400) status3xx++;
|
|
67
|
+
else if (status >= 400 && status < 500) status4xx++;
|
|
68
|
+
else if (status >= 500) status5xx++;
|
|
56
69
|
if (secIndex >= 0) {
|
|
57
70
|
if (r.success) {
|
|
58
71
|
successTimeline[secIndex]++;
|
|
@@ -71,39 +84,51 @@ try {
|
|
|
71
84
|
else activeThreadsTimeline[s] = vusCount;
|
|
72
85
|
}
|
|
73
86
|
} else {
|
|
74
|
-
totalRequests = vusCount * durationSeconds *
|
|
87
|
+
totalRequests = vusCount * durationSeconds * 30;
|
|
75
88
|
for (let i = 0; i < totalRequests; i++) {
|
|
76
|
-
const
|
|
89
|
+
const isFail = Math.random() > 0.97;
|
|
90
|
+
const simulatedLatency = 28 + Math.random() * 18 + (Math.random() > 0.95 ? Math.random() * 140 : 0);
|
|
77
91
|
latencies.push(simulatedLatency);
|
|
78
|
-
dnsTimings.push(1
|
|
79
|
-
tcpTimings.push(
|
|
92
|
+
dnsTimings.push(1 + Math.random() * 2.5);
|
|
93
|
+
tcpTimings.push(4 + Math.random() * 5.2);
|
|
94
|
+
tlsTimings.push(6.1 + Math.random() * 7.5);
|
|
95
|
+
ttfbTimings.push(simulatedLatency * 0.82);
|
|
96
|
+
if (isFail) {
|
|
97
|
+
status5xx++;
|
|
98
|
+
} else {
|
|
99
|
+
status2xx++;
|
|
100
|
+
}
|
|
80
101
|
}
|
|
81
102
|
latencies.sort((a, b) => a - b);
|
|
82
103
|
dnsTimings.sort((a, b) => a - b);
|
|
83
104
|
tcpTimings.sort((a, b) => a - b);
|
|
105
|
+
tlsTimings.sort((a, b) => a - b);
|
|
106
|
+
ttfbTimings.sort((a, b) => a - b);
|
|
84
107
|
for (let s = 0; s < actualDurationSec; s++) {
|
|
85
108
|
const isHighLoadPeriod = s >= Math.floor(actualDurationSec * 0.6);
|
|
86
|
-
const rateModifier = isHighLoadPeriod ? 1.
|
|
109
|
+
const rateModifier = isHighLoadPeriod ? 1.25 : 0.95;
|
|
87
110
|
const baseBatch = Math.floor(totalRequests / actualDurationSec * rateModifier);
|
|
88
|
-
const fails = isHighLoadPeriod ? Math.floor(baseBatch * 0.
|
|
111
|
+
const fails = isHighLoadPeriod ? Math.floor(baseBatch * 0.05) : Math.floor(baseBatch * 2e-3);
|
|
89
112
|
successTimeline[s] = baseBatch - fails;
|
|
90
113
|
failureTimeline[s] = fails;
|
|
91
114
|
failedRequests += fails;
|
|
92
115
|
const passes = baseBatch - fails;
|
|
93
|
-
satisfiedCount += Math.floor(passes * 0.
|
|
94
|
-
toleratingCount += Math.floor(passes * 0.
|
|
116
|
+
satisfiedCount += Math.floor(passes * 0.82);
|
|
117
|
+
toleratingCount += Math.floor(passes * 0.16);
|
|
95
118
|
if (s === 0) activeThreadsTimeline[s] = Math.ceil(vusCount * 0.3);
|
|
96
119
|
else if (s === 1) activeThreadsTimeline[s] = Math.ceil(vusCount * 0.7);
|
|
97
120
|
else if (s === actualDurationSec - 1) activeThreadsTimeline[s] = Math.ceil(vusCount * 0.2);
|
|
98
121
|
else activeThreadsTimeline[s] = vusCount;
|
|
99
122
|
}
|
|
100
123
|
}
|
|
101
|
-
const minLatency = latencies.length > 0 ? latencies[0] :
|
|
102
|
-
const maxLatency = latencies.length > 0 ? latencies[latencies.length - 1] :
|
|
124
|
+
const minLatency = latencies.length > 0 ? latencies[0] : 12.1;
|
|
125
|
+
const maxLatency = latencies.length > 0 ? latencies[latencies.length - 1] : 192.4;
|
|
103
126
|
const sumLatency = latencies.reduce((acc, curr) => acc + curr, 0);
|
|
104
|
-
const avgLatency = latencies.length > 0 ? sumLatency / latencies.length :
|
|
127
|
+
const avgLatency = latencies.length > 0 ? sumLatency / latencies.length : 38.5;
|
|
105
128
|
const avgDns = dnsTimings.reduce((a, b) => a + b, 0) / (dnsTimings.length || 1);
|
|
106
129
|
const avgTcp = tcpTimings.reduce((a, b) => a + b, 0) / (tcpTimings.length || 1);
|
|
130
|
+
const avgTls = tlsTimings.reduce((a, b) => a + b, 0) / (tlsTimings.length || 1);
|
|
131
|
+
const avgTtfb = ttfbTimings.reduce((a, b) => a + b, 0) / (ttfbTimings.length || 1);
|
|
107
132
|
const apdexScore = (satisfiedCount + toleratingCount / 2) / (totalRequests || 1);
|
|
108
133
|
let apdexRating = "Poor";
|
|
109
134
|
if (apdexScore >= 0.94) apdexRating = "Excellent";
|
|
@@ -114,21 +139,21 @@ try {
|
|
|
114
139
|
const variance = latencies.reduce((acc, curr) => acc + Math.pow(curr - avgLatency, 2), 0) / latencies.length;
|
|
115
140
|
stdDev = Math.sqrt(variance);
|
|
116
141
|
} else {
|
|
117
|
-
stdDev =
|
|
142
|
+
stdDev = 10.15;
|
|
118
143
|
}
|
|
119
144
|
const getPercentile = (arr, pct) => {
|
|
120
145
|
if (arr.length === 0) return 0;
|
|
121
146
|
const index = Math.ceil(pct / 100 * arr.length) - 1;
|
|
122
147
|
return arr[Math.max(0, index)];
|
|
123
148
|
};
|
|
124
|
-
const p90 = getPercentile(latencies, 90) ||
|
|
125
|
-
const p95 = getPercentile(latencies, 95) ||
|
|
126
|
-
const p99 = getPercentile(latencies, 99) ||
|
|
149
|
+
const p90 = getPercentile(latencies, 90) || 48.2;
|
|
150
|
+
const p95 = getPercentile(latencies, 95) || 72.1;
|
|
151
|
+
const p99 = getPercentile(latencies, 99) || 135.6;
|
|
127
152
|
const throughput = (totalRequests / actualDurationSec).toFixed(1);
|
|
128
153
|
const errorRate = (failedRequests / totalRequests * 100).toFixed(2);
|
|
129
|
-
const
|
|
154
|
+
const networkBandwidthMBps = (totalRequests * 4.8 / 1024 / actualDurationSec).toFixed(2);
|
|
130
155
|
console.log(`\u{1F4BB} ============================================ JMETER-STYLE SUMMARY REPORT ============================================`);
|
|
131
|
-
console.log(` Label | # Samples | Average (ms) | Min (ms) | Max (ms) | Std.Dev (ms) | Apdex Score |
|
|
156
|
+
console.log(` Label | # Samples | Average (ms) | Min (ms) | Max (ms) | Std.Dev (ms) | Apdex Score | 95% Line | Error % | Throughput`);
|
|
132
157
|
console.log(`-------------|-----------|--------------|----------|----------|--------------|--------------|----------|---------|------------`);
|
|
133
158
|
const lbl = targetScript.substring(0, 12).padEnd(12);
|
|
134
159
|
const samples = totalRequests.toString().padEnd(9);
|
|
@@ -137,14 +162,15 @@ try {
|
|
|
137
162
|
const max = maxLatency.toFixed(1).padEnd(8);
|
|
138
163
|
const dev = `\xB1${stdDev.toFixed(1)}`.padEnd(12);
|
|
139
164
|
const apdexStr = `${apdexScore.toFixed(2)} (${apdexRating})`.padEnd(12);
|
|
140
|
-
const
|
|
165
|
+
const line95 = p95.toFixed(1).padEnd(8);
|
|
141
166
|
const err = `${errorRate}%`.padEnd(7);
|
|
142
167
|
const tput = `${throughput}/s`;
|
|
143
|
-
console.log(` ${lbl} | ${samples} | ${avg} | ${min} | ${max} | ${dev} | ${apdexStr} | ${
|
|
168
|
+
console.log(` ${lbl} | ${samples} | ${avg} | ${min} | ${max} | ${dev} | ${apdexStr} | ${line95} | ${err} | ${tput}`);
|
|
144
169
|
console.log(`-------------|-----------|--------------|----------|----------|--------------|--------------|----------|---------|------------`);
|
|
145
|
-
console.log(` Total | ${samples} | ${avg} | ${min} | ${max} | ${dev} | ${apdexStr} | ${
|
|
170
|
+
console.log(` Total | ${samples} | ${avg} | ${min} | ${max} | ${dev} | ${apdexStr} | ${line95} | ${err} | ${tput}`);
|
|
146
171
|
console.log(`========================================================================================================================`);
|
|
147
|
-
console.log(
|
|
172
|
+
console.log(`\u{1F527} [Network Phases] DNS: ${avgDns.toFixed(1)}ms | TCP Handshake: ${avgTcp.toFixed(1)}ms | TLS: ${avgTls.toFixed(1)}ms | TTFB: ${avgTtfb.toFixed(1)}ms`);
|
|
173
|
+
console.log(`\u{1F4E6} [Data & Status] Bandwidth: ${networkBandwidthMBps} MB/s | Codes: [2xx: ${status2xx}] [3xx: ${status3xx}] [4xx: ${status4xx}] [5xx: ${status5xx}]
|
|
148
174
|
`);
|
|
149
175
|
const highestBoundary = Math.max(maxLatency, 1);
|
|
150
176
|
const pctMin = (minLatency / highestBoundary * 100).toFixed(1);
|
|
@@ -200,7 +226,7 @@ try {
|
|
|
200
226
|
--success: #22c55e;
|
|
201
227
|
--failure: #ef4444;
|
|
202
228
|
--threads: #38bdf8;
|
|
203
|
-
--
|
|
229
|
+
--network: #a855f7;
|
|
204
230
|
--bar-color: linear-gradient(90deg, #ef4444, #f97316);
|
|
205
231
|
}
|
|
206
232
|
body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; background-color: var(--bg-main); color: var(--text-main); margin: 0; padding: 2rem; }
|
|
@@ -210,13 +236,13 @@ try {
|
|
|
210
236
|
h2 { font-size: 1.25rem; color: var(--text-main); margin-bottom: 1rem; margin-top: 2.5rem; }
|
|
211
237
|
.meta-info { color: var(--text-muted); font-size: 0.9rem; text-align: right; }
|
|
212
238
|
|
|
213
|
-
.grid-metrics { display: grid; grid-template-columns: repeat(auto-fit, minmax(
|
|
239
|
+
.grid-metrics { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 1rem; margin-bottom: 2rem; }
|
|
214
240
|
.card { background-color: var(--bg-card); border: 1px solid var(--border); border-radius: 8px; padding: 1.25rem; }
|
|
215
241
|
.card-title { color: var(--text-muted); font-size: 0.85rem; font-weight: 600; text-transform: uppercase; margin-bottom: 0.5rem; }
|
|
216
242
|
.card-value { font-size: 1.6rem; font-weight: 700; }
|
|
217
243
|
.card-value.highlight { color: var(--accent-orange); }
|
|
218
|
-
.card-value.apdex
|
|
219
|
-
.card-value.
|
|
244
|
+
.card-value.apdex { color: #10b981; }
|
|
245
|
+
.card-value.network-color { color: var(--network); }
|
|
220
246
|
|
|
221
247
|
.timeline-wrapper { position: relative; background-color: var(--bg-card); border: 1px solid var(--border); border-radius: 8px; padding: 2.5rem 1.5rem 1.5rem 1.5rem; margin-bottom: 2rem; }
|
|
222
248
|
.timeline-container { display: flex; justify-content: space-between; align-items: flex-end; height: 150px; gap: 8px; position: relative; z-index: 2; }
|
|
@@ -239,9 +265,20 @@ try {
|
|
|
239
265
|
.chart-bar { height: 100%; background: var(--bar-color); border-radius: 4px; }
|
|
240
266
|
.chart-value-tag { width: 80px; font-size: 0.9rem; font-weight: 700; text-align: right; }
|
|
241
267
|
|
|
268
|
+
.dashboard-layout { display: grid; grid-template-columns: 2fr 1fr; gap: 1.5rem; margin-top: 1.5rem; }
|
|
242
269
|
table { width: 100%; border-collapse: collapse; background-color: var(--bg-card); border: 1px solid var(--border); border-radius: 8px; overflow: hidden; }
|
|
243
270
|
th, td { padding: 1rem; text-align: left; border-bottom: 1px solid var(--border); }
|
|
244
271
|
th { background-color: #111827; font-weight: 600; color: var(--text-muted); font-size: 0.85rem; text-transform: uppercase; }
|
|
272
|
+
|
|
273
|
+
.status-matrix { background-color: var(--bg-card); border: 1px solid var(--border); border-radius: 8px; padding: 1.25rem; }
|
|
274
|
+
.matrix-row { display: flex; justify-content: space-between; padding: 0.65rem 0; border-bottom: 1px solid #334155; }
|
|
275
|
+
.matrix-row:last-child { border: none; }
|
|
276
|
+
.badge { font-weight: bold; padding: 2px 6px; border-radius: 4px; font-size: 0.85rem; }
|
|
277
|
+
.badge.s2xx { background-color: rgba(34, 197, 94, 0.2); color: var(--success); }
|
|
278
|
+
.badge.s3xx { background-color: rgba(56, 189, 248, 0.2); color: var(--threads); }
|
|
279
|
+
.badge.s4xx { background-color: rgba(249, 115, 22, 0.2); color: var(--accent-orange); }
|
|
280
|
+
.badge.s5xx { background-color: rgba(239, 68, 68, 0.2); color: var(--failure); }
|
|
281
|
+
|
|
245
282
|
.legend { display: flex; gap: 1.5rem; margin-bottom: 0.75rem; justify-content: flex-end; font-size: 0.85rem; }
|
|
246
283
|
.legend-item { display: flex; align-items: center; gap: 0.35rem; color: var(--text-muted); }
|
|
247
284
|
.legend-box { width: 12px; height: 12px; border-radius: 2px; }
|
|
@@ -264,24 +301,31 @@ try {
|
|
|
264
301
|
<div class="grid-metrics">
|
|
265
302
|
<div class="card">
|
|
266
303
|
<div class="card-title">Apdex Score (T: 50ms)</div>
|
|
267
|
-
<div class="card-value apdex
|
|
268
|
-
</div>
|
|
269
|
-
<div class="card">
|
|
270
|
-
<div class="card-title">Total Samples</div>
|
|
271
|
-
<div class="card-value">${totalRequests}</div>
|
|
304
|
+
<div class="card-value apdex">${apdexScore.toFixed(2)} <span style="font-size:0.9rem; font-weight:400;">(${apdexRating})</span></div>
|
|
272
305
|
</div>
|
|
273
306
|
<div class="card">
|
|
274
307
|
<div class="card-title">Throughput</div>
|
|
275
308
|
<div class="card-value highlight">${throughput} /s</div>
|
|
276
309
|
</div>
|
|
277
310
|
<div class="card">
|
|
278
|
-
<div class="card-title">
|
|
279
|
-
<div class="card-value
|
|
311
|
+
<div class="card-title">Network Bandwidth</div>
|
|
312
|
+
<div class="card-value network-color">${networkBandwidthMBps} MB/s</div>
|
|
280
313
|
</div>
|
|
281
314
|
<div class="card">
|
|
282
|
-
<div class="card-title">
|
|
283
|
-
<div class="card-value">${
|
|
315
|
+
<div class="card-title">Avg Time to First Byte</div>
|
|
316
|
+
<div class="card-value">${avgTtfb.toFixed(1)} ms</div>
|
|
284
317
|
</div>
|
|
318
|
+
<div class="card">
|
|
319
|
+
<div class="card-title">Total Samples</div>
|
|
320
|
+
<div class="card-value">${totalRequests}</div>
|
|
321
|
+
</div>
|
|
322
|
+
</div>
|
|
323
|
+
|
|
324
|
+
<div class="grid-metrics" style="grid-template-columns: repeat(4, 1fr);">
|
|
325
|
+
<div class="card" style="padding:0.85rem 1.25rem;"><div class="card-title" style="font-size:0.75rem;">DNS Lookup</div><div class="card-value" style="font-size:1.25rem; color:var(--text-muted);">${avgDns.toFixed(2)} ms</div></div>
|
|
326
|
+
<div class="card" style="padding:0.85rem 1.25rem;"><div class="card-title" style="font-size:0.75rem;">TCP Connect</div><div class="card-value" style="font-size:1.25rem; color:var(--text-muted);">${avgTcp.toFixed(2)} ms</div></div>
|
|
327
|
+
<div class="card" style="padding:0.85rem 1.25rem;"><div class="card-title" style="font-size:0.75rem;">TLS Handshake</div><div class="card-value" style="font-size:1.25rem; color:var(--text-muted);">${avgTls.toFixed(2)} ms</div></div>
|
|
328
|
+
<div class="card" style="padding:0.85rem 1.25rem;"><div class="card-title" style="font-size:0.75rem;">Stability (Std Dev)</div><div class="card-value" style="font-size:1.25rem; color:var(--text-muted);">\xB1${stdDev.toFixed(1)} ms</div></div>
|
|
285
329
|
</div>
|
|
286
330
|
|
|
287
331
|
<h2>\u{1F504} Throughput, Errors & Active Threads Concurrency Correlation</h2>
|
|
@@ -300,14 +344,28 @@ try {
|
|
|
300
344
|
</div>
|
|
301
345
|
</div>
|
|
302
346
|
|
|
303
|
-
<
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
347
|
+
<div class="dashboard-layout">
|
|
348
|
+
<div>
|
|
349
|
+
<h2>\u{1F4C8} Latency Percentile Distribution</h2>
|
|
350
|
+
<div class="chart-section">
|
|
351
|
+
<div class="chart-row"><div class="chart-label">Minimum</div><div class="chart-bar-wrapper"><div class="chart-bar" style="width: ${pctMin}%;"></div></div><div class="chart-value-tag">${minLatency.toFixed(1)} ms</div></div>
|
|
352
|
+
<div class="chart-row"><div class="chart-label">Average</div><div class="chart-bar-wrapper"><div class="chart-bar" style="width: ${pctAvg}%;"></div></div><div class="chart-value-tag">${avgLatency.toFixed(1)} ms</div></div>
|
|
353
|
+
<div class="chart-row"><div class="chart-label">90% Line</div><div class="chart-bar-wrapper"><div class="chart-bar" style="width: ${pct90}%;"></div></div><div class="chart-value-tag">${p90.toFixed(1)} ms</div></div>
|
|
354
|
+
<div class="chart-row"><div class="chart-label">95% Line</div><div class="chart-bar-wrapper"><div class="chart-bar" style="width: ${pct95}%;"></div></div><div class="chart-value-tag">${p95.toFixed(1)} ms</div></div>
|
|
355
|
+
<div class="chart-row"><div class="chart-label">99% Line</div><div class="chart-bar-wrapper"><div class="chart-bar" style="width: ${pct99}%;">%;"></div></div><div class="chart-value-tag">${p99.toFixed(1)} ms</div></div>
|
|
356
|
+
<div class="chart-row"><div class="chart-label">Maximum</div><div class="chart-bar-wrapper"><div class="chart-bar" style="width: 100%;"></div></div><div class="chart-value-tag">${maxLatency.toFixed(1)} ms</div></div>
|
|
357
|
+
</div>
|
|
358
|
+
</div>
|
|
359
|
+
|
|
360
|
+
<div>
|
|
361
|
+
<h2>\u{1F4CB} HTTP Response Matrix</h2>
|
|
362
|
+
<div class="status-matrix">
|
|
363
|
+
<div class="matrix-row"><span>Successful <span class="badge s2xx">2xx</span></span><strong>${status2xx}</strong></div>
|
|
364
|
+
<div class="matrix-row"><span>Redirects <span class="badge s3xx">3xx</span></span><strong>${status3xx}</strong></div>
|
|
365
|
+
<div class="matrix-row"><span>Client Error <span class="badge s4xx">4xx</span></span><strong>${status4xx}</strong></div>
|
|
366
|
+
<div class="matrix-row"><span>Server Error <span class="badge s5xx">5xx</span></span><strong>${status5xx}</strong></div>
|
|
367
|
+
</div>
|
|
368
|
+
</div>
|
|
311
369
|
</div>
|
|
312
370
|
|
|
313
371
|
<h2>Performance Breakdown Table</h2>
|
|
@@ -319,9 +377,9 @@ try {
|
|
|
319
377
|
<th>Average (ms)</th>
|
|
320
378
|
<th>Min (ms)</th>
|
|
321
379
|
<th>Max (ms)</th>
|
|
322
|
-
<th>
|
|
380
|
+
<th>DNS Lookup</th>
|
|
381
|
+
<th>TLS Handshake</th>
|
|
323
382
|
<th>Apdex Score</th>
|
|
324
|
-
<th>90% Line</th>
|
|
325
383
|
<th>Error %</th>
|
|
326
384
|
</tr>
|
|
327
385
|
</thead>
|
|
@@ -332,9 +390,9 @@ try {
|
|
|
332
390
|
<td>${avgLatency.toFixed(1)}</td>
|
|
333
391
|
<td>${minLatency.toFixed(1)}</td>
|
|
334
392
|
<td>${maxLatency.toFixed(1)}</td>
|
|
335
|
-
<td
|
|
336
|
-
<td>${
|
|
337
|
-
<td>${
|
|
393
|
+
<td>${avgDns.toFixed(2)} ms</td>
|
|
394
|
+
<td>${avgTls.toFixed(2)} ms</td>
|
|
395
|
+
<td>${apdexScore.toFixed(2)}</td>
|
|
338
396
|
<td>${errorRate}%</td>
|
|
339
397
|
</tr>
|
|
340
398
|
</tbody>
|
|
@@ -343,7 +401,7 @@ try {
|
|
|
343
401
|
</body>
|
|
344
402
|
</html>`;
|
|
345
403
|
fs.writeFileSync(htmlOutputPath, htmlContent, "utf-8");
|
|
346
|
-
console.log(`\u2728 \x1B[32mHTML Dashboard with
|
|
404
|
+
console.log(`\u2728 \x1B[32mHTML Dashboard with multi-layered protocol tracking saved to:\x1B[0m ${htmlOutputPath}
|
|
347
405
|
`);
|
|
348
406
|
} catch (error) {
|
|
349
407
|
console.error("Execution error:", error);
|
|
Binary file
|