@olane/o-monitor 0.7.12-alpha.9 → 0.7.12
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/README.md +65 -1
- package/dist/src/http/server.d.ts +8 -1
- package/dist/src/http/server.d.ts.map +1 -1
- package/dist/src/http/server.js +65 -6
- package/dist/src/index.d.ts +1 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +2 -0
- package/dist/src/monitor.tool.d.ts +3 -0
- package/dist/src/monitor.tool.d.ts.map +1 -1
- package/dist/src/monitor.tool.js +36 -6
- package/dist/src/providers/libp2p-metrics.provider.d.ts +40 -1
- package/dist/src/providers/libp2p-metrics.provider.d.ts.map +1 -1
- package/dist/src/providers/libp2p-metrics.provider.js +338 -20
- package/dist/src/providers/node-health.provider.d.ts.map +1 -1
- package/dist/src/providers/node-health.provider.js +21 -31
- package/dist/src/utils/metrics-store.d.ts +17 -0
- package/dist/src/utils/metrics-store.d.ts.map +1 -1
- package/package.json +12 -12
package/README.md
CHANGED
|
@@ -81,6 +81,10 @@ MONITOR_POLLING_INTERVAL=60000 # Polling interval in ms (default: 60000)
|
|
|
81
81
|
# Cleanup
|
|
82
82
|
MONITOR_CLEANUP_INTERVAL=3600000 # Metrics cleanup interval (default: 1 hour)
|
|
83
83
|
|
|
84
|
+
# LibP2P Metrics Polling
|
|
85
|
+
LIBP2P_METRICS_AUTO_POLL=true # Enable automatic libp2p metrics polling (default: false)
|
|
86
|
+
LIBP2P_METRICS_POLLING_INTERVAL=60000 # Polling interval in ms (default: 60000)
|
|
87
|
+
|
|
84
88
|
# Optional Heartbeat (for all nodes)
|
|
85
89
|
MONITOR_ENABLED=true # Enable heartbeat from all nodes
|
|
86
90
|
MONITOR_ADDRESS=o://monitor # Monitor address for heartbeats
|
|
@@ -300,6 +304,56 @@ Get all libp2p metrics in one call.
|
|
|
300
304
|
}
|
|
301
305
|
```
|
|
302
306
|
|
|
307
|
+
#### `collect_libp2p_metrics`
|
|
308
|
+
|
|
309
|
+
Manually trigger collection of libp2p metrics into MetricsStore.
|
|
310
|
+
|
|
311
|
+
**Returns:**
|
|
312
|
+
```typescript
|
|
313
|
+
{
|
|
314
|
+
message: 'libp2p metrics collected',
|
|
315
|
+
timestamp: 1234567890,
|
|
316
|
+
metrics: {
|
|
317
|
+
peerCount: 10,
|
|
318
|
+
connectionCount: 5,
|
|
319
|
+
inboundConnections: 2,
|
|
320
|
+
outboundConnections: 3,
|
|
321
|
+
dhtEnabled: true,
|
|
322
|
+
dhtMode: 'server',
|
|
323
|
+
dhtRoutingTableSize: 20,
|
|
324
|
+
protocols: ['/olane/1.0.0', '/ipfs/id/1.0.0'],
|
|
325
|
+
selfPeerId: '12D3KooW...',
|
|
326
|
+
multiaddrs: ['/ip4/127.0.0.1/tcp/4001']
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
#### `get_stored_libp2p_metrics`
|
|
332
|
+
|
|
333
|
+
Get historical libp2p metrics from MetricsStore.
|
|
334
|
+
|
|
335
|
+
**Returns:**
|
|
336
|
+
```typescript
|
|
337
|
+
{
|
|
338
|
+
timestamp: 1234567890,
|
|
339
|
+
latest: {
|
|
340
|
+
peerCount: 10,
|
|
341
|
+
connectionCount: 5,
|
|
342
|
+
inboundConnections: 2,
|
|
343
|
+
outboundConnections: 3,
|
|
344
|
+
dhtEnabled: true,
|
|
345
|
+
dhtMode: 'server',
|
|
346
|
+
dhtRoutingTableSize: 20
|
|
347
|
+
},
|
|
348
|
+
history: [
|
|
349
|
+
{
|
|
350
|
+
timestamp: 1234567000,
|
|
351
|
+
metrics: { ... }
|
|
352
|
+
}
|
|
353
|
+
]
|
|
354
|
+
}
|
|
355
|
+
```
|
|
356
|
+
|
|
303
357
|
## HTTP API Endpoints
|
|
304
358
|
|
|
305
359
|
### Prometheus Metrics
|
|
@@ -317,11 +371,21 @@ Returns Prometheus-formatted metrics including:
|
|
|
317
371
|
- `olane_service_last_heartbeat_timestamp{node_address="o://storage"}` - Last heartbeat timestamp
|
|
318
372
|
- `olane_network_node_count` - Total nodes in network
|
|
319
373
|
|
|
320
|
-
**libp2p metrics** (
|
|
374
|
+
**libp2p metrics** (when polling is enabled):
|
|
375
|
+
- `libp2p_peer_count` - Number of known peers
|
|
376
|
+
- `libp2p_connection_count` - Total active connections
|
|
377
|
+
- `libp2p_inbound_connections` - Inbound connections
|
|
378
|
+
- `libp2p_outbound_connections` - Outbound connections
|
|
379
|
+
- `libp2p_dht_routing_table_size` - DHT routing table size
|
|
380
|
+
|
|
381
|
+
**Native libp2p metrics** (from @libp2p/prometheus-metrics when registry is shared):
|
|
321
382
|
- `libp2p_data_transfer_bytes_total` - Network I/O
|
|
322
383
|
- `libp2p_kad_dht_wan_query_time_seconds` - DHT query latency
|
|
384
|
+
|
|
385
|
+
**Default Node.js metrics:**
|
|
323
386
|
- `process_cpu_user_seconds_total` - CPU usage
|
|
324
387
|
- `nodejs_memory_usage_bytes` - Memory usage
|
|
388
|
+
- And many more...
|
|
325
389
|
|
|
326
390
|
### REST API
|
|
327
391
|
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import express from 'express';
|
|
1
|
+
import * as express from 'express';
|
|
2
2
|
import * as promClient from 'prom-client';
|
|
3
3
|
import { MetricsStore } from '../utils/metrics-store.js';
|
|
4
4
|
export interface MonitorHTTPServerConfig {
|
|
5
5
|
port: number;
|
|
6
6
|
metricsStore: MetricsStore;
|
|
7
|
+
registry?: promClient.Registry;
|
|
7
8
|
onNodeQuery?: (address: string) => Promise<any>;
|
|
8
9
|
onNetworkQuery?: () => Promise<any>;
|
|
9
10
|
}
|
|
@@ -20,6 +21,12 @@ export declare class MonitorHTTPServer {
|
|
|
20
21
|
private olaneNodeActiveRequests;
|
|
21
22
|
private olaneServiceLastHeartbeat;
|
|
22
23
|
private olaneNetworkNodeCount;
|
|
24
|
+
private libp2pPeerCount;
|
|
25
|
+
private libp2pConnectionCount;
|
|
26
|
+
private libp2pInboundConnections;
|
|
27
|
+
private libp2pOutboundConnections;
|
|
28
|
+
private libp2pStreamCount;
|
|
29
|
+
private libp2pDhtRoutingTableSize;
|
|
23
30
|
constructor(config: MonitorHTTPServerConfig);
|
|
24
31
|
private setupRoutes;
|
|
25
32
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../../src/http/server.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../../src/http/server.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,SAAS,CAAC;AAGnC,OAAO,KAAK,UAAU,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAKzD,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,YAAY,CAAC;IAC3B,QAAQ,CAAC,EAAE,UAAU,CAAC,QAAQ,CAAC;IAC/B,WAAW,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC;IAChD,cAAc,CAAC,EAAE,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC;CACrC;AAED,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,GAAG,CAAc;IACzB,OAAO,CAAC,MAAM,CAAC,CAAS;IACxB,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,IAAI,CAAS;IACrB,OAAO,CAAC,WAAW,CAAC,CAAoC;IACxD,OAAO,CAAC,cAAc,CAAC,CAAqB;IAG5C,OAAO,CAAC,QAAQ,CAAsB;IACtC,OAAO,CAAC,qBAAqB,CAAmB;IAChD,OAAO,CAAC,mBAAmB,CAAmB;IAC9C,OAAO,CAAC,uBAAuB,CAAmB;IAClD,OAAO,CAAC,yBAAyB,CAAmB;IACpD,OAAO,CAAC,qBAAqB,CAAmB;IAGhD,OAAO,CAAC,eAAe,CAAmB;IAC1C,OAAO,CAAC,qBAAqB,CAAmB;IAChD,OAAO,CAAC,wBAAwB,CAAmB;IACnD,OAAO,CAAC,yBAAyB,CAAmB;IACpD,OAAO,CAAC,iBAAiB,CAAmB;IAC5C,OAAO,CAAC,yBAAyB,CAAmB;gBAExC,MAAM,EAAE,uBAAuB;IA6F3C,OAAO,CAAC,WAAW;IA0JnB;;OAEG;IACH,OAAO,CAAC,uBAAuB;IA2D/B;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAW5B;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAkB3B;;OAEG;IACH,MAAM,IAAI,OAAO,CAAC,WAAW;IAI7B;;OAEG;IACH,WAAW,IAAI,UAAU,CAAC,QAAQ;CAGnC"}
|
package/dist/src/http/server.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import express from 'express';
|
|
1
|
+
import * as express from 'express';
|
|
2
|
+
import { json } from 'express';
|
|
2
3
|
import * as promClient from 'prom-client';
|
|
3
4
|
import debug from 'debug';
|
|
4
5
|
const logger = debug('olane-os:monitor:http');
|
|
@@ -9,8 +10,10 @@ export class MonitorHTTPServer {
|
|
|
9
10
|
this.port = config.port;
|
|
10
11
|
this.onNodeQuery = config.onNodeQuery;
|
|
11
12
|
this.onNetworkQuery = config.onNetworkQuery;
|
|
12
|
-
//
|
|
13
|
-
this.registry = new promClient.Registry();
|
|
13
|
+
// Use provided registry or create new one
|
|
14
|
+
this.registry = config.registry || new promClient.Registry();
|
|
15
|
+
// Determine if we should register custom metrics
|
|
16
|
+
const shouldRegisterCustomMetrics = !config.registry;
|
|
14
17
|
// Register custom Olane metrics
|
|
15
18
|
this.olaneNodeSuccessCount = new promClient.Gauge({
|
|
16
19
|
name: 'olane_node_success_count',
|
|
@@ -41,12 +44,45 @@ export class MonitorHTTPServer {
|
|
|
41
44
|
help: 'Total number of nodes in the network',
|
|
42
45
|
registers: [this.registry],
|
|
43
46
|
});
|
|
44
|
-
//
|
|
45
|
-
promClient.
|
|
47
|
+
// Register libp2p metrics
|
|
48
|
+
this.libp2pPeerCount = new promClient.Gauge({
|
|
49
|
+
name: 'libp2p_peer_count',
|
|
50
|
+
help: 'Number of known peers in libp2p peer store',
|
|
51
|
+
registers: [this.registry],
|
|
52
|
+
});
|
|
53
|
+
this.libp2pConnectionCount = new promClient.Gauge({
|
|
54
|
+
name: 'libp2p_connection_count',
|
|
55
|
+
help: 'Total number of active libp2p connections',
|
|
56
|
+
registers: [this.registry],
|
|
57
|
+
});
|
|
58
|
+
this.libp2pInboundConnections = new promClient.Gauge({
|
|
59
|
+
name: 'libp2p_inbound_connections',
|
|
60
|
+
help: 'Number of inbound libp2p connections',
|
|
61
|
+
registers: [this.registry],
|
|
62
|
+
});
|
|
63
|
+
this.libp2pOutboundConnections = new promClient.Gauge({
|
|
64
|
+
name: 'libp2p_outbound_connections',
|
|
65
|
+
help: 'Number of outbound libp2p connections',
|
|
66
|
+
registers: [this.registry],
|
|
67
|
+
});
|
|
68
|
+
this.libp2pStreamCount = new promClient.Gauge({
|
|
69
|
+
name: 'libp2p_stream_count',
|
|
70
|
+
help: 'Total number of active libp2p streams',
|
|
71
|
+
registers: [this.registry],
|
|
72
|
+
});
|
|
73
|
+
this.libp2pDhtRoutingTableSize = new promClient.Gauge({
|
|
74
|
+
name: 'libp2p_dht_routing_table_size',
|
|
75
|
+
help: 'Size of the DHT routing table',
|
|
76
|
+
registers: [this.registry],
|
|
77
|
+
});
|
|
78
|
+
// Only collect default metrics if we created the registry
|
|
79
|
+
if (shouldRegisterCustomMetrics) {
|
|
80
|
+
promClient.collectDefaultMetrics({ register: this.registry });
|
|
81
|
+
}
|
|
46
82
|
this.setupRoutes();
|
|
47
83
|
}
|
|
48
84
|
setupRoutes() {
|
|
49
|
-
this.app.use(
|
|
85
|
+
this.app.use(json());
|
|
50
86
|
// Health check endpoint
|
|
51
87
|
this.app.get('/health', (req, res) => {
|
|
52
88
|
res.status(200).json({ status: 'ok', timestamp: Date.now() });
|
|
@@ -212,6 +248,29 @@ export class MonitorHTTPServer {
|
|
|
212
248
|
// Update network-wide metrics
|
|
213
249
|
const summary = this.metricsStore.getSummary();
|
|
214
250
|
this.olaneNetworkNodeCount.set(summary.totalNodes);
|
|
251
|
+
// Update libp2p metrics from stored data
|
|
252
|
+
const libp2pMetrics = this.metricsStore.getLatestMetrics('o://libp2p');
|
|
253
|
+
if (libp2pMetrics?.libp2pMetrics) {
|
|
254
|
+
const lm = libp2pMetrics.libp2pMetrics;
|
|
255
|
+
if (lm.peerCount !== undefined) {
|
|
256
|
+
this.libp2pPeerCount.set(lm.peerCount);
|
|
257
|
+
}
|
|
258
|
+
if (lm.connectionCount !== undefined) {
|
|
259
|
+
this.libp2pConnectionCount.set(lm.connectionCount);
|
|
260
|
+
}
|
|
261
|
+
if (lm.inboundConnections !== undefined) {
|
|
262
|
+
this.libp2pInboundConnections.set(lm.inboundConnections);
|
|
263
|
+
}
|
|
264
|
+
if (lm.outboundConnections !== undefined) {
|
|
265
|
+
this.libp2pOutboundConnections.set(lm.outboundConnections);
|
|
266
|
+
}
|
|
267
|
+
if (lm.streamCount !== undefined) {
|
|
268
|
+
this.libp2pStreamCount.set(lm.streamCount);
|
|
269
|
+
}
|
|
270
|
+
if (lm.dhtRoutingTableSize !== undefined) {
|
|
271
|
+
this.libp2pDhtRoutingTableSize.set(lm.dhtRoutingTableSize);
|
|
272
|
+
}
|
|
273
|
+
}
|
|
215
274
|
}
|
|
216
275
|
/**
|
|
217
276
|
* Start the HTTP server
|
package/dist/src/index.d.ts
CHANGED
|
@@ -7,4 +7,5 @@ export { MetricsStore } from './utils/metrics-store.js';
|
|
|
7
7
|
export type { MetricEntry, HeartbeatEntry } from './utils/metrics-store.js';
|
|
8
8
|
export { MonitorHTTPServer } from './http/server.js';
|
|
9
9
|
export type { MonitorHTTPServerConfig } from './http/server.js';
|
|
10
|
+
export { prometheusMetrics } from '@libp2p/prometheus-metrics';
|
|
10
11
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/src/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,YAAY,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAG3D,OAAO,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AACtE,OAAO,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AACzE,OAAO,EAAE,qBAAqB,EAAE,MAAM,wCAAwC,CAAC;AAG/E,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,YAAY,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAG5E,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,YAAY,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,YAAY,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAG3D,OAAO,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AACtE,OAAO,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AACzE,OAAO,EAAE,qBAAqB,EAAE,MAAM,wCAAwC,CAAC;AAG/E,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,YAAY,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAG5E,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,YAAY,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AAGhE,OAAO,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC"}
|
package/dist/src/index.js
CHANGED
|
@@ -8,3 +8,5 @@ export { LibP2PMetricsProvider } from './providers/libp2p-metrics.provider.js';
|
|
|
8
8
|
export { MetricsStore } from './utils/metrics-store.js';
|
|
9
9
|
// HTTP server exports
|
|
10
10
|
export { MonitorHTTPServer } from './http/server.js';
|
|
11
|
+
// Prometheus exports
|
|
12
|
+
export { prometheusMetrics } from '@libp2p/prometheus-metrics';
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { oAddress, oRequest } from '@olane/o-core';
|
|
2
2
|
import { oNodeToolConfig } from '@olane/o-node';
|
|
3
3
|
import { oLaneTool } from '@olane/o-lane';
|
|
4
|
+
import * as promClient from 'prom-client';
|
|
4
5
|
export interface MonitorToolConfig extends Partial<oNodeToolConfig> {
|
|
5
6
|
httpPort?: number;
|
|
6
7
|
enableHTTP?: boolean;
|
|
7
8
|
address?: oAddress;
|
|
9
|
+
prometheusRegistry?: promClient.Registry;
|
|
8
10
|
}
|
|
9
11
|
/**
|
|
10
12
|
* MonitorTool - Comprehensive monitoring tool for Olane OS
|
|
@@ -24,6 +26,7 @@ export declare class MonitorTool extends oLaneTool {
|
|
|
24
26
|
private httpPort;
|
|
25
27
|
private enableHTTP;
|
|
26
28
|
private cleanupInterval?;
|
|
29
|
+
private prometheusRegistry?;
|
|
27
30
|
private heartbeatProvider?;
|
|
28
31
|
private nodeHealthProvider?;
|
|
29
32
|
private libp2pMetricsProvider?;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"monitor.tool.d.ts","sourceRoot":"","sources":["../../src/monitor.tool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"monitor.tool.d.ts","sourceRoot":"","sources":["../../src/monitor.tool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAM1C,OAAO,KAAK,UAAU,MAAM,aAAa,CAAC;AAE1C,MAAM,WAAW,iBAAkB,SAAQ,OAAO,CAAC,eAAe,CAAC;IACjE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,OAAO,CAAC,EAAE,QAAQ,CAAC;IACnB,kBAAkB,CAAC,EAAE,UAAU,CAAC,QAAQ,CAAC;CAC1C;AAED;;;;;;;;;;;GAWG;AACH,qBAAa,WAAY,SAAQ,SAAS;IACxC,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,UAAU,CAAC,CAAoB;IACvC,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,UAAU,CAAU;IAC5B,OAAO,CAAC,eAAe,CAAC,CAAiB;IACzC,OAAO,CAAC,kBAAkB,CAAC,CAAsB;IAGjD,OAAO,CAAC,iBAAiB,CAAC,CAAoB;IAC9C,OAAO,CAAC,kBAAkB,CAAC,CAAqB;IAChD,OAAO,CAAC,qBAAqB,CAAC,CAAwB;gBAE1C,MAAM,EAAE,iBAAiB;IAsB/B,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAiB3B,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IA0B/B;;OAEG;YACW,mBAAmB;IAuDjC;;OAEG;YACW,eAAe;IAsC7B;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAgB5B;;OAEG;IACG,sBAAsB,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC;IAO7D;;OAEG;IACG,wBAAwB,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC;IAO/D;;OAEG;IACG,sBAAsB,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC;IAO7D;;OAEG;IACG,wBAAwB,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC;IAO/D;;OAEG;IACG,qBAAqB,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC;IAyB5D;;OAEG;IACG,wBAAwB,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC;IAwC/D;;OAEG;IACG,sBAAsB,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC;IAqB7D;;OAEG;IACG,4BAA4B,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC;IAOnE;;OAEG;IACG,mBAAmB,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC;IAO1D;;OAEG;IACG,oBAAoB,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC;IAO3D;;OAEG;IACG,wBAAwB,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC;IAO/D;;OAEG;IACG,cAAc,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC;IAOrD;;OAEG;IACG,yBAAyB,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC;IAgChE;;OAEG;IACG,+BAA+B,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC;CAcvE"}
|
package/dist/src/monitor.tool.js
CHANGED
|
@@ -5,6 +5,7 @@ import { MonitorHTTPServer } from './http/server.js';
|
|
|
5
5
|
import { HeartbeatProvider } from './providers/heartbeat.provider.js';
|
|
6
6
|
import { NodeHealthProvider } from './providers/node-health.provider.js';
|
|
7
7
|
import { LibP2PMetricsProvider } from './providers/libp2p-metrics.provider.js';
|
|
8
|
+
import * as promClient from 'prom-client';
|
|
8
9
|
/**
|
|
9
10
|
* MonitorTool - Comprehensive monitoring tool for Olane OS
|
|
10
11
|
*
|
|
@@ -26,12 +27,15 @@ export class MonitorTool extends oLaneTool {
|
|
|
26
27
|
'Monitoring and observability tool for Olane OS network',
|
|
27
28
|
leader: config.leader || null,
|
|
28
29
|
parent: config.parent || null,
|
|
30
|
+
network: config.network,
|
|
29
31
|
});
|
|
30
32
|
this.metricsStore = new MetricsStore();
|
|
31
33
|
this.httpPort =
|
|
32
34
|
config.httpPort || parseInt(process.env.MONITOR_HTTP_PORT || '9090', 10);
|
|
33
35
|
this.enableHTTP =
|
|
34
36
|
config.enableHTTP ?? process.env.MONITOR_HTTP_ENABLED !== 'false';
|
|
37
|
+
// Create a Prometheus registry if not provided
|
|
38
|
+
this.prometheusRegistry = config.prometheusRegistry || new promClient.Registry();
|
|
35
39
|
}
|
|
36
40
|
async initialize() {
|
|
37
41
|
await super.initialize();
|
|
@@ -77,23 +81,48 @@ export class MonitorTool extends oLaneTool {
|
|
|
77
81
|
leader: this.leader,
|
|
78
82
|
metricsStore: this.metricsStore,
|
|
79
83
|
});
|
|
84
|
+
this.heartbeatProvider.initConnectionManager = async () => {
|
|
85
|
+
this.heartbeatProvider.connectionManager = this.connectionManager;
|
|
86
|
+
};
|
|
87
|
+
this.heartbeatProvider.hookInitializeFinished = async () => {
|
|
88
|
+
if (!this.heartbeatProvider)
|
|
89
|
+
return;
|
|
90
|
+
this.addChildNode(this.heartbeatProvider);
|
|
91
|
+
};
|
|
80
92
|
await this.heartbeatProvider.start();
|
|
81
|
-
this.addChildNode(this.heartbeatProvider);
|
|
82
93
|
// Node Health Provider
|
|
83
94
|
this.nodeHealthProvider = new NodeHealthProvider({
|
|
84
95
|
parent: this.address,
|
|
85
96
|
leader: this.leader,
|
|
86
97
|
metricsStore: this.metricsStore,
|
|
87
98
|
});
|
|
99
|
+
this.nodeHealthProvider.initConnectionManager = async () => {
|
|
100
|
+
this.nodeHealthProvider.connectionManager = this.connectionManager;
|
|
101
|
+
};
|
|
102
|
+
this.nodeHealthProvider.hookInitializeFinished = async () => {
|
|
103
|
+
if (!this.nodeHealthProvider)
|
|
104
|
+
return;
|
|
105
|
+
this.addChildNode(this.nodeHealthProvider);
|
|
106
|
+
};
|
|
88
107
|
await this.nodeHealthProvider.start();
|
|
89
|
-
this.addChildNode(this.nodeHealthProvider);
|
|
90
108
|
// LibP2P Metrics Provider
|
|
91
109
|
this.libp2pMetricsProvider = new LibP2PMetricsProvider({
|
|
92
110
|
parent: this.address,
|
|
93
111
|
leader: this.leader,
|
|
112
|
+
metricsStore: this.metricsStore,
|
|
113
|
+
prometheusRegistry: this.prometheusRegistry,
|
|
114
|
+
enablePolling: process.env.LIBP2P_METRICS_AUTO_POLL !== 'false',
|
|
115
|
+
pollingInterval: parseInt(process.env.LIBP2P_METRICS_POLLING_INTERVAL || '60000', 10),
|
|
94
116
|
});
|
|
117
|
+
this.libp2pMetricsProvider.initConnectionManager = async () => {
|
|
118
|
+
this.libp2pMetricsProvider.connectionManager = this.connectionManager;
|
|
119
|
+
};
|
|
120
|
+
this.libp2pMetricsProvider.hookInitializeFinished = async () => {
|
|
121
|
+
if (!this.libp2pMetricsProvider)
|
|
122
|
+
return;
|
|
123
|
+
this.addChildNode(this.libp2pMetricsProvider);
|
|
124
|
+
};
|
|
95
125
|
await this.libp2pMetricsProvider.start();
|
|
96
|
-
this.addChildNode(this.libp2pMetricsProvider);
|
|
97
126
|
this.logger.debug('All provider nodes initialized');
|
|
98
127
|
}
|
|
99
128
|
/**
|
|
@@ -103,6 +132,7 @@ export class MonitorTool extends oLaneTool {
|
|
|
103
132
|
this.httpServer = new MonitorHTTPServer({
|
|
104
133
|
port: this.httpPort,
|
|
105
134
|
metricsStore: this.metricsStore,
|
|
135
|
+
registry: this.prometheusRegistry,
|
|
106
136
|
onNodeQuery: async (address) => {
|
|
107
137
|
// Query live node data
|
|
108
138
|
try {
|
|
@@ -119,7 +149,7 @@ export class MonitorTool extends oLaneTool {
|
|
|
119
149
|
onNetworkQuery: async () => {
|
|
120
150
|
// Query network-wide data
|
|
121
151
|
try {
|
|
122
|
-
const registry = await this.use(new oAddress('o://
|
|
152
|
+
const registry = await this.use(new oAddress('o://registry'), {
|
|
123
153
|
method: 'find_all',
|
|
124
154
|
params: {},
|
|
125
155
|
});
|
|
@@ -191,7 +221,7 @@ export class MonitorTool extends oLaneTool {
|
|
|
191
221
|
*/
|
|
192
222
|
async _tool_collect_metrics(request) {
|
|
193
223
|
// Get all registered nodes from leader
|
|
194
|
-
const registry = await this.use(new oAddress('o://
|
|
224
|
+
const registry = await this.use(new oAddress('o://registry'), {
|
|
195
225
|
method: 'find_all',
|
|
196
226
|
params: {},
|
|
197
227
|
});
|
|
@@ -219,7 +249,7 @@ export class MonitorTool extends oLaneTool {
|
|
|
219
249
|
// Get registry data
|
|
220
250
|
let registryData = null;
|
|
221
251
|
try {
|
|
222
|
-
const registry = await this.use(new oAddress('o://
|
|
252
|
+
const registry = await this.use(new oAddress('o://registry'), {
|
|
223
253
|
method: 'find_all',
|
|
224
254
|
params: {},
|
|
225
255
|
});
|
|
@@ -1,30 +1,69 @@
|
|
|
1
1
|
import { oRequest } from '@olane/o-core';
|
|
2
2
|
import { oNodeToolConfig, oNodeTool } from '@olane/o-node';
|
|
3
|
+
import { MetricsStore } from '../utils/metrics-store.js';
|
|
4
|
+
import type { Registry } from 'prom-client';
|
|
5
|
+
export interface LibP2PMetricsProviderConfig extends oNodeToolConfig {
|
|
6
|
+
metricsStore?: MetricsStore;
|
|
7
|
+
pollingInterval?: number;
|
|
8
|
+
enablePolling?: boolean;
|
|
9
|
+
prometheusRegistry?: Registry;
|
|
10
|
+
}
|
|
3
11
|
/**
|
|
4
12
|
* LibP2P Metrics Provider - Extracts metrics from libp2p node
|
|
5
13
|
* Child node: o://monitor/libp2p
|
|
6
14
|
*/
|
|
7
15
|
export declare class LibP2PMetricsProvider extends oNodeTool {
|
|
8
|
-
|
|
16
|
+
private metricsStore?;
|
|
17
|
+
private pollingInterval?;
|
|
18
|
+
private pollingIntervalMs;
|
|
19
|
+
private prometheusRegistry?;
|
|
20
|
+
constructor(config: LibP2PMetricsProviderConfig);
|
|
9
21
|
initialize(): Promise<void>;
|
|
22
|
+
teardown(): Promise<void>;
|
|
23
|
+
/**
|
|
24
|
+
* Collect libp2p metrics from all nodes and store in MetricsStore
|
|
25
|
+
*/
|
|
26
|
+
private collectAndStoreMetrics;
|
|
27
|
+
/**
|
|
28
|
+
* Start automatic polling of libp2p metrics
|
|
29
|
+
*/
|
|
30
|
+
private startPolling;
|
|
31
|
+
/**
|
|
32
|
+
* Stop automatic polling
|
|
33
|
+
*/
|
|
34
|
+
private stopPolling;
|
|
35
|
+
/**
|
|
36
|
+
* Manually trigger libp2p metrics collection from all nodes
|
|
37
|
+
*/
|
|
38
|
+
_tool_collect_libp2p_metrics(request: oRequest): Promise<any>;
|
|
39
|
+
/**
|
|
40
|
+
* Get stored libp2p metrics from MetricsStore
|
|
41
|
+
* @param request.params.nodeAddress - Optional: specific node address to query (defaults to all nodes)
|
|
42
|
+
*/
|
|
43
|
+
_tool_get_stored_libp2p_metrics(request: oRequest): Promise<any>;
|
|
10
44
|
/**
|
|
11
45
|
* Get peer information from libp2p peer store
|
|
46
|
+
* @param request.params.nodeAddress - Optional: specific node to query (defaults to this monitor's node)
|
|
12
47
|
*/
|
|
13
48
|
_tool_get_peer_info(request: oRequest): Promise<any>;
|
|
14
49
|
/**
|
|
15
50
|
* Get DHT (Distributed Hash Table) status
|
|
51
|
+
* @param request.params.nodeAddress - Optional: specific node to query (defaults to this monitor's node)
|
|
16
52
|
*/
|
|
17
53
|
_tool_get_dht_status(request: oRequest): Promise<any>;
|
|
18
54
|
/**
|
|
19
55
|
* Get transport and connection statistics
|
|
56
|
+
* @param request.params.nodeAddress - Optional: specific node to query (defaults to this monitor's node)
|
|
20
57
|
*/
|
|
21
58
|
_tool_get_transport_stats(request: oRequest): Promise<any>;
|
|
22
59
|
/**
|
|
23
60
|
* Get connection manager status
|
|
61
|
+
* @param request.params.nodeAddress - Optional: specific node to query (defaults to this monitor's node)
|
|
24
62
|
*/
|
|
25
63
|
_tool_get_connection_manager_status(request: oRequest): Promise<any>;
|
|
26
64
|
/**
|
|
27
65
|
* Get all libp2p metrics in one call
|
|
66
|
+
* @param request.params.nodeAddress - Optional: specific node to query (defaults to all nodes)
|
|
28
67
|
*/
|
|
29
68
|
_tool_get_all_libp2p_metrics(request: oRequest): Promise<any>;
|
|
30
69
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"libp2p-metrics.provider.d.ts","sourceRoot":"","sources":["../../../src/providers/libp2p-metrics.provider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAY,QAAQ,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"libp2p-metrics.provider.d.ts","sourceRoot":"","sources":["../../../src/providers/libp2p-metrics.provider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAY,QAAQ,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC3D,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE5C,MAAM,WAAW,2BAA4B,SAAQ,eAAe;IAClE,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,kBAAkB,CAAC,EAAE,QAAQ,CAAC;CAC/B;AAED;;;GAGG;AACH,qBAAa,qBAAsB,SAAQ,SAAS;IAClD,OAAO,CAAC,YAAY,CAAC,CAAe;IACpC,OAAO,CAAC,eAAe,CAAC,CAAiB;IACzC,OAAO,CAAC,iBAAiB,CAAiB;IAC1C,OAAO,CAAC,kBAAkB,CAAC,CAAW;gBAE1B,MAAM,EAAE,2BAA2B;IAgBzC,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAS3B,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAK/B;;OAEG;YACW,sBAAsB;IAwEpC;;OAEG;IACH,OAAO,CAAC,YAAY;IAoBpB;;OAEG;IACH,OAAO,CAAC,WAAW;IAQnB;;OAEG;IACG,4BAA4B,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC;IA2BnE;;;OAGG;IACG,+BAA+B,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC;IA8CtE;;;OAGG;IACG,mBAAmB,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC;IAgE1D;;;OAGG;IACG,oBAAoB,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC;IAyE3D;;;OAGG;IACG,yBAAyB,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC;IA4EhE;;;OAGG;IACG,mCAAmC,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC;IAsE1E;;;OAGG;IACG,4BAA4B,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC;IAwEnE;;OAEG;IACG,eAAe,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC;CAiCvD"}
|
|
@@ -12,17 +12,208 @@ export class LibP2PMetricsProvider extends oNodeTool {
|
|
|
12
12
|
name: 'libp2p-metrics-provider',
|
|
13
13
|
description: 'Extracts and exposes libp2p network metrics',
|
|
14
14
|
});
|
|
15
|
+
this.pollingIntervalMs = 60000;
|
|
16
|
+
this.metricsStore = config.metricsStore;
|
|
17
|
+
this.prometheusRegistry = config.prometheusRegistry;
|
|
18
|
+
this.pollingIntervalMs =
|
|
19
|
+
config.pollingInterval ||
|
|
20
|
+
parseInt(process.env.LIBP2P_METRICS_POLLING_INTERVAL || '60000', 10);
|
|
15
21
|
}
|
|
16
22
|
async initialize() {
|
|
17
23
|
await super.initialize();
|
|
24
|
+
const enablePolling = process.env.LIBP2P_METRICS_AUTO_POLL !== 'false';
|
|
25
|
+
if (enablePolling && this.metricsStore) {
|
|
26
|
+
this.startPolling();
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
async teardown() {
|
|
30
|
+
this.stopPolling();
|
|
31
|
+
await super.teardown();
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Collect libp2p metrics from all nodes and store in MetricsStore
|
|
35
|
+
*/
|
|
36
|
+
async collectAndStoreMetrics() {
|
|
37
|
+
if (!this.metricsStore)
|
|
38
|
+
return;
|
|
39
|
+
try {
|
|
40
|
+
// Get all registered nodes from the registry
|
|
41
|
+
const registry = await this.use(oAddress.registry(), {
|
|
42
|
+
method: 'find_all',
|
|
43
|
+
params: {},
|
|
44
|
+
});
|
|
45
|
+
if (!registry.result || !registry.result.data) {
|
|
46
|
+
this.logger.warn('No nodes found in registry for libp2p metrics collection');
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
const addresses = Array.isArray(registry.result.data)
|
|
50
|
+
? registry.result.data.map((node) => node.address)
|
|
51
|
+
: [];
|
|
52
|
+
let successCount = 0;
|
|
53
|
+
let failureCount = 0;
|
|
54
|
+
// Collect libp2p metrics from each node
|
|
55
|
+
for (const address of addresses) {
|
|
56
|
+
try {
|
|
57
|
+
const result = await this.use(new oAddress(address), {
|
|
58
|
+
method: 'get_libp2p_metrics',
|
|
59
|
+
params: {},
|
|
60
|
+
});
|
|
61
|
+
const libp2pMetrics = result.result.data;
|
|
62
|
+
if (libp2pMetrics && libp2pMetrics.available) {
|
|
63
|
+
// Store per-node metrics in MetricsStore
|
|
64
|
+
this.metricsStore.storeMetrics(this.address.toStaticAddress().toString(), {
|
|
65
|
+
successCount: 0,
|
|
66
|
+
errorCount: 0,
|
|
67
|
+
activeRequests: libp2pMetrics.connectionCount || 0,
|
|
68
|
+
libp2pMetrics,
|
|
69
|
+
});
|
|
70
|
+
successCount++;
|
|
71
|
+
this.logger.debug(`Collected libp2p metrics from ${address}: ${libp2pMetrics.peerCount} peers, ${libp2pMetrics.connectionCount} connections`);
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
this.logger.debug(`libp2p not available on node ${address}: ${libp2pMetrics?.error || 'unknown reason'}`);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
catch (error) {
|
|
78
|
+
this.logger.error(`Failed to collect libp2p metrics from ${address}:`, error.message);
|
|
79
|
+
failureCount++;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
this.logger.debug(`Libp2p metrics collection complete: ${successCount} successful, ${failureCount} failed`);
|
|
83
|
+
}
|
|
84
|
+
catch (error) {
|
|
85
|
+
this.logger.error('Error during libp2p metrics collection:', error);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Start automatic polling of libp2p metrics
|
|
90
|
+
*/
|
|
91
|
+
startPolling() {
|
|
92
|
+
if (this.pollingInterval) {
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
this.logger.info(`Starting libp2p metrics polling every ${this.pollingIntervalMs}ms`);
|
|
96
|
+
// Immediate first collection
|
|
97
|
+
this.collectAndStoreMetrics().catch((err) => this.logger.error('Error in initial metrics collection:', err));
|
|
98
|
+
// Set up interval
|
|
99
|
+
this.pollingInterval = setInterval(async () => {
|
|
100
|
+
await this.collectAndStoreMetrics();
|
|
101
|
+
}, this.pollingIntervalMs);
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Stop automatic polling
|
|
105
|
+
*/
|
|
106
|
+
stopPolling() {
|
|
107
|
+
if (this.pollingInterval) {
|
|
108
|
+
clearInterval(this.pollingInterval);
|
|
109
|
+
this.pollingInterval = undefined;
|
|
110
|
+
this.logger.info('Stopped libp2p metrics polling');
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Manually trigger libp2p metrics collection from all nodes
|
|
115
|
+
*/
|
|
116
|
+
async _tool_collect_libp2p_metrics(request) {
|
|
117
|
+
await this.collectAndStoreMetrics();
|
|
118
|
+
if (!this.metricsStore) {
|
|
119
|
+
return {
|
|
120
|
+
message: 'MetricsStore not configured',
|
|
121
|
+
timestamp: Date.now(),
|
|
122
|
+
collected: 0,
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
// Get all tracked nodes with libp2p metrics
|
|
126
|
+
const allNodes = this.metricsStore.getAllTrackedNodes();
|
|
127
|
+
const nodesWithMetrics = allNodes.filter((address) => {
|
|
128
|
+
const metrics = this.metricsStore?.getLatestMetrics(address);
|
|
129
|
+
return metrics?.libp2pMetrics?.available;
|
|
130
|
+
});
|
|
131
|
+
return {
|
|
132
|
+
message: 'libp2p metrics collected from all nodes',
|
|
133
|
+
timestamp: Date.now(),
|
|
134
|
+
nodesCollected: nodesWithMetrics.length,
|
|
135
|
+
totalNodes: allNodes.length,
|
|
136
|
+
nodes: nodesWithMetrics,
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Get stored libp2p metrics from MetricsStore
|
|
141
|
+
* @param request.params.nodeAddress - Optional: specific node address to query (defaults to all nodes)
|
|
142
|
+
*/
|
|
143
|
+
async _tool_get_stored_libp2p_metrics(request) {
|
|
144
|
+
if (!this.metricsStore) {
|
|
145
|
+
throw new Error('MetricsStore not configured');
|
|
146
|
+
}
|
|
147
|
+
const { nodeAddress } = request.params;
|
|
148
|
+
// If a specific node is requested, return only that node's metrics
|
|
149
|
+
if (nodeAddress) {
|
|
150
|
+
const latestMetrics = this.metricsStore.getLatestMetrics(nodeAddress);
|
|
151
|
+
const allMetrics = this.metricsStore.getAllMetrics(nodeAddress);
|
|
152
|
+
return {
|
|
153
|
+
timestamp: Date.now(),
|
|
154
|
+
nodeAddress,
|
|
155
|
+
latest: latestMetrics?.libp2pMetrics || null,
|
|
156
|
+
history: allMetrics
|
|
157
|
+
.filter((m) => m.libp2pMetrics)
|
|
158
|
+
.map((m) => ({
|
|
159
|
+
timestamp: m.timestamp,
|
|
160
|
+
metrics: m.libp2pMetrics,
|
|
161
|
+
})),
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
// Otherwise, return metrics from all nodes
|
|
165
|
+
const allNodes = this.metricsStore.getAllTrackedNodes();
|
|
166
|
+
const nodeMetrics = {};
|
|
167
|
+
for (const address of allNodes) {
|
|
168
|
+
const latestMetrics = this.metricsStore.getLatestMetrics(address);
|
|
169
|
+
if (latestMetrics?.libp2pMetrics) {
|
|
170
|
+
nodeMetrics[address] = {
|
|
171
|
+
latest: latestMetrics.libp2pMetrics,
|
|
172
|
+
lastUpdated: latestMetrics.timestamp,
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
return {
|
|
177
|
+
timestamp: Date.now(),
|
|
178
|
+
nodeCount: Object.keys(nodeMetrics).length,
|
|
179
|
+
nodes: nodeMetrics,
|
|
180
|
+
};
|
|
18
181
|
}
|
|
19
182
|
/**
|
|
20
183
|
* Get peer information from libp2p peer store
|
|
184
|
+
* @param request.params.nodeAddress - Optional: specific node to query (defaults to this monitor's node)
|
|
21
185
|
*/
|
|
22
186
|
async _tool_get_peer_info(request) {
|
|
187
|
+
const { nodeAddress } = request.params;
|
|
188
|
+
// If querying a remote node, forward the request
|
|
189
|
+
if (nodeAddress) {
|
|
190
|
+
try {
|
|
191
|
+
const result = await this.use(new oAddress(nodeAddress), {
|
|
192
|
+
method: 'get_libp2p_metrics',
|
|
193
|
+
params: {},
|
|
194
|
+
});
|
|
195
|
+
const metrics = result.result.data;
|
|
196
|
+
if (!metrics || !metrics.available) {
|
|
197
|
+
throw new Error(`libp2p not available on node ${nodeAddress}`);
|
|
198
|
+
}
|
|
199
|
+
// Return peer information from the metrics
|
|
200
|
+
return {
|
|
201
|
+
timestamp: Date.now(),
|
|
202
|
+
nodeAddress,
|
|
203
|
+
peerCount: metrics.peerCount,
|
|
204
|
+
selfPeerId: metrics.selfPeerId,
|
|
205
|
+
selfMultiaddrs: metrics.multiaddrs,
|
|
206
|
+
protocols: metrics.protocols,
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
catch (error) {
|
|
210
|
+
throw new Error(`Failed to get peer info from ${nodeAddress}: ${error.message}`);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
// Otherwise, query this node's libp2p instance
|
|
23
214
|
const p2pNode = this.p2pNode;
|
|
24
215
|
if (!p2pNode) {
|
|
25
|
-
throw new Error('libp2p node not available');
|
|
216
|
+
throw new Error('libp2p node not available on monitor');
|
|
26
217
|
}
|
|
27
218
|
try {
|
|
28
219
|
const peers = await p2pNode.peerStore.all();
|
|
@@ -50,11 +241,37 @@ export class LibP2PMetricsProvider extends oNodeTool {
|
|
|
50
241
|
}
|
|
51
242
|
/**
|
|
52
243
|
* Get DHT (Distributed Hash Table) status
|
|
244
|
+
* @param request.params.nodeAddress - Optional: specific node to query (defaults to this monitor's node)
|
|
53
245
|
*/
|
|
54
246
|
async _tool_get_dht_status(request) {
|
|
247
|
+
const { nodeAddress } = request.params;
|
|
248
|
+
// If querying a remote node, forward the request
|
|
249
|
+
if (nodeAddress) {
|
|
250
|
+
try {
|
|
251
|
+
const result = await this.use(new oAddress(nodeAddress), {
|
|
252
|
+
method: 'get_libp2p_metrics',
|
|
253
|
+
params: {},
|
|
254
|
+
});
|
|
255
|
+
const metrics = result.result.data;
|
|
256
|
+
if (!metrics || !metrics.available) {
|
|
257
|
+
throw new Error(`libp2p not available on node ${nodeAddress}`);
|
|
258
|
+
}
|
|
259
|
+
return {
|
|
260
|
+
timestamp: Date.now(),
|
|
261
|
+
nodeAddress,
|
|
262
|
+
enabled: metrics.dhtEnabled,
|
|
263
|
+
mode: metrics.dhtMode,
|
|
264
|
+
routingTableSize: metrics.dhtRoutingTableSize,
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
catch (error) {
|
|
268
|
+
throw new Error(`Failed to get DHT status from ${nodeAddress}: ${error.message}`);
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
// Otherwise, query this node's libp2p instance
|
|
55
272
|
const p2pNode = this.p2pNode;
|
|
56
273
|
if (!p2pNode) {
|
|
57
|
-
throw new Error('libp2p node not available');
|
|
274
|
+
throw new Error('libp2p node not available on monitor');
|
|
58
275
|
}
|
|
59
276
|
try {
|
|
60
277
|
// Get DHT service if available
|
|
@@ -69,11 +286,20 @@ export class LibP2PMetricsProvider extends oNodeTool {
|
|
|
69
286
|
// Get routing table info
|
|
70
287
|
const routingTable = dht?.routingTable;
|
|
71
288
|
const kBuckets = routingTable?.kb || null;
|
|
289
|
+
let routingTableSize = 0;
|
|
290
|
+
if (kBuckets) {
|
|
291
|
+
if (Array.isArray(kBuckets)) {
|
|
292
|
+
routingTableSize = kBuckets.length;
|
|
293
|
+
}
|
|
294
|
+
else if (typeof kBuckets === 'object') {
|
|
295
|
+
routingTableSize = Object.keys(kBuckets).length;
|
|
296
|
+
}
|
|
297
|
+
}
|
|
72
298
|
return {
|
|
73
299
|
timestamp: Date.now(),
|
|
74
300
|
enabled: true,
|
|
75
301
|
mode: dht.clientMode ? 'client' : 'server',
|
|
76
|
-
routingTableSize
|
|
302
|
+
routingTableSize,
|
|
77
303
|
// Add more DHT-specific metrics as needed
|
|
78
304
|
};
|
|
79
305
|
}
|
|
@@ -83,16 +309,44 @@ export class LibP2PMetricsProvider extends oNodeTool {
|
|
|
83
309
|
}
|
|
84
310
|
/**
|
|
85
311
|
* Get transport and connection statistics
|
|
312
|
+
* @param request.params.nodeAddress - Optional: specific node to query (defaults to this monitor's node)
|
|
86
313
|
*/
|
|
87
314
|
async _tool_get_transport_stats(request) {
|
|
315
|
+
const { nodeAddress } = request.params;
|
|
316
|
+
// If querying a remote node, forward the request
|
|
317
|
+
if (nodeAddress) {
|
|
318
|
+
try {
|
|
319
|
+
const result = await this.use(new oAddress(nodeAddress), {
|
|
320
|
+
method: 'get_libp2p_metrics',
|
|
321
|
+
params: {},
|
|
322
|
+
});
|
|
323
|
+
const metrics = result.result.data;
|
|
324
|
+
if (!metrics || !metrics.available) {
|
|
325
|
+
throw new Error(`libp2p not available on node ${nodeAddress}`);
|
|
326
|
+
}
|
|
327
|
+
return {
|
|
328
|
+
timestamp: Date.now(),
|
|
329
|
+
nodeAddress,
|
|
330
|
+
connectionCount: metrics.connectionCount,
|
|
331
|
+
protocols: metrics.protocols,
|
|
332
|
+
multiaddrs: metrics.multiaddrs,
|
|
333
|
+
inboundConnections: metrics.inboundConnections,
|
|
334
|
+
outboundConnections: metrics.outboundConnections,
|
|
335
|
+
streamCount: metrics.streamCount,
|
|
336
|
+
};
|
|
337
|
+
}
|
|
338
|
+
catch (error) {
|
|
339
|
+
throw new Error(`Failed to get transport stats from ${nodeAddress}: ${error.message}`);
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
// Otherwise, query this node's libp2p instance
|
|
88
343
|
const p2pNode = this.p2pNode;
|
|
89
344
|
if (!p2pNode) {
|
|
90
|
-
throw new Error('libp2p node not available');
|
|
345
|
+
throw new Error('libp2p node not available on monitor');
|
|
91
346
|
}
|
|
92
347
|
try {
|
|
93
348
|
const connections = p2pNode.getConnections();
|
|
94
|
-
const dialQueue = p2pNode.services.connectionManager
|
|
95
|
-
?.dialQueue;
|
|
349
|
+
const dialQueue = p2pNode.services.connectionManager?.dialQueue;
|
|
96
350
|
const connectionStats = connections.map((conn) => ({
|
|
97
351
|
remotePeer: conn.remotePeer.toString(),
|
|
98
352
|
remoteAddr: conn.remoteAddr.toString(),
|
|
@@ -125,11 +379,38 @@ export class LibP2PMetricsProvider extends oNodeTool {
|
|
|
125
379
|
}
|
|
126
380
|
/**
|
|
127
381
|
* Get connection manager status
|
|
382
|
+
* @param request.params.nodeAddress - Optional: specific node to query (defaults to this monitor's node)
|
|
128
383
|
*/
|
|
129
384
|
async _tool_get_connection_manager_status(request) {
|
|
385
|
+
const { nodeAddress } = request.params;
|
|
386
|
+
// If querying a remote node, forward the request
|
|
387
|
+
if (nodeAddress) {
|
|
388
|
+
try {
|
|
389
|
+
const result = await this.use(new oAddress(nodeAddress), {
|
|
390
|
+
method: 'get_libp2p_metrics',
|
|
391
|
+
params: {},
|
|
392
|
+
});
|
|
393
|
+
const metrics = result.result.data;
|
|
394
|
+
if (!metrics || !metrics.available) {
|
|
395
|
+
throw new Error(`libp2p not available on node ${nodeAddress}`);
|
|
396
|
+
}
|
|
397
|
+
return {
|
|
398
|
+
timestamp: Date.now(),
|
|
399
|
+
nodeAddress,
|
|
400
|
+
totalConnections: metrics.connectionCount,
|
|
401
|
+
uniquePeers: metrics.peerCount,
|
|
402
|
+
inboundConnections: metrics.inboundConnections,
|
|
403
|
+
outboundConnections: metrics.outboundConnections,
|
|
404
|
+
};
|
|
405
|
+
}
|
|
406
|
+
catch (error) {
|
|
407
|
+
throw new Error(`Failed to get connection manager status from ${nodeAddress}: ${error.message}`);
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
// Otherwise, query this node's libp2p instance
|
|
130
411
|
const p2pNode = this.p2pNode;
|
|
131
412
|
if (!p2pNode) {
|
|
132
|
-
throw new Error('libp2p node not available');
|
|
413
|
+
throw new Error('libp2p node not available on monitor');
|
|
133
414
|
}
|
|
134
415
|
try {
|
|
135
416
|
const connections = p2pNode.getConnections();
|
|
@@ -157,25 +438,62 @@ export class LibP2PMetricsProvider extends oNodeTool {
|
|
|
157
438
|
}
|
|
158
439
|
/**
|
|
159
440
|
* Get all libp2p metrics in one call
|
|
441
|
+
* @param request.params.nodeAddress - Optional: specific node to query (defaults to all nodes)
|
|
160
442
|
*/
|
|
161
443
|
async _tool_get_all_libp2p_metrics(request) {
|
|
162
|
-
const
|
|
163
|
-
|
|
164
|
-
|
|
444
|
+
const { nodeAddress } = request.params;
|
|
445
|
+
// If querying a specific node, get all its metrics
|
|
446
|
+
if (nodeAddress) {
|
|
447
|
+
try {
|
|
448
|
+
const [peerInfoResult, dhtStatusResult, transportStatsResult, connectionManagerStatusResult,] = await Promise.all([
|
|
449
|
+
this.use(this.address, {
|
|
450
|
+
method: 'get_peer_info',
|
|
451
|
+
params: { nodeAddress },
|
|
452
|
+
}),
|
|
453
|
+
this.use(this.address, {
|
|
454
|
+
method: 'get_dht_status',
|
|
455
|
+
params: { nodeAddress },
|
|
456
|
+
}),
|
|
457
|
+
this.use(this.address, {
|
|
458
|
+
method: 'get_transport_stats',
|
|
459
|
+
params: { nodeAddress },
|
|
460
|
+
}),
|
|
461
|
+
this.use(this.address, {
|
|
462
|
+
method: 'get_connection_manager_status',
|
|
463
|
+
params: { nodeAddress },
|
|
464
|
+
}),
|
|
465
|
+
]);
|
|
466
|
+
return {
|
|
467
|
+
timestamp: Date.now(),
|
|
468
|
+
nodeAddress,
|
|
469
|
+
peerInfo: peerInfoResult.result.data,
|
|
470
|
+
dhtStatus: dhtStatusResult.result.data,
|
|
471
|
+
transportStats: transportStatsResult.result.data,
|
|
472
|
+
connectionManagerStatus: connectionManagerStatusResult.result.data,
|
|
473
|
+
};
|
|
474
|
+
}
|
|
475
|
+
catch (error) {
|
|
476
|
+
throw new Error(`Failed to get all libp2p metrics from ${nodeAddress}: ${error.message}`);
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
// Otherwise, get metrics from all nodes
|
|
480
|
+
if (!this.metricsStore) {
|
|
481
|
+
throw new Error('MetricsStore not configured');
|
|
165
482
|
}
|
|
166
483
|
try {
|
|
167
|
-
const
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
this.
|
|
171
|
-
|
|
172
|
-
|
|
484
|
+
const allNodes = this.metricsStore.getAllTrackedNodes();
|
|
485
|
+
const nodeMetrics = {};
|
|
486
|
+
for (const address of allNodes) {
|
|
487
|
+
const latestMetrics = this.metricsStore.getLatestMetrics(address);
|
|
488
|
+
if (latestMetrics?.libp2pMetrics?.available) {
|
|
489
|
+
nodeMetrics[address] = latestMetrics.libp2pMetrics;
|
|
490
|
+
}
|
|
491
|
+
}
|
|
173
492
|
return {
|
|
174
493
|
timestamp: Date.now(),
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
connectionManagerStatus,
|
|
494
|
+
nodeCount: Object.keys(nodeMetrics).length,
|
|
495
|
+
totalNodes: allNodes.length,
|
|
496
|
+
nodes: nodeMetrics,
|
|
179
497
|
};
|
|
180
498
|
}
|
|
181
499
|
catch (error) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"node-health.provider.d.ts","sourceRoot":"","sources":["../../../src/providers/node-health.provider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAY,QAAQ,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC3D,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAEzD,MAAM,WAAW,wBAAyB,SAAQ,eAAe;IAC/D,YAAY,EAAE,YAAY,CAAC;CAC5B;AAED;;;GAGG;AACH,qBAAa,kBAAmB,SAAQ,SAAS;IAC/C,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,eAAe,CAAC,CAAiB;IACzC,OAAO,CAAC,iBAAiB,CAAiB;gBAE9B,MAAM,EAAE,wBAAwB;IAgBtC,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAS3B,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAK/B;;OAEG;IACG,0BAA0B,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC;
|
|
1
|
+
{"version":3,"file":"node-health.provider.d.ts","sourceRoot":"","sources":["../../../src/providers/node-health.provider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAY,QAAQ,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC3D,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAEzD,MAAM,WAAW,wBAAyB,SAAQ,eAAe;IAC/D,YAAY,EAAE,YAAY,CAAC;CAC5B;AAED;;;GAGG;AACH,qBAAa,kBAAmB,SAAQ,SAAS;IAC/C,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,eAAe,CAAC,CAAiB;IACzC,OAAO,CAAC,iBAAiB,CAAiB;gBAE9B,MAAM,EAAE,wBAAwB;IAgBtC,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAS3B,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAK/B;;OAEG;IACG,0BAA0B,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC;IAwDjE;;OAEG;IACG,yBAAyB,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC;IA2ChE;;OAEG;IACG,0BAA0B,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC;IAwCjE;;OAEG;IACG,4BAA4B,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC;IAmDnE;;OAEG;IACH,OAAO,CAAC,YAAY;IAkCpB;;OAEG;IACH,OAAO,CAAC,WAAW;IAQnB;;OAEG;IACG,cAAc,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC;CA+BtD"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { oAddress
|
|
1
|
+
import { oAddress } from '@olane/o-core';
|
|
2
2
|
import { oNodeTool } from '@olane/o-node';
|
|
3
3
|
/**
|
|
4
4
|
* Node Health Provider - Polls nodes for health status and metrics
|
|
@@ -47,16 +47,17 @@ export class NodeHealthProvider extends oNodeTool {
|
|
|
47
47
|
method: 'get_metrics',
|
|
48
48
|
params: {},
|
|
49
49
|
});
|
|
50
|
+
const data = metrics.result.data;
|
|
50
51
|
// Store in metrics store
|
|
51
52
|
if (metrics.result) {
|
|
52
53
|
this.metricsStore.storeMetrics(address, {
|
|
53
|
-
successCount:
|
|
54
|
-
errorCount:
|
|
55
|
-
activeRequests:
|
|
56
|
-
state:
|
|
57
|
-
uptime:
|
|
58
|
-
memoryUsage:
|
|
59
|
-
children:
|
|
54
|
+
successCount: data.successCount || 0,
|
|
55
|
+
errorCount: data.errorCount || 0,
|
|
56
|
+
activeRequests: data.activeRequests || 0,
|
|
57
|
+
state: data.state,
|
|
58
|
+
uptime: data.uptime,
|
|
59
|
+
memoryUsage: data.memoryUsage,
|
|
60
|
+
children: data.children,
|
|
60
61
|
});
|
|
61
62
|
}
|
|
62
63
|
results.push({
|
|
@@ -137,13 +138,12 @@ export class NodeHealthProvider extends oNodeTool {
|
|
|
137
138
|
method: 'get_metrics',
|
|
138
139
|
params: {},
|
|
139
140
|
});
|
|
140
|
-
|
|
141
|
+
const data = metrics.result.data;
|
|
142
|
+
if (data && data.children) {
|
|
141
143
|
hierarchyData.push({
|
|
142
144
|
address,
|
|
143
|
-
children:
|
|
144
|
-
childCount: Array.isArray(
|
|
145
|
-
? metrics.result.children.length
|
|
146
|
-
: 0,
|
|
145
|
+
children: data.children,
|
|
146
|
+
childCount: Array.isArray(data.children) ? data.children.length : 0,
|
|
147
147
|
});
|
|
148
148
|
}
|
|
149
149
|
}
|
|
@@ -216,7 +216,7 @@ export class NodeHealthProvider extends oNodeTool {
|
|
|
216
216
|
this.pollingInterval = setInterval(async () => {
|
|
217
217
|
try {
|
|
218
218
|
// Get all registered nodes from leader
|
|
219
|
-
const registry = await this.use(
|
|
219
|
+
const registry = await this.use(oAddress.registry(), {
|
|
220
220
|
method: 'find_all',
|
|
221
221
|
params: {},
|
|
222
222
|
});
|
|
@@ -225,15 +225,10 @@ export class NodeHealthProvider extends oNodeTool {
|
|
|
225
225
|
? registry.result.data.map((node) => node.address)
|
|
226
226
|
: [];
|
|
227
227
|
// Collect metrics from all nodes
|
|
228
|
-
await this.
|
|
228
|
+
await this.use(this.address, {
|
|
229
229
|
method: 'collect_node_metrics',
|
|
230
|
-
params: {
|
|
231
|
-
|
|
232
|
-
_connectionId: 'auto-poll',
|
|
233
|
-
_requestMethod: 'collect_node_metrics',
|
|
234
|
-
},
|
|
235
|
-
id: 'auto-poll',
|
|
236
|
-
}));
|
|
230
|
+
params: { addresses },
|
|
231
|
+
});
|
|
237
232
|
}
|
|
238
233
|
}
|
|
239
234
|
catch (error) {
|
|
@@ -256,7 +251,7 @@ export class NodeHealthProvider extends oNodeTool {
|
|
|
256
251
|
*/
|
|
257
252
|
async _tool_poll_now(request) {
|
|
258
253
|
try {
|
|
259
|
-
const registry = await this.use(
|
|
254
|
+
const registry = await this.use(oAddress.registry(), {
|
|
260
255
|
method: 'find_all',
|
|
261
256
|
params: {},
|
|
262
257
|
});
|
|
@@ -269,15 +264,10 @@ export class NodeHealthProvider extends oNodeTool {
|
|
|
269
264
|
const addresses = Array.isArray(registry.result.data)
|
|
270
265
|
? registry.result.data.map((node) => node.address)
|
|
271
266
|
: [];
|
|
272
|
-
const result = await this.
|
|
267
|
+
const result = await this.use(this.address, {
|
|
273
268
|
method: 'collect_node_metrics',
|
|
274
|
-
params: {
|
|
275
|
-
|
|
276
|
-
_connectionId: 'manual-poll',
|
|
277
|
-
_requestMethod: 'collect_node_metrics',
|
|
278
|
-
},
|
|
279
|
-
id: 'manual-poll',
|
|
280
|
-
}));
|
|
269
|
+
params: { addresses },
|
|
270
|
+
});
|
|
281
271
|
return {
|
|
282
272
|
message: 'Polling completed',
|
|
283
273
|
...result,
|
|
@@ -3,6 +3,22 @@
|
|
|
3
3
|
* Stores metrics with timestamps for each node
|
|
4
4
|
*/
|
|
5
5
|
/// <reference types="node" />
|
|
6
|
+
export interface LibP2PMetrics {
|
|
7
|
+
peerCount?: number;
|
|
8
|
+
connectionCount?: number;
|
|
9
|
+
inboundConnections?: number;
|
|
10
|
+
outboundConnections?: number;
|
|
11
|
+
streamCount?: number;
|
|
12
|
+
dhtEnabled?: boolean;
|
|
13
|
+
dhtMode?: string;
|
|
14
|
+
dhtRoutingTableSize?: number;
|
|
15
|
+
protocols?: string[];
|
|
16
|
+
selfPeerId?: string;
|
|
17
|
+
multiaddrs?: string[];
|
|
18
|
+
bytesReceived?: number;
|
|
19
|
+
bytesSent?: number;
|
|
20
|
+
[key: string]: any;
|
|
21
|
+
}
|
|
6
22
|
export interface MetricEntry {
|
|
7
23
|
timestamp: number;
|
|
8
24
|
successCount: number;
|
|
@@ -12,6 +28,7 @@ export interface MetricEntry {
|
|
|
12
28
|
uptime?: number;
|
|
13
29
|
memoryUsage?: NodeJS.MemoryUsage;
|
|
14
30
|
children?: string[];
|
|
31
|
+
libp2pMetrics?: LibP2PMetrics;
|
|
15
32
|
[key: string]: any;
|
|
16
33
|
}
|
|
17
34
|
export interface HeartbeatEntry {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"metrics-store.d.ts","sourceRoot":"","sources":["../../../src/utils/metrics-store.ts"],"names":[],"mappings":"AAAA;;;GAGG;;AAEH,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC,WAAW,CAAC;IACjC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACpB;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,GAAG,CAAC;CACf;AAED,qBAAa,YAAY;IACvB,OAAO,CAAC,WAAW,CAAyC;IAC5D,OAAO,CAAC,UAAU,CAA0C;IAC5D,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAgB;IAClD,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAiB;IAEpD;;OAEG;IACH,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,WAAW,EAAE,WAAW,CAAC,GAAG,IAAI;IAsB5E;;OAEG;IACH,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,GAAG,IAAI;IAQrD;;OAEG;IACH,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI;IAQrD;;OAEG;IACH,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW,EAAE;IAI7C;;OAEG;IACH,iBAAiB,CACf,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,GACd,WAAW,EAAE;IAOhB;;OAEG;IACH,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI;IAIxD;;OAEG;IACH,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAQrC;;OAEG;IACH,gBAAgB,IAAI,cAAc,EAAE;IAIpC;;OAEG;IACH,gBAAgB,IAAI,MAAM,EAAE;IAa5B;;OAEG;IACH,kBAAkB,IAAI,MAAM,EAAE;IAI9B;;OAEG;IACH,OAAO,CAAC,WAAW,GAAE,MAAgB,GAAG,IAAI;IAc5C;;OAEG;IACH,UAAU,IAAI;QACZ,UAAU,EAAE,MAAM,CAAC;QACnB,UAAU,EAAE,MAAM,CAAC;QACnB,UAAU,EAAE,MAAM,CAAC;QACnB,kBAAkB,EAAE,MAAM,CAAC;KAC5B;CAuBF"}
|
|
1
|
+
{"version":3,"file":"metrics-store.d.ts","sourceRoot":"","sources":["../../../src/utils/metrics-store.ts"],"names":[],"mappings":"AAAA;;;GAGG;;AAEH,MAAM,WAAW,aAAa;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACpB;AAED,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC,WAAW,CAAC;IACjC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACpB;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,GAAG,CAAC;CACf;AAED,qBAAa,YAAY;IACvB,OAAO,CAAC,WAAW,CAAyC;IAC5D,OAAO,CAAC,UAAU,CAA0C;IAC5D,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAgB;IAClD,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAiB;IAEpD;;OAEG;IACH,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,WAAW,EAAE,WAAW,CAAC,GAAG,IAAI;IAsB5E;;OAEG;IACH,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,GAAG,IAAI;IAQrD;;OAEG;IACH,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI;IAQrD;;OAEG;IACH,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW,EAAE;IAI7C;;OAEG;IACH,iBAAiB,CACf,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,GACd,WAAW,EAAE;IAOhB;;OAEG;IACH,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI;IAIxD;;OAEG;IACH,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAQrC;;OAEG;IACH,gBAAgB,IAAI,cAAc,EAAE;IAIpC;;OAEG;IACH,gBAAgB,IAAI,MAAM,EAAE;IAa5B;;OAEG;IACH,kBAAkB,IAAI,MAAM,EAAE;IAI9B;;OAEG;IACH,OAAO,CAAC,WAAW,GAAE,MAAgB,GAAG,IAAI;IAc5C;;OAEG;IACH,UAAU,IAAI;QACZ,UAAU,EAAE,MAAM,CAAC;QACnB,UAAU,EAAE,MAAM,CAAC;QACnB,UAAU,EAAE,MAAM,CAAC;QACnB,kBAAkB,EAAE,MAAM,CAAC;KAC5B;CAuBF"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@olane/o-monitor",
|
|
3
|
-
"version": "0.7.12
|
|
3
|
+
"version": "0.7.12",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/src/index.js",
|
|
6
6
|
"types": "dist/src/index.d.ts",
|
|
@@ -37,16 +37,16 @@
|
|
|
37
37
|
"@modelcontextprotocol/sdk": "^1.18.1"
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"@libp2p/prometheus-metrics": "^
|
|
41
|
-
"@olane/o-config": "0.7.12
|
|
42
|
-
"@olane/o-core": "0.7.12
|
|
43
|
-
"@olane/o-intelligence": "0.7.12
|
|
44
|
-
"@olane/o-lane": "0.7.12
|
|
45
|
-
"@olane/o-leader": "0.7.12
|
|
46
|
-
"@olane/o-node": "0.7.12
|
|
47
|
-
"@olane/o-protocol": "0.7.12
|
|
48
|
-
"@olane/o-storage": "0.7.12
|
|
49
|
-
"@olane/o-tool": "0.7.12
|
|
40
|
+
"@libp2p/prometheus-metrics": "^5.0.7",
|
|
41
|
+
"@olane/o-config": "0.7.12",
|
|
42
|
+
"@olane/o-core": "0.7.12",
|
|
43
|
+
"@olane/o-intelligence": "0.7.12",
|
|
44
|
+
"@olane/o-lane": "0.7.12",
|
|
45
|
+
"@olane/o-leader": "0.7.12",
|
|
46
|
+
"@olane/o-node": "0.7.12",
|
|
47
|
+
"@olane/o-protocol": "0.7.12",
|
|
48
|
+
"@olane/o-storage": "0.7.12",
|
|
49
|
+
"@olane/o-tool": "0.7.12",
|
|
50
50
|
"debug": "^4.4.1",
|
|
51
51
|
"dotenv": "^16.5.0",
|
|
52
52
|
"express": "^4.18.2",
|
|
@@ -74,5 +74,5 @@
|
|
|
74
74
|
"tsx": "^4.20.3",
|
|
75
75
|
"typescript": "5.4.5"
|
|
76
76
|
},
|
|
77
|
-
"gitHead": "
|
|
77
|
+
"gitHead": "3ae788ffdde8a9ea7d01245cfda5e67052ec263f"
|
|
78
78
|
}
|