{ "info": { "author": "Will Keeling", "author_email": "will@zifferent.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Natural Language :: English", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7" ], "description": "RateLimitingFilter\n==================\n\n.. image:: https://travis-ci.org/wkeeling/ratelimitingfilter.svg?branch=master\n :target: https://travis-ci.org/wkeeling/ratelimitingfilter\n\n.. image:: https://codecov.io/gh/wkeeling/ratelimitingfilter/branch/master/graph/badge.svg\n :target: https://codecov.io/gh/wkeeling/ratelimitingfilter\n\n.. image:: https://img.shields.io/badge/python-2.7%2C%203.4%2C%203.5%2C%203.6%2C%203.7-blue.svg\n :target: https://pypi.python.org/pypi/ratelimitingfilter\n\n.. image:: https://img.shields.io/pypi/v/ratelimitingfilter.svg\n :target: https://pypi.python.org/pypi/ratelimitingfilter\n\n.. image:: https://img.shields.io/pypi/l/ratelimitingfilter.svg\n :target: https://pypi.python.org/pypi/ratelimitingfilter\n\n\nThe ``RateLimitingFilter`` is a filter for the Python logging system\nthat allows you to restrict the rate at which messages can pass through\nyour logging handlers.\n\nThe filter can be useful if you're using a handler such as Python's\n``logging.handlers.SMTPHandler`` to send error notification emails.\nError notification emails provide a useful means of keeping an eye on\nthe health of a running system, but these emails have the potential to\noverload a mailbox if they start arriving in quick succession due to\nsome kind of critical failure.\n\nThe ``RateLimitingFilter`` can help prevent mailbox overload by\nthrottling messages based on a configurable rate, whilst allowing for\nperiodic bursts of messages which can be a useful indicator that\nsomething somewhere has broken.\n\nCompatibility\n-------------\n\n* Python 2.7, 3.4+\n\nInstalling\n----------\n\n::\n\n $ pip install ratelimitingfilter\n\nor\n\n::\n\n $ git clone https://github.com/wkeeling/ratelimitingfilter.git\n $ cd ratelimitingfilter\n $ python setup.py install\n\nUsage\n-----\n\nYou can rate-limit a logging handler simply by creating a new instance of the\n``RateLimitingFilter`` and adding it to the handler:\n\n.. code:: python\n\n from ratelimitingfilter import RateLimitingFilter\n\n ...\n\n ratelimit = RateLimitingFilter()\n handler.addFilter(ratelimit)\n\nCreating an instance of the ``RateLimitingFilter`` without any arguments\nlike in the example above will restrict the flow of messages to 1 every\n30 seconds.\n\nYou can customize the flow rate by supplying your own values for the\n``rate``, ``per`` and ``burst`` attributes. For example, to allow a rate\nof 1 message every 2 minutes with a periodic burst of up to 5 messages:\n\n.. code:: python\n\n ratelimit = RateLimitingFilter(rate=1, per=120, burst=5)\n handler.addFilter(ratelimit)\n\nSMTPHandler Example\n~~~~~~~~~~~~~~~~~~~\n\nA typical use case may be to throttle error notification emails sent by\nthe ``logging.handlers.SMTPHandler``.\n\nHere's an example of how you might set that up:\n\n.. code:: python\n\n import logging.handlers\n import time\n\n from ratelimitingfilter import RateLimitingFilter\n\n logger = logging.getLogger('throttled_smtp_example')\n\n # Create an SMTPHandler\n smtp = logging.handlers.SMTPHandler(\n mailhost='smtp.example.com',\n fromaddr='from@example.com',\n toaddrs='to@example.com',\n subject='An error has occurred'\n )\n smtp.setLevel(logging.ERROR)\n\n # Create a formatter and set it on the handler\n formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')\n smtp.setFormatter(formatter)\n\n # Create an instance of the RateLimitingFilter, and add it to the handler\n ratelimit = RateLimitingFilter()\n smtp.addFilter(ratelimit)\n\n # Add the handler to the logger\n logger.addHandler(smtp)\n\n # Logged errors will now be restricted to 1 every 30 seconds\n while True:\n logger.error('An error message')\n time.sleep(2)\n\nAdvanced Usage\n--------------\n\nIt is possible to pass some additional configuration options to the\n``RateLimitingFilter`` initializer for further control over message\nthrottling.\n\nPerhaps you want to selectively throttle particular error messages\nwhilst allowing other messages to pass through freely. This might be the\ncase if there is part of the application which you know can generate\nlarge volumes of errors, whilst the rest of the application is unlikely\nto.\n\nOne way to achieve this might be to use separate loggers, one configured\nwith rate limiting, one without, for the different parts of the\napplication. Alternatively, you can use a single logger and configure\nthe ``RateLimitingFilter`` to match only those messages that you want to\nthrottle.\n\nApplying selective rate limiting allows for constant visbility of lower\nvolume errors whilst keeping the higher volume errors in check.\n\nThe ``RateLimitingFilter`` supports two ways to selectively throttle\nmessages:\n\nSubstring based message throttling\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nYou can pass a list of substrings to the ``RateLimitingFilter`` which it\nwill use to match messages to apply to.\n\n.. code:: python\n\n config = {'match': ['some error', 'a different error']}\n\n ratelimit = RateLimitingFilter(rate=1, per=60, burst=1, **config)\n smtp.addFilter(ratelimit)\n\n # Can be rate limited\n logger.error('some error occurred')\n\n # Can be rate limited\n logger.error('a different error occurred')\n\n # Will not be rate limited\n logger.error('something completely different happened')\n\nAutomatic message throttling\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n*This is an experimental feature*.\n\nYou can let the ``RateLimitingFilter`` automatically throttle messages\nby setting the ``match`` option to ``auto``.\n\n.. code:: python\n\n config = {'match': 'auto'}\n ratelimit = RateLimitingFilter(rate=1, per=60, burst=1, **config)\n\nThe filter will then attempt to identify messages based on their content\nin order to figure out whether to throttle them or not. It will tolerate\nslight differences in content when identifying messages. So for example,\nif error messages are being rapidly logged that are the same apart from\na timestamp, or perhaps an incrementing id, then these messages will be\ntreated as the same as far as rate limiting is concerned.\n\nLicense\n-------\n\nMIT\n\nContributing\n------------\n\nFeedback and improvements are more than welcome. Please submit a pull\nrequest!\n\nhttps://github.com/wkeeling/ratelimitingfilter\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/wkeeling/ratelimitingfilter", "keywords": "ratelimitingfilter", "license": "MIT", "maintainer": "", "maintainer_email": "", "name": "ratelimitingfilter", "package_url": "https://pypi.org/project/ratelimitingfilter/", "platform": "", "project_url": "https://pypi.org/project/ratelimitingfilter/", "project_urls": { "Homepage": "https://github.com/wkeeling/ratelimitingfilter" }, "release_url": "https://pypi.org/project/ratelimitingfilter/1.2/", "requires_dist": null, "requires_python": "", "summary": "A rate limiting filter for the Python logging system", "version": "1.2" }, "last_serial": 5012067, "releases": { "0.4": [ { "comment_text": "", "digests": { "md5": "b196962d41613885ef9c80131a88fcf4", "sha256": "d6e25eeeb99b4c8d886fd79bbb0a01b7a950b70211db70f7f2dbdb79263c9270" }, "downloads": -1, "filename": "ratelimitingfilter-0.4.tar.gz", "has_sig": false, "md5_digest": "b196962d41613885ef9c80131a88fcf4", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 5595, "upload_time": "2017-11-04T09:27:15", "url": "https://files.pythonhosted.org/packages/90/93/b1251a18acd9d7ae2e88ceb45086a8196a996b3d9746860e511011668c3e/ratelimitingfilter-0.4.tar.gz" } ], "0.5": [ { "comment_text": "", "digests": { "md5": "0db71a746e004cf08acf287a4b7e5ce2", "sha256": "c535d6debf5d75841f8bd6a7b0e0d8feb0cdab47f41a6bb99f7e5b4a7b0d72e5" }, "downloads": -1, "filename": "ratelimitingfilter-0.5.tar.gz", "has_sig": false, "md5_digest": "0db71a746e004cf08acf287a4b7e5ce2", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 5628, "upload_time": "2017-11-04T09:45:05", "url": "https://files.pythonhosted.org/packages/f1/8a/c5c466d9800539ece5d40e65235d4c7c16bf68ced51df61357124ca19925/ratelimitingfilter-0.5.tar.gz" } ], "0.6": [ { "comment_text": "", "digests": { "md5": "6ae026a869dc653418379c592b725320", "sha256": "32d9e16394176fcefa123cd56ab19e229d4942b471d7c43a93a4ad0c33be93fa" }, "downloads": -1, "filename": "ratelimitingfilter-0.6.tar.gz", "has_sig": false, "md5_digest": "6ae026a869dc653418379c592b725320", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 5650, "upload_time": "2017-12-17T20:02:12", "url": "https://files.pythonhosted.org/packages/90/37/fa79aa56bbe3f34cc644bbb265108e1e28ee23a88ad8925e4aba6cd7e6b2/ratelimitingfilter-0.6.tar.gz" } ], "0.7": [ { "comment_text": "", "digests": { "md5": "42da0a77f099d37b256f60747e80da20", "sha256": "991ba9711f4bbe80b76ff81d275c7f4b99e3e223810d526f5db481ecdfef2d79" }, "downloads": -1, "filename": "ratelimitingfilter-0.7-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "42da0a77f099d37b256f60747e80da20", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 8732, "upload_time": "2018-08-25T10:20:16", "url": "https://files.pythonhosted.org/packages/18/73/2e024e613c7b01005185f52dbcd6314420863daac78dcb83ed50f06b1ba4/ratelimitingfilter-0.7-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "becb872a06b5ca2e9f26588fe854ca19", "sha256": "82e734e5a801bfb4feb3a8f319ae54b8e8ce5b45d39d7bbc1d7922c7dfc5aeff" }, "downloads": -1, "filename": "ratelimitingfilter-0.7.tar.gz", "has_sig": false, "md5_digest": "becb872a06b5ca2e9f26588fe854ca19", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 5512, "upload_time": "2018-08-25T10:20:17", "url": "https://files.pythonhosted.org/packages/59/fd/e2adeff18655a41038df280c31e5a26fe87f3a812eb53a8bc6f13374f90f/ratelimitingfilter-0.7.tar.gz" } ], "1.0": [ { "comment_text": "", "digests": { "md5": "210f93bf1e47d6b940b1df13412a5fb7", "sha256": "f2628b13d4f9e7a655f10a99d4f34ed2bd94a50fe4e3a76fd7a22faab9d32586" }, "downloads": -1, "filename": "ratelimitingfilter-1.0-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "210f93bf1e47d6b940b1df13412a5fb7", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 8725, "upload_time": "2018-08-25T10:48:05", "url": "https://files.pythonhosted.org/packages/7d/8a/26f15d794b126d9c1228fdb6673cdd925dd2e1c55b99259a877641557c9e/ratelimitingfilter-1.0-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "e369b23bfb939869e3e4bb159a05c5f9", "sha256": "66d53ba9c9d0c44796537dff04c7d1f71512d1ca160dde8802c40fa44083f598" }, "downloads": -1, "filename": "ratelimitingfilter-1.0.tar.gz", "has_sig": false, "md5_digest": "e369b23bfb939869e3e4bb159a05c5f9", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 5501, "upload_time": "2018-08-25T10:48:07", "url": "https://files.pythonhosted.org/packages/af/f9/10904a92b8f252e1495614159b7f4c5a1592a2f602fd38f5b1a3f8d7b425/ratelimitingfilter-1.0.tar.gz" } ], "1.1": [ { "comment_text": "", "digests": { "md5": "3c32b8cc924ccf25260766ac0629d012", "sha256": "a5e978e3dfda24f8bf51c4c4c91dd1022a01c8068be888489d72836bff71fa14" }, "downloads": -1, "filename": "ratelimitingfilter-1.1-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "3c32b8cc924ccf25260766ac0629d012", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 8753, "upload_time": "2018-08-29T19:36:33", "url": "https://files.pythonhosted.org/packages/79/bc/e0cbe07873dbe02959359fb4ec9bd5e52d9ce3bc58aa394777aeca912a11/ratelimitingfilter-1.1-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "0efc476408b86044ded5b2b7ee0a626a", "sha256": "660e55b6b6c058d3349b729c5c988cb0032016bf82a433d1ceb9882beefa7704" }, "downloads": -1, "filename": "ratelimitingfilter-1.1.tar.gz", "has_sig": false, "md5_digest": "0efc476408b86044ded5b2b7ee0a626a", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 5529, "upload_time": "2018-08-29T19:36:33", "url": "https://files.pythonhosted.org/packages/5f/af/0389b49d1f7065f0676decb8baad23c8b53b3f2926e8c1f8714d294c0c87/ratelimitingfilter-1.1.tar.gz" } ], "1.2": [ { "comment_text": "", "digests": { "md5": "3323dfac55a7f19ac8c5e63f87063309", "sha256": "f4e35b73f8177c099a5baa48ab2d07fdfd9ae20d7764b8ed7193deb310a39cf5" }, "downloads": -1, "filename": "ratelimitingfilter-1.2-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "3323dfac55a7f19ac8c5e63f87063309", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 5599, "upload_time": "2019-04-01T08:52:57", "url": "https://files.pythonhosted.org/packages/6d/e4/e735c7757329206424486f32470b9cdb185d8810591c1b7bc665c254f29d/ratelimitingfilter-1.2-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "9e09051b1ac21c700fc85f73aa6e694b", "sha256": "2b6bdc0e81f7b470ffb011fb309054d6279eb980489de1a00edc15f69a9c518d" }, "downloads": -1, "filename": "ratelimitingfilter-1.2.tar.gz", "has_sig": false, "md5_digest": "9e09051b1ac21c700fc85f73aa6e694b", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 5550, "upload_time": "2019-04-01T08:52:58", "url": "https://files.pythonhosted.org/packages/65/fb/2a8b0151cb3304f3a682db4b357e5bf82c47a3cabef160c272dfb4364891/ratelimitingfilter-1.2.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "3323dfac55a7f19ac8c5e63f87063309", "sha256": "f4e35b73f8177c099a5baa48ab2d07fdfd9ae20d7764b8ed7193deb310a39cf5" }, "downloads": -1, "filename": "ratelimitingfilter-1.2-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "3323dfac55a7f19ac8c5e63f87063309", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 5599, "upload_time": "2019-04-01T08:52:57", "url": "https://files.pythonhosted.org/packages/6d/e4/e735c7757329206424486f32470b9cdb185d8810591c1b7bc665c254f29d/ratelimitingfilter-1.2-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "9e09051b1ac21c700fc85f73aa6e694b", "sha256": "2b6bdc0e81f7b470ffb011fb309054d6279eb980489de1a00edc15f69a9c518d" }, "downloads": -1, "filename": "ratelimitingfilter-1.2.tar.gz", "has_sig": false, "md5_digest": "9e09051b1ac21c700fc85f73aa6e694b", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 5550, "upload_time": "2019-04-01T08:52:58", "url": "https://files.pythonhosted.org/packages/65/fb/2a8b0151cb3304f3a682db4b357e5bf82c47a3cabef160c272dfb4364891/ratelimitingfilter-1.2.tar.gz" } ] }