From 1731bfe33955083b05bafd96b4be4daed23da3fc Mon Sep 17 00:00:00 2001 From: Jarrad Whitaker Date: Tue, 18 Jun 2019 15:12:32 +1000 Subject: [PATCH 1/4] implement backoff in case of 429 --- sumologic/backoff.py | 30 ++++++++++++++++++++++++++++++ sumologic/sumologic.py | 5 +++++ 2 files changed, 35 insertions(+) create mode 100644 sumologic/backoff.py diff --git a/sumologic/backoff.py b/sumologic/backoff.py new file mode 100644 index 0000000..6c78fdb --- /dev/null +++ b/sumologic/backoff.py @@ -0,0 +1,30 @@ +import requests +import logging +import time + +logger = logging.getLogger('sumologic.backoff') + +MAX_TRIES = 1 + +def backoff(func): + def limited(*args, **kwargs): + delay = 0.1 + tries = 0 + lastException = None + while tries < MAX_TRIES: + tries += 1 + try: + return func(*args, **kwargs) + except requests.exceptions.HTTPError as e: + if e.response.status_code == 429: # rate limited + logging.debug("Rate limited, sleeping for {0}s".format(delay)) + time.sleep(delay) + delay *= 2 + lastException = e + continue + else: + raise + logging.debug("Rate limited function still failed after {0} retries.".format(MAX_TRIES)) + raise lastException + + return limited diff --git a/sumologic/sumologic.py b/sumologic/sumologic.py index 1af018a..51bfb1d 100644 --- a/sumologic/sumologic.py +++ b/sumologic/sumologic.py @@ -2,6 +2,7 @@ import json import logging import requests +from .backoff import backoff try: import cookielib @@ -41,6 +42,7 @@ def _get_endpoint(self): endpoint = self.response.url.replace('/collectors', '') # dirty hack to sanitise URI and retain domain return endpoint + @backoff def delete(self, method, params=None): r = self.session.delete(self.endpoint + method, params=params) if 400 <= r.status_code < 600: @@ -48,6 +50,7 @@ def delete(self, method, params=None): r.raise_for_status() return r + @backoff def get(self, method, params=None): r = self.session.get(self.endpoint + method, params=params) if 400 <= r.status_code < 600: @@ -55,6 +58,7 @@ def get(self, method, params=None): r.raise_for_status() return r + @backoff def post(self, method, params, headers=None): r = self.session.post(self.endpoint + method, data=json.dumps(params), headers=headers) if 400 <= r.status_code < 600: @@ -62,6 +66,7 @@ def post(self, method, params, headers=None): r.raise_for_status() return r + @backoff def put(self, method, params, headers=None): r = self.session.put(self.endpoint + method, data=json.dumps(params), headers=headers) if 400 <= r.status_code < 600: From 8352e5678d3e538b6a5475cd91cd294bf6447b3a Mon Sep 17 00:00:00 2001 From: Jarrad Whitaker Date: Tue, 18 Jun 2019 15:12:49 +1000 Subject: [PATCH 2/4] endpoint fix --- sumologic/sumologic.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sumologic/sumologic.py b/sumologic/sumologic.py index 51bfb1d..5bfbaf3 100644 --- a/sumologic/sumologic.py +++ b/sumologic/sumologic.py @@ -21,7 +21,7 @@ def __init__(self, accessId, accessKey, endpoint=None, cookieFile='cookies.txt') self.endpoint = self._get_endpoint() else: self.endpoint = endpoint - if endpoint[-1:] == "/": + if self.endpoint[-1:] == "/": raise Exception("Endpoint should not end with a slash character") def _get_endpoint(self): From bd73372a0df26b27bd75d70bdab6c83ff1c6bb75 Mon Sep 17 00:00:00 2001 From: Jarrad Whitaker Date: Tue, 18 Jun 2019 15:10:46 +1000 Subject: [PATCH 3/4] whitespace --- sumologic/sumologic.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sumologic/sumologic.py b/sumologic/sumologic.py index 5bfbaf3..7795c90 100644 --- a/sumologic/sumologic.py +++ b/sumologic/sumologic.py @@ -68,10 +68,10 @@ def post(self, method, params, headers=None): @backoff def put(self, method, params, headers=None): - r = self.session.put(self.endpoint + method, data=json.dumps(params), headers=headers) + r = self.session.put(self.endpoint + method, data=json.dumps(params), headers=headers) if 400 <= r.status_code < 600: r.reason = r.text - r.raise_for_status() + r.raise_for_status() return r def search(self, query, fromTime=None, toTime=None, timeZone='UTC'): From 4c6280b9ea4d5c81539956e9e1bf9bef53ffa55a Mon Sep 17 00:00:00 2001 From: Jarrad Whitaker Date: Tue, 18 Jun 2019 15:21:59 +1000 Subject: [PATCH 4/4] fix max tries to 8 --- sumologic/backoff.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sumologic/backoff.py b/sumologic/backoff.py index 6c78fdb..6b9c1bc 100644 --- a/sumologic/backoff.py +++ b/sumologic/backoff.py @@ -4,7 +4,7 @@ logger = logging.getLogger('sumologic.backoff') -MAX_TRIES = 1 +MAX_TRIES = 8 def backoff(func): def limited(*args, **kwargs):