|
20 | 20 | from libp2p.rcmgr import Direction |
21 | 21 | from libp2p.rcmgr.manager import ResourceLimits, ResourceManager |
22 | 22 | from libp2p.rcmgr.monitoring import Monitor |
| 23 | +from libp2p.rcmgr.prometheus_exporter import create_prometheus_exporter |
23 | 24 |
|
24 | 25 |
|
25 | 26 | def _is_port_free(port: int) -> bool: |
@@ -74,33 +75,80 @@ def main() -> None: |
74 | 75 | type=str, |
75 | 76 | default=os.getenv("DEMO_LOG_LEVEL", "INFO"), |
76 | 77 | ) |
| 78 | + parser.add_argument( |
| 79 | + "--max-connections", |
| 80 | + type=int, |
| 81 | + default=10, |
| 82 | + metavar="N", |
| 83 | + help="Resource limit: max connections (default: 10)", |
| 84 | + ) |
| 85 | + parser.add_argument( |
| 86 | + "--max-streams", |
| 87 | + type=int, |
| 88 | + default=20, |
| 89 | + metavar="N", |
| 90 | + help="Resource limit: max streams (default: 20)", |
| 91 | + ) |
| 92 | + parser.add_argument( |
| 93 | + "--max-memory-mb", |
| 94 | + type=int, |
| 95 | + default=32, |
| 96 | + metavar="MB", |
| 97 | + help="Resource limit: max memory in MB (default: 32)", |
| 98 | + ) |
| 99 | + parser.add_argument( |
| 100 | + "--interval", |
| 101 | + type=float, |
| 102 | + default=1.0, |
| 103 | + metavar="SECS", |
| 104 | + help="Seconds between iterations (default: 1.0)", |
| 105 | + ) |
| 106 | + parser.add_argument( |
| 107 | + "--no-connection-tracking", |
| 108 | + action="store_true", |
| 109 | + help="Disable connection tracking in the monitor", |
| 110 | + ) |
| 111 | + parser.add_argument( |
| 112 | + "--no-protocol-metrics", |
| 113 | + action="store_true", |
| 114 | + help="Disable protocol metrics in the monitor", |
| 115 | + ) |
77 | 116 | args = parser.parse_args() |
78 | 117 |
|
79 | 118 | _setup_logging(args.log_level) |
80 | 119 |
|
81 | 120 | port = _pick_port(args.port) |
82 | 121 |
|
83 | 122 | limits = ResourceLimits( |
84 | | - max_connections=10, |
85 | | - max_streams=20, |
86 | | - max_memory_mb=32, |
| 123 | + max_connections=args.max_connections, |
| 124 | + max_streams=args.max_streams, |
| 125 | + max_memory_mb=args.max_memory_mb, |
87 | 126 | ) |
88 | 127 |
|
| 128 | + # Single shared exporter so only one HTTP server binds to the port |
| 129 | + shared_exporter = create_prometheus_exporter(port=port, enable_server=True) |
| 130 | + |
89 | 131 | monitor = Monitor( |
90 | | - enable_prometheus=True, |
91 | | - prometheus_port=port, |
92 | | - enable_connection_tracking=True, |
93 | | - enable_protocol_metrics=True, |
| 132 | + prometheus_exporter=shared_exporter, |
| 133 | + enable_connection_tracking=not args.no_connection_tracking, |
| 134 | + enable_protocol_metrics=not args.no_protocol_metrics, |
94 | 135 | ) |
95 | 136 |
|
96 | 137 | rcmgr = ResourceManager( |
97 | 138 | limits=limits, |
98 | | - enable_prometheus=True, |
99 | | - prometheus_port=port, |
| 139 | + prometheus_exporter=shared_exporter, |
100 | 140 | enable_metrics=True, |
101 | 141 | ) |
102 | 142 |
|
103 | | - logging.info("Resource Manager initialized on port %s", port) |
| 143 | + logging.info( |
| 144 | + "Resource Manager initialized on port %s (limits: %s conns, %s streams, " |
| 145 | + "%s MB; interval %.2fs)", |
| 146 | + port, |
| 147 | + limits.max_connections, |
| 148 | + limits.max_streams, |
| 149 | + args.max_memory_mb, |
| 150 | + args.interval, |
| 151 | + ) |
104 | 152 |
|
105 | 153 | connection_count = 0 |
106 | 154 | blocked_connections = 0 |
@@ -276,7 +324,7 @@ def _handle_signal(signum: int, _: object) -> None: |
276 | 324 | monitor.prometheus_exporter.update_from_metrics(rcmgr.metrics) |
277 | 325 |
|
278 | 326 | iteration += 1 |
279 | | - time.sleep(1) |
| 327 | + time.sleep(args.interval) |
280 | 328 |
|
281 | 329 | logging.info( |
282 | 330 | "%s active connections, %s blocked", |
|
0 commit comments