Repository: modin-project/modin

Issue:
Improve RPyC logging
Currently stdout/stderr of rpyc server is not logged, and it can contain clues needed for bug hunting, so we should store it when `MODIN_LOG_RPYC` is set.


Discussion:

Resolving patch:
diff --git a/modin/experimental/cloud/connection.py b/modin/experimental/cloud/connection.py
--- a/modin/experimental/cloud/connection.py
+++ b/modin/experimental/cloud/connection.py
@@ -38,8 +38,11 @@ def __wait_noexc(proc: subprocess.Popen, timeout: float):
             return None
 
     def __init__(self, details: ConnectionDetails, main_python: str, log_rpyc=None):
-        if log_rpyc is None:
-            log_rpyc = os.environ.get("MODIN_LOG_RPYC", "").title() == "True"
+        self.log_rpyc = (
+            log_rpyc
+            if log_rpyc is not None
+            else os.environ.get("MODIN_LOG_RPYC", "").title() == "True"
+        )
         self.proc = None
 
         # find where rpyc_classic is located
@@ -70,7 +73,7 @@ def __init__(self, details: ConnectionDetails, main_python: str, log_rpyc=None):
             main_python,
             rpyc_classic,
         ]
-        if log_rpyc:
+        if self.log_rpyc:
             cmd.extend(["--logfile", f"{tempfile.gettempdir()}/rpyc.log"])
         for _ in range(self.tries):
             proc = self._run(
@@ -78,7 +81,7 @@ def __init__(self, details: ConnectionDetails, main_python: str, log_rpyc=None):
                 cmd + ["--port", str(port)],
                 capture_out=False,
             )
-            if self.__wait_noexc(proc, 1) is None:
+            if self.__wait_noexc(proc, 3) is None:
                 # started successfully
                 self.proc = proc
                 self.rpyc_port = port
@@ -186,9 +189,15 @@ def _build_sshcmd(self, details: ConnectionDetails, forward_port: int = None):
 
         return cmdline
 
-    @staticmethod
-    def _run(sshcmd: list, cmd: list, capture_out: bool = True):
-        redirect = subprocess.PIPE if capture_out else subprocess.DEVNULL
+    def _redirect(self, capture_out):
+        if capture_out:
+            return subprocess.PIPE
+        if self.log_rpyc:
+            return open(f"{tempfile.gettempdir()}/rpyc.out", "a")
+        return subprocess.DEVNULL
+
+    def _run(self, sshcmd: list, cmd: list, capture_out: bool = True):
+        redirect = self._redirect(capture_out)
         return subprocess.Popen(
             sshcmd + [subprocess.list2cmdline(cmd)],
             stdin=subprocess.DEVNULL,
diff --git a/modin/experimental/cloud/local_cluster.py b/modin/experimental/cloud/local_cluster.py
--- a/modin/experimental/cloud/local_cluster.py
+++ b/modin/experimental/cloud/local_cluster.py
@@ -49,10 +49,11 @@ class LocalConnection(Connection):
     def _build_sshcmd(self, details: ConnectionDetails, forward_port: int = None):
         return []
 
-    @staticmethod
-    def _run(sshcmd: list, cmd: list, capture_out: bool = True):
+    def _run(self, sshcmd: list, cmd: list, capture_out: bool = True):
         assert not sshcmd, "LocalConnection does not support running things via ssh"
-        redirect = subprocess.PIPE if capture_out else subprocess.DEVNULL
+        redirect = self._redirect(capture_out)
+        if not capture_out and hasattr(redirect, "write"):
+            redirect.write(f"Running: {cmd}\n")
         return subprocess.Popen(
             cmd,
             stdin=subprocess.DEVNULL,


Test patch: