{ "info": { "author": "Dave Shawley", "author_email": "daveshawley@gmail.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 2 - Pre-Alpha", "Environment :: Web Environment", "Intended Audience :: Developers", "License :: OSI Approved :: BSD License", "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Topic :: Internet :: WWW/HTTP" ], "description": "=============\ndiv\u00e1k-tornado\n=============\n\n|Version| |ReadTheDocs| |CI| |Coverage| |CodeClimate|\n\nHelper classes for observing your Tornado-based HTTP code.\n\n+---------------+----------------------------------------------------+\n| Source Code | https://github.com/dave-shawley/divak-tornado |\n+---------------+----------------------------------------------------+\n| Download | https://pypi.org/project/divak-tornado |\n+---------------+----------------------------------------------------+\n| Documentation | https://divak-tornado.readthedocs.io |\n+---------------+----------------------------------------------------+\n| Issue Tracker | https://github.com/dave-shawley/divak-tornado |\n+---------------+----------------------------------------------------+\n\nDiv\u00e1k implements patterns for observing inter-service communication in\ndistributed systems from both a client and a server perspective. The\nprimary goal is to provide a nice framework for all aspects of\nobservability:\n\n* measuring time spent during execution\n* counting interesting events\n* propagating tokens across inter-service communication that\n allow for tracing of messages\n* injecting tracing tokens into log messages\n\nIn the past I have approached the problem of observing data flows from\nthe perspective of the individual aspects of logging, metrics recording,\nand error reporting. Div\u00e1k takes a different approach. It provides the\ntools to include measurements in your code and the ability to propagate\ntokens that correlate all parts of a data flow across multiple services.\n\nThis particular library implements observation as an application level\nobserver, a mix-in class that reads tokens from incoming HTTP requests,\na wrapper that propagates tokens to other services when you make HTTP\nrequests, and other similar helpers. The goal is to make it possible\nto easily instrument your application code in such a way that operational\nmetrics are recorded, correlation identifiers are created and propagated\nbetween services, and the same identifiers are included in log messages.\nAll of this using a single context-manager based instrumentation\nmechanism.\n\nHere's an example of the API that I am aiming for, The request handler uses\ntwo new mix-in classes: ``divak.api.RequestTracker`` and ``divak.api.Logger``.\nThe request tracker adds methods that implement operation tracing and the\nlogger is essentially a ``logging.LoggingAdapter`` that injects the\ncorrelation identifiers into ``LogRecord`` instances. I also used the\n``divak.api.HttpClientMixin`` which adds a method to send HTTP requests to\nother services that propagates the active span information.\n\nThe application also uses two mix-in classes: ``divak.api.Recorder`` and\n``divak.api.ProbabilisticSampler``. The record is responsible for submitting\ntrace data out-of-band to whatever aggregators you add and the sampler is what\ndetermines how frequently to sample requests.\n\n.. code-block:: python\n\n from tornado import gen, web\n import divak.api\n\n class MyHandler(divak.api.RequestTracker, divak.api.Logger,\n divak.api.HttpClientMixin, web.RequestHandler):\n def initialize(self):\n super(self, MyHandler).initialize()\n self.set_divak_name('foo')\n\n @gen.coroutine\n def get(self):\n with self.record_operation('query-db'):\n rows = yield self.query('...')\n self.add_divak_tag('query-db.rowcount', len(rows))\n\n output = []\n for row in rows:\n self.logger.debug('requesting %r', row['id'])\n response = yield self.send_request(\n 'http://.../?id={}'.format(row['id']),\n method='GET')\n output.append(response.body)\n self.set_status(200)\n self.send_response(output)\n\n class Application(divak.api.Recorder, divak.api.ProbabilisticSampler,\n web.Application):\n\n def __init__(self, *args, **kwargs):\n handlers = [web.url(r'/', MyHandler)]\n\n super(Application, self).__init__(handlers, *args, **kwargs)\n self.set_divak_service('my-service')\n self.set_divak_sample_probability(1.0 / 1000.0)\n self.add_divak_reporter(\n divak.api.ZipkinReporter('http://127.0.0.1:9411/api/v2'))\n self.add_divak_propagator(divak.api.ZipkinPropagation())\n\nThis example will result in `zipkin`_ tracing for ``GET /`` requests which\nrecord spans for the database query and each HTTP API call.\n\nRelated Work\n------------\n* `sprockets.http`_ - implements helpers that run Tornado HTTP applications\n and configure logging to facilitate tracing\n* `sprockets.mixins.correlation`_ - creates a correlation ID that can be\n passed from service to service using HTTP headers\n* `sprockets.mixins.metrics`_ - implements recording of runtime metrics using\n either statsd or InfluxDB\n* `sprockets.mixins.sentry`_ - implements error reporting to `sentry`_ for\n unhandled exceptions\n* `sprockets.mixins.statsd`_ - implements recording of runtime metrics using\n statsd\n* `sprockets-influxdb`_ - implements recording of runtime measurements using\n InfluxDB as a back end\n\n.. |CI| image:: https://img.shields.io/circleci/project/github\n /dave-shawley/divak-tornado.svg\n :target: https://circleci.com/gh/dave-shawley/divak-tornado\n.. |CodeClimate| image:: https://codeclimate.com/github/dave-shawley\n /divak-tornado/badges/gpa.svg\n :target: https://codeclimate.com/github/dave-shawley/divak-tornado\n.. |Coverage| image:: https://img.shields.io/codecov/c/github/dave-shawley\n /divak-tornado.svg\n :target: https://codecov.io/gh/dave-shawley/divak-tornado\n.. |ReadTheDocs| image:: https://readthedocs.org/projects/divak-tornado\n /badge/?version=stable\n :target: https://divak-tornado.readthedocs.io/\n.. |Version| image:: https://badge.fury.io/py/divak-tornado.svg\n :target: https://pypi.org/project/divak-tornado\n\n.. _sentry: https://sentry.io/\n.. _sprockets.http: https://github.com/sprockets/sprockets.http\n.. _sprockets.mixins.correlation: https://github.com/sprockets\n /sprockets.mixins.correlation\n.. _sprockets.mixins.metrics: https://github.com/sprockets\n /sprockets.mixins.metrics\n.. _sprockets.mixins.sentry: https://github.com/sprockets\n /sprockets.mixins.sentry\n.. _sprockets.mixins.statsd: https://github.com/sprockets\n /sprockets.mixins.statsd\n.. _sprockets-influxdb: https://github.com/sprockets/sprockets-influxdb\n.. _zipkin: https://zipkin.io\n\n\n", "description_content_type": null, "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/dave-shawley/divak", "keywords": "", "license": "BSD", "maintainer": "", "maintainer_email": "", "name": "divak-tornado", "package_url": "https://pypi.org/project/divak-tornado/", "platform": "", "project_url": "https://pypi.org/project/divak-tornado/", "project_urls": { "Homepage": "https://github.com/dave-shawley/divak" }, "release_url": "https://pypi.org/project/divak-tornado/0.0.3/", "requires_dist": [ "tornado (<5,>=4.2)" ], "requires_python": "", "summary": "Observe the behavior of your Tornado code", "version": "0.0.3" }, "last_serial": 3605216, "releases": { "0.0.0": [ { "comment_text": "", "digests": { "md5": "8d9634bcd5ac015c17de5a2f67356c2c", "sha256": "4d9f7abfea3b3861afbc41490ba3967826261460e2d5c674b115405d4e6c51f6" }, "downloads": -1, "filename": "divak_tornado-0.0.0-py3-none-any.whl", "has_sig": false, "md5_digest": "8d9634bcd5ac015c17de5a2f67356c2c", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 6984, "upload_time": "2018-02-04T13:32:41", "url": "https://files.pythonhosted.org/packages/51/03/ca2819331be352aa64ab68f15bf1474b36e08bf0901ef65123a6e62bcf55/divak_tornado-0.0.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "10d03ec43c186f3301b53a59abf79faa", "sha256": "4f35daba0431f1373f1bdf183f095ffbdf7fae4f3a593d90501e88e1bab3560f" }, "downloads": -1, "filename": "divak-tornado-0.0.0.tar.gz", "has_sig": false, "md5_digest": "10d03ec43c186f3301b53a59abf79faa", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8133, "upload_time": "2018-02-04T13:32:42", "url": "https://files.pythonhosted.org/packages/a1/75/a47fa8cdbb0554baba1adcbf6e845b9cdad363655d7dec58cf632d99f479/divak-tornado-0.0.0.tar.gz" } ], "0.0.1": [ { "comment_text": "", "digests": { "md5": "c9eb5748a4746f0b055270af7bc4fcd9", "sha256": "92192505dbb629f2e35f4c13f95496ebca58fc7bc6fc4e0dd2c523d1e0fc9027" }, "downloads": -1, "filename": "divak_tornado-0.0.1-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "c9eb5748a4746f0b055270af7bc4fcd9", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 6992, "upload_time": "2018-02-04T13:40:13", "url": "https://files.pythonhosted.org/packages/69/e3/cd8adcbcd8728685d54ec8b2c86bef8f126ec8d8a33a1ac810b668c98277/divak_tornado-0.0.1-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "1498b0452bd7ccec657ca809a0e856ec", "sha256": "a0109696b7b789687ca1e0c15146897a8979e2f7344d63eae1323e26059f915d" }, "downloads": -1, "filename": "divak-tornado-0.0.1.tar.gz", "has_sig": false, "md5_digest": "1498b0452bd7ccec657ca809a0e856ec", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8188, "upload_time": "2018-02-04T13:40:14", "url": "https://files.pythonhosted.org/packages/7d/e2/629d9048ae36a4eb5c5f4e849b4aed9771ce32c25731f99987a1332188e4/divak-tornado-0.0.1.tar.gz" } ], "0.0.2": [ { "comment_text": "", "digests": { "md5": "90e3f89c4f673fb92fb5d032614e2743", "sha256": "335bba343395291b166cf7c59d3e5e8318febb9d553a92ee898cb4d2601ef22f" }, "downloads": -1, "filename": "divak_tornado-0.0.2-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "90e3f89c4f673fb92fb5d032614e2743", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 10531, "upload_time": "2018-02-10T17:48:48", "url": "https://files.pythonhosted.org/packages/17/45/f1972020341d4c5ec465297d35c1c9d6a704def9bee7d1d26991ddfe1be6/divak_tornado-0.0.2-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "fc73dd2a7f180390233cc1c7c39d1098", "sha256": "2a2d7ba4bc9a1a4daf08fc9ed64dd0d4c240102c40017474e5e7ed7320b51c31" }, "downloads": -1, "filename": "divak-tornado-0.0.2.tar.gz", "has_sig": false, "md5_digest": "fc73dd2a7f180390233cc1c7c39d1098", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 13059, "upload_time": "2018-02-10T17:48:49", "url": "https://files.pythonhosted.org/packages/dc/15/d7f87d77190ca119163c589760fbc8eb04f335de1043f26fd35349b248b7/divak-tornado-0.0.2.tar.gz" } ], "0.0.3": [ { "comment_text": "", "digests": { "md5": "e19afd37b9c2b5d690050b1a60b67907", "sha256": "b2de49c2a16581ad7a664e6304e5fb3c44dd25efc5b88f04d292e2e5cc35a247" }, "downloads": -1, "filename": "divak_tornado-0.0.3-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "e19afd37b9c2b5d690050b1a60b67907", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 11859, "upload_time": "2018-02-22T12:27:22", "url": "https://files.pythonhosted.org/packages/0c/2f/167ac8663bc21976e6cde073947743765f236723f0eb5e20c874d62b74ed/divak_tornado-0.0.3-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "28a1f16c9480f4234d0e7e3f1f8c44d8", "sha256": "337cb37d236169124dc4e1659df4ce1e00fa465445b02a0bc2925585bbbca93c" }, "downloads": -1, "filename": "divak-tornado-0.0.3.tar.gz", "has_sig": false, "md5_digest": "28a1f16c9480f4234d0e7e3f1f8c44d8", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 17651, "upload_time": "2018-02-22T12:27:24", "url": "https://files.pythonhosted.org/packages/cd/57/fe575414fd07b78e602333f2603a2a7b7c9059222e40ba2e078189ba9d8b/divak-tornado-0.0.3.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "e19afd37b9c2b5d690050b1a60b67907", "sha256": "b2de49c2a16581ad7a664e6304e5fb3c44dd25efc5b88f04d292e2e5cc35a247" }, "downloads": -1, "filename": "divak_tornado-0.0.3-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "e19afd37b9c2b5d690050b1a60b67907", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 11859, "upload_time": "2018-02-22T12:27:22", "url": "https://files.pythonhosted.org/packages/0c/2f/167ac8663bc21976e6cde073947743765f236723f0eb5e20c874d62b74ed/divak_tornado-0.0.3-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "28a1f16c9480f4234d0e7e3f1f8c44d8", "sha256": "337cb37d236169124dc4e1659df4ce1e00fa465445b02a0bc2925585bbbca93c" }, "downloads": -1, "filename": "divak-tornado-0.0.3.tar.gz", "has_sig": false, "md5_digest": "28a1f16c9480f4234d0e7e3f1f8c44d8", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 17651, "upload_time": "2018-02-22T12:27:24", "url": "https://files.pythonhosted.org/packages/cd/57/fe575414fd07b78e602333f2603a2a7b7c9059222e40ba2e078189ba9d8b/divak-tornado-0.0.3.tar.gz" } ] }