fix: periodic cProfile dump every 60s (survives hard kills)
Replace cProfile.runctx with Profile() + daemon thread that dumps stats to disk every 60 seconds. Final dump on clean exit. Profile data no longer lost on container stop, OOM, or SIGKILL. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -193,10 +193,32 @@ def main(argv: list[str] | None = None) -> int:
|
||||
|
||||
if args.cprofile:
|
||||
import cProfile
|
||||
import threading
|
||||
|
||||
log.info("cProfile enabled, output: %s", args.cprofile)
|
||||
cProfile.runctx("_run(bots)", globals(), {"bots": bots, "_run": _run}, args.cprofile)
|
||||
log.info("profile saved to %s", args.cprofile)
|
||||
prof = cProfile.Profile()
|
||||
prof_path = args.cprofile
|
||||
prof_interval = 60 # dump every 60 seconds
|
||||
prof_stop = threading.Event()
|
||||
|
||||
def _periodic_dump():
|
||||
while not prof_stop.wait(prof_interval):
|
||||
try:
|
||||
prof.dump_stats(prof_path)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
dumper = threading.Thread(target=_periodic_dump, daemon=True)
|
||||
dumper.start()
|
||||
log.info("cProfile enabled, output: %s (saves every %ds)",
|
||||
prof_path, prof_interval)
|
||||
prof.enable()
|
||||
try:
|
||||
_run(bots)
|
||||
finally:
|
||||
prof.disable()
|
||||
prof_stop.set()
|
||||
prof.dump_stats(prof_path)
|
||||
log.info("profile saved to %s", prof_path)
|
||||
else:
|
||||
_run(bots)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user