11import subprocess
22from logging import Logger
33from pathlib import Path
4- from typing import List
54
6- from logger .utils import get_external_console_logging
5+ from logger .utils import get_external_console_logging , get_services , get_services_id
76
87TAIL_LINES = 100
9- WORKER_PREFIX = "worker"
10- SIM_SERVICE_NAME = "simulation_server"
11-
12-
13- def get_services () -> List [str ]:
14- """Return a list of all docker compose service names."""
15- try :
16- container_ids = subprocess .check_output (
17- ["docker" , "ps" , "-q" ], text = True
18- ).splitlines ()
19-
20- services = set ()
21- for cid in container_ids :
22- inspect_output = subprocess .check_output (
23- [
24- "docker" ,
25- "inspect" ,
26- "--format" ,
27- '{{ index .Config.Labels "com.docker.compose.service" }}' ,
28- cid ,
29- ],
30- text = True ,
31- ).strip ()
32- if inspect_output and inspect_output != "<no value>" :
33- services .add (inspect_output )
34- return list (services )
35- except Exception as e :
36- raise RuntimeError (
37- "Failed to get Docker services. Ensure Docker is running and you have access to it."
38- ) from e
8+ WORKER_PREFIX = "simulation-worker"
9+ SIM_SERVICE_NAME = "simulation-server"
3910
4011
4112def _start_external_xterm_log_terminal (title : str , command : str ) -> None :
@@ -57,6 +28,8 @@ def _start_external_log_terminal(title: str, command: str) -> None:
5728 title ,
5829 command ,
5930 )
31+ except Exception as e :
32+ raise RuntimeError (f"Failed to open external terminal for logging: { e } " ) from e
6033
6134
6235def _start_file_logging (command : str ) -> None :
@@ -69,7 +42,7 @@ def _start_file_logging(command: str) -> None:
6942 )
7043
7144
72- def log_docker_logs (logger : Logger ) -> None :
45+ def log_docker_logs (logger : Logger , disperse_worker_logs : bool = True ) -> None :
7346 """Fetch and log docker logs for workers and simulation service."""
7447 assert logger is not None , "Logger must be initialized before logging Docker logs."
7548
@@ -78,7 +51,7 @@ def log_docker_logs(logger: Logger) -> None:
7851 log_dir .mkdir (exist_ok = True )
7952
8053 try :
81- services = get_services ()
54+ services = get_services (logger )
8255 except RuntimeError as e :
8356 logger .error (f"Error fetching Docker services: { e } " )
8457 return
@@ -89,35 +62,69 @@ def log_docker_logs(logger: Logger) -> None:
8962 return
9063
9164 worker_services = sorted ([s for s in services if s .startswith (WORKER_PREFIX )])
92-
93- worker_log_path = (log_dir / "docker_workers.log" ).resolve ()
9465 sim_log_path = (log_dir / "docker_simulation_server.log" ).resolve ()
9566
67+ logger .info (f"Logging Docker worker services: { worker_services } " )
68+
9669 if worker_services :
97- worker_cmd = f"docker compose logs --tail { TAIL_LINES } --follow { ' ' .join (worker_services )} "
70+ if disperse_worker_logs :
71+ for worker_service in worker_services :
72+ worker_log_path = (
73+ log_dir / f'docker_{ worker_service .replace ("-" , "_" )} .log'
74+ ).resolve ()
75+ worker_cmd = (
76+ f"docker logs --tail { TAIL_LINES } --follow { worker_service } "
77+ )
78+
79+ if get_external_console_logging ():
80+ _start_external_log_terminal (
81+ f"Docker Logs: { worker_service } " ,
82+ f"{ worker_cmd } | stdbuf -oL -eL tee '{ worker_log_path } '" ,
83+ )
84+ logger .info (
85+ f"Opened external terminal for { worker_service } logs (also logging to { worker_log_path } )."
86+ )
87+
88+ _start_file_logging (f"{ worker_cmd } > '{ worker_log_path } '" )
89+ logger .info (f"Logging { worker_service } logs to file: { worker_log_path } " )
90+ else :
91+ worker_log_path = (log_dir / "docker_workers.log" ).resolve ()
92+ worker_services = sorted (
93+ [s for s in get_services_id () if s .startswith (WORKER_PREFIX )]
94+ )
95+
96+ logger .info (f"Aggregating logs for worker services: { worker_services } " )
97+ worker_cmd = f"docker compose logs --tail { TAIL_LINES } --follow { ' ' .join (worker_services )} "
98+
99+ if get_external_console_logging ():
100+ _start_external_log_terminal (
101+ "Docker Worker Logs" ,
102+ f"{ worker_cmd } | stdbuf -oL -eL tee '{ worker_log_path } '" ,
103+ )
104+ logger .info (
105+ f"Opened external terminal for aggregated worker logs (also logging to { worker_log_path } )."
106+ )
107+
108+ _start_file_logging (f"{ worker_cmd } > '{ worker_log_path } '" )
109+ logger .info (f"Logging aggregated worker logs to file: { worker_log_path } " )
110+
111+ if SIM_SERVICE_NAME in services :
112+ sim_cmd = f"docker logs --tail { TAIL_LINES } --follow { SIM_SERVICE_NAME } "
98113
99114 if get_external_console_logging ():
100115 _start_external_log_terminal (
101- "Docker Worker Logs" ,
102- f"{ worker_cmd } | stdbuf -oL -eL tee '{ worker_log_path } '" ,
116+ "Docker Simulation Server Logs" ,
117+ f"{ sim_cmd } | stdbuf -oL -eL tee '{ sim_log_path } '" ,
103118 )
104119 logger .info (
105- f"Opened external terminal for worker logs (also logging to { worker_log_path } )."
120+ f"Opened external terminal for simulation logs (also logging to { sim_log_path } )."
106121 )
107122
108- _start_file_logging (f"{ worker_cmd } > '{ worker_log_path } '" )
109- logger .info (f"Logging worker logs to file: { worker_log_path } " )
110-
111- sim_cmd = f"docker logs --tail { TAIL_LINES } --follow { SIM_SERVICE_NAME } "
112-
113- if get_external_console_logging ():
114- _start_external_log_terminal (
115- "Docker Simulation Server Logs" ,
116- f"{ sim_cmd } | stdbuf -oL -eL tee '{ sim_log_path } '" ,
123+ _start_file_logging (f"{ sim_cmd } > '{ sim_log_path } '" )
124+ logger .info (f"Logging simulation logs to file: { sim_log_path } " )
125+ elif SIM_SERVICE_NAME not in services and any (
126+ s .startswith (WORKER_PREFIX ) for s in services
127+ ):
128+ logger .warning (
129+ f"Simulation service '{ SIM_SERVICE_NAME } ' not found. Skipping simulation server logs."
117130 )
118- logger .info (
119- f"Opened external terminal for simulation logs (also logging to { sim_log_path } )."
120- )
121-
122- _start_file_logging (f"{ sim_cmd } > '{ sim_log_path } '" )
123- logger .info (f"Logging simulation logs to file: { sim_log_path } " )
0 commit comments