Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
self._logger.info('Logging configuration file: ' + log_config_file)
try:
logging.config.fileConfig(log_config_file)
except Exception:
exc_type, exc_value, exc_traceback = sys.exc_info()
traceback.print_exception(exc_type, exc_value, exc_traceback, limit=2, file=sys.stderr)
raise PanoptesConfigurationError(
'Could not instantiate logger with logging configuration provided in file "%s": (%s) %s' % (
log_config_file, exc_type, exc_value))
# Create a filter to rate limit logs so that a misconfiguration or failure does not make the disk I/O go
# beserk or fill up the disk space. We do this in code instead if configuration for two reasons:
# - It enforces a filter on every handler, so no chance of messing them up in configuration
# - We use fileConfig (nof dictConfig) to setup our logging and fileConfig does not support filter configuration
throttle = RateLimitingFilter(rate=config['log']['rate'], per=config['log']['per'],
burst=config['log']['burst'])
# Apply the filter to all handlers. Note that this would be a shared filter across ALL logs generated by this
# process and thus the rate/burst should be set appropriately high
for handler in logging._handlerList:
# _handlerList is a list of weakrefs, so the object returned has to be dereferenced
handler().addFilter(throttle)
import logging.handlers
import time
from ratelimitingfilter import RateLimitingFilter
logger = logging.getLogger('throttled_smtp_example')
# Create an SMTPHandler
smtp = logging.handlers.SMTPHandler(mailhost='relay.somehost.net',
fromaddr='will@mailinator.com',
toaddrs='will@mailinator.com',
subject='An error has occurred')
smtp.setLevel(logging.ERROR)
# Create an instance of the RateLimitingFilter, and add it to the handler
throttle = RateLimitingFilter()
smtp.addFilter(throttle)
# Create a formatter and set it on the handler
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
smtp.setFormatter(formatter)
# Add the handler to the logger
logger.addHandler(smtp)
# Logged errors will now be restricted to 1 every 30 seconds
while True:
logger.error('An error message')
time.sleep(2)
if not app.debug:
credentials = None
if app.config['MAIL_USERNAME'] or app.config['MAIL_PASSWORD']:
credentials = (app.config['MAIL_USERNAME'],
app.config['MAIL_PASSWORD'])
mail_handler = SMTPHandler(
(app.config['MAIL_SERVER'],
app.config['MAIL_PORT']),
app.config['MAIL_FROM'],
app.config['ADMINS'],
'webfaf exception', credentials)
mail_handler.setLevel(logging.ERROR)
rate_limiter = RateLimitingFilter(app.config['THROTTLING_RATE'],
app.config['THROTTLING_TIMEFRAME'],
app.config['THROTTLING_BURST'])
mail_handler.addFilter(rate_limiter)
app.logger.addHandler(mail_handler) # pylint: disable=no-member
@app.errorhandler(403)
def forbidden(_):
return flask.render_template("403.html"), 403
@app.errorhandler(404)
def not_found(_):
return flask.render_template("404.html"), 404
from ratelimitingfilter import RateLimitingFilter
logger = logging.getLogger('console_example')
logger.setLevel(logging.DEBUG)
# Create a console handler
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)
ch.setFormatter(logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s'))
logger.addHandler(ch)
# Create a rate limiting filter and add it to the console handler.
# We limit the throughput to 1 record per second, allowing a burst of 3.
throttle = RateLimitingFilter(rate=1, per=1, burst=3)
ch.addFilter(throttle)
for i in range(31):
# This attempts to log 31 messages in a little over 3 seconds. The messages are equally
# spaced with 1/10 second between them. This allows the first 3 messages through in the
# first second based on the burst, and then just 1 message in the 2nd, 3rd and 4th seconds,
# based on the 1 per second rate, which totals 6.
logger.debug('This is message {0}'.format(i))
time.sleep(0.1)
self.rate = rate
self.per = per
self.burst = burst
self._default_bucket = TokenBucket(rate, per, burst)
self._substr_buckets = None
self._auto_buckets = None
if 'match' in kwargs:
if kwargs['match'] == 'auto':
self._auto_buckets = defaultdict(partial(TokenBucket, rate, per, burst))
else:
self._substr_buckets = {}
for s in kwargs['match']:
# Create a new token bucket for each substring
self._substr_buckets[s] = TokenBucket(rate, per, burst)
:param kwargs:
Additional config options that can be passed to the filter.
"""
super(RateLimitingFilter, self).__init__()
self.rate = rate
self.per = per
self.burst = burst
self._default_bucket = TokenBucket(rate, per, burst)
self._substr_buckets = None
self._auto_buckets = None
if 'match' in kwargs:
if kwargs['match'] == 'auto':
self._auto_buckets = defaultdict(partial(TokenBucket, rate, per, burst))
else:
self._substr_buckets = {}
for s in kwargs['match']:
# Create a new token bucket for each substring
self._substr_buckets[s] = TokenBucket(rate, per, burst)
:param rate:
The number of records to restrict to, per the specified time interval. Default 1.
:param per:
The number of seconds during which 'rate' records may be sent. Default 30.
:param burst:
The maximum number of records that can be sent before rate limiting kicks in.
:param kwargs:
Additional config options that can be passed to the filter.
"""
super(RateLimitingFilter, self).__init__()
self.rate = rate
self.per = per
self.burst = burst
self._default_bucket = TokenBucket(rate, per, burst)
self._substr_buckets = None
self._auto_buckets = None
if 'match' in kwargs:
if kwargs['match'] == 'auto':
self._auto_buckets = defaultdict(partial(TokenBucket, rate, per, burst))
else:
self._substr_buckets = {}
for s in kwargs['match']:
# Create a new token bucket for each substring
self._substr_buckets[s] = TokenBucket(rate, per, burst)
def __init__(self, rate=1, per=30, burst=1, **kwargs):
"""Initialise an instance of the RateLimitingFilter allowing a default rate of 1 record
every 30 seconds when no arguments are supplied.
:param rate:
The number of records to restrict to, per the specified time interval. Default 1.
:param per:
The number of seconds during which 'rate' records may be sent. Default 30.
:param burst:
The maximum number of records that can be sent before rate limiting kicks in.
:param kwargs:
Additional config options that can be passed to the filter.
"""
super(RateLimitingFilter, self).__init__()
self.rate = rate
self.per = per
self.burst = burst
self._default_bucket = TokenBucket(rate, per, burst)
self._substr_buckets = None
self._auto_buckets = None
if 'match' in kwargs:
if kwargs['match'] == 'auto':
self._auto_buckets = defaultdict(partial(TokenBucket, rate, per, burst))
else:
self._substr_buckets = {}
for s in kwargs['match']:
# Create a new token bucket for each substring