11from aiodocker .docker import DockerContainer
2+ from asyncio import gather
23
3- def calculate_cpu_percentage (stats :dict ) -> float :
4- cpu_percent = 0
5-
6- cpu_delta = stats ['cpu_stats' ]['cpu_usage' ]['total_usage' ] - stats ['precpu_stats' ]['cpu_usage' ]['total_usage' ]
4+ def calculate_cpu_percentage (stats : dict ) -> float :
5+ cpu_stats = stats .get ('cpu_stats' , {})
6+ precpu_stats = stats .get ('precpu_stats' , {})
7+ total = cpu_stats .get ('cpu_usage' , {}).get ('total_usage' )
8+ prev_total = precpu_stats .get ('cpu_usage' , {}).get ('total_usage' )
9+ system = cpu_stats .get ('system_cpu_usage' )
10+ prev_system = precpu_stats .get ('system_cpu_usage' )
11+ n_cpus = cpu_stats .get ('online_cpus' )
712
8- system_delta = stats ['cpu_stats' ]['system_cpu_usage' ] - stats ['precpu_stats' ]['system_cpu_usage' ]
13+ if None in (total , prev_total , system , prev_system , n_cpus ):
14+ return 0.0
915
10- number_cpus = stats ['cpu_stats' ]['online_cpus' ]
11- if cpu_delta is not None and system_delta is not None and number_cpus is not None :
12- cpu_percent = (cpu_delta / system_delta ) * number_cpus * 100.0
16+ cpu_delta = total - prev_total
17+ system_delta = system - prev_system
1318
14- return cpu_percent
19+ if system_delta <= 0 :
20+ return 0.0
1521
16- def calculate_memory_percentage (stats ) -> float :
17- memory_percent = 0
18- memory_usage_bytes = 0
19-
20- memory_usage_bytes = stats ['memory_stats' ]['usage' ]
21- memory_limit = stats ['memory_stats' ]['limit' ]
22- if memory_usage_bytes is not None and memory_limit is not None :
23- memory_percent = (memory_usage_bytes / memory_limit ) * 100.0
22+ return (cpu_delta / system_delta ) * n_cpus * 100.0
23+
24+
25+ def calculate_memory_percentage (stats : dict ) -> float :
26+ mem_stats = stats .get ('memory_stats' , {})
27+ usage = mem_stats .get ('usage' )
28+ limit = mem_stats .get ('limit' )
29+
30+ if usage is None or limit is None or limit == 0 :
31+ return 0.0
32+
33+ return (usage / limit ) * 100.0
2434
25- return memory_percent
2635
2736def calculate_memory_bytes (stats ) -> bytes :
28- memory_usage_bytes = stats ['memory_stats' ]['usage' ]
37+ mem_stats = stats .get ('memory_stats' , {}) or {}
38+ memory_usage_bytes = mem_stats .get ('usage' )
39+
2940 if memory_usage_bytes is not None :
3041 return memory_usage_bytes
31- return 0
42+ return 0.0
3243
33- def calculate_disk_io (stats ) -> bytes :
44+ def calculate_disk_io (stats : dict ) -> bytes :
3445 disk_io_read = 0
3546 disk_io_write = 0
3647
37- if "blkio_stats" in stats and "io_service_bytes_recursive" in stats ["blkio_stats" ]:
38- io_service_bytes_recursive = stats ["blkio_stats" ]["io_service_bytes_recursive" ]
48+ io_list = stats .get ("blkio_stats" , {}) \
49+ .get ("io_service_bytes_recursive" ) or []
50+
51+ for io_stat in io_list :
52+ op = io_stat .get ("op" )
53+ value = io_stat .get ("value" , 0 )
54+ if op == "read" :
55+ disk_io_read += value
56+ elif op == "write" :
57+ disk_io_write += value
3958
40- if io_service_bytes_recursive is not None :
41- for io_stat in io_service_bytes_recursive :
42- if "op" in io_stat and "value" in io_stat :
43- if io_stat ["op" ] == "read" :
44- disk_io_read += io_stat ["value" ]
45- elif io_stat ["op" ] == "write" :
46- disk_io_write += io_stat ["value" ]
4759
4860 return disk_io_read , disk_io_write
4961
@@ -60,6 +72,6 @@ def calculate_network_io(stats) -> bytes:
6072
6173 return network_rx_bytes , network_tx_bytes
6274
63- async def get_container_stats ( container : DockerContainer ):
64- stats = await container .stats (stream = False )
65- return stats
75+ async def get_containers_stats ( containers : list [ DockerContainer ] ):
76+ tasks = [ container .stats (stream = False ) for container in containers ]
77+ return await gather ( * tasks )
0 commit comments