Skip to content

Commit faba7d3

Browse files
committed
add stderr log content while shutdown with exception while chrome crash
1 parent b983ab1 commit faba7d3

File tree

2 files changed

+58
-23
lines changed

2 files changed

+58
-23
lines changed

ichrome/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from .logs import logger
66
from .pool import ChromeEngine
77

8-
__version__ = "5.0.0"
8+
__version__ = "5.0.1"
99
__tips__ = "[github]: https://github.com/ClericPy/ichrome\n[cdp]: https://chromedevtools.github.io/devtools-protocol/\n[cmd args]: https://peter.sh/experiments/chromium-command-line-switches/"
1010
__all__ = [
1111
"ChromeDaemon",

ichrome/daemon.py

Lines changed: 57 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@ class ChromeDaemon(object):
147147
"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome",
148148
"/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge",
149149
]
150+
SYSTEM_ENCODING = os.getenv("SYSTEM_ENCODING") or ""
150151

151152
def __init__(
152153
self,
@@ -482,30 +483,57 @@ def get_cmd_args(self):
482483
)
483484
if need_reopen:
484485
_path = self.user_data_dir / stdout_path
485-
self.opened_files[0] = _path.open("wb")
486+
self.opened_files[0] = _path.open("wb+")
486487
kwargs["stdout"] = self.opened_files[0]
487488
logger.debug(f"stdout_path -> {_path.absolute().as_posix()}")
488489
if "stderr" not in kwargs and stderr_path:
489490
if stderr_path == "/dev/null":
490491
kwargs["stderr"] = subprocess.DEVNULL
491492
elif stdout_path and stderr_path == stdout_path:
492493
kwargs["stderr"] = subprocess.STDOUT
494+
self.opened_files[1] = self.opened_files[0]
493495
else:
494496
need_reopen = (
495497
not self.opened_files[1] or self.opened_files[1].closed
496498
)
497499
if need_reopen:
498500
_path = self.user_data_dir / stderr_path
499-
self.opened_files[1] = _path.open("wb")
501+
self.opened_files[1] = _path.open("wb+")
500502
kwargs["stderr"] = self.opened_files[1]
501503
logger.debug(f"stderr_path -> {_path.absolute().as_posix()}")
502504
self.cmd_args = kwargs
503505
return kwargs
504506

505-
def close_stdout_stderr(self):
507+
def close_stdout_stderr(self, error_name=""):
506508
for f in self.opened_files:
507509
try:
508510
if f and not f.closed:
511+
try:
512+
if error_name and f is self.opened_files[1]:
513+
last_5_lines = []
514+
f.seek(0)
515+
for line in f:
516+
if not line.strip():
517+
continue
518+
last_5_lines.append(line)
519+
if len(last_5_lines) > 5:
520+
last_5_lines.pop(0)
521+
if last_5_lines:
522+
content = b"".join(last_5_lines)
523+
if self.SYSTEM_ENCODING:
524+
text = content.decode(self.SYSTEM_ENCODING)
525+
else:
526+
try:
527+
text = content.decode("utf-8")
528+
except UnicodeDecodeError:
529+
text = content.decode(
530+
"gb18030", errors="replace"
531+
)
532+
logger.error(
533+
f"stderr file last 5 lines for {error_name}: {text}"
534+
)
535+
except Exception:
536+
pass
509537
f.close()
510538
except Exception:
511539
pass
@@ -692,20 +720,23 @@ def restart(self):
692720
def update_shutdown_time(self):
693721
self._shutdown = time.time()
694722

