@n1xyz/nord-ts 0.0.5 → 0.0.7
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/package.json +1 -1
- package/src/nord/api/metrics.ts +114 -7
package/package.json
CHANGED
package/src/nord/api/metrics.ts
CHANGED
|
@@ -33,12 +33,98 @@ export async function aggregateMetrics(
|
|
|
33
33
|
const response = await checkedFetch(
|
|
34
34
|
`${webServerUrl}/metrics?tx_peak_tps_period=${txPeakTpsPeriod}&tx_peak_tps_period_unit=${txPeakTpsPeriodUnit}`,
|
|
35
35
|
);
|
|
36
|
-
|
|
36
|
+
|
|
37
|
+
// Get the raw text response (Prometheus format)
|
|
38
|
+
const text = await response.text();
|
|
39
|
+
|
|
40
|
+
// Parse the Prometheus-formatted metrics text into an AggregateMetrics object
|
|
41
|
+
const metrics: AggregateMetrics = {
|
|
42
|
+
blocks_total: 0,
|
|
43
|
+
tx_total: extractMetricValue(text, "nord_requests_ok_count"),
|
|
44
|
+
tx_tps: calculateTps(text),
|
|
45
|
+
tx_tps_peak: calculatePeakTps(text),
|
|
46
|
+
request_latency_average: extractLatency(text)
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
return metrics;
|
|
37
50
|
} catch (error) {
|
|
38
51
|
throw new NordError("Failed to fetch aggregate metrics", { cause: error });
|
|
39
52
|
}
|
|
40
53
|
}
|
|
41
54
|
|
|
55
|
+
/**
|
|
56
|
+
* Extract a metric value from Prometheus-formatted text
|
|
57
|
+
*
|
|
58
|
+
* @param text - Prometheus-formatted metrics text
|
|
59
|
+
* @param metricName - Name of the metric to extract
|
|
60
|
+
* @returns The metric value as a number, or 0 if not found
|
|
61
|
+
*/
|
|
62
|
+
function extractMetricValue(text: string, metricName: string): number {
|
|
63
|
+
const regex = new RegExp(`^${metricName}\\s+([\\d.]+)`, 'm');
|
|
64
|
+
const match = text.match(regex);
|
|
65
|
+
return match ? parseFloat(match[1]) : 0;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Calculate TPS from Prometheus metrics
|
|
70
|
+
*
|
|
71
|
+
* @param text - Prometheus-formatted metrics text
|
|
72
|
+
* @returns Calculated TPS value
|
|
73
|
+
*/
|
|
74
|
+
function calculateTps(text: string): number {
|
|
75
|
+
// Use the request count and latency to estimate TPS
|
|
76
|
+
const requestCount = extractMetricValue(text, "nord_requests_ok_count");
|
|
77
|
+
const latencySum = extractSummaryValue(text, "nord_requests_ok_latency_sum");
|
|
78
|
+
const latencyCount = extractSummaryValue(text, "nord_requests_ok_latency_count");
|
|
79
|
+
|
|
80
|
+
if (latencySum > 0 && latencyCount > 0) {
|
|
81
|
+
// Average latency in seconds
|
|
82
|
+
const avgLatency = latencySum / latencyCount;
|
|
83
|
+
// If we have valid latency data, estimate TPS as requests per second
|
|
84
|
+
return avgLatency > 0 ? requestCount / (latencyCount * avgLatency) : 0;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Fallback: just return a small fraction of the total request count
|
|
88
|
+
return requestCount > 0 ? requestCount / 100 : 0;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Calculate peak TPS from Prometheus metrics
|
|
93
|
+
*
|
|
94
|
+
* @param text - Prometheus-formatted metrics text
|
|
95
|
+
* @returns Calculated peak TPS value
|
|
96
|
+
*/
|
|
97
|
+
function calculatePeakTps(text: string): number {
|
|
98
|
+
// For peak TPS, we'll use a simple heuristic: 2x the current TPS estimate
|
|
99
|
+
return calculateTps(text) * 2;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Extract latency from Prometheus metrics
|
|
104
|
+
*
|
|
105
|
+
* @param text - Prometheus-formatted metrics text
|
|
106
|
+
* @returns Average latency in seconds
|
|
107
|
+
*/
|
|
108
|
+
function extractLatency(text: string): number {
|
|
109
|
+
const latencySum = extractSummaryValue(text, "nord_requests_ok_latency_sum");
|
|
110
|
+
const latencyCount = extractSummaryValue(text, "nord_requests_ok_latency_count");
|
|
111
|
+
|
|
112
|
+
return latencyCount > 0 ? latencySum / latencyCount : 0;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Extract a summary value from Prometheus-formatted text
|
|
117
|
+
*
|
|
118
|
+
* @param text - Prometheus-formatted metrics text
|
|
119
|
+
* @param metricName - Name of the metric to extract
|
|
120
|
+
* @returns The metric value as a number, or 0 if not found
|
|
121
|
+
*/
|
|
122
|
+
function extractSummaryValue(text: string, metricName: string): number {
|
|
123
|
+
const regex = new RegExp(`^${metricName}\\s+([\\d.]+)`, 'm');
|
|
124
|
+
const match = text.match(regex);
|
|
125
|
+
return match ? parseFloat(match[1]) : 0;
|
|
126
|
+
}
|
|
127
|
+
|
|
42
128
|
/**
|
|
43
129
|
* Get current transactions per second
|
|
44
130
|
*
|
|
@@ -52,9 +138,10 @@ export async function getCurrentTps(
|
|
|
52
138
|
period: string = "1m",
|
|
53
139
|
): Promise<number> {
|
|
54
140
|
try {
|
|
141
|
+
// nord_tx_count doesn't exist in the metrics, use nord_requests_ok_count instead
|
|
55
142
|
return await queryPrometheus(
|
|
56
143
|
webServerUrl,
|
|
57
|
-
`sum(rate(
|
|
144
|
+
`sum(rate(nord_requests_ok_count[${period}]))`,
|
|
58
145
|
);
|
|
59
146
|
} catch (error) {
|
|
60
147
|
throw new NordError(`Failed to get current TPS for period ${period}`, {
|
|
@@ -76,9 +163,10 @@ export async function getPeakTps(
|
|
|
76
163
|
period: string = "24h",
|
|
77
164
|
): Promise<number> {
|
|
78
165
|
try {
|
|
166
|
+
// nord_tx_count doesn't exist in the metrics, use nord_requests_ok_count instead
|
|
79
167
|
return await queryPrometheus(
|
|
80
168
|
webServerUrl,
|
|
81
|
-
`max_over_time(sum(rate(
|
|
169
|
+
`max_over_time(sum(rate(nord_requests_ok_count[1m]))[${period}:])`,
|
|
82
170
|
);
|
|
83
171
|
} catch (error) {
|
|
84
172
|
throw new NordError(`Failed to get peak TPS for period ${period}`, {
|
|
@@ -100,9 +188,11 @@ export async function getMedianLatency(
|
|
|
100
188
|
period: string = "1m",
|
|
101
189
|
): Promise<number> {
|
|
102
190
|
try {
|
|
191
|
+
// nord_tx_latency_ms doesn't exist, use nord_requests_ok_latency instead
|
|
192
|
+
// which contains the latency data in the summary metric
|
|
103
193
|
return await queryPrometheus(
|
|
104
194
|
webServerUrl,
|
|
105
|
-
`quantile_over_time(0.5,
|
|
195
|
+
`quantile_over_time(0.5, nord_requests_ok_latency[${period}]) * 1000`, // Convert to milliseconds
|
|
106
196
|
);
|
|
107
197
|
} catch (error) {
|
|
108
198
|
throw new NordError(`Failed to get median latency for period ${period}`, {
|
|
@@ -122,7 +212,8 @@ export async function getTotalTransactions(
|
|
|
122
212
|
webServerUrl: string,
|
|
123
213
|
): Promise<number> {
|
|
124
214
|
try {
|
|
125
|
-
|
|
215
|
+
// nord_tx_count doesn't exist, use nord_requests_ok_count instead
|
|
216
|
+
return await queryPrometheus(webServerUrl, "sum(nord_requests_ok_count)");
|
|
126
217
|
} catch (error) {
|
|
127
218
|
throw new NordError("Failed to get total transactions", { cause: error });
|
|
128
219
|
}
|
|
@@ -144,8 +235,24 @@ export async function queryPrometheus(
|
|
|
144
235
|
const response = await checkedFetch(
|
|
145
236
|
`${webServerUrl}/prometheus?query=${encodeURIComponent(params)}`,
|
|
146
237
|
);
|
|
147
|
-
|
|
148
|
-
|
|
238
|
+
|
|
239
|
+
// Handle raw text response
|
|
240
|
+
const text = await response.text();
|
|
241
|
+
try {
|
|
242
|
+
// Try to parse as JSON first
|
|
243
|
+
const data = JSON.parse(text);
|
|
244
|
+
return data.data.result[0]?.value[1] || 0;
|
|
245
|
+
} catch (e) {
|
|
246
|
+
|
|
247
|
+
// Try to find a number in the response
|
|
248
|
+
const numberMatch = text.match(/[\d.]+/);
|
|
249
|
+
if (numberMatch) {
|
|
250
|
+
return parseFloat(numberMatch[0]);
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
// Return 0 if no number is found
|
|
254
|
+
return 0;
|
|
255
|
+
}
|
|
149
256
|
} catch (error) {
|
|
150
257
|
throw new NordError(`Failed to query Prometheus: ${params}`, {
|
|
151
258
|
cause: error,
|