@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 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** (if enabled):
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,OAA8B,MAAM,SAAS,CAAC;AAErD,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,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,CAAsB;IACjC,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;gBAEpC,MAAM,EAAE,uBAAuB;IAmD3C,OAAO,CAAC,WAAW;IA0JnB;;OAEG;IACH,OAAO,CAAC,uBAAuB;IA0B/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"}
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"}
@@ -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
- // Initialize Prometheus registry
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
- // Merge with default Prometheus metrics (if libp2p metrics are enabled)
45
- promClient.collectDefaultMetrics({ register: this.registry });
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(express.json());
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
@@ -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
@@ -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;AAO1C,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;CACpB;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;IAGzC,OAAO,CAAC,iBAAiB,CAAC,CAAoB;IAC9C,OAAO,CAAC,kBAAkB,CAAC,CAAqB;IAChD,OAAO,CAAC,qBAAqB,CAAC,CAAwB;gBAE1C,MAAM,EAAE,iBAAiB;IAkB/B,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAiB3B,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IA0B/B;;OAEG;YACW,mBAAmB;IA8BjC;;OAEG;YACW,eAAe;IAqC7B;;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"}
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"}
@@ -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://leader'), {
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://leader'), {
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://leader'), {
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
- constructor(config: oNodeToolConfig);
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;AAE3D;;;GAGG;AACH,qBAAa,qBAAsB,SAAQ,SAAS;gBACtC,MAAM,EAAE,eAAe;IAS7B,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAIjC;;OAEG;IACG,mBAAmB,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC;IAgC1D;;OAEG;IACG,oBAAoB,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC;IAkC3D;;OAEG;IACG,yBAAyB,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC;IA4ChE;;OAEG;IACG,mCAAmC,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC;IAuC1E;;OAEG;IACG,4BAA4B,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC;IA2BnE;;OAEG;IACG,eAAe,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC;CAiCvD"}
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: kBuckets ? kBuckets.length : 0,
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 p2pNode = this.p2pNode;
163
- if (!p2pNode) {
164
- throw new Error('libp2p node not available');
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 [peerInfo, dhtStatus, transportStats, connectionManagerStatus] = await Promise.all([
168
- this._tool_get_peer_info(request),
169
- this._tool_get_dht_status(request),
170
- this._tool_get_transport_stats(request),
171
- this._tool_get_connection_manager_status(request),
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
- peerInfo,
176
- dhtStatus,
177
- transportStats,
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;IAsDjE;;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;IAyCpB;;OAEG;IACH,OAAO,CAAC,WAAW;IAQnB;;OAEG;IACG,cAAc,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC;CAsCtD"}
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, oRequest } from '@olane/o-core';
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: metrics.result.successCount || 0,
54
- errorCount: metrics.result.errorCount || 0,
55
- activeRequests: metrics.result.activeRequests || 0,
56
- state: metrics.result.state,
57
- uptime: metrics.result.uptime,
58
- memoryUsage: metrics.result.memoryUsage,
59
- children: metrics.result.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
- if (metrics.result && metrics.result.children) {
141
+ const data = metrics.result.data;
142
+ if (data && data.children) {
141
143
  hierarchyData.push({
142
144
  address,
143
- children: metrics.result.children,
144
- childCount: Array.isArray(metrics.result.children)
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(new oAddress('o://leader'), {
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._tool_collect_node_metrics(new oRequest({
228
+ await this.use(this.address, {
229
229
  method: 'collect_node_metrics',
230
- params: {
231
- addresses,
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(new oAddress('o://leader'), {
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._tool_collect_node_metrics(new oRequest({
267
+ const result = await this.use(this.address, {
273
268
  method: 'collect_node_metrics',
274
- params: {
275
- addresses,
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-alpha.9",
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": "^4.3.29",
41
- "@olane/o-config": "0.7.12-alpha.9",
42
- "@olane/o-core": "0.7.12-alpha.9",
43
- "@olane/o-intelligence": "0.7.12-alpha.9",
44
- "@olane/o-lane": "0.7.12-alpha.9",
45
- "@olane/o-leader": "0.7.12-alpha.9",
46
- "@olane/o-node": "0.7.12-alpha.9",
47
- "@olane/o-protocol": "0.7.12-alpha.9",
48
- "@olane/o-storage": "0.7.12-alpha.9",
49
- "@olane/o-tool": "0.7.12-alpha.9",
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": "21427acbdc1d87ff9465bf19bda58cca89e8d3c7"
77
+ "gitHead": "3ae788ffdde8a9ea7d01245cfda5e67052ec263f"
78
78
  }