{ "info": { "author": "Shayne Sweeney", "author_email": "shayne@instagram.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 4 - Beta", "Intended Audience :: Developers", "License :: OSI Approved :: GNU Library or Lesser General Public License (LGPL)", "Natural Language :: English", "Operating System :: OS Independent", "Programming Language :: Python :: 2.5", "Programming Language :: Python :: 2.6", "Programming Language :: Python :: 2.7", "Topic :: Software Development :: Debuggers", "Topic :: Utilities" ], "description": "====================================================\nTripod - Slow Script Watchdog\n====================================================\n\n\nOverview\n--------\n\nTripod is a module that samples running scripts, logging tracebacks to a temp file.\n\nMost of the code was brought over from the `Django watchdog middleware project, Dogslow`_.\n\n.. _Django watchdog middleware project, Dogslow: https://bitbucket.org/evzijst/dogslow\n\n\nInstallation\n------------\n\nInstall tripod::\n\n $ pip install tripod\n\n\nConfiguration\n-------------\n\nYou can use the following environmental variables to adjust the sampler::\n\n # Log traceback of running script every 5 seconds\n TRIPOD_INTERVAL = 5\n\n\nUsage\n-----\n\nRun tripod::\n\n $ python -m tripod.sampler ./some_script.py\n [Tripod] Sampling every 5.000000 seconds\n [Tripod] Writing output to: /tmp/slow_process_tkM6Rt.log\n\nEvery 5 seconds the watchdog is activated and takes a peek at the script's\nstack and appends the backtrace (including all local stack variables) to the\nlog file.\n\nEvery stack is appended to the log file and looks like this::\n\n\n File \"/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/runpy.py\", line 162, in _run_module_as_main\n \"__main__\", fname, loader, pkg_name)\n File \"/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/runpy.py\", line 72, in _run_code\n exec code in run_globals\n File \"/Users/shayne/Code/tripod/tripod/sampler.py\", line 128, in \n main()\n File \"/Users/shayne/Code/tripod/tripod/sampler.py\", line 118, in main\n exec f.read() in globals(), globals()\n File \"\", line 5, in \n File \"/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/socket.py\", line 351, in read\n data = self._sock.recv(rbufsize)\n File \"/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/httplib.py\", line 553, in read\n s = self.fp.read(amt)\n File \"/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/socket.py\", line 380, in read\n data = self._sock.recv(left)\n\n Full backtrace with local variables:\n\n File \"/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/runpy.py\", line 162, in _run_module_as_main\n \"__main__\", fname, loader, pkg_name)\n\n Arguments: _run_module_as_main(mod_name='tripod.sampler', alter_argv=1)\n Local variables:\n\n {'alter_argv': 1,\n 'code': at 0x10ba09a30, file \"/Users/shayne/Code/tripod/tripod/sampler.py\", line 1>,\n 'fname': '/Users/shayne/Code/tripod/tripod/sampler.py',\n 'loader': ,\n 'main_globals': {'SafePrettyPrinter': ,\n 'Timer': ,\n '__builtins__': ,\n '__doc__': None,\n '__file__': 'slow.py',\n '__loader__': ,\n '__name__': '__main__',\n '__package__': 'tripod',\n 'dt': ,\n 'f': >,\n 'formatvalue': ,\n 'inspect': ,\n 'linecache': ,\n 'main': ,\n 'os': ,\n 'peek': ,\n 'pprint': ,\n 'spformat': ,\n 'stack': ,\n 'sys': ,\n 'tempfile': ,\n 'thread': ,\n 'urllib2': },\n 'mod_name': 'tripod.sampler',\n 'pkg_name': 'tripod'}\n\n File \"/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/runpy.py\", line 72, in _run_code\n exec code in run_globals\n\n Arguments: _run_code(code= at 0x10ba09a30, file \"/Users/shayne/Code/tripod/tripod/sampler.py\", line 1>, run_globals=, init_globals=None, mod_name='__main__', mod_fname='/Users/shayne/Code/tripod/tripod/sampler.py', mod_loader=, pkg_name='tripod')\n Local variables:\n\n {'code': at 0x10ba09a30, file \"/Users/shayne/Code/tripod/tripod/sampler.py\", line 1>,\n 'init_globals': None,\n 'mod_fname': '/Users/shayne/Code/tripod/tripod/sampler.py',\n 'mod_loader': ,\n 'mod_name': '__main__',\n\n ...loads more...\n\nThe example above shows that the request thread was blocked in\n``f.read()`` at the time ``tripod`` took its snapshot.\n\nNote that ``tripod`` only takes a peek at the thread's stack. It does not\ninterrupt the script, or influence it in any other way.\n\n\nCaveats\n-------\n\nTripod, like Dogslow uses multithreading. It has a single background thread that handles the\ntimer timeouts and takes the tracebacks, so that the original script\nthreads are not interrupted. This has some consequences.\n\n\nMultithreading and the GIL\n~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nIn cPython, the GIL (Global Interpreter Lock) prevents multiple threads from\nexecuting Python code simultaneously. Only when a thread explicitly releases\nits lock on the GIL, can a second thread run.\n\nReleasing the GIL is done automatically whenever a Python program makes\nblocking calls outside of the interpreter, for example when doing IO.\n\nFor ``tripod`` this means that it can only reliably sample scripts that\nare slow because they are doing IO, calling sleep or busy waiting to acquire\nlocks themselves.\n\nIn most cases this is fine. A scenario where cPython's GIL is problematic\nis when the request's thread hits an infinite loop in Python code\n(or legitimate Python that is extremely expensive and takes a long time\nto execute), never releasing the GIL. Even though ``tripod``'s watchdog\ntimer does become runnable, it cannot log the stack.\n\n\nCo-routines and Greenlets\n~~~~~~~~~~~~~~~~~~~~~~~~~\n\n``Tripod`` is intended for use in a synchronous configuration. A\nprocess that uses dedicated threads (or single-threaded processes).\n\nWhen running with a \"co-routines framework\" where multiple requests are served\nconcurrently by one thread, backtraces might become nonsensical.", "description_content_type": null, "docs_url": null, "download_url": "https://github.com/downloads/shayne/tripod/tripod-0.1.tar.gz", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/shayne/tripod", "keywords": "debug watchdog middleware traceback", "license": "GNU LGPL", "maintainer": null, "maintainer_email": null, "name": "tripod", "package_url": "https://pypi.org/project/tripod/", "platform": "UNKNOWN", "project_url": "https://pypi.org/project/tripod/", "project_urls": { "Download": "https://github.com/downloads/shayne/tripod/tripod-0.1.tar.gz", "Homepage": "https://github.com/shayne/tripod" }, "release_url": "https://pypi.org/project/tripod/0.1/", "requires_dist": null, "requires_python": null, "summary": "A module that samples running scripts, logging tracebacks.", "version": "0.1" }, "last_serial": 803419, "releases": { "0.1": [ { "comment_text": "", "digests": { "md5": "c6ab3f2f1c2a135e6e4c73a6c4ae8e73", "sha256": "ff5b1471cd910e1ed3be46ca3730ec9e24aa2db08bdd46730c7e6697d8fc9231" }, "downloads": -1, "filename": "tripod-0.1.tar.gz", "has_sig": false, "md5_digest": "c6ab3f2f1c2a135e6e4c73a6c4ae8e73", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 15614, "upload_time": "2012-08-29T19:29:54", "url": "https://files.pythonhosted.org/packages/db/79/3b2e5677b33f011e61691a900050da26dbf4184f455d4321ca2670d2715a/tripod-0.1.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "c6ab3f2f1c2a135e6e4c73a6c4ae8e73", "sha256": "ff5b1471cd910e1ed3be46ca3730ec9e24aa2db08bdd46730c7e6697d8fc9231" }, "downloads": -1, "filename": "tripod-0.1.tar.gz", "has_sig": false, "md5_digest": "c6ab3f2f1c2a135e6e4c73a6c4ae8e73", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 15614, "upload_time": "2012-08-29T19:29:54", "url": "https://files.pythonhosted.org/packages/db/79/3b2e5677b33f011e61691a900050da26dbf4184f455d4321ca2670d2715a/tripod-0.1.tar.gz" } ] }