blaze-performance-tester 3.0.36 → 3.0.37

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 CHANGED
@@ -209,7 +209,7 @@ async function runBlazeCoreEngine(config) {
209
209
  const steadyStateRequests = rawRequests.slice(warmUpCutoff);
210
210
  const metrics = processMetricsTelemetry(steadyStateRequests.length > 0 ? steadyStateRequests : rawRequests, config.durationSec);
211
211
  const rawErrors = rawRequests.filter((r) => r.errorMessage).map((r) => r.errorMessage);
212
- resolve2({ metrics, rawErrors });
212
+ resolve2({ metrics, rawErrors, rawRequests: steadyStateRequests.length > 0 ? steadyStateRequests : rawRequests });
213
213
  }, 1e3);
214
214
  });
215
215
  }
@@ -217,6 +217,7 @@ async function runIntelligentAgenticStressTest(config) {
217
217
  console.log("\u{1F680} Initializing Intelligent Autonomous Load Agent...");
218
218
  const history = [];
219
219
  let aggregateErrorLogs = [];
220
+ let lastRawRequests = [];
220
221
  let total1xx = 0, total2xx = 0, total3xx = 0, total4xx = 0, total5xx = 0;
221
222
  let globalMetricsAccumulator = { dns: [], tcp: [], tls: [], ttfb: [], latencies: [], bandwidths: [] };
222
223
  let currentThreads = Math.min(config.maxThreads, Math.max(5, Math.floor(config.maxThreads * 0.2)));
@@ -226,10 +227,11 @@ async function runIntelligentAgenticStressTest(config) {
226
227
  let saturationKneePoint = null;
227
228
  while (currentThreads <= config.maxThreads && isStable) {
228
229
  console.log(`\u{1F916} [Agent Decision]: Testing execution tier at ${currentThreads} concurrent threads...`);
229
- const { metrics, rawErrors } = await runBlazeCoreEngine({ ...config, threads: currentThreads });
230
+ const { metrics, rawErrors, rawRequests } = await runBlazeCoreEngine({ ...config, threads: currentThreads });
230
231
  if (config.clusterLogs) {
231
232
  aggregateErrorLogs = aggregateErrorLogs.concat(rawErrors);
232
233
  }
234
+ lastRawRequests = rawRequests;
233
235
  total1xx += metrics.c1xx;
234
236
  total2xx += metrics.c2xx;
235
237
  total3xx += metrics.c3xx;
@@ -303,11 +305,11 @@ async function runIntelligentAgenticStressTest(config) {
303
305
  saturationKneePoint: saturationKneePoint || history[history.length - 1]?.threads || 50
304
306
  };
305
307
  generateFinalAgentReport(history);
306
- exportHtmlDashboard(history, config, verdictReason, semanticReport, { total1xx, total2xx, total3xx, total4xx, total5xx }, finalSummaryCards);
308
+ exportHtmlDashboard(history, config, verdictReason, semanticReport, { total1xx, total2xx, total3xx, total4xx, total5xx }, finalSummaryCards, lastRawRequests);
307
309
  }
308
310
  async function runStandardStressTest(config) {
309
311
  console.log(`\u{1F3CB}\uFE0F Running Standard Stress Test [Threads: ${config.threads} | Duration: ${config.durationSec}s]`);
310
- const { metrics, rawErrors } = await runBlazeCoreEngine(config);
312
+ const { metrics, rawErrors, rawRequests } = await runBlazeCoreEngine(config);
311
313
  printMatrixDashboard(metrics, config.threads);
312
314
  const history = [{
313
315
  threads: config.threads,
@@ -345,7 +347,7 @@ async function runStandardStressTest(config) {
345
347
  total3xx: metrics.c3xx,
346
348
  total4xx: metrics.c4xx,
347
349
  total5xx: metrics.c5xx
348
- }, finalSummaryCards);
350
+ }, finalSummaryCards, rawRequests);
349
351
  }
350
352
  function getFallbackClusterLogs() {
351
353
  const logs = [];
@@ -454,7 +456,7 @@ function generateFinalAgentReport(history) {
454
456
  console.log(`\u26A1 Peak Achieved Cluster Velocity : ${peakThroughput.toFixed(0)} req/sec`);
455
457
  console.log("=======================================================\n");
456
458
  }
457
- function exportHtmlDashboard(history, config, verdictReason, semanticReport, responseMatrix, cards) {
459
+ function exportHtmlDashboard(history, config, verdictReason, semanticReport, responseMatrix, cards, rawRequests = []) {
458
460
  const labels = history.map((h, i) => `${i + 1}s`);
459
461
  const successRequestsData = history.map((h) => h.successRequests);
460
462
  const failedWorkloadsData = history.map((h) => h.failedRequests);
@@ -466,6 +468,11 @@ function exportHtmlDashboard(history, config, verdictReason, semanticReport, res
466
468
  const estimatedMonthlyCost = (cards.throughput * 0.045 * 24 * 30).toFixed(2);
467
469
  const recommendedCpuCores = Math.max(2, Math.ceil(cards.saturationKneePoint / 75));
468
470
  const recommendedRamGb = recommendedCpuCores * 2;
471
+ const firstTimestamp = rawRequests[0]?.timestampMs || Date.now();
472
+ const scatterPoints = rawRequests.slice(0, 180).map((r) => ({
473
+ x: Number(((r.timestampMs - firstTimestamp) / 1e3).toFixed(2)),
474
+ y: Number(((r.dnsTimeMs || 0) + (r.tcpTimeMs || 0) + (r.tlsTimeMs || 0) + r.durationMs * 0.3).toFixed(1))
475
+ }));
469
476
  let logClustersHtml = "";
470
477
  if (semanticReport) {
471
478
  const totalLogCount = semanticReport.clusters.reduce((sum, c) => sum + c.count, 0);
@@ -603,7 +610,7 @@ function exportHtmlDashboard(history, config, verdictReason, semanticReport, res
603
610
  .badge-5xx { background: rgba(220, 38, 38, 0.2); color: #f87171; }
604
611
  .matrix-value { font-size: 1rem; font-weight: bold; color: #ffffff; }
605
612
 
606
- .charts-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1.5rem; margin-bottom: 2rem; }
613
+ .charts-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 1.5rem; margin-bottom: 2rem; }
607
614
  .graph-card { background: #131c2e; border: 1px solid #1e293b; border-radius: 8px; padding: 1.5rem; }
608
615
  .graph-title { font-size: 1.1rem; font-weight: 700; color: #ffffff; margin-bottom: 1.2rem; display: flex; align-items: center; gap: 0.5rem; }
609
616
 
@@ -710,6 +717,13 @@ function exportHtmlDashboard(history, config, verdictReason, semanticReport, res
710
717
  <canvas id="statusDonutChart"></canvas>
711
718
  </div>
712
719
  </div>
720
+
721
+ <div class="graph-card">
722
+ <div class="graph-title">\u{1F4C8} Time-to-First-Byte Scatter Plot</div>
723
+ <div style="height: 280px; position: relative;">
724
+ <canvas id="ttfbScatterChart"></canvas>
725
+ </div>
726
+ </div>
713
727
  </div>
714
728
 
715
729
  <div class="card">
@@ -861,6 +875,30 @@ function exportHtmlDashboard(history, config, verdictReason, semanticReport, res
861
875
  cutout: '65%'
862
876
  }
863
877
  });
878
+
879
+ new Chart(document.getElementById('ttfbScatterChart'), {
880
+ type: 'scatter',
881
+ data: {
882
+ datasets: [{
883
+ label: 'Request Processing Delay',
884
+ data: ${JSON.stringify(scatterPoints)},
885
+ backgroundColor: '#a855f7',
886
+ pointRadius: 4,
887
+ pointHoverRadius: 6
888
+ }]
889
+ },
890
+ options: {
891
+ responsive: true,
892
+ maintainAspectRatio: false,
893
+ plugins: {
894
+ legend: { position: 'top', labels: { color: '#94a3b8', font: { size: 11 } } }
895
+ },
896
+ scales: {
897
+ x: { grid: { color: '#1e293b' }, ticks: { color: '#64748b' }, title: { display: true, text: 'Time offset (s)', color: '#64748b' } },
898
+ y: { grid: { color: '#1e293b' }, ticks: { color: '#64748b' }, title: { display: true, text: 'TTFB / Delay (ms)', color: '#64748b' } }
899
+ }
900
+ }
901
+ });
864
902
  </script></body></html>`;
865
903
  try {
866
904
  fs.writeFileSync(config.outputHtml, htmlContent, "utf-8");
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "blaze-performance-tester",
3
- "version": "3.0.36",
3
+ "version": "3.0.37",
4
4
  "description": "A high-performance, multi-threaded load testing engine built with Rust and QuickJS.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",