diff --git a/copyparty/__main__.py b/copyparty/__main__.py index a48f47de..93a2aad5 100644 --- a/copyparty/__main__.py +++ b/copyparty/__main__.py @@ -23,7 +23,7 @@ from textwrap import dedent from .__init__ import E, WINDOWS, VT100, PY2, unicode from .__version__ import S_VERSION, S_BUILD_DT, CODENAME from .svchub import SvcHub -from .util import py_desc, align_tab, IMPLICATIONS, alltrace +from .util import py_desc, align_tab, IMPLICATIONS HAVE_SSL = True try: @@ -191,16 +191,6 @@ def sighandler(sig=None, frame=None): print("\n".join(msg)) -def stackmon(fp, ival): - ctr = 0 - while True: - ctr += 1 - time.sleep(ival) - st = "{}, {}\n{}".format(ctr, time.time(), alltrace()) - with open(fp, "wb") as f: - f.write(st.encode("utf-8", "replace")) - - def run_argparse(argv, formatter): ap = argparse.ArgumentParser( formatter_class=formatter, @@ -346,6 +336,7 @@ def run_argparse(argv, formatter): ap2.add_argument("--no-fastboot", action="store_true", help="wait for up2k indexing") ap2.add_argument("--no-htp", action="store_true", help="disable httpserver threadpool, create threads as-needed instead") ap2.add_argument("--stackmon", metavar="P,S", type=u, help="write stacktrace to Path every S second") + ap2.add_argument("--log-thrs", metavar="SEC", type=float, help="list active threads every SEC") return ap.parse_args(args=argv[1:]) # fmt: on @@ -385,16 +376,6 @@ def main(argv=None): except AssertionError: al = run_argparse(argv, Dodge11874) - if al.stackmon: - fp, f = al.stackmon.rsplit(",", 1) - f = int(f) - t = threading.Thread( - target=stackmon, - args=(fp, f), - ) - t.daemon = True - t.start() - # propagate implications for k1, k2 in IMPLICATIONS: if getattr(al, k1): diff --git a/copyparty/svchub.py b/copyparty/svchub.py index c72f1fac..5c35b553 100644 --- a/copyparty/svchub.py +++ b/copyparty/svchub.py @@ -11,7 +11,7 @@ from datetime import datetime, timedelta import calendar from .__init__ import E, PY2, WINDOWS, MACOS, VT100 -from .util import mp +from .util import mp, start_log_thrs, start_stackmon from .authsrv import AuthSrv from .tcpsrv import TcpSrv from .up2k import Up2k @@ -42,6 +42,12 @@ class SvcHub(object): if args.lo: self._setup_logfile(printed) + if args.stackmon: + start_stackmon(args.stackmon, 0) + + if args.log_thrs: + start_log_thrs(self.log, args.log_thrs, 0) + # initiate all services to manage self.asrv = AuthSrv(self.args, self.log, False) if args.ls: diff --git a/copyparty/util.py b/copyparty/util.py index 692e8127..29e1efa4 100644 --- a/copyparty/util.py +++ b/copyparty/util.py @@ -16,6 +16,7 @@ import mimetypes import contextlib import subprocess as sp # nosec from datetime import datetime +from collections import Counter from .__init__ import PY2, WINDOWS, ANYWIN from .stolen import surrogateescape @@ -282,6 +283,62 @@ def alltrace(): return "\n".join(rret + bret) +def start_stackmon(arg_str, nid): + suffix = "-{}".format(nid) if nid else "" + fp, f = arg_str.rsplit(",", 1) + f = int(f) + t = threading.Thread( + target=stackmon, + args=(fp, f, suffix), + name="stackmon" + suffix, + ) + t.daemon = True + t.start() + + +def stackmon(fp, ival, suffix): + ctr = 0 + while True: + ctr += 1 + time.sleep(ival) + st = "{}, {}\n{}".format(ctr, time.time(), alltrace()) + with open(fp + suffix, "wb") as f: + f.write(st.encode("utf-8", "replace")) + + +def start_log_thrs(logger, ival, nid): + ival = int(ival) + tname = lname = "log-thrs" + if nid: + tname = "logthr-n{}-i{:x}".format(nid, os.getpid()) + lname = tname[3:] + + t = threading.Thread( + target=log_thrs, + args=(logger, ival, lname), + name=tname, + ) + t.daemon = True + t.start() + + +def log_thrs(log, ival, name): + while True: + time.sleep(ival) + tv = [x.name for x in threading.enumerate()] + tv = [ + x.split("-")[0] + if x.startswith("httpconn-") or x.startswith("thumb-") + else "listen" + if "-listen-" in x + else x + for x in tv + if not x.startswith("pydevd.") + ] + tv = ["{}\033[36m{}".format(v, k) for k, v in sorted(Counter(tv).items())] + log(name, "\033[0m \033[33m".join(tv), 3) + + def min_ex(): et, ev, tb = sys.exc_info() tb = traceback.extract_tb(tb)