1919
2020class PoolCollector (BaseCollector ):
2121 ''' IP Pool Metrics collector
22- '''
22+ '''
2323 @staticmethod
2424 def collect (router_entry ):
2525 # ~*~*~*~*~*~ IPv4 ~*~*~*~*~*~
@@ -36,21 +36,60 @@ def _process_ip_stack(router_entry, ipv6=False):
3636 ip_stack = 'ipv6' if ipv6 else 'ipv4'
3737
3838 # initialize all pool counts, including those currently not used
39- pool_records = PoolMetricsDataSource .metric_records (router_entry , metric_labels = ['name' ], ipv6 = ipv6 )
39+ pool_records = PoolMetricsDataSource .metric_records (router_entry , metric_labels = ['name' , 'ranges' , 'total' ], ipv6 = ipv6 )
4040 if pool_records :
4141 pool_used_labels = ['pool' ]
4242 pool_used_counts = {pool_record ['name' ]: 0 for pool_record in pool_records }
43+ pool_size_counts = {pool_record ['name' ]: int (pool_record .get ('total' , PoolCollector ._calculate_pool_size (pool_record .get ('ranges' , '' )))) for pool_record in pool_records }
4344
4445 # for pools in usage, calculate the current numbers
45- pool_used_records = PoolUsedMetricsDataSource .metric_records (router_entry , metric_labels = pool_used_labels , ipv6 = ipv6 )
46+ pool_used_records = PoolUsedMetricsDataSource .metric_records (router_entry , metric_labels = pool_used_labels , ipv6 = ipv6 )
4647 for pool_used_record in pool_used_records :
4748 pool_used_counts [pool_used_record ['pool' ]] = pool_used_counts .get (pool_used_record ['pool' ], 0 ) + 1
4849
4950 # compile used-per-pool records
5051 used_per_pool_records = [{ MKTXPConfigKeys .ROUTERBOARD_NAME : router_entry .router_id [MKTXPConfigKeys .ROUTERBOARD_NAME ],
5152 MKTXPConfigKeys .ROUTERBOARD_ADDRESS : router_entry .router_id [MKTXPConfigKeys .ROUTERBOARD_ADDRESS ],
5253 'pool' : key , 'count' : value } for key , value in pool_used_counts .items ()]
53-
54+
5455 # yield used-per-pool metrics
5556 used_per_pool_metrics = BaseCollector .gauge_collector (f'ip_pool_used{ "_ipv6" if ipv6 else "" } ' , f'Number of used addresses per IP pool ({ ip_stack .upper ()} )' , used_per_pool_records , 'count' , ['pool' ])
5657 yield used_per_pool_metrics
58+
59+ # compile total-per-pool records
60+ total_per_pool_records = [{ MKTXPConfigKeys .ROUTERBOARD_NAME : router_entry .router_id [MKTXPConfigKeys .ROUTERBOARD_NAME ],
61+ MKTXPConfigKeys .ROUTERBOARD_ADDRESS : router_entry .router_id [MKTXPConfigKeys .ROUTERBOARD_ADDRESS ],
62+ 'pool' : key , 'count' : value } for key , value in pool_size_counts .items ()]
63+
64+ # yield total-per-pool metrics
65+ total_per_pool_metrics = BaseCollector .gauge_collector (f'ip_pool_total{ "_ipv6" if ipv6 else "" } ' , f'Total capacity of IP pool ({ ip_stack .upper ()} )' , total_per_pool_records , 'count' , ['pool' ])
66+ yield total_per_pool_metrics
67+
68+ @staticmethod
69+ def _calculate_pool_size (ranges_str ):
70+ import ipaddress
71+ total = 0
72+ if not ranges_str :
73+ return total
74+ for r in ranges_str .split (',' ):
75+ r = r .strip ()
76+ if not r :
77+ continue
78+ if '-' in r :
79+ start , end = r .split ('-' , 1 )
80+ try :
81+ total += int (ipaddress .ip_address (end .strip ())) - int (ipaddress .ip_address (start .strip ())) + 1
82+ except Exception :
83+ pass
84+ elif '/' in r :
85+ try :
86+ total += ipaddress .ip_network (r , strict = False ).num_addresses
87+ except Exception :
88+ pass
89+ else :
90+ try :
91+ ipaddress .ip_address (r )
92+ total += 1
93+ except Exception :
94+ pass
95+ return total
0 commit comments