blaze-performance-tester 3.1.58 → 3.1.61

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
@@ -1,8 +1,6 @@
1
- #!/usr/bin/env node
1
+ #!/usr/bin/env ts-node
2
2
 
3
3
  // cli.ts
4
- import { Command } from "commander";
5
- import chalk from "chalk";
6
4
  import { createRequire } from "module";
7
5
  import * as path from "path";
8
6
  import { fileURLToPath } from "url";
@@ -136,7 +134,8 @@ var blazeCore;
136
134
  try {
137
135
  blazeCore = require2(nativeBindingPath);
138
136
  } catch (e) {
139
- console.error(chalk.red(`\u274C Failed to load native C++ bindings from ${nativeBindingPath}`));
137
+ console.error(`\u274C Failed to load native C++ bindings from ${nativeBindingPath}`);
138
+ process.exit(1);
140
139
  }
141
140
  var mathUtils = {
142
141
  mean: (arr) => arr.length === 0 ? 0 : arr.reduce((p, c) => p + c, 0) / arr.length,
@@ -152,46 +151,6 @@ var mathUtils = {
152
151
  return sorted[Math.max(0, index)];
153
152
  }
154
153
  };
155
- function getMockRegionalData() {
156
- return [
157
- { zone: "us-east-1", location: "N. Virginia", latencyAvg: 24, p99: 68, errorRate: 0.02, status: "optimal" },
158
- { zone: "eu-central-1", location: "Frankfurt", latencyAvg: 42, p99: 115, errorRate: 0.14, status: "stable" },
159
- { zone: "ap-south-1", location: "Mumbai", latencyAvg: 88, p99: 210, errorRate: 0.85, status: "elevated" },
160
- { zone: "ap-northeast-1", location: "Tokyo", latencyAvg: 55, p99: 130, errorRate: 0.05, status: "stable" },
161
- { zone: "sa-east-1", location: "S\xE3o Paulo", latencyAvg: 112, p99: 285, errorRate: 1.2, status: "critical" }
162
- ];
163
- }
164
- function renderStatusBadge(status) {
165
- switch (status) {
166
- case "optimal":
167
- return chalk.green("\u{1F7E2} OPTIMAL");
168
- case "stable":
169
- return chalk.green("\u{1F7E2} STABLE");
170
- case "elevated":
171
- return chalk.yellow("\u{1F7E1} ELEVATED");
172
- case "critical":
173
- return chalk.red("\u{1F534} CRITICAL");
174
- default:
175
- return chalk.gray("\u26AA UNKNOWN");
176
- }
177
- }
178
- function renderGeographicHeatmap(regions) {
179
- console.log(chalk.bold.cyan("\n============================================================"));
180
- console.log(chalk.bold.cyan(" BLAZE: GEOGRAPHIC LATENCY HEATMAP & MATRIX "));
181
- console.log(chalk.bold.cyan("============================================================\n"));
182
- console.log(
183
- `${chalk.bold("Zone".padEnd(16))} | ${chalk.bold("Location".padEnd(14))} | ${chalk.bold("Avg (ms)".padEnd(10))} | ${chalk.bold("P99 (ms)".padEnd(10))} | ${chalk.bold("Error Rate".padEnd(12))} | ${chalk.bold("Status")}`
184
- );
185
- console.log("-".repeat(78));
186
- for (const r of regions) {
187
- const errorColor = r.errorRate > 1 ? chalk.red : r.errorRate > 0.5 ? chalk.yellow : chalk.green;
188
- const latencyColor = r.latencyAvg > 100 ? chalk.yellow : chalk.white;
189
- console.log(
190
- `${r.zone.padEnd(16)} | ${r.location.padEnd(14)} | ${latencyColor(String(r.latencyAvg).padEnd(10))} | ${String(r.p99).padEnd(10)} | ${errorColor(`${r.errorRate.toFixed(2)}%`).padEnd(20)} | ${renderStatusBadge(r.status)}`
191
- );
192
- }
193
- console.log("\n");
194
- }
195
154
  function getLoadMultiplier(elapsedMs, rampUpMs, steadyMs, rampDownMs) {
196
155
  const totalDurationMs = rampUpMs + steadyMs + rampDownMs;
197
156
  if (elapsedMs < rampUpMs && rampUpMs > 0) {
@@ -209,64 +168,20 @@ function loadBaselineData(filePath) {
209
168
  try {
210
169
  const resolved = path.resolve(filePath);
211
170
  if (fs.existsSync(resolved)) {
212
- console.log(chalk.blue(`\u{1F4C1} Loaded baseline comparison telemetry from: ${resolved}`));
171
+ console.log(`\u{1F4C1} Loaded baseline comparison telemetry from: ${resolved}`);
213
172
  return JSON.parse(fs.readFileSync(resolved, "utf-8"));
214
173
  }
215
174
  } catch (e) {
216
- console.error(chalk.red(`\u274C Failed to parse baseline telemetry file: ${e}`));
175
+ console.error(`\u274C Failed to parse baseline telemetry file: ${e}`);
217
176
  }
218
177
  return null;
219
178
  }
220
- function calculateSeoImpactMetrics(avgLatencyMs) {
221
- const baseLineOptimalMs = 200;
222
- if (avgLatencyMs <= baseLineOptimalMs) {
223
- return { trafficLoss: 0, status: "Excellent", crawlPenalty: "None", color: "#10b981" };
224
- }
225
- const delayFactor = avgLatencyMs - baseLineOptimalMs;
226
- const trafficLoss = Math.min(94, Math.floor(delayFactor / 1200 * 100));
227
- let status = "Healthy";
228
- let crawlPenalty = "Minimal impact on indexing rates.";
229
- let color = "#10b981";
230
- if (trafficLoss >= 50) {
231
- status = "Critical Exposure";
232
- crawlPenalty = "Severe penalty. Googlebot will heavily restrict crawl budgets due to timeout risks.";
233
- color = "#ef4444";
234
- } else if (trafficLoss >= 20) {
235
- status = "Moderate Danger";
236
- crawlPenalty = "Delayed indexation. Core Web Vital thresholds are officially breached.";
237
- color = "#f97316";
238
- } else if (trafficLoss > 5) {
239
- status = "Minor Impact";
240
- crawlPenalty = "Slightly elevated bounce trends could impact highly volatile rankings.";
241
- color = "#eab308";
242
- }
243
- return { trafficLoss, status, crawlPenalty, color };
244
- }
245
- function computeHealthScoreValue(apdex, errorRate, p95Latency, maxAllowedLatency) {
246
- const apdexComponent = apdex * 50;
247
- const errorComponent = Math.max(0, 1 - errorRate) * 30;
248
- const latencyRatio = p95Latency / maxAllowedLatency;
249
- const latencyComponent = Math.max(0, 1 - Math.min(1, latencyRatio)) * 20;
250
- return Math.min(100, Math.max(0, Math.round(apdexComponent + errorComponent + latencyComponent)));
251
- }
252
- function getFallbackClusterLogs() {
253
- const logs = [];
254
- const add = (msg, count) => {
255
- for (let i = 0; i < count; i++) logs.push(`[2026-07-08T12:08:18.000Z] ${msg}`);
256
- };
257
- add("JsonWebTokenError: jwt expired at JMT.verify (\\app\\node_modules\\jsonwebtoken\\index.js:5)", 37);
258
- add("Error: ECONNREFUSED 127.0.0.1:5432 at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1)", 33);
259
- add("TypeError: Cannot read properties of undefined (reading 'config_id') at Object.execute (\\app\\dist\\handler.js:42:19)", 31);
260
- add("HTTP/1.1 504 Gateway Timeout on POST /api/v1/checkout - upstream socket drop after 15000ms", 25);
261
- add("HTTP/1.1 504 Gateway Timeout on POST /api/v1/checkout - upstream socket drop after 30000ms", 19);
262
- return logs;
263
- }
264
179
  async function generateGeminiRCA(history, finalSummary, errorLogs) {
265
180
  const apiKey = process.env.GEMINI_API_KEY;
266
181
  if (!apiKey) {
267
182
  return `<span style="color: #ef4444;">\u26A0\uFE0F Gemini API Key missing. Export GEMINI_API_KEY to enable automated 2.5 Flash RCA analysis.</span>`;
268
183
  }
269
- console.log(chalk.magenta("\u{1F9E0} Querying Gemini 2.5 Flash for Advanced Root Cause Analysis..."));
184
+ console.log("\u{1F9E0} Querying Gemini 2.5 Flash for Advanced Root Cause Analysis...");
270
185
  const formattedHistory = history.map(
271
186
  (h) => `Threads: ${h.threads} VUs | Throughput: ${h.throughput.toFixed(1)} req/s | Avg Latency: ${h.avgLatency.toFixed(1)}ms | Errors: ${(h.errorRate * 100).toFixed(2)}% | Apdex: ${h.apdex.toFixed(2)}`
272
187
  ).join("\n");
@@ -322,97 +237,127 @@ CRITICAL: Return ONLY plain paragraph text. Do not use markdown headers (###). I
322
237
  }
323
238
  return candidateText.replace(/\*\*(.*?)\*\*/g, "<strong>$1</strong>").replace(/\n/g, "<br>");
324
239
  } catch (error) {
325
- console.error(chalk.red("\u274C Gemini API processing breakdown failure:"), error);
240
+ console.error("\u274C Gemini API processing breakdown failure:", error);
326
241
  return `<span style="color: #f87171;">Failed to generate AI diagnosis framework: ${error.message || error}</span>`;
327
242
  }
328
243
  }
329
- function generateSimulationData(threads, durationSec, maxAllowedLatencyMs, rampUpSec = 0, rampDownSec = 0) {
330
- const data = [];
331
- const totalRequests = Math.max(15, threads * durationSec * 30);
332
- const startTime = Date.now();
333
- const rampUpMs = rampUpSec * 1e3;
334
- const steadyMs = durationSec * 1e3;
335
- const rampDownMs = rampDownSec * 1e3;
336
- const totalTestMs = rampUpMs + steadyMs + rampDownMs;
337
- const targetThresholdBreak = Math.max(5, Math.floor(maxAllowedLatencyMs * 0.05));
338
- const errorPool = getFallbackClusterLogs();
339
- for (let i = 0; i < totalRequests; i++) {
340
- const offsetMs = Math.random() * totalTestMs;
341
- const loadFactor = getLoadMultiplier(offsetMs, rampUpMs, steadyMs, rampDownMs);
342
- if (loadFactor <= 0) continue;
343
- const effectiveThreads = Math.max(1, threads * loadFactor);
344
- const isBreached = effectiveThreads > targetThresholdBreak;
345
- const stressFactor = isBreached ? Math.pow(effectiveThreads / targetThresholdBreak, 1.5) : 1;
346
- const isError = Math.random() < (isBreached ? 0.05 : 1e-3);
347
- const baseLatency = (25 + Math.random() * 35) * stressFactor;
348
- let errorMessage;
349
- let statusCode = 200;
350
- if (isError) {
351
- const targetResponseCodes = [400, 401, 403, 404, 429, 500, 502, 503, 504];
352
- statusCode = targetResponseCodes[Math.floor(Math.random() * targetResponseCodes.length)];
353
- errorMessage = errorPool[Math.floor(Math.random() * errorPool.length)];
244
+ async function executeTestPipeline(config) {
245
+ if (!blazeCore || typeof blazeCore.runCorrelatedTransaction !== "function") {
246
+ console.error("\u274C Error: runCorrelatedTransaction function is missing from the compiled binary bindings.");
247
+ return;
248
+ }
249
+ const transactionalScenario = [
250
+ {
251
+ name: "Fetch Target Anti-Forgery Nonce",
252
+ url: "https://httpbin.org/json",
253
+ method: "GET",
254
+ body: null
255
+ },
256
+ {
257
+ name: "Perform Contextual Post Action",
258
+ url: "https://httpbin.org/post?verification=${csrf_token}",
259
+ method: "POST",
260
+ body: JSON.stringify({
261
+ data: "performance_payload",
262
+ security_token: "${csrf_token}"
263
+ })
354
264
  }
355
- data.push({
356
- durationMs: isError ? baseLatency * 0.1 : baseLatency,
357
- timestampMs: startTime + offsetMs,
358
- dnsTimeMs: 1 + Math.random() * 0.9,
359
- tcpTimeMs: 4 + Math.random() * 1.5,
360
- tlsTimeMs: 6 + Math.random() * 1.8,
361
- statusCode,
362
- errorMessage
363
- });
265
+ ];
266
+ console.log(`Launching automated script transaction analysis for: ${config.targetScript}`);
267
+ const sanitizedSteps = transactionalScenario.map((step) => ({
268
+ ...step,
269
+ body: typeof step.body === "string" ? step.body : step.body ? JSON.stringify(step.body) : ""
270
+ }));
271
+ const success = await blazeCore.runCorrelatedTransaction(sanitizedSteps);
272
+ if (success) {
273
+ console.log("Pipeline run complete. Parameter tracking successfully mitigated breaking changes.");
364
274
  }
365
- return data.sort((a, b) => a.timestampMs - b.timestampMs);
366
275
  }
367
- function processMetricsTelemetry(requests, durationSec) {
368
- const totalRequests = requests.length;
369
- const durations = requests.map((r) => r.durationMs);
370
- const avgLatencyMs = mathUtils.mean(durations);
371
- const stdDevMs = mathUtils.stdDev(durations, avgLatencyMs);
372
- const p95LatencyMs = mathUtils.percentile(durations, 95);
373
- const avgDnsMs = mathUtils.mean(requests.map((r) => r.dnsTimeMs || 0));
374
- const avgTcpMs = mathUtils.mean(requests.map((r) => r.tcpTimeMs || 0));
375
- const avgTlsMs = mathUtils.mean(requests.map((r) => r.tlsTimeMs || 0));
376
- const avgTtfbMs = avgDnsMs + avgTcpMs + avgTlsMs + avgLatencyMs * 0.3;
377
- let c1xx = 0, c2xx = 0, c3xx = 0, c4xx = 0, c5xx = 0;
378
- const codeCounts = { 400: 0, 401: 0, 403: 0, 404: 0, 429: 0, 500: 0, 502: 0, 503: 0, 504: 0 };
379
- [400, 401, 403, 404, 429, 500, 502, 503, 504].forEach((c) => codeCounts[c] = 0);
380
- requests.forEach((r) => {
381
- if (r.statusCode >= 100 && r.statusCode < 200) c1xx++;
382
- else if (r.statusCode >= 200 && r.statusCode < 300) c2xx++;
383
- else if (r.statusCode >= 300 && r.statusCode < 400) c3xx++;
384
- else if (r.statusCode >= 400 && r.statusCode < 500) c4xx++;
385
- else if (r.statusCode >= 500) c5xx++;
386
- if (r.statusCode in codeCounts) {
387
- codeCounts[r.statusCode]++;
276
+ async function main() {
277
+ const args = process.argv.slice(2);
278
+ if (args.length === 0 || args.includes("--help") || args.includes("-h")) {
279
+ printUsage();
280
+ return;
281
+ }
282
+ const config = parseArguments(args);
283
+ if (config.isCorrelate) {
284
+ await executeTestPipeline(config);
285
+ }
286
+ if (config.isAgentic) {
287
+ await runIntelligentAgenticStressTest(config);
288
+ } else {
289
+ await runStandardStressTest(config);
290
+ }
291
+ }
292
+ function parseArguments(args) {
293
+ const targetScript = path.resolve(args[0] || ".");
294
+ const isAgentic = args.includes("--agentic");
295
+ const isCorrelate = args.includes("--correlate");
296
+ const isSeo = args.includes("--seo");
297
+ const clusterLogs = !args.includes("--no-cluster-logs");
298
+ let threads = 10;
299
+ let durationSec = 10;
300
+ let rampUpSec = 0;
301
+ let rampDownSec = 0;
302
+ let targetApdex = 0.85;
303
+ let targetErrorRate = 0.01;
304
+ let maxThreads = 300;
305
+ let maxAllowedLatencyMs = 800;
306
+ let outputHtml = "blaze-dashboard.html";
307
+ let baselinePath = null;
308
+ const threadsIdx = args.indexOf("--threads");
309
+ if (threadsIdx !== -1) threads = parseInt(args[threadsIdx + 1], 10);
310
+ const durationIdx = args.indexOf("--duration");
311
+ if (durationIdx !== -1) durationSec = parseInt(args[durationIdx + 1], 10);
312
+ const rampUpIdx = args.indexOf("--ramp-up");
313
+ if (rampUpIdx !== -1) rampUpSec = parseInt(args[rampUpIdx + 1], 10);
314
+ const rampDownIdx = args.indexOf("--ramp-down");
315
+ if (rampDownIdx !== -1) rampDownSec = parseInt(args[rampDownIdx + 1], 10);
316
+ const apdexIdx = args.indexOf("--target-apdex");
317
+ if (apdexIdx !== -1) targetApdex = parseFloat(apdexIdx + 1);
318
+ const errorIdx = args.indexOf("--target-error");
319
+ if (errorIdx !== -1) targetErrorRate = parseFloat(args[errorIdx + 1]);
320
+ const maxThreadsIdx = args.indexOf("--max-threads");
321
+ if (maxThreadsIdx !== -1) maxThreads = parseInt(args[maxThreadsIdx + 1], 10);
322
+ const outputIdx = args.indexOf("--output");
323
+ if (outputIdx !== -1) outputHtml = args[outputIdx + 1];
324
+ const baselineIdx = args.indexOf("--baseline");
325
+ if (baselineIdx !== -1) baselinePath = args[baselineIdx + 1];
326
+ const positionalNums = args.slice(1).filter((arg) => !arg.startsWith("-")).map(Number).filter((n) => !isNaN(n));
327
+ if (positionalNums.length > 0 && threadsIdx === -1 && !isAgentic) threads = positionalNums[0];
328
+ if (positionalNums.length > 1 && durationIdx === -1 && !isAgentic) durationSec = positionalNums[1];
329
+ if (positionalNums.length > 2 && errorIdx === -1 && !isAgentic) targetErrorRate = positionalNums[2] / 100;
330
+ if (isAgentic) {
331
+ const agenticIdx = args.indexOf("--agentic");
332
+ const trailingArgs = args.slice(agenticIdx + 1).filter((arg) => !arg.startsWith("--"));
333
+ if (trailingArgs[0]) maxThreads = parseInt(trailingArgs[0], 10);
334
+ if (trailingArgs[1]) {
335
+ let rawLatency = parseFloat(trailingArgs[1]);
336
+ if (rawLatency < 50) {
337
+ maxAllowedLatencyMs = rawLatency * 1e3;
338
+ } else {
339
+ maxAllowedLatencyMs = rawLatency;
340
+ }
388
341
  }
389
- });
390
- const errorCount = c4xx + c5xx;
391
- const errorRate = totalRequests === 0 ? 0 : errorCount / totalRequests;
392
- const T = 50;
393
- const satisfied = requests.filter((r) => r.durationMs <= T && r.statusCode < 400).length;
394
- const tolerating = requests.filter((r) => r.durationMs > T && r.durationMs <= T * 4 && r.statusCode < 400).length;
395
- const apdexScore = totalRequests === 0 ? 0 : (satisfied + tolerating / 2) / totalRequests;
396
- const bandwidthMb = totalRequests * 1.2 / durationSec / 10;
342
+ if (trailingArgs[2]) targetErrorRate = parseFloat(trailingArgs[2]) / 100;
343
+ }
397
344
  return {
398
- totalRequests,
399
- requestsPerSecond: totalRequests / durationSec,
400
- avgLatencyMs,
401
- stdDevMs,
402
- p95LatencyMs,
403
- errorRate,
404
- apdexScore,
405
- c1xx,
406
- c2xx,
407
- c3xx,
408
- c4xx,
409
- c5xx,
410
- avgDnsMs,
411
- avgTcpMs,
412
- avgTlsMs,
413
- avgTtfbMs,
414
- bandwidthMb,
415
- codeCounts
345
+ targetScript,
346
+ isAgentic,
347
+ isCorrelate,
348
+ isSeo,
349
+ clusterLogs,
350
+ threads,
351
+ durationSec,
352
+ rampUpSec,
353
+ rampDownSec,
354
+ targetApdex,
355
+ targetErrorRate,
356
+ maxThreads,
357
+ stepSize: 15,
358
+ maxAllowedLatencyMs,
359
+ outputHtml,
360
+ baselinePath
416
361
  };
417
362
  }
418
363
  async function runBlazeCoreEngine(config) {
@@ -436,62 +381,40 @@ async function runBlazeCoreEngine(config) {
436
381
  }, 1e3);
437
382
  });
438
383
  }
439
- function printMatrixDashboard(m, threads) {
440
- const pad = (val, size) => String(val).padEnd(size).substring(0, size);
441
- console.log(`-----------------------------------------------------------------------------------------`);
442
- console.log(`| Threads | Samples | Avg Latency | P95 Latency | Throughput | Error Rate | Apdex |`);
443
- console.log(`-----------------------------------------------------------------------------------------`);
444
- console.log(`| ${pad(threads, 7)} | ${pad(m.totalRequests, 9)} | ${pad(m.avgLatencyMs.toFixed(1) + "ms", 11)} | ${pad(m.p95LatencyMs.toFixed(1) + "ms", 11)} | ${pad(m.requestsPerSecond.toFixed(0) + "/s", 10)} | ${pad((m.errorRate * 100).toFixed(2) + "%", 10)} | ${pad(m.apdexScore.toFixed(2), 9)} |`);
445
- console.log(`-----------------------------------------------------------------------------------------`);
446
- }
447
- function generateFinalAgentReport(history, score) {
448
- if (history.length === 0) return;
449
- const peakThroughput = Math.max(...history.map((h) => h.throughput));
450
- const cleanRuns = history.filter((h) => h.apdex >= 0.85 && h.errorRate <= 0.01);
451
- const maxSafeThreads = cleanRuns.length > 0 ? cleanRuns[cleanRuns.length - 1].threads : history[0].threads;
452
- console.log(chalk.bold.green("\n======================================================="));
453
- console.log(chalk.bold.cyan("\u{1F9E0} INTELLIGENT AUTONOMOUS LOAD AGENT FINAL REPORT"));
454
- console.log(chalk.bold.green("======================================================="));
455
- console.log(`\u{1F7E2} Unified Blaze Health Score : ${score}/100`);
456
- console.log(`\u{1F3C6} Recommended Max Safe Concurrency : ${maxSafeThreads} allocation threads`);
457
- console.log(`\u{1F4A5} Infrastructure Failure Boundary : ${history[history.length - 1].threads} concurrency allocation`);
458
- console.log(`\u26A1 Peak Achieved Cluster Velocity : ${peakThroughput.toFixed(0)} req/sec`);
459
- console.log(chalk.bold.green("=======================================================\n"));
460
- }
461
- async function executeTestPipeline(config) {
462
- if (!blazeCore || typeof blazeCore.runCorrelatedTransaction !== "function") {
463
- console.error(chalk.red("\u274C Error: runCorrelatedTransaction function is missing from the compiled binary bindings."));
464
- return;
384
+ function calculateSeoImpactMetrics(avgLatencyMs) {
385
+ const baseLineOptimalMs = 200;
386
+ if (avgLatencyMs <= baseLineOptimalMs) {
387
+ return { trafficLoss: 0, status: "Excellent", crawlPenalty: "None", color: "#10b981" };
465
388
  }
466
- const transactionalScenario = [
467
- {
468
- name: "Fetch Target Anti-Forgery Nonce",
469
- url: "https://httpbin.org/json",
470
- method: "GET",
471
- body: null
472
- },
473
- {
474
- name: "Perform Contextual Post Action",
475
- url: "https://httpbin.org/post?verification=${csrf_token}",
476
- method: "POST",
477
- body: JSON.stringify({
478
- data: "performance_payload",
479
- security_token: "${csrf_token}"
480
- })
481
- }
482
- ];
483
- console.log(chalk.blue(`Launching automated script transaction analysis for: ${config.targetScript}`));
484
- const sanitizedSteps = transactionalScenario.map((step) => ({
485
- ...step,
486
- body: typeof step.body === "string" ? step.body : step.body ? JSON.stringify(step.body) : ""
487
- }));
488
- const success = await blazeCore.runCorrelatedTransaction(sanitizedSteps);
489
- if (success) {
490
- console.log(chalk.green("Pipeline run complete. Parameter tracking successfully mitigated breaking changes."));
389
+ const delayFactor = avgLatencyMs - baseLineOptimalMs;
390
+ const trafficLoss = Math.min(94, Math.floor(delayFactor / 1200 * 100));
391
+ let status = "Healthy";
392
+ let crawlPenalty = "Minimal impact on indexing rates.";
393
+ let color = "#10b981";
394
+ if (trafficLoss >= 50) {
395
+ status = "Critical Exposure";
396
+ crawlPenalty = "Severe penalty. Googlebot will heavily restrict crawl budgets due to timeout risks.";
397
+ color = "#ef4444";
398
+ } else if (trafficLoss >= 20) {
399
+ status = "Moderate Danger";
400
+ crawlPenalty = "Delayed indexation. Core Web Vital thresholds are officially breached.";
401
+ color = "#f97316";
402
+ } else if (trafficLoss > 5) {
403
+ status = "Minor Impact";
404
+ crawlPenalty = "Slightly elevated bounce trends could impact highly volatile rankings.";
405
+ color = "#eab308";
491
406
  }
407
+ return { trafficLoss, status, crawlPenalty, color };
408
+ }
409
+ function computeHealthScoreValue(apdex, errorRate, p95Latency, maxAllowedLatency) {
410
+ const apdexComponent = apdex * 50;
411
+ const errorComponent = Math.max(0, 1 - errorRate) * 30;
412
+ const latencyRatio = p95Latency / maxAllowedLatency;
413
+ const latencyComponent = Math.max(0, 1 - Math.min(1, latencyRatio)) * 20;
414
+ return Math.min(100, Math.max(0, Math.round(apdexComponent + errorComponent + latencyComponent)));
492
415
  }
493
416
  async function runIntelligentAgenticStressTest(config) {
494
- console.log(chalk.magenta("\u{1F680} Initializing Intelligent Autonomous Load Agent..."));
417
+ console.log("\u{1F680} Initializing Intelligent Autonomous Load Agent...");
495
418
  const history = [];
496
419
  let aggregateErrorLogs = [];
497
420
  let lastRawRequests = [];
@@ -505,7 +428,7 @@ async function runIntelligentAgenticStressTest(config) {
505
428
  let verdictReason = "The system successfully scaled and remained stable within parameters up to maximum configured capacity allocations.";
506
429
  let saturationKneePoint = null;
507
430
  while (currentThreads <= config.maxThreads && isStable) {
508
- console.log(chalk.yellow(`\u{1F916} [Agent Decision]: Testing execution tier at ${currentThreads} concurrent threads...`));
431
+ console.log(`\u{1F916} [Agent Decision]: Testing execution tier at ${currentThreads} concurrent threads...`);
509
432
  const { metrics, rawErrors, rawRequests } = await runBlazeCoreEngine({ ...config, threads: currentThreads });
510
433
  if (config.clusterLogs) {
511
434
  aggregateErrorLogs = aggregateErrorLogs.concat(rawErrors);
@@ -598,7 +521,7 @@ async function runIntelligentAgenticStressTest(config) {
598
521
  if (config.isSeo) {
599
522
  const finalLat = finalState.avgLatency || finalSummaryCards.ttfb;
600
523
  const seo = calculateSeoImpactMetrics(finalLat);
601
- console.log(chalk.bold.yellow(`\u{1F50E} [SEO Impact Report]: Target latency under stress (${finalLat.toFixed(1)}ms) triggers a predicted Search Visibility Loss of -${seo.trafficLoss}% [Status: ${seo.status}].`));
524
+ console.log(`\u{1F50E} [SEO Impact Report]: Target latency under stress (${finalLat.toFixed(1)}ms) triggers a predicted Search Visibility Loss of -${seo.trafficLoss}% [Status: ${seo.status}].`);
602
525
  }
603
526
  const breakdownRates = {};
604
527
  Object.keys(globalCodeCounts).forEach((codeStr) => {
@@ -609,11 +532,11 @@ async function runIntelligentAgenticStressTest(config) {
609
532
  exportHtmlDashboard(history, config, verdictReason, semanticReport, { total1xx, total2xx, total3xx, total4xx, total5xx, breakdownRates }, finalSummaryCards, lastRawRequests, geminiAnalysisHtml, baselineData);
610
533
  }
611
534
  async function runStandardStressTest(config) {
612
- console.log(chalk.blue(`\u{1F3CB}\uFE0F Running Standard Stress Test [Threads: ${config.threads} | Duration: ${config.durationSec}s | RampUp: ${config.rampUpSec}s | RampDown: ${config.rampDownSec}s]`));
535
+ console.log(`\u{1F3CB}\uFE0F Running Standard Stress Test [Threads: ${config.threads} | Duration: ${config.durationSec}s | RampUp: ${config.rampUpSec}s | RampDown: ${config.rampDownSec}s]`);
613
536
  const { metrics, rawErrors, rawRequests } = await runBlazeCoreEngine(config);
614
537
  printMatrixDashboard(metrics, config.threads);
615
538
  const healthScore = computeHealthScoreValue(metrics.apdexScore, metrics.errorRate, metrics.p95LatencyMs, config.maxAllowedLatencyMs);
616
- console.log(chalk.green(`\u{1F49A} Unified Blaze Health Score: ${healthScore}/100`));
539
+ console.log(`\u{1F49A} Unified Blaze Health Score: ${healthScore}/100`);
617
540
  const history = [{
618
541
  threads: config.threads,
619
542
  avgLatency: metrics.avgLatencyMs,
@@ -650,7 +573,7 @@ async function runStandardStressTest(config) {
650
573
  const geminiAnalysisHtml = await generateGeminiRCA(history, finalSummaryCards, rawErrors.length > 0 ? rawErrors : getFallbackClusterLogs());
651
574
  if (config.isSeo) {
652
575
  const seo = calculateSeoImpactMetrics(metrics.avgLatencyMs);
653
- console.log(chalk.bold.yellow(`\u{1F50E} [SEO Impact Report]: Target latency (${metrics.avgLatencyMs.toFixed(1)}ms) triggers a predicted Search Visibility Loss of -${seo.trafficLoss}% [Status: ${seo.status}].`));
576
+ console.log(`\u{1F50E} [SEO Impact Report]: Target latency (${metrics.avgLatencyMs.toFixed(1)}ms) triggers a predicted Search Visibility Loss of -${seo.trafficLoss}% [Status: ${seo.status}].`);
654
577
  }
655
578
  const breakdownRates = {};
656
579
  Object.keys(metrics.codeCounts).forEach((codeStr) => {
@@ -667,6 +590,129 @@ async function runStandardStressTest(config) {
667
590
  breakdownRates
668
591
  }, finalSummaryCards, rawRequests, geminiAnalysisHtml, baselineData);
669
592
  }
593
+ function getFallbackClusterLogs() {
594
+ const logs = [];
595
+ const add = (msg, count) => {
596
+ for (let i = 0; i < count; i++) logs.push(`[2026-07-08T12:08:18.000Z] ${msg}`);
597
+ };
598
+ add("JsonWebTokenError: jwt expired at JMT.verify (\\app\\node_modules\\jsonwebtoken\\index.js:5)", 37);
599
+ add("Error: ECONNREFUSED 127.0.0.1:5432 at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1)", 33);
600
+ add("TypeError: Cannot read properties of undefined (reading 'config_id') at Object.execute (\\app\\dist\\handler.js:42:19)", 31);
601
+ add("HTTP/1.1 504 Gateway Timeout on POST /api/v1/checkout - upstream socket drop after 15000ms", 25);
602
+ add("HTTP/1.1 504 Gateway Timeout on POST /api/v1/checkout - upstream socket drop after 30000ms", 19);
603
+ return logs;
604
+ }
605
+ function generateSimulationData(threads, durationSec, maxAllowedLatencyMs, rampUpSec = 0, rampDownSec = 0) {
606
+ const data = [];
607
+ const totalRequests = Math.max(15, threads * durationSec * 30);
608
+ const startTime = Date.now();
609
+ const rampUpMs = rampUpSec * 1e3;
610
+ const steadyMs = durationSec * 1e3;
611
+ const rampDownMs = rampDownSec * 1e3;
612
+ const totalTestMs = rampUpMs + steadyMs + rampDownMs;
613
+ const targetThresholdBreak = Math.max(5, Math.floor(maxAllowedLatencyMs * 0.05));
614
+ const errorPool = getFallbackClusterLogs();
615
+ for (let i = 0; i < totalRequests; i++) {
616
+ const offsetMs = Math.random() * totalTestMs;
617
+ const loadFactor = getLoadMultiplier(offsetMs, rampUpMs, steadyMs, rampDownMs);
618
+ if (loadFactor <= 0) continue;
619
+ const effectiveThreads = Math.max(1, threads * loadFactor);
620
+ const isBreached = effectiveThreads > targetThresholdBreak;
621
+ const stressFactor = isBreached ? Math.pow(effectiveThreads / targetThresholdBreak, 1.5) : 1;
622
+ const isError = Math.random() < (isBreached ? 0.05 : 1e-3);
623
+ const baseLatency = (25 + Math.random() * 35) * stressFactor;
624
+ let errorMessage;
625
+ let statusCode = 200;
626
+ if (isError) {
627
+ const targetResponseCodes = [400, 401, 403, 404, 429, 500, 502, 503, 504];
628
+ statusCode = targetResponseCodes[Math.floor(Math.random() * targetResponseCodes.length)];
629
+ errorMessage = errorPool[Math.floor(Math.random() * errorPool.length)];
630
+ }
631
+ data.push({
632
+ durationMs: isError ? baseLatency * 0.1 : baseLatency,
633
+ timestampMs: startTime + offsetMs,
634
+ dnsTimeMs: 1 + Math.random() * 0.9,
635
+ tcpTimeMs: 4 + Math.random() * 1.5,
636
+ tlsTimeMs: 6 + Math.random() * 1.8,
637
+ statusCode,
638
+ errorMessage
639
+ });
640
+ }
641
+ return data.sort((a, b) => a.timestampMs - b.timestampMs);
642
+ }
643
+ function processMetricsTelemetry(requests, durationSec) {
644
+ const totalRequests = requests.length;
645
+ const durations = requests.map((r) => r.durationMs);
646
+ const avgLatencyMs = mathUtils.mean(durations);
647
+ const stdDevMs = mathUtils.stdDev(durations, avgLatencyMs);
648
+ const p95LatencyMs = mathUtils.percentile(durations, 95);
649
+ const avgDnsMs = mathUtils.mean(requests.map((r) => r.dnsTimeMs || 0));
650
+ const avgTcpMs = mathUtils.mean(requests.map((r) => r.tcpTimeMs || 0));
651
+ const avgTlsMs = mathUtils.mean(requests.map((r) => r.tlsTimeMs || 0));
652
+ const avgTtfbMs = avgDnsMs + avgTcpMs + avgTlsMs + avgLatencyMs * 0.3;
653
+ let c1xx = 0, c2xx = 0, c3xx = 0, c4xx = 0, c5xx = 0;
654
+ const codeCounts = { 400: 0, 401: 0, 403: 0, 404: 0, 429: 0, 500: 0, 502: 0, 503: 0, 504: 0 };
655
+ [400, 401, 403, 404, 429, 500, 502, 503, 504].forEach((c) => codeCounts[c] = 0);
656
+ requests.forEach((r) => {
657
+ if (r.statusCode >= 100 && r.statusCode < 200) c1xx++;
658
+ else if (r.statusCode >= 200 && r.statusCode < 300) c2xx++;
659
+ else if (r.statusCode >= 300 && r.statusCode < 400) c3xx++;
660
+ else if (r.statusCode >= 400 && r.statusCode < 500) c4xx++;
661
+ else if (r.statusCode >= 500) c5xx++;
662
+ if (r.statusCode in codeCounts) {
663
+ codeCounts[r.statusCode]++;
664
+ }
665
+ });
666
+ const errorCount = c4xx + c5xx;
667
+ const errorRate = totalRequests === 0 ? 0 : errorCount / totalRequests;
668
+ const T = 50;
669
+ const satisfied = requests.filter((r) => r.durationMs <= T && r.statusCode < 400).length;
670
+ const tolerating = requests.filter((r) => r.durationMs > T && r.durationMs <= T * 4 && r.statusCode < 400).length;
671
+ const apdexScore = totalRequests === 0 ? 0 : (satisfied + tolerating / 2) / totalRequests;
672
+ const bandwidthMb = totalRequests * 1.2 / durationSec / 10;
673
+ return {
674
+ totalRequests,
675
+ requestsPerSecond: totalRequests / durationSec,
676
+ avgLatencyMs,
677
+ stdDevMs,
678
+ p95LatencyMs,
679
+ errorRate,
680
+ apdexScore,
681
+ c1xx,
682
+ c2xx,
683
+ c3xx,
684
+ c4xx,
685
+ c5xx,
686
+ avgDnsMs,
687
+ avgTcpMs,
688
+ avgTlsMs,
689
+ avgTtfbMs,
690
+ bandwidthMb,
691
+ codeCounts
692
+ };
693
+ }
694
+ function printMatrixDashboard(m, threads) {
695
+ const pad = (val, size) => String(val).padEnd(size).substring(0, size);
696
+ console.log(`-----------------------------------------------------------------------------------------`);
697
+ console.log(`| Threads | Samples | Avg Latency | P95 Latency | Throughput | Error Rate | Apdex |`);
698
+ console.log(`-----------------------------------------------------------------------------------------`);
699
+ console.log(`| ${pad(threads, 7)} | ${pad(m.totalRequests, 9)} | ${pad(m.avgLatencyMs.toFixed(1) + "ms", 11)} | ${pad(m.p95LatencyMs.toFixed(1) + "ms", 11)} | ${pad(m.requestsPerSecond.toFixed(0) + "/s", 10)} | ${pad((m.errorRate * 100).toFixed(2) + "%", 10)} | ${pad(m.apdexScore.toFixed(2), 9)} |`);
700
+ console.log(`-----------------------------------------------------------------------------------------`);
701
+ }
702
+ function generateFinalAgentReport(history, score) {
703
+ if (history.length === 0) return;
704
+ const peakThroughput = Math.max(...history.map((h) => h.throughput));
705
+ const cleanRuns = history.filter((h) => h.apdex >= 0.85 && h.errorRate <= 0.01);
706
+ const maxSafeThreads = cleanRuns.length > 0 ? cleanRuns[cleanRuns.length - 1].threads : history[0].threads;
707
+ console.log("\n=======================================================");
708
+ console.log("\u{1F9E0} INTELLIGENT AUTONOMOUS LOAD AGENT FINAL REPORT");
709
+ console.log("=======================================================");
710
+ console.log(`\u{1F49A} Unified Blaze Health Score : ${score}/100`);
711
+ console.log(`\u{1F3C6} Recommended Max Safe Concurrency : ${maxSafeThreads} allocation threads`);
712
+ console.log(`\u{1F4A5} Infrastructure Failure Boundary : ${history[history.length - 1].threads} concurrency allocation`);
713
+ console.log(`\u26A1 Peak Achieved Cluster Velocity : ${peakThroughput.toFixed(0)} req/sec`);
714
+ console.log("=======================================================\n");
715
+ }
670
716
  function exportHtmlDashboard(history, config, verdictReason, semanticReport, responseMatrix, cards, rawRequests = [], geminiAnalysisHtml = "", baselineData = null) {
671
717
  const summaryArtifactPath = config.outputHtml.replace(/\.html$/, "-summary.json");
672
718
  try {
@@ -1157,7 +1203,7 @@ function exportHtmlDashboard(history, config, verdictReason, semanticReport, res
1157
1203
  const feedback = document.getElementById('nlpQueryFeedback');
1158
1204
 
1159
1205
  let filterFn = (row, data) => true;
1160
- const numMatch = q.match(/(\\d+(?:\\.\\d+)?)/);
1206
+ const numMatch = q.match(/(d+(?:.d+)?)/);
1161
1207
  const targetNum = numMatch ? parseFloat(numMatch[1]) : null;
1162
1208
 
1163
1209
  const isGreater = q.includes('>') || q.includes('greater') || q.includes('above') || q.includes('more');
@@ -1385,69 +1431,14 @@ function exportHtmlDashboard(history, config, verdictReason, semanticReport, res
1385
1431
  </script></body></html>`;
1386
1432
  try {
1387
1433
  fs.writeFileSync(config.outputHtml, htmlContent, "utf-8");
1388
- console.log(chalk.bold.green(`\u{1F4CA} Standalone Dashboard exported successfully to: ${path.resolve(config.outputHtml)}`));
1434
+ console.log(`\u{1F4CA} Standalone Dashboard exported successfully to: ${path.resolve(config.outputHtml)}`);
1389
1435
  } catch (err) {
1390
- console.error(chalk.red(`\u274C Failed to write HTML output dashboard: ${err}`));
1436
+ console.error(`\u274C Failed to write HTML output dashboard: ${err}`);
1391
1437
  }
1392
1438
  }
1393
- var program = new Command();
1394
- program.name("blaze").description("Blaze CLI - High-performance distributed load and latency tester").version("1.0.0");
1395
- program.command("run").description("Run a distributed load or local performance/stress test pipeline").argument("[script]", "Target script or directory path to evaluate", ".").option("-u, --url <url>", "Target simulation URL for distributed load routing", "https://api.example.com/health").option("-r, --regions <zones>", "Comma-separated list of target AWS/Cloud zones to simulate (e.g. us-east-1,eu-central-1,ap-south-1)").option("-t, --threads <threads>", "Number of parallel virtual users (VUs)", "10").option("-d, --duration <seconds>", "Test duration in seconds", "10").option("--ramp-up <seconds>", "Ramp-up duration in seconds", "0").option("--ramp-down <seconds>", "Ramp-down duration in seconds", "0").option("--target-apdex <score>", "Target Apdex satisfaction index (0.0 to 1.0)", "0.85").option("--target-error <rate>", "Target maximum allowed error rate (e.g. 0.01 for 1%)", "0.01").option("--max-threads <max>", "Maximum parallel threads for dynamic agentic scaling tests", "300").option("--max-allowed-latency <ms>", "SLA violation latency threshold (in milliseconds)", "800").option("-o, --output <filename>", "Destination path of the exported interactive HTML telemetry dashboard", "blaze-dashboard.html").option("--baseline <filepath>", "Reference JSON summary data to run automatic regression comparisons").option("--agentic", "Deploy the autonomous cognitive agent to auto-scale load until failure limits are hit", false).option("--correlate", "Enable transaction tracking pipelines (mitigates CSRF/nonce state mutations)", false).option("--seo", "Model SEO bounce rate, googlebot budget indexing penalties, and visibility impact", false).option("--no-cluster-logs", "Disable structural failure pattern clustering").action(async (script, options) => {
1396
- const parsedThreads = parseInt(options.threads, 10);
1397
- const parsedDuration = parseInt(options.duration, 10);
1398
- const parsedRampUp = parseInt(options.rampUp, 10) || 0;
1399
- const parsedRampDown = parseInt(options.rampDown, 10) || 0;
1400
- const parsedApdex = parseFloat(options.targetApdex);
1401
- const parsedError = parseFloat(options.targetError);
1402
- const parsedMaxThreads = parseInt(options.maxThreads, 10);
1403
- const parsedMaxLatencyRaw = parseFloat(options.maxAllowedLatency || "800");
1404
- const parsedMaxLatency = parsedMaxLatencyRaw < 50 ? parsedMaxLatencyRaw * 1e3 : parsedMaxLatencyRaw;
1405
- const config = {
1406
- targetScript: path.resolve(script || "."),
1407
- isAgentic: !!options.agentic,
1408
- isCorrelate: !!options.correlate,
1409
- isSeo: !!options.seo,
1410
- clusterLogs: options.clusterLogs !== false,
1411
- threads: parsedThreads,
1412
- durationSec: parsedDuration,
1413
- rampUpSec: parsedRampUp,
1414
- rampDownSec: parsedRampDown,
1415
- targetApdex: parsedApdex,
1416
- targetErrorRate: parsedError,
1417
- maxThreads: parsedMaxThreads,
1418
- stepSize: 15,
1419
- maxAllowedLatencyMs: parsedMaxLatency,
1420
- outputHtml: options.output,
1421
- baselinePath: options.baseline || null
1422
- };
1423
- if (options.regions) {
1424
- console.log(chalk.blue(`
1425
- Initializing Blaze load test simulation against ${chalk.bold(options.url)}...`));
1426
- console.log(chalk.gray(`Target regions: ${options.regions}`));
1427
- console.log(chalk.gray(`Duration: ${options.duration}s
1428
- `));
1429
- await new Promise((resolve2) => {
1430
- setTimeout(() => {
1431
- const allRegions = getMockRegionalData();
1432
- const requestedZones = options.regions.split(",").map((z) => z.trim());
1433
- const filteredRegions = allRegions.filter((r) => requestedZones.includes(r.zone));
1434
- renderGeographicHeatmap(filteredRegions.length > 0 ? filteredRegions : allRegions);
1435
- console.log(chalk.gray(`Executing localized system stress verification pipelines...
1436
- `));
1437
- resolve2(null);
1438
- }, 1e3);
1439
- });
1440
- }
1441
- if (config.isCorrelate) {
1442
- await executeTestPipeline(config);
1443
- }
1444
- if (config.isAgentic) {
1445
- await runIntelligentAgenticStressTest(config);
1446
- } else {
1447
- await runStandardStressTest(config);
1448
- }
1449
- });
1450
- program.command("heatmap").description("Display real-time geographic latency heatmap breakdown").action(() => {
1451
- renderGeographicHeatmap(getMockRegionalData());
1452
- });
1453
- program.parse(process.argv);
1439
+ function printUsage() {
1440
+ console.log(`Blaze Core Performance Test CLI Engine
1441
+ Options:
1442
+ --threads <count> | --duration <seconds> | --baseline <json_file> | --output <html_file>`);
1443
+ }
1444
+ main().catch(console.error);
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "blaze-performance-tester",
3
- "version": "3.1.58",
3
+ "version": "3.1.61",
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",