{ "info": { "author": "Will Kahn-Greene", "author_email": "willkg@mozilla.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", "License :: OSI Approved :: Mozilla Public License 2.0 (MPL 2.0)", "Natural Language :: English", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3 :: Only" ], "description": "======\nMarkus\n======\n\nMarkus is a Python library for generating metrics.\n\n:Code: https://github.com/willkg/markus\n:Issues: https://github.com/willkg/markus/issues\n:License: MPL v2\n:Documentation: http://markus.readthedocs.io/en/latest/\n\n\nGoals\n=====\n\nMarkus makes it easier to generate metrics in your program by:\n\n* providing multiple backends (Datadog statsd, statsd, logging, logging rollup,\n and so on) for sending data to different places\n\n* sending metrics to multiple backends at the same time\n\n* providing a testing framework for easy testing\n\n* providing a decoupled architecture making it easier to write code to generate\n metrics without having to worry about making sure creating and configuring a\n metrics client has been done--similar to the Python logging Python logging\n module in this way\n\nI use it at Mozilla in the collector of our crash ingestion pipeline. Peter used\nit to build our symbols lookup server, too.\n\n\nInstall\n=======\n\nTo install Markus, run::\n\n $ pip install markus\n\n\n(Optional) To install the requirements for the\n``markus.backends.datadog.DatadogMetrics`` backend::\n\n $ pip install markus[datadog]\n\n\nQuick start\n===========\n\nSimilar to using the logging library, every Python module can create a\n``MetricsInterface`` (loosely equivalent to a Python logging logger) at any time\nincluding at module import time and use that to generate metrics.\n\nFor example::\n\n import markus\n\n metrics = markus.get_metrics(__name__)\n\n\nCreating a ``MetricsImplementation`` using ``__name__`` will cause it to\ngenerate all stats keys with a prefix determined from ``__name__`` which\nis a dotted Python path to that module.\n\nThen you can use the ``MetricsImplementation`` anywhere in that module::\n\n @metrics.timer_decorator('chopping_vegetables')\n def some_long_function(vegetable):\n for veg in vegetable:\n chop_vegetable()\n metrics.incr('vegetable', value=1)\n\n\nAt application startup, configure Markus with the backends you want to use to\npublish metrics and any options they require.\n\nFor example, lets configure metrics to publish to logs and Datadog::\n\n import markus\n\n markus.configure(\n backends=[\n {\n # Log metrics to the logs\n 'class': 'markus.backends.logging.LoggingMetrics',\n },\n {\n # Log metrics to Datadog\n 'class': 'markus.backends.datadog.DatadogMetrics',\n 'options': {\n 'statsd_host': 'example.com',\n 'statsd_port': 8125,\n 'statsd_namespace': ''\n }\n }\n ]\n )\n\n\nWhen you're writing your tests, use the ``MetricsMock`` to make testing easier::\n\n import markus\n from markus.testing import MetricsMock\n\n\n def test_something():\n with MetricsMock() as mm:\n # ... Do things that might publish metrics\n\n # This helps you debug and write your test\n mm.print_records()\n\n # Make assertions on metrics published\n assert mm.has_record(markus.INCR, 'some.key', value=1)\n\n\nHistory\n=======\n\n2.1.0 (October 7th, 2019)\n-------------------------\n\n**Features**\n\n* Fix ``get_metrics()`` so you can call it without passing in a `thing`\n and it'll now create a ``MetricsInterface`` that doesn't have a key\n prefix. (#59)\n\n\n2.0.0 (September 19th, 2019)\n----------------------------\n\n**Features**\n\n* Use ``time.perf_counter()`` if available. Thank you, Mike! (#34)\n* Support Python 3.7 officially.\n* Add filters for adjusting and dropping metrics getting emitted.\n See documentation for more details. (#40)\n\n**Backwards incompatible changes**\n\n* ``tags`` now defaults to ``[]`` instead of ``None`` which may affect some\n expected test output.\n* Adjust internals to run ``.emit()`` on backends. If you wrote your own\n backend, you may need to adjust it.\n* Drop support for Python 3.4. (#39)\n* Drop support for Python 2.7.\n\n If you're still using Python 2.7, you'll need to pin to ``<2.0.0``. (#42)\n\n**Bug fixes**\n\n* Document feature support in backends. (#47)\n* Fix ``MetricsMock.has_record()`` example. Thank you, John!\n\n\n1.2.0 (April 27th, 2018)\n------------------------\n\n**Features**\n\n* Add ``.clear()`` to ``MetricsMock`` making it easier to build a pytest\n fixture with the ``MetricsMock`` context and manipulate records for easy\n testing. (#29)\n\n**Bug fixes**\n\n* Update Cloudwatch backend fixing ``.timing()`` and ``.histogram()`` to\n send ``histogram`` metrics type which Datadog now supports. (#31)\n\n\n1.1.2 (April 5th, 2018)\n-----------------------\n\n**Typo fixes**\n\n* Fix the date from the previous release. Ugh.\n\n\n1.1.1 (April 5th, 2018)\n-----------------------\n\n**Features**\n\n* Official switch to semver.\n\n**Bug fixes**\n\n* Fix ``MetricsMock`` so it continues to work even if ``configure``\n is called. (#27)\n\n\n1.1 (November 13th, 2017)\n-------------------------\n\n**Features**\n\n* Added ``markus.utils.generate_tag`` utility function\n\n\n1.0 (October 30th, 2017)\n------------------------\n\n**Features**\n\n* Added support for Python 2.7.\n\n* Added a ``markus.backends.statsd.StatsdMetrics`` backend that uses\n pystatsd client for statsd pings. Thank you, Javier!\n\n**Bug fixes**\n\n* Added ``LoggingRollupMetrics`` to docs.\n\n* Mozilla has been running Markus in production for 6 months so we\n can mark it production-ready now.\n\n\n0.2 (April 19th, 2017)\n----------------------\n\n**Features**\n\n* Added a ``markus.backends.logging.LoggingRollupMetrics`` backend that\n rolls up metrics and does some light math on them. Possibly helpful\n for light profiling for development.\n\n**Bug fixes**\n\n* Lots of documentation fixes. Thank you, Peter!\n\n\n0.1 (April 10th, 2017)\n----------------------\n\nInitial writing.\n\n\n", "description_content_type": "", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/willkg/markus", "keywords": "metrics datadog statsd", "license": "MPLv2", "maintainer": "", "maintainer_email": "", "name": "markus", "package_url": "https://pypi.org/project/markus/", "platform": "", "project_url": "https://pypi.org/project/markus/", "project_urls": { "Homepage": "https://github.com/willkg/markus" }, "release_url": "https://pypi.org/project/markus/2.1.0/", "requires_dist": [ "datadog ; extra == 'datadog'", "statsd ; extra == 'statsd'" ], "requires_python": "", "summary": "Metrics system for generating statistics about your app", "version": "2.1.0" }, "last_serial": 5940749, "releases": { "0.1": [ { "comment_text": "", "digests": { "md5": "c4566909f9dce99b537dadbee51aa69a", "sha256": "f7552c1fcfdb87f1713c1f9d3302b0c8dd52b266e28e63b69c96190dd8d2b631" }, "downloads": -1, "filename": "markus-0.1-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "c4566909f9dce99b537dadbee51aa69a", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 13713, "upload_time": "2017-04-10T22:36:43", "url": "https://files.pythonhosted.org/packages/88/7d/f81b083dff28ba812ddcfb2a201d58e22da746359bba8a933627ad55d64f/markus-0.1-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "c866b3988a240f33579a1569b16056af", "sha256": "12e06e8518bbcede7d646ab7c0fa5ca4449ff514dad05fce06968d65b0426ce1" }, "downloads": -1, "filename": "markus-0.1.tar.gz", "has_sig": false, "md5_digest": "c866b3988a240f33579a1569b16056af", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 23133, "upload_time": "2017-04-10T22:36:44", "url": "https://files.pythonhosted.org/packages/6f/51/5d46c517422d8db9ec9ffe73bab17730db8e727a03c48f93e1d1e73fc60d/markus-0.1.tar.gz" } ], "0.2": [ { "comment_text": "", "digests": { "md5": "7771c13fe1b1740d01aa881937d57081", "sha256": "94c72fc024d807411efd1065a818f46c77b2ace44b028a14efdab80fb3f3a44f" }, "downloads": -1, "filename": "markus-0.2-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "7771c13fe1b1740d01aa881937d57081", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 15152, "upload_time": "2017-04-19T23:46:33", "url": "https://files.pythonhosted.org/packages/2b/1c/a63cabe28eb6583daa452de184ea9c5ea034a6220e09a1c12e2a47e2d3b6/markus-0.2-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "84739db78fb4bf2a17e0180402fc33dd", "sha256": "ca2625716cf9e519280df0754a67780ee44a3d3d0e0e12fb93c8a9afce8fe868" }, "downloads": -1, "filename": "markus-0.2.tar.gz", "has_sig": false, "md5_digest": "84739db78fb4bf2a17e0180402fc33dd", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 25392, "upload_time": "2017-04-19T23:46:35", "url": "https://files.pythonhosted.org/packages/80/9d/99246e9b65040e33678296c17acf289feceef5edb2fe9be7dee92a26c0e1/markus-0.2.tar.gz" } ], "1.0": [ { "comment_text": "", "digests": { "md5": "b1867b990f9f9a663ba5837efda174f7", "sha256": "e96c111391a641d88bf2f21e899060e5417d3735d7061782465b95cee73d0da2" }, "downloads": -1, "filename": "markus-1.0-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "b1867b990f9f9a663ba5837efda174f7", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 16783, "upload_time": "2017-10-30T12:53:20", "url": "https://files.pythonhosted.org/packages/bf/07/704371de27319fbca6468b074479ef33fe984e97cf0200d850d0e27f5a02/markus-1.0-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "bfb1762782f179eebe513e63c5093f89", "sha256": "c1100c79cd4f63890694fb3c805ce44e14b3fe53a5318a01df52cbf281aee408" }, "downloads": -1, "filename": "markus-1.0.tar.gz", "has_sig": false, "md5_digest": "bfb1762782f179eebe513e63c5093f89", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 26710, "upload_time": "2017-10-30T12:53:23", "url": "https://files.pythonhosted.org/packages/96/ce/b15aaba625d3cdd3f1a26ab08badc30b5ccdeb335a45a717d2a7aedc97d9/markus-1.0.tar.gz" } ], "1.1": [ { "comment_text": "", "digests": { "md5": "3a18d2321426a0d0037f24c51833963b", "sha256": "813ac8cd0eb68bcf7ee618ac2544ce20de5eb0ba27b12f50973c29742800b058" }, "downloads": -1, "filename": "markus-1.1-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "3a18d2321426a0d0037f24c51833963b", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 18144, "upload_time": "2017-11-13T21:35:55", "url": "https://files.pythonhosted.org/packages/22/de/1f885169ff6bf2d5a838db4c90f87b5c9bb831dd0c88bfadeab3fdb3ec5e/markus-1.1-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "f1847ac7fdb292d8d4f6256072df5c96", "sha256": "821377379e0d225a870996e4dcd1aa5305e4030a8b9b5d8b38dc843cbc30dfa8" }, "downloads": -1, "filename": "markus-1.1.tar.gz", "has_sig": false, "md5_digest": "f1847ac7fdb292d8d4f6256072df5c96", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 28497, "upload_time": "2017-11-13T21:35:56", "url": "https://files.pythonhosted.org/packages/a6/73/7a28ae2f0f61b21bfe3726128b6d2e6b037ab9010ffd135f12dfa9772dca/markus-1.1.tar.gz" } ], "1.1.1": [ { "comment_text": "", "digests": { "md5": "da65a9a8aab847363d78fb2282793054", "sha256": "f60ed129baa51fe2883b776af2c861142f954b9f06cae07a8fc0c6cfaab626ef" }, "downloads": -1, "filename": "markus-1.1.1-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "da65a9a8aab847363d78fb2282793054", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 18330, "upload_time": "2018-04-05T21:12:57", "url": "https://files.pythonhosted.org/packages/00/78/8d156ee4f903524cef7c1c44d801ae165943a2037b511ef4f6943caf7ad2/markus-1.1.1-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "70600a62a7fb1dd7057a5bb2f84f9255", "sha256": "f06a5721b437f79cc7dee5992572c47b7748f5416096f0cf4587f5266e6ad3f8" }, "downloads": -1, "filename": "markus-1.1.1.tar.gz", "has_sig": false, "md5_digest": "70600a62a7fb1dd7057a5bb2f84f9255", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 27266, "upload_time": "2018-04-05T21:12:59", "url": "https://files.pythonhosted.org/packages/3b/8b/6c5fbf5300a35b481cd67426d430595552f44e7bb6d590ed107019094d0d/markus-1.1.1.tar.gz" } ], "1.1.2": [ { "comment_text": "", "digests": { "md5": "fe62c8e1bbc3676e4fbb40f62ed75a37", "sha256": "61c5d355c41b91f84315a9d96f94573c975d532230367572a7806a83eaeaf6f5" }, "downloads": -1, "filename": "markus-1.1.2-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "fe62c8e1bbc3676e4fbb40f62ed75a37", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 18418, "upload_time": "2018-04-05T21:17:08", "url": "https://files.pythonhosted.org/packages/cb/f7/896ad195258b5d61500f349bc8b880ef1f53380312d29c543087fca25824/markus-1.1.2-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "39efa6d2458f9c4696d72faf2f187385", "sha256": "7e4f12718a17ea5098ca778479b8254868ac997bd89c1b6bfaed32e3c6292927" }, "downloads": -1, "filename": "markus-1.1.2.tar.gz", "has_sig": false, "md5_digest": "39efa6d2458f9c4696d72faf2f187385", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 27353, "upload_time": "2018-04-05T21:17:10", "url": "https://files.pythonhosted.org/packages/c1/68/b88ec029256b0c48a20942d013c34bd33dbf191308d28fa62c1396f3d978/markus-1.1.2.tar.gz" } ], "1.2.0": [ { "comment_text": "", "digests": { "md5": "0b58750b5dbe85d7e42710d63864d379", "sha256": "86bbeb16de1b1920d291c81a39b7a7c61c94b665cd8d10c6b69c994ce4fd5bcc" }, "downloads": -1, "filename": "markus-1.2.0-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "0b58750b5dbe85d7e42710d63864d379", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 18665, "upload_time": "2018-04-27T17:19:03", "url": "https://files.pythonhosted.org/packages/3b/4f/cd8a972a61e08879105e5fbec3f63f05d8b47e67bb247483ee31340b050e/markus-1.2.0-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "07bfc97a631029381d8fb539f7a8732c", "sha256": "9bce7bd152578703a8e4aa5a765c7c0d94bcdd69f7bc5e42d29b893e3abf2e5a" }, "downloads": -1, "filename": "markus-1.2.0.tar.gz", "has_sig": false, "md5_digest": "07bfc97a631029381d8fb539f7a8732c", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 27680, "upload_time": "2018-04-27T17:19:04", "url": "https://files.pythonhosted.org/packages/bf/97/a2d534492ef660f5c6248570e82f909e2e93ba877b0f170e185ea24339b6/markus-1.2.0.tar.gz" } ], "2.0.0": [ { "comment_text": "", "digests": { "md5": "49831cf1f92f8aed67843fb5097b86c7", "sha256": "0080cee440426ae6e55c6e6130eba6f60e63715def77b7fda751310aacb63a4c" }, "downloads": -1, "filename": "markus-2.0.0-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "49831cf1f92f8aed67843fb5097b86c7", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 23226, "upload_time": "2019-09-19T15:06:45", "url": "https://files.pythonhosted.org/packages/93/20/a7f3e647f495c616cb513df38c7088a022608e4ae4b6178ba560a7d8a4d4/markus-2.0.0-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "bbcce47d820f36111864a00d150053b1", "sha256": "a1c0da25166d8126d52bfa23b8258d1700b99ceb5d260d781e71cbd38020f078" }, "downloads": -1, "filename": "markus-2.0.0.tar.gz", "has_sig": false, "md5_digest": "bbcce47d820f36111864a00d150053b1", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 31920, "upload_time": "2019-09-19T15:06:47", "url": "https://files.pythonhosted.org/packages/75/1d/74a3b884559dde07d6c3407b30a33a5ad975d06d49166bff3c25aa751c61/markus-2.0.0.tar.gz" } ], "2.1.0": [ { "comment_text": "", "digests": { "md5": "c66e9fe137fed86029f7d7e26725bb44", "sha256": "bfa276c69b25006e37449eed447bc27105bf6f26c9ca27d01ddefbd1077b44ea" }, "downloads": -1, "filename": "markus-2.1.0-py3-none-any.whl", "has_sig": false, "md5_digest": "c66e9fe137fed86029f7d7e26725bb44", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 23322, "upload_time": "2019-10-07T18:46:51", "url": "https://files.pythonhosted.org/packages/84/74/a550787214c80819f2e7de661488161082de9e9a31f908c5712de140208a/markus-2.1.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "721beb577b17b9964f8261752f409395", "sha256": "3408818d4d78ca0f4085c6ea32b02f4b3d2a2520b169ddec3167b50f0b7c700d" }, "downloads": -1, "filename": "markus-2.1.0.tar.gz", "has_sig": false, "md5_digest": "721beb577b17b9964f8261752f409395", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 32287, "upload_time": "2019-10-07T18:46:54", "url": "https://files.pythonhosted.org/packages/9e/9c/d5262dca46423278a864f84f4a99ba9282e03c70aa87f95b26fcf7ebb119/markus-2.1.0.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "c66e9fe137fed86029f7d7e26725bb44", "sha256": "bfa276c69b25006e37449eed447bc27105bf6f26c9ca27d01ddefbd1077b44ea" }, "downloads": -1, "filename": "markus-2.1.0-py3-none-any.whl", "has_sig": false, "md5_digest": "c66e9fe137fed86029f7d7e26725bb44", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 23322, "upload_time": "2019-10-07T18:46:51", "url": "https://files.pythonhosted.org/packages/84/74/a550787214c80819f2e7de661488161082de9e9a31f908c5712de140208a/markus-2.1.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "721beb577b17b9964f8261752f409395", "sha256": "3408818d4d78ca0f4085c6ea32b02f4b3d2a2520b169ddec3167b50f0b7c700d" }, "downloads": -1, "filename": "markus-2.1.0.tar.gz", "has_sig": false, "md5_digest": "721beb577b17b9964f8261752f409395", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 32287, "upload_time": "2019-10-07T18:46:54", "url": "https://files.pythonhosted.org/packages/9e/9c/d5262dca46423278a864f84f4a99ba9282e03c70aa87f95b26fcf7ebb119/markus-2.1.0.tar.gz" } ] }