@calltelemetry/cli 0.4.21 → 0.4.23
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/index.js +1 -1
- package/dist/lib/loadtest-stats.d.ts +36 -5
- package/dist/lib/loadtest-stats.d.ts.map +1 -1
- package/dist/lib/loadtest-stats.js +32 -2
- package/dist/lib/loadtest-stats.js.map +1 -1
- package/dist/lib/loadtest.d.ts.map +1 -1
- package/dist/lib/loadtest.js +54 -15
- package/dist/lib/loadtest.js.map +1 -1
- package/dist/lib/rpc.d.ts +6 -0
- package/dist/lib/rpc.d.ts.map +1 -1
- package/dist/lib/rpc.js +50 -3
- package/dist/lib/rpc.js.map +1 -1
- package/dist/ui/components/BrailleChart.d.ts +23 -0
- package/dist/ui/components/BrailleChart.d.ts.map +1 -0
- package/dist/ui/components/BrailleChart.js +94 -0
- package/dist/ui/components/BrailleChart.js.map +1 -0
- package/dist/ui/components/Histogram.d.ts +12 -0
- package/dist/ui/components/Histogram.d.ts.map +1 -0
- package/dist/ui/components/Histogram.js +42 -0
- package/dist/ui/components/Histogram.js.map +1 -0
- package/dist/ui/components/LineChart.d.ts +17 -0
- package/dist/ui/components/LineChart.d.ts.map +1 -0
- package/dist/ui/components/LineChart.js +47 -0
- package/dist/ui/components/LineChart.js.map +1 -0
- package/dist/ui/components/Sparkline.d.ts +3 -1
- package/dist/ui/components/Sparkline.d.ts.map +1 -1
- package/dist/ui/components/Sparkline.js +14 -2
- package/dist/ui/components/Sparkline.js.map +1 -1
- package/dist/ui/components/StatusCodeBar.d.ts +10 -0
- package/dist/ui/components/StatusCodeBar.d.ts.map +1 -0
- package/dist/ui/components/StatusCodeBar.js +38 -0
- package/dist/ui/components/StatusCodeBar.js.map +1 -0
- package/dist/ui/components/index.d.ts +4 -0
- package/dist/ui/components/index.d.ts.map +1 -1
- package/dist/ui/components/index.js +4 -0
- package/dist/ui/components/index.js.map +1 -1
- package/dist/ui/views/LoadTestRunView.d.ts.map +1 -1
- package/dist/ui/views/LoadTestRunView.js +12 -23
- package/dist/ui/views/LoadTestRunView.js.map +1 -1
- package/dist/ui/views/LoadTestSummaryView.d.ts.map +1 -1
- package/dist/ui/views/LoadTestSummaryView.js +11 -36
- package/dist/ui/views/LoadTestSummaryView.js.map +1 -1
- package/dist/ui/views/MainMenu.d.ts.map +1 -1
- package/dist/ui/views/MainMenu.js +2 -2
- package/dist/ui/views/MainMenu.js.map +1 -1
- package/package.json +3 -1
package/dist/index.js
CHANGED
|
@@ -38,6 +38,21 @@ export interface RecentResponse {
|
|
|
38
38
|
/** Timestamp (elapsed seconds when received) */
|
|
39
39
|
elapsed: number;
|
|
40
40
|
}
|
|
41
|
+
/** A latency histogram bucket. */
|
|
42
|
+
export interface LatencyBucket {
|
|
43
|
+
label: string;
|
|
44
|
+
min: number;
|
|
45
|
+
max: number;
|
|
46
|
+
count: number;
|
|
47
|
+
}
|
|
48
|
+
/** Bucket boundary thresholds in ms. */
|
|
49
|
+
export declare const LATENCY_BUCKET_BOUNDS: number[];
|
|
50
|
+
/** Human-readable labels for each bucket. */
|
|
51
|
+
export declare const LATENCY_BUCKET_LABELS: string[];
|
|
52
|
+
/** Assign a latency value to a bucket index. */
|
|
53
|
+
export declare function assignBucket(latencyMs: number): number;
|
|
54
|
+
/** Create an empty set of latency buckets. */
|
|
55
|
+
export declare function createEmptyBuckets(): LatencyBucket[];
|
|
41
56
|
export interface LoadTestSnapshot {
|
|
42
57
|
/** Elapsed seconds */
|
|
43
58
|
elapsed: number;
|
|
@@ -60,14 +75,20 @@ export interface LoadTestSnapshot {
|
|
|
60
75
|
p99: number;
|
|
61
76
|
max: number;
|
|
62
77
|
mean: number;
|
|
63
|
-
/** Rate history for
|
|
78
|
+
/** Rate history for charts (last N intervals) */
|
|
64
79
|
rateHistory: number[];
|
|
65
|
-
/** Latency p99 history for
|
|
80
|
+
/** Latency p99 history for charts (last N intervals) */
|
|
66
81
|
latencyHistory: number[];
|
|
67
|
-
/**
|
|
82
|
+
/** Latency p50 history for charts (last N intervals) */
|
|
83
|
+
p50History: number[];
|
|
84
|
+
/** Latency p95 history for charts (last N intervals) */
|
|
85
|
+
p95History: number[];
|
|
86
|
+
/** Error rate history for charts (last N intervals, 0-100%) */
|
|
68
87
|
errorRateHistory: number[];
|
|
69
88
|
/** Last N individual responses for live log display */
|
|
70
89
|
recentResponses: RecentResponse[];
|
|
90
|
+
/** Latency distribution histogram */
|
|
91
|
+
latencyBuckets: LatencyBucket[];
|
|
71
92
|
}
|
|
72
93
|
export interface LoadTestResults {
|
|
73
94
|
config: LoadTestConfig;
|
|
@@ -101,6 +122,14 @@ export interface LoadTestResults {
|
|
|
101
122
|
max: number;
|
|
102
123
|
min: number;
|
|
103
124
|
};
|
|
125
|
+
/** Full rate history for summary charts (every interval) */
|
|
126
|
+
rateHistory: number[];
|
|
127
|
+
/** Full p50 latency history for summary charts */
|
|
128
|
+
latencyP50History: number[];
|
|
129
|
+
/** Full p99 latency history for summary charts */
|
|
130
|
+
latencyP99History: number[];
|
|
131
|
+
/** Final latency distribution histogram */
|
|
132
|
+
latencyBuckets: LatencyBucket[];
|
|
104
133
|
}
|
|
105
134
|
export interface CurriPolicy {
|
|
106
135
|
id: number;
|
|
@@ -124,10 +153,12 @@ export interface ResourceSample {
|
|
|
124
153
|
export interface ResourceHistory {
|
|
125
154
|
samples: ResourceSample[];
|
|
126
155
|
}
|
|
127
|
-
/** Maximum number of rate samples kept in the
|
|
128
|
-
export declare const MAX_RATE_HISTORY =
|
|
156
|
+
/** Maximum number of rate samples kept in the live chart history. */
|
|
157
|
+
export declare const MAX_RATE_HISTORY = 60;
|
|
129
158
|
/** Maximum number of recent responses kept for the live log. */
|
|
130
159
|
export declare const MAX_RECENT_RESPONSES = 25;
|
|
160
|
+
/** Maximum entries for full-run history (summary charts). 10 minutes. */
|
|
161
|
+
export declare const MAX_FULL_HISTORY = 600;
|
|
131
162
|
/** Compute percentile from a sorted array of numbers. */
|
|
132
163
|
export declare function percentile(sorted: number[], p: number): number;
|
|
133
164
|
/** Build a LoadTestSnapshot from live tick data. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loadtest-stats.d.ts","sourceRoot":"","sources":["../../src/lib/loadtest-stats.ts"],"names":[],"mappings":"AAAA,+CAA+C;AAE/C,MAAM,WAAW,cAAc;IAC7B,uDAAuD;IACvD,GAAG,EAAE,MAAM,CAAC;IACZ,yCAAyC;IACzC,MAAM,EAAE,MAAM,CAAC;IACf,8BAA8B;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,iCAAiC;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,+BAA+B;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,iCAAiC;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,4CAA4C;IAC5C,aAAa,EAAE,MAAM,CAAC;IACtB,2CAA2C;IAC3C,YAAY,EAAE,MAAM,CAAC;IACrB,yCAAyC;IACzC,UAAU,EAAE,MAAM,CAAC;IACnB,yBAAyB;IACzB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,iCAAiC;AACjC,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AAED,+DAA+D;AAC/D,MAAM,WAAW,cAAc;IAC7B,gDAAgD;IAChD,MAAM,EAAE,MAAM,CAAC;IACf,0BAA0B;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,gDAAgD;IAChD,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,gBAAgB;IAC/B,sBAAsB;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,0CAA0C;IAC1C,kBAAkB,EAAE,MAAM,CAAC;IAC3B,wBAAwB;IACxB,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,iEAAiE;IACjE,gBAAgB,EAAE,MAAM,CAAC;IACzB,iCAAiC;IACjC,WAAW,EAAE,gBAAgB,CAAC;IAC9B,qEAAqE;IACrE,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,+DAA+D;IAC/D,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,
|
|
1
|
+
{"version":3,"file":"loadtest-stats.d.ts","sourceRoot":"","sources":["../../src/lib/loadtest-stats.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,8 +1,35 @@
|
|
|
1
1
|
/** Types for the CURRI load testing engine. */
|
|
2
|
-
/**
|
|
3
|
-
export const
|
|
2
|
+
/** Bucket boundary thresholds in ms. */
|
|
3
|
+
export const LATENCY_BUCKET_BOUNDS = [0, 1, 2, 5, 10, 20, 50, 100, 500, Infinity];
|
|
4
|
+
/** Human-readable labels for each bucket. */
|
|
5
|
+
export const LATENCY_BUCKET_LABELS = [
|
|
6
|
+
'0-1ms', '1-2ms', '2-5ms', '5-10ms', '10-20ms',
|
|
7
|
+
'20-50ms', '50-100ms', '100-500ms', '500ms+',
|
|
8
|
+
];
|
|
9
|
+
/** Assign a latency value to a bucket index. */
|
|
10
|
+
export function assignBucket(latencyMs) {
|
|
11
|
+
for (let i = 0; i < LATENCY_BUCKET_BOUNDS.length - 1; i++) {
|
|
12
|
+
if (latencyMs < LATENCY_BUCKET_BOUNDS[i + 1]) {
|
|
13
|
+
return i;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
return LATENCY_BUCKET_BOUNDS.length - 2;
|
|
17
|
+
}
|
|
18
|
+
/** Create an empty set of latency buckets. */
|
|
19
|
+
export function createEmptyBuckets() {
|
|
20
|
+
return LATENCY_BUCKET_LABELS.map((label, i) => ({
|
|
21
|
+
label,
|
|
22
|
+
min: LATENCY_BUCKET_BOUNDS[i],
|
|
23
|
+
max: LATENCY_BUCKET_BOUNDS[i + 1],
|
|
24
|
+
count: 0,
|
|
25
|
+
}));
|
|
26
|
+
}
|
|
27
|
+
/** Maximum number of rate samples kept in the live chart history. */
|
|
28
|
+
export const MAX_RATE_HISTORY = 60;
|
|
4
29
|
/** Maximum number of recent responses kept for the live log. */
|
|
5
30
|
export const MAX_RECENT_RESPONSES = 25;
|
|
31
|
+
/** Maximum entries for full-run history (summary charts). 10 minutes. */
|
|
32
|
+
export const MAX_FULL_HISTORY = 600;
|
|
6
33
|
/** Compute percentile from a sorted array of numbers. */
|
|
7
34
|
export function percentile(sorted, p) {
|
|
8
35
|
if (sorted.length === 0)
|
|
@@ -36,8 +63,11 @@ export function buildSnapshot(counter, elapsed, rateHistory, latencyData, totals
|
|
|
36
63
|
mean: latencyData.mean,
|
|
37
64
|
rateHistory: updatedRateHistory,
|
|
38
65
|
latencyHistory: updatedLatencyHistory,
|
|
66
|
+
p50History: [],
|
|
67
|
+
p95History: [],
|
|
39
68
|
errorRateHistory: updatedErrorRateHistory,
|
|
40
69
|
recentResponses: [],
|
|
70
|
+
latencyBuckets: createEmptyBuckets(),
|
|
41
71
|
};
|
|
42
72
|
}
|
|
43
73
|
//# sourceMappingURL=loadtest-stats.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loadtest-stats.js","sourceRoot":"","sources":["../../src/lib/loadtest-stats.ts"],"names":[],"mappings":"AAAA,+CAA+C;
|
|
1
|
+
{"version":3,"file":"loadtest-stats.js","sourceRoot":"","sources":["../../src/lib/loadtest-stats.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loadtest.d.ts","sourceRoot":"","sources":["../../src/lib/loadtest.ts"],"names":[],"mappings":"AAAA,kDAAkD;AAIlD,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,gBAAgB,
|
|
1
|
+
{"version":3,"file":"loadtest.d.ts","sourceRoot":"","sources":["../../src/lib/loadtest.ts"],"names":[],"mappings":"AAAA,kDAAkD;AAIlD,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,gBAAgB,EAAmD,MAAM,qBAAqB,CAAC;AAO9I,YAAY,EAAE,cAAc,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAE7F;8FAC8F;AAC9F,eAAO,MAAM,iBAAiB,qBAAqB,CAAC;AAEpD;oFACoF;AACpF,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAErD;AAKD,MAAM,WAAW,cAAc;IAC7B,qDAAqD;IACrD,OAAO,EAAE,OAAO,CAAC,eAAe,CAAC,CAAC;IAClC,gCAAgC;IAChC,IAAI,EAAE,MAAM,IAAI,CAAC;CAClB;AAED,4DAA4D;AAC5D,wBAAgB,aAAa,CAC3B,MAAM,EAAE,cAAc,EACtB,UAAU,EAAE,CAAC,QAAQ,EAAE,gBAAgB,KAAK,IAAI,GAC/C,cAAc,CA0RhB"}
|
package/dist/lib/loadtest.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/** CURRI load test engine wrapping autocannon. */
|
|
2
2
|
import { createRequire } from 'module';
|
|
3
3
|
import { buildCurriXmlFromConfig } from './curri-xml.js';
|
|
4
|
-
import { MAX_RATE_HISTORY, MAX_RECENT_RESPONSES, percentile } from './loadtest-stats.js';
|
|
4
|
+
import { MAX_RATE_HISTORY, MAX_RECENT_RESPONSES, MAX_FULL_HISTORY, percentile, assignBucket, createEmptyBuckets } from './loadtest-stats.js';
|
|
5
5
|
// autocannon is CJS — use createRequire for ESM compatibility
|
|
6
6
|
const require = createRequire(import.meta.url);
|
|
7
7
|
const autocannon = require('autocannon');
|
|
@@ -35,10 +35,18 @@ export function startLoadTest(config, onProgress) {
|
|
|
35
35
|
const latencyWindow = [];
|
|
36
36
|
let latencyWindowPos = 0; // Ring buffer position
|
|
37
37
|
let latencyWindowFull = false;
|
|
38
|
-
// History arrays for
|
|
38
|
+
// History arrays for live charts (capped at MAX_RATE_HISTORY)
|
|
39
39
|
const rateHistory = [];
|
|
40
40
|
const latencyHistory = [];
|
|
41
|
+
const p50History = [];
|
|
42
|
+
const p95History = [];
|
|
41
43
|
const errorRateHistory = [];
|
|
44
|
+
// Full-run history for summary charts (capped at MAX_FULL_HISTORY)
|
|
45
|
+
const rateHistoryFull = [];
|
|
46
|
+
const latencyP50HistoryFull = [];
|
|
47
|
+
const latencyP99HistoryFull = [];
|
|
48
|
+
// Latency distribution buckets (cumulative over entire test)
|
|
49
|
+
const latencyBuckets = createEmptyBuckets();
|
|
42
50
|
// Ring buffer of recent individual responses
|
|
43
51
|
const recentResponses = [];
|
|
44
52
|
function addLatencySample(ms) {
|
|
@@ -50,6 +58,9 @@ export function startLoadTest(config, onProgress) {
|
|
|
50
58
|
latencyWindowFull = true;
|
|
51
59
|
}
|
|
52
60
|
latencyWindowPos = (latencyWindowPos + 1) % LATENCY_WINDOW_SIZE;
|
|
61
|
+
// Assign to histogram bucket
|
|
62
|
+
const bucketIdx = assignBucket(ms);
|
|
63
|
+
latencyBuckets[bucketIdx].count++;
|
|
53
64
|
}
|
|
54
65
|
function computeLatencyStats() {
|
|
55
66
|
const samples = latencyWindowFull
|
|
@@ -83,23 +94,28 @@ export function startLoadTest(config, onProgress) {
|
|
|
83
94
|
const targetUrl = `${config.url}/api/policy?api_key=${config.apiKey}`;
|
|
84
95
|
const instance = autocannon({
|
|
85
96
|
url: targetUrl,
|
|
86
|
-
method: 'POST',
|
|
87
|
-
headers: { 'content-type': 'application/xml' },
|
|
88
97
|
connections: config.connections,
|
|
89
98
|
duration: config.duration,
|
|
90
99
|
overallRate: config.rate,
|
|
91
100
|
timeout: 10,
|
|
92
101
|
// Accept self-signed certs (appliances use Caddy with auto-generated certs)
|
|
93
102
|
tlsOptions: { rejectUnauthorized: false },
|
|
94
|
-
setupRequest
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
+
// IMPORTANT: setupRequest MUST be inside requests[] — autocannon's run.js
|
|
104
|
+
// silently drops top-level setupRequest when creating per-client URL objects.
|
|
105
|
+
// Using requests[] ensures setupRequest is called for every request.
|
|
106
|
+
requests: [{
|
|
107
|
+
method: 'POST',
|
|
108
|
+
headers: { 'content-type': 'application/xml' },
|
|
109
|
+
setupRequest(req) {
|
|
110
|
+
req.body = buildCurriXmlFromConfig({
|
|
111
|
+
callingNumber: config.callingNumber,
|
|
112
|
+
calledNumber: config.calledNumber,
|
|
113
|
+
deviceName: config.deviceName,
|
|
114
|
+
triggerType: config.triggerType,
|
|
115
|
+
});
|
|
116
|
+
return req;
|
|
117
|
+
},
|
|
118
|
+
}],
|
|
103
119
|
});
|
|
104
120
|
// Suppress autocannon's built-in progress output
|
|
105
121
|
autocannon.track(instance, {
|
|
@@ -122,7 +138,7 @@ export function startLoadTest(config, onProgress) {
|
|
|
122
138
|
recentResponses.push({ status: statusCode, latencyMs: responseTime, elapsed });
|
|
123
139
|
if (recentResponses.length > MAX_RECENT_RESPONSES)
|
|
124
140
|
recentResponses.shift();
|
|
125
|
-
// Add to latency sliding window
|
|
141
|
+
// Add to latency sliding window + histogram bucket
|
|
126
142
|
addLatencySample(responseTime);
|
|
127
143
|
});
|
|
128
144
|
// Track connection-level errors (ECONNREFUSED, ECONNRESET, socket errors)
|
|
@@ -148,19 +164,35 @@ export function startLoadTest(config, onProgress) {
|
|
|
148
164
|
const requestsInInterval = value.counter;
|
|
149
165
|
// Compute live latency percentiles from sliding window
|
|
150
166
|
const latencyStats = computeLatencyStats();
|
|
151
|
-
// Update
|
|
167
|
+
// Update live chart histories (capped)
|
|
152
168
|
rateHistory.push(requestsInInterval);
|
|
153
169
|
if (rateHistory.length > MAX_RATE_HISTORY)
|
|
154
170
|
rateHistory.shift();
|
|
155
171
|
latencyHistory.push(latencyStats.p99);
|
|
156
172
|
if (latencyHistory.length > MAX_RATE_HISTORY)
|
|
157
173
|
latencyHistory.shift();
|
|
174
|
+
p50History.push(latencyStats.p50);
|
|
175
|
+
if (p50History.length > MAX_RATE_HISTORY)
|
|
176
|
+
p50History.shift();
|
|
177
|
+
p95History.push(latencyStats.p95);
|
|
178
|
+
if (p95History.length > MAX_RATE_HISTORY)
|
|
179
|
+
p95History.shift();
|
|
158
180
|
const intervalErrorRate = intervalRequests > 0
|
|
159
181
|
? (intervalErrors / intervalRequests) * 100
|
|
160
182
|
: 0;
|
|
161
183
|
errorRateHistory.push(intervalErrorRate);
|
|
162
184
|
if (errorRateHistory.length > MAX_RATE_HISTORY)
|
|
163
185
|
errorRateHistory.shift();
|
|
186
|
+
// Update full-run history for summary charts (capped at MAX_FULL_HISTORY)
|
|
187
|
+
rateHistoryFull.push(requestsInInterval);
|
|
188
|
+
if (rateHistoryFull.length > MAX_FULL_HISTORY)
|
|
189
|
+
rateHistoryFull.shift();
|
|
190
|
+
latencyP50HistoryFull.push(latencyStats.p50);
|
|
191
|
+
if (latencyP50HistoryFull.length > MAX_FULL_HISTORY)
|
|
192
|
+
latencyP50HistoryFull.shift();
|
|
193
|
+
latencyP99HistoryFull.push(latencyStats.p99);
|
|
194
|
+
if (latencyP99HistoryFull.length > MAX_FULL_HISTORY)
|
|
195
|
+
latencyP99HistoryFull.shift();
|
|
164
196
|
// Reset per-interval counters
|
|
165
197
|
intervalRequests = 0;
|
|
166
198
|
intervalErrors = 0;
|
|
@@ -181,8 +213,11 @@ export function startLoadTest(config, onProgress) {
|
|
|
181
213
|
mean: latencyStats.mean,
|
|
182
214
|
rateHistory: [...rateHistory],
|
|
183
215
|
latencyHistory: [...latencyHistory],
|
|
216
|
+
p50History: [...p50History],
|
|
217
|
+
p95History: [...p95History],
|
|
184
218
|
errorRateHistory: [...errorRateHistory],
|
|
185
219
|
recentResponses: [...recentResponses],
|
|
220
|
+
latencyBuckets: latencyBuckets.map(b => ({ ...b })),
|
|
186
221
|
};
|
|
187
222
|
onProgress(snapshot);
|
|
188
223
|
});
|
|
@@ -225,6 +260,10 @@ export function startLoadTest(config, onProgress) {
|
|
|
225
260
|
max: result.requests?.max ?? 0,
|
|
226
261
|
min: result.requests?.min ?? 0,
|
|
227
262
|
},
|
|
263
|
+
rateHistory: [...rateHistoryFull],
|
|
264
|
+
latencyP50History: [...latencyP50HistoryFull],
|
|
265
|
+
latencyP99History: [...latencyP99HistoryFull],
|
|
266
|
+
latencyBuckets: latencyBuckets.map(b => ({ ...b })),
|
|
228
267
|
});
|
|
229
268
|
});
|
|
230
269
|
instance.on('error', reject);
|
package/dist/lib/loadtest.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loadtest.js","sourceRoot":"","sources":["../../src/lib/loadtest.ts"],"names":[],"mappings":"AAAA,kDAAkD;AAElD,OAAO,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AACvC,OAAO,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AAEzD,OAAO,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"loadtest.js","sourceRoot":"","sources":["../../src/lib/loadtest.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/rpc.d.ts
CHANGED
|
@@ -7,12 +7,18 @@ export interface AppHealthDetail {
|
|
|
7
7
|
rpc: boolean;
|
|
8
8
|
dbConnected: boolean;
|
|
9
9
|
dbDirect: boolean;
|
|
10
|
+
curriProxy: boolean;
|
|
11
|
+
adminProxy: boolean;
|
|
12
|
+
sftp: boolean;
|
|
10
13
|
overall: 'healthy' | 'degraded' | 'down';
|
|
11
14
|
apiError?: string;
|
|
12
15
|
curriError?: string;
|
|
13
16
|
rpcError?: string;
|
|
14
17
|
dbError?: string;
|
|
15
18
|
dbDirectError?: string;
|
|
19
|
+
curriProxyError?: string;
|
|
20
|
+
adminProxyError?: string;
|
|
21
|
+
sftpError?: string;
|
|
16
22
|
}
|
|
17
23
|
export declare function getAppHealth(): Promise<AppHealthDetail>;
|
|
18
24
|
export declare function getReleaseBin(): string;
|
package/dist/lib/rpc.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rpc.d.ts","sourceRoot":"","sources":["../../src/lib/rpc.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"rpc.d.ts","sourceRoot":"","sources":["../../src/lib/rpc.ts"],"names":[],"mappings":"AAgBA,wBAAsB,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAGvD;AAED,wBAAsB,KAAK,IAAI,OAAO,CAAC,OAAO,CAAC,CAO9C;AAED,wBAAsB,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC,CAOpD;AAED,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,OAAO,CAAC;IACb,KAAK,EAAE,OAAO,CAAC;IACf,GAAG,EAAE,OAAO,CAAC;IACb,WAAW,EAAE,OAAO,CAAC;IACrB,QAAQ,EAAE,OAAO,CAAC;IAClB,UAAU,EAAE,OAAO,CAAC;IACpB,UAAU,EAAE,OAAO,CAAC;IACpB,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,SAAS,GAAG,UAAU,GAAG,MAAM,CAAC;IACzC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAsB,YAAY,IAAI,OAAO,CAAC,eAAe,CAAC,CAiI7D;AAED,wBAAgB,aAAa,IAAI,MAAM,CAEtC"}
|
package/dist/lib/rpc.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { execa } from 'execa';
|
|
1
2
|
import { composeExec } from './compose.js';
|
|
2
3
|
import { DB_USER, DB_NAME } from './db.js';
|
|
3
4
|
const RELEASE_BIN = '/home/app/onprem/bin/onprem';
|
|
@@ -37,7 +38,10 @@ export async function getAppHealth() {
|
|
|
37
38
|
let rpcError;
|
|
38
39
|
let dbError;
|
|
39
40
|
let dbDirectError;
|
|
40
|
-
|
|
41
|
+
let curriProxyError;
|
|
42
|
+
let adminProxyError;
|
|
43
|
+
let sftpError;
|
|
44
|
+
const [api, curri, rpc_ok, db, dbDirect, curriProxy, adminProxy, sftp] = await Promise.all([
|
|
41
45
|
(async () => {
|
|
42
46
|
try {
|
|
43
47
|
const result = await withTimeout(composeExec('web', ['curl', '-sf', 'http://127.0.0.1:4000/healthz'], { pipe: true }), TIMEOUT, 'Admin API health check');
|
|
@@ -88,13 +92,56 @@ export async function getAppHealth() {
|
|
|
88
92
|
return false;
|
|
89
93
|
}
|
|
90
94
|
})(),
|
|
95
|
+
// CURRI through Caddy (port 80) — runs on HOST, not in container
|
|
96
|
+
// Caddy routes /healthz on :80 to web:4080 (CURRI endpoint)
|
|
97
|
+
(async () => {
|
|
98
|
+
try {
|
|
99
|
+
await withTimeout(execa('curl', ['-sf', 'http://127.0.0.1:80/healthz'], { timeout: 5000 }), TIMEOUT, 'CURRI Proxy');
|
|
100
|
+
return true;
|
|
101
|
+
}
|
|
102
|
+
catch (err) {
|
|
103
|
+
curriProxyError = err.stderr?.trim() || err.message || 'CURRI proxy check failed';
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
106
|
+
})(),
|
|
107
|
+
// Admin through Caddy (port 443) — runs on HOST, not in container
|
|
108
|
+
// Caddy routes /api* on :443 to web:4000; -k for self-signed cert
|
|
109
|
+
(async () => {
|
|
110
|
+
try {
|
|
111
|
+
const r = await withTimeout(execa('curl', ['-sfk', '-o', '/dev/null', '-w', '%{http_code}', 'https://127.0.0.1:443/'], { timeout: 5000 }), TIMEOUT, 'Admin Proxy');
|
|
112
|
+
return r.stdout.trim() !== '000';
|
|
113
|
+
}
|
|
114
|
+
catch (err) {
|
|
115
|
+
adminProxyError = err.stderr?.trim() || err.message || 'Admin proxy check failed';
|
|
116
|
+
return false;
|
|
117
|
+
}
|
|
118
|
+
})(),
|
|
119
|
+
// SFTP daemon status via RPC
|
|
120
|
+
(async () => {
|
|
121
|
+
try {
|
|
122
|
+
const out = await withTimeout(rpc('case Cdrcisco.CTSFTPD.status() do {:error, :down} -> IO.puts("down"); _ -> IO.puts("ok") end'), TIMEOUT, 'SFTP');
|
|
123
|
+
return out.trim() === 'ok';
|
|
124
|
+
}
|
|
125
|
+
catch (err) {
|
|
126
|
+
sftpError = err.stderr?.trim() || err.message || 'SFTP check failed';
|
|
127
|
+
return false;
|
|
128
|
+
}
|
|
129
|
+
})(),
|
|
91
130
|
]);
|
|
131
|
+
// Core checks determine healthy/down; proxy + SFTP are supplementary
|
|
132
|
+
const coreAllPass = api && curri && rpc_ok && db && dbDirect;
|
|
133
|
+
const allPass = coreAllPass && curriProxy && adminProxy && sftp;
|
|
92
134
|
let overall = 'down';
|
|
93
|
-
if (
|
|
135
|
+
if (allPass)
|
|
94
136
|
overall = 'healthy';
|
|
95
137
|
else if (api || curri || rpc_ok || dbDirect)
|
|
96
138
|
overall = 'degraded';
|
|
97
|
-
return {
|
|
139
|
+
return {
|
|
140
|
+
api, curri, rpc: rpc_ok, dbConnected: db, dbDirect,
|
|
141
|
+
curriProxy, adminProxy, sftp,
|
|
142
|
+
overall, apiError, curriError, rpcError, dbError, dbDirectError,
|
|
143
|
+
curriProxyError, adminProxyError, sftpError,
|
|
144
|
+
};
|
|
98
145
|
}
|
|
99
146
|
export function getReleaseBin() {
|
|
100
147
|
return RELEASE_BIN;
|
package/dist/lib/rpc.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rpc.js","sourceRoot":"","sources":["../../src/lib/rpc.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAE3C,MAAM,WAAW,GAAG,6BAA6B,CAAC;AAElD,wCAAwC;AACxC,SAAS,WAAW,CAAI,OAAmB,EAAE,EAAU,EAAE,KAAa;IACpE,OAAO,OAAO,CAAC,IAAI,CAAC;QAClB,OAAO;QACP,IAAI,OAAO,CAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,CAC/B,UAAU,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,GAAG,KAAK,oBAAoB,EAAE,IAAI,CAAC,CAAC,EAAE,EAAE,CAAC,CAC5E;KACF,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,GAAG,CAAC,IAAY;IACpC,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,KAAK,EAAE,CAAC,WAAW,EAAE,KAAK,EAAE,IAAI,CAAC,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;IACpF,OAAO,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC;AAC7B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,KAAK;IACzB,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,eAAe,CAAC,CAAC;QAC1C,OAAO,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC/B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW;IAC/B,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,KAAK,EAAE,+BAA+B,CAAC,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QAC1G,OAAO,MAAM,CAAC,QAAQ,KAAK,CAAC,CAAC;IAC/B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;
|
|
1
|
+
{"version":3,"file":"rpc.js","sourceRoot":"","sources":["../../src/lib/rpc.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
interface BrailleChartProps {
|
|
2
|
+
/** Array of numeric values to plot. */
|
|
3
|
+
data: number[];
|
|
4
|
+
/** Chart width in characters. Default 40. */
|
|
5
|
+
width?: number;
|
|
6
|
+
/** Chart height in rows. Default 5. */
|
|
7
|
+
height?: number;
|
|
8
|
+
/** Label shown above the chart. */
|
|
9
|
+
label?: string;
|
|
10
|
+
/** Right-side detail text. */
|
|
11
|
+
detail?: string;
|
|
12
|
+
/** Chart color. Default 'cyan'. */
|
|
13
|
+
color?: string;
|
|
14
|
+
/** Show Y-axis scale labels. Default true. */
|
|
15
|
+
showAxis?: boolean;
|
|
16
|
+
/** Force minimum Y value. */
|
|
17
|
+
min?: number;
|
|
18
|
+
/** Force maximum Y value. */
|
|
19
|
+
max?: number;
|
|
20
|
+
}
|
|
21
|
+
export declare function BrailleChart({ data, width, height, label, detail, color, showAxis, min: forceMin, max: forceMax, }: BrailleChartProps): import("react/jsx-runtime").JSX.Element;
|
|
22
|
+
export {};
|
|
23
|
+
//# sourceMappingURL=BrailleChart.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BrailleChart.d.ts","sourceRoot":"","sources":["../../../src/ui/components/BrailleChart.tsx"],"names":[],"mappings":"AAmBA,UAAU,iBAAiB;IACzB,uCAAuC;IACvC,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,6CAA6C;IAC7C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,uCAAuC;IACvC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,mCAAmC;IACnC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,8BAA8B;IAC9B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,mCAAmC;IACnC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,8CAA8C;IAC9C,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,6BAA6B;IAC7B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,6BAA6B;IAC7B,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,wBAAgB,YAAY,CAAC,EAC3B,IAAI,EACJ,KAAU,EACV,MAAU,EACV,KAAK,EACL,MAAM,EACN,KAAc,EACd,QAAe,EACf,GAAG,EAAE,QAAQ,EACb,GAAG,EAAE,QAAQ,GACd,EAAE,iBAAiB,2CAwGnB"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Box, Text } from 'ink';
|
|
3
|
+
/**
|
|
4
|
+
* Braille dot encoding for high-resolution terminal charts.
|
|
5
|
+
* Each character cell is a 2-wide x 4-tall dot grid (U+2800-U+28FF).
|
|
6
|
+
* Left column bits: [0,1,2,6], Right column bits: [3,4,5,7]
|
|
7
|
+
*/
|
|
8
|
+
const LEFT_BITS = [0, 1, 2, 6];
|
|
9
|
+
const RIGHT_BITS = [3, 4, 5, 7];
|
|
10
|
+
function encodeBraille(grid) {
|
|
11
|
+
let code = 0x2800;
|
|
12
|
+
for (let row = 0; row < 4; row++) {
|
|
13
|
+
if (grid[row]?.[0])
|
|
14
|
+
code |= (1 << LEFT_BITS[row]);
|
|
15
|
+
if (grid[row]?.[1])
|
|
16
|
+
code |= (1 << RIGHT_BITS[row]);
|
|
17
|
+
}
|
|
18
|
+
return String.fromCodePoint(code);
|
|
19
|
+
}
|
|
20
|
+
export function BrailleChart({ data, width = 40, height = 5, label, detail, color = 'cyan', showAxis = true, min: forceMin, max: forceMax, }) {
|
|
21
|
+
if (data.length === 0) {
|
|
22
|
+
return (_jsxs(Box, { flexDirection: "column", children: [label && (_jsxs(Box, { children: [_jsx(Text, { bold: true, children: label }), detail && _jsx(Text, { dimColor: true, children: ` ${detail}` })] })), _jsx(Text, { dimColor: true, children: " No data" })] }));
|
|
23
|
+
}
|
|
24
|
+
// Each character column represents 2 horizontal dots, so we can fit width*2 data points.
|
|
25
|
+
// Take the last width*2 data points (or pad with first value if shorter).
|
|
26
|
+
const maxPoints = width * 2;
|
|
27
|
+
const visible = data.length > maxPoints ? data.slice(-maxPoints) : data;
|
|
28
|
+
const fillValue = visible[0] ?? 0;
|
|
29
|
+
const padded = visible.length < maxPoints
|
|
30
|
+
? [...Array(maxPoints - visible.length).fill(fillValue), ...visible]
|
|
31
|
+
: visible;
|
|
32
|
+
// Compute Y range
|
|
33
|
+
const dataMin = Math.min(...padded);
|
|
34
|
+
const dataMax = Math.max(...padded);
|
|
35
|
+
const yMin = forceMin ?? dataMin;
|
|
36
|
+
const yMax = forceMax ?? (dataMax === dataMin ? dataMax + 1 : dataMax);
|
|
37
|
+
const yRange = yMax - yMin;
|
|
38
|
+
// Canvas: height*4 vertical dots, width*2 horizontal dots
|
|
39
|
+
const canvasHeight = height * 4;
|
|
40
|
+
// Map data to Y positions (0 = bottom, canvasHeight-1 = top)
|
|
41
|
+
const yPositions = padded.map(v => {
|
|
42
|
+
const normalized = (v - yMin) / yRange;
|
|
43
|
+
return Math.round(normalized * (canvasHeight - 1));
|
|
44
|
+
});
|
|
45
|
+
// Build canvas: canvas[row][col] where row 0 = top
|
|
46
|
+
const canvas = Array.from({ length: canvasHeight }, () => Array(maxPoints).fill(false));
|
|
47
|
+
// Fill-area style: fill all dots at or below the data point
|
|
48
|
+
for (let x = 0; x < maxPoints; x++) {
|
|
49
|
+
const yPos = yPositions[x];
|
|
50
|
+
// yPos is from bottom; row index from top = canvasHeight - 1 - yPos
|
|
51
|
+
for (let y = 0; y <= yPos; y++) {
|
|
52
|
+
const row = canvasHeight - 1 - y;
|
|
53
|
+
canvas[row][x] = true;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
// Encode canvas into braille characters
|
|
57
|
+
const rows = [];
|
|
58
|
+
for (let rowGroup = 0; rowGroup < height; rowGroup++) {
|
|
59
|
+
let line = '';
|
|
60
|
+
for (let col = 0; col < width; col++) {
|
|
61
|
+
const grid = [];
|
|
62
|
+
for (let dr = 0; dr < 4; dr++) {
|
|
63
|
+
const canvasRow = rowGroup * 4 + dr;
|
|
64
|
+
grid.push([
|
|
65
|
+
canvas[canvasRow]?.[col * 2] ?? false,
|
|
66
|
+
canvas[canvasRow]?.[col * 2 + 1] ?? false,
|
|
67
|
+
]);
|
|
68
|
+
}
|
|
69
|
+
line += encodeBraille(grid);
|
|
70
|
+
}
|
|
71
|
+
rows.push(line);
|
|
72
|
+
}
|
|
73
|
+
// Y-axis labels (show at top, middle, bottom)
|
|
74
|
+
const axisWidth = showAxis ? 6 : 0;
|
|
75
|
+
const axisLabels = new Map();
|
|
76
|
+
if (showAxis) {
|
|
77
|
+
axisLabels.set(0, formatAxisLabel(yMax));
|
|
78
|
+
axisLabels.set(Math.floor(height / 2), formatAxisLabel((yMax + yMin) / 2));
|
|
79
|
+
axisLabels.set(height - 1, formatAxisLabel(yMin));
|
|
80
|
+
}
|
|
81
|
+
return (_jsxs(Box, { flexDirection: "column", children: [label && (_jsxs(Box, { children: [showAxis && _jsx(Text, { children: ' '.repeat(axisWidth) }), _jsx(Text, { bold: true, children: label }), detail && _jsx(Text, { dimColor: true, children: ` ${detail}` })] })), rows.map((row, i) => (_jsxs(Box, { children: [showAxis && (_jsxs(Text, { dimColor: true, children: [(axisLabels.get(i) ?? '').padStart(axisWidth - 1), '┤'] })), _jsx(Text, { color: color, children: row })] }, i)))] }));
|
|
82
|
+
}
|
|
83
|
+
function formatAxisLabel(value) {
|
|
84
|
+
if (value >= 1000)
|
|
85
|
+
return `${(value / 1000).toFixed(0)}k`;
|
|
86
|
+
if (value >= 100)
|
|
87
|
+
return `${Math.round(value)}`;
|
|
88
|
+
if (value >= 10)
|
|
89
|
+
return `${value.toFixed(0)}`;
|
|
90
|
+
if (value >= 1)
|
|
91
|
+
return `${value.toFixed(1)}`;
|
|
92
|
+
return `${value.toFixed(2)}`;
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=BrailleChart.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BrailleChart.js","sourceRoot":"","sources":["../../../src/ui/components/BrailleChart.tsx"],"names":[],"mappings":"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"}
|