695-
def shutdown(self, reason=None):
723+
def shutdown(self, reason=None, exc_type=None):
696724
if self._shutdown:
697725
logger.debug(f"{self} shutdown at {ttime(self._shutdown)} yet.")
698726
return
699727
self._shutdown_reason = reason
700728
self.update_shutdown_time()
701-
reason = f" for {reason}" if reason else ""
702-
logger.debug(
703-
f"{self} shutting down{reason}, start-up: {ttime(self.start_time)}, duration: {read_time(time.time() - self.start_time)}."
704-
)
729+
msg = f"{self} shutting down, reason={reason!r}, start-up: {ttime(self.start_time)}, duration: {read_time(time.time() - self.start_time)}."
730+
if exc_type:
731+
logger.exception(msg)
732+
else:
733+
logger.debug(msg)
705734
if self.on_shutdown:
706735
self.on_shutdown(self)
707736
self.kill(True)
708-
self.close_stdout_stderr()
737+
self.close_stdout_stderr(
738+
error_name=getattr(exc_type, "__name__", repr(exc_type))
739+
)
709740
if self.after_shutdown:
710741
self.after_shutdown(self)
711742
if self.clear_after_shutdown:
@@ -714,8 +745,8 @@ def shutdown(self, reason=None):
714745
def __enter__(self):
715746
return self
716747

717-
def __exit__(self, *args):
718-
self.shutdown("__exit__")
748+
def __exit__(self, exc_type, exc_val, exc_tb):
749+
self.shutdown("__exit__", exc_type)
719750

720751
@staticmethod
721752
def get_proc(port, host=None):
@@ -1013,8 +1044,8 @@ async def _daemon(self, interval=None):
10131044
async def __aenter__(self):
10141045
return await self._init_coro
10151046

1016-
async def __aexit__(self, *args, **kwargs):
1017-
await self.shutdown("__aexit__")
1047+
async def __aexit__(self, exc_type, exc_val, exc_tb):
1048+
await self.shutdown("__aexit__", exc_type=exc_type)
10181049

10191050
@property
10201051
def x(self):
@@ -1024,21 +1055,25 @@ def x(self):
10241055
else:
10251056
return asyncio.sleep(0)
10261057

1027-
async def shutdown(self, reason=None):
1058+
async def shutdown(self, reason=None, exc_type=None):
10281059
"shutdown the chrome, but do not use it, use async with instead."
10291060
if self._shutdown:
10301061
# logger.debug(f"{self} shutdown at {ttime(self._shutdown)} yet.")
10311062
return
10321063
self._shutdown_reason = reason
10331064
self.update_shutdown_time()
1034-
reason = f" for {reason}" if reason else ""
1035-
logger.debug(
1036-
f"{self} shutting down{reason}, start-up: {ttime(self.start_time)}, duration: {read_time(time.time() - self.start_time)}."
1037-
)
1065+
msg = f"{self} shutting down, reason={reason!r}, start-up: {ttime(self.start_time)}, duration: {read_time(time.time() - self.start_time)}."
1066+
if exc_type:
1067+
logger.exception(msg)
1068+
else:
1069+
logger.debug(msg)
10381070
if self.on_shutdown:
10391071
await ensure_awaitable(self.on_shutdown(self))
10401072
await async_run(self.kill, True)
1041-
await async_run(self.close_stdout_stderr)
1073+
await async_run(
1074+
self.close_stdout_stderr,
1075+
error_name=getattr(exc_type, "__name__", repr(exc_type)),
1076+
)
10421077
if self.after_shutdown:
10431078
await ensure_awaitable(self.after_shutdown(self))
10441079
if self.clear_after_shutdown:
@@ -1145,7 +1180,7 @@ def __init__(self, start_port=9222, workers=1, kwargs=None):
11451180
self.start_port = start_port or 9222
11461181
self.workers = workers or 1
11471182
self.kwargs = kwargs or {}
1148-
self.daemons = []
1183+
self.daemons: List[AsyncChromeDaemon] = []
11491184
self.tasks = []
11501185

11511186
async def __aenter__(self):
@@ -1170,9 +1205,9 @@ async def wait(self):
11701205
except asyncio.CancelledError:
11711206
pass
11721207

1173-
async def __aexit__(self, *args):
1208+
async def __aexit__(self, exc_type, exc_val, exc_tb):
11741209
for daemon in self.daemons:
1175-
await daemon.shutdown("__aexit__")
1210+
await daemon.shutdown("__aexit__", exc_type=exc_type)
11761211

11771212
@classmethod
11781213
async def run_chrome_workers(cls, start_port, workers, kwargs):

0 commit comments

Comments
 (0)