prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Marathon >= 0.7 failing
  The Marathon plugin checks the TaskRateLimit attribute from the Marathon 0.6 API version, which has been removed https://github.com/mesosphere/marathon/blob/master/docs/docs/upgrade/06xto070.md#task-rate-limit
  
  you can see the dependency here:
  https://github.com/DataDog/dd-agent/blob/73dd75035f1982d31818bb8a4a2a6cc856cf8bb7/checks.d/marathon.py#L30
  
  using marathon v0.7.6, the `dd-agent info` looks like this:
  
  ```
      marathon
      --------
        - instance #0 [ERROR]: KeyError('taskRateLimit',)
        - Collected 1 metric, 0 events & 1 service check
  ```
  
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `checks.d/marathon.py`
  Content:
  ```
  1 # stdlib
  2 import time
  3 from hashlib import md5
  4 import urllib2
  5 
  6 # project
  7 from checks import AgentCheck
  8 from util import headers
  9 
  10 # 3rd party
  11 import simplejson as json
  12 import requests
  13 
  14 class Marathon(AgentCheck):
  15     def check(self, instance):
  16         if 'url' not in instance:
  17             raise Exception('Marathon instance missing "url" value.')
  18 
  19         # Load values from the instance config
  20         url = instance['url']
  21         instance_tags = instance.get('tags', [])
  22         default_timeout = self.init_config.get('default_timeout', 5)
  23         timeout = float(instance.get('timeout', default_timeout))
  24 
  25         response = self.get_v2_apps(url, timeout)
  26         if response is not None:
  27             self.gauge('marathon.apps', len(response['apps']), tags=instance_tags)
  28             for app in response['apps']:
  29                 tags = ['app_id:' + app['id'], 'version:' + app['version']] + instance_tags
  30                 for attr in ['taskRateLimit','instances','cpus','mem','tasksStaged','tasksRunning']:
  31                     self.gauge('marathon.' + attr, app[attr], tags=tags)
  32                 versions_reply = self.get_v2_app_versions(url, app['id'], timeout)
  33                 if versions_reply is not None:
  34                     self.gauge('marathon.versions', len(versions_reply['versions']), tags=tags)
  35 
  36     def get_v2_apps(self, url, timeout):
  37         # Use a hash of the URL as an aggregation key
  38         aggregation_key = md5(url).hexdigest()
  39         try:
  40             r = requests.get(url + "/v2/apps", timeout=timeout)
  41         except requests.exceptions.Timeout as e:
  42             # If there's a timeout
  43             self.timeout_event(url, timeout, aggregation_key)
  44             raise Exception("Timeout when hitting %s" % url)
  45 
  46         if r.status_code != 200:
  47             self.status_code_event(url, r, aggregation_key)
  48             raise Exception("Got %s when hitting %s" % (r.status_code, url))
  49 
  50         # Condition for request v1.x backward compatibility
  51         if hasattr(r.json, '__call__'):
  52             return r.json()
  53         else:
  54             return r.json
  55 
  56     def get_v2_app_versions(self, url, app_id, timeout):
  57         # Use a hash of the URL as an aggregation key
  58         aggregation_key = md5(url).hexdigest()
  59         
  60         try:
  61             r = requests.get(url + "/v2/apps/" + app_id + "/versions", timeout=timeout)
  62         except requests.exceptions.Timeout as e:
  63             # If there's a timeout
  64             self.timeout_event(url, timeout, aggregation_key)
  65             self.warning("Timeout when hitting %s" % url)
  66             return None
  67 
  68         if r.status_code != 200:
  69             self.status_code_event(url, r, aggregation_key)
  70             self.warning("Got %s when hitting %s" % (r.status_code, url))
  71             return None
  72 
  73         return r.json()
  74 
  75     def timeout_event(self, url, timeout, aggregation_key):
  76         self.event({
  77             'timestamp': int(time.time()),
  78             'event_type': 'http_check',
  79             'msg_title': 'URL timeout',
  80             'msg_text': '%s timed out after %s seconds.' % (url, timeout),
  81             'aggregation_key': aggregation_key
  82         })
  83 
  84     def status_code_event(self, url, r, aggregation_key):
  85         self.event({
  86             'timestamp': int(time.time()),
  87             'event_type': 'http_check',
  88             'msg_title': 'Invalid reponse code for %s' % url,
  89             'msg_text': '%s returned a status of %s' % (url, r.status_code),
  90             'aggregation_key': aggregation_key
  91         })
  92
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/checks.d/marathon.py b/checks.d/marathon.py
  --- a/checks.d/marathon.py
  +++ b/checks.d/marathon.py
  @@ -1,11 +1,9 @@
   # stdlib
   import time
   from hashlib import md5
  -import urllib2
   
   # project
   from checks import AgentCheck
  -from util import headers
   
   # 3rd party
   import simplejson as json
  @@ -27,8 +25,9 @@
               self.gauge('marathon.apps', len(response['apps']), tags=instance_tags)
               for app in response['apps']:
                   tags = ['app_id:' + app['id'], 'version:' + app['version']] + instance_tags
  -                for attr in ['taskRateLimit','instances','cpus','mem','tasksStaged','tasksRunning']:
  -                    self.gauge('marathon.' + attr, app[attr], tags=tags)
  +                for attr in ['taskRateLimit', 'instances', 'cpus', 'mem', 'tasksStaged', 'tasksRunning', 'backoffSeconds', 'backoffFactor']:
  +                    if attr in app:
  +                        self.gauge('marathon.' + attr, app[attr], tags=tags)
                   versions_reply = self.get_v2_app_versions(url, app['id'], timeout)
                   if versions_reply is not None:
                       self.gauge('marathon.versions', len(versions_reply['versions']), tags=tags)
  @@ -38,7 +37,7 @@
           aggregation_key = md5(url).hexdigest()
           try:
               r = requests.get(url + "/v2/apps", timeout=timeout)
  -        except requests.exceptions.Timeout as e:
  +        except requests.exceptions.Timeout:
               # If there's a timeout
               self.timeout_event(url, timeout, aggregation_key)
               raise Exception("Timeout when hitting %s" % url)
  @@ -56,10 +55,10 @@
       def get_v2_app_versions(self, url, app_id, timeout):
           # Use a hash of the URL as an aggregation key
           aggregation_key = md5(url).hexdigest()
  -        
  +
           try:
               r = requests.get(url + "/v2/apps/" + app_id + "/versions", timeout=timeout)
  -        except requests.exceptions.Timeout as e:
  +        except requests.exceptions.Timeout:
               # If there's a timeout
               self.timeout_event(url, timeout, aggregation_key)
               self.warning("Timeout when hitting %s" % url)
  
verification_info: {"golden_diff": "diff --git a/checks.d/marathon.py b/checks.d/marathon.py\n--- a/checks.d/marathon.py\n+++ b/checks.d/marathon.py\n@@ -1,11 +1,9 @@\n # stdlib\n import time\n from hashlib import md5\n-import urllib2\n \n # project\n from checks import AgentCheck\n-from util import headers\n \n # 3rd party\n import simplejson as json\n@@ -27,8 +25,9 @@\n             self.gauge('marathon.apps', len(response['apps']), tags=instance_tags)\n             for app in response['apps']:\n                 tags = ['app_id:' + app['id'], 'version:' + app['version']] + instance_tags\n-                for attr in ['taskRateLimit','instances','cpus','mem','tasksStaged','tasksRunning']:\n-                    self.gauge('marathon.' + attr, app[attr], tags=tags)\n+                for attr in ['taskRateLimit', 'instances', 'cpus', 'mem', 'tasksStaged', 'tasksRunning', 'backoffSeconds', 'backoffFactor']:\n+                    if attr in app:\n+                        self.gauge('marathon.' + attr, app[attr], tags=tags)\n                 versions_reply = self.get_v2_app_versions(url, app['id'], timeout)\n                 if versions_reply is not None:\n                     self.gauge('marathon.versions', len(versions_reply['versions']), tags=tags)\n@@ -38,7 +37,7 @@\n         aggregation_key = md5(url).hexdigest()\n         try:\n             r = requests.get(url + \"/v2/apps\", timeout=timeout)\n-        except requests.exceptions.Timeout as e:\n+        except requests.exceptions.Timeout:\n             # If there's a timeout\n             self.timeout_event(url, timeout, aggregation_key)\n             raise Exception(\"Timeout when hitting %s\" % url)\n@@ -56,10 +55,10 @@\n     def get_v2_app_versions(self, url, app_id, timeout):\n         # Use a hash of the URL as an aggregation key\n         aggregation_key = md5(url).hexdigest()\n-        \n+\n         try:\n             r = requests.get(url + \"/v2/apps/\" + app_id + \"/versions\", timeout=timeout)\n-        except requests.exceptions.Timeout as e:\n+        except requests.exceptions.Timeout:\n             # If there's a timeout\n             self.timeout_event(url, timeout, aggregation_key)\n             self.warning(\"Timeout when hitting %s\" % url)\n", "issue": "Marathon >= 0.7 failing\nThe Marathon plugin checks the TaskRateLimit attribute from the Marathon 0.6 API version, which has been removed https://github.com/mesosphere/marathon/blob/master/docs/docs/upgrade/06xto070.md#task-rate-limit\n\nyou can see the dependency here:\nhttps://github.com/DataDog/dd-agent/blob/73dd75035f1982d31818bb8a4a2a6cc856cf8bb7/checks.d/marathon.py#L30\n\nusing marathon v0.7.6, the `dd-agent info` looks like this:\n\n```\n    marathon\n    --------\n      - instance #0 [ERROR]: KeyError('taskRateLimit',)\n      - Collected 1 metric, 0 events & 1 service check\n```\n\n", "before_files": [{"content": "# stdlib\nimport time\nfrom hashlib import md5\nimport urllib2\n\n# project\nfrom checks import AgentCheck\nfrom util import headers\n\n# 3rd party\nimport simplejson as json\nimport requests\n\nclass Marathon(AgentCheck):\n    def check(self, instance):\n        if 'url' not in instance:\n            raise Exception('Marathon instance missing \"url\" value.')\n\n        # Load values from the instance config\n        url = instance['url']\n        instance_tags = instance.get('tags', [])\n        default_timeout = self.init_config.get('default_timeout', 5)\n        timeout = float(instance.get('timeout', default_timeout))\n\n        response = self.get_v2_apps(url, timeout)\n        if response is not None:\n            self.gauge('marathon.apps', len(response['apps']), tags=instance_tags)\n            for app in response['apps']:\n                tags = ['app_id:' + app['id'], 'version:' + app['version']] + instance_tags\n                for attr in ['taskRateLimit','instances','cpus','mem','tasksStaged','tasksRunning']:\n                    self.gauge('marathon.' + attr, app[attr], tags=tags)\n                versions_reply = self.get_v2_app_versions(url, app['id'], timeout)\n                if versions_reply is not None:\n                    self.gauge('marathon.versions', len(versions_reply['versions']), tags=tags)\n\n    def get_v2_apps(self, url, timeout):\n        # Use a hash of the URL as an aggregation key\n        aggregation_key = md5(url).hexdigest()\n        try:\n            r = requests.get(url + \"/v2/apps\", timeout=timeout)\n        except requests.exceptions.Timeout as e:\n            # If there's a timeout\n            self.timeout_event(url, timeout, aggregation_key)\n            raise Exception(\"Timeout when hitting %s\" % url)\n\n        if r.status_code != 200:\n            self.status_code_event(url, r, aggregation_key)\n            raise Exception(\"Got %s when hitting %s\" % (r.status_code, url))\n\n        # Condition for request v1.x backward compatibility\n        if hasattr(r.json, '__call__'):\n            return r.json()\n        else:\n            return r.json\n\n    def get_v2_app_versions(self, url, app_id, timeout):\n        # Use a hash of the URL as an aggregation key\n        aggregation_key = md5(url).hexdigest()\n        \n        try:\n            r = requests.get(url + \"/v2/apps/\" + app_id + \"/versions\", timeout=timeout)\n        except requests.exceptions.Timeout as e:\n            # If there's a timeout\n            self.timeout_event(url, timeout, aggregation_key)\n            self.warning(\"Timeout when hitting %s\" % url)\n            return None\n\n        if r.status_code != 200:\n            self.status_code_event(url, r, aggregation_key)\n            self.warning(\"Got %s when hitting %s\" % (r.status_code, url))\n            return None\n\n        return r.json()\n\n    def timeout_event(self, url, timeout, aggregation_key):\n        self.event({\n            'timestamp': int(time.time()),\n            'event_type': 'http_check',\n            'msg_title': 'URL timeout',\n            'msg_text': '%s timed out after %s seconds.' % (url, timeout),\n            'aggregation_key': aggregation_key\n        })\n\n    def status_code_event(self, url, r, aggregation_key):\n        self.event({\n            'timestamp': int(time.time()),\n            'event_type': 'http_check',\n            'msg_title': 'Invalid reponse code for %s' % url,\n            'msg_text': '%s returned a status of %s' % (url, r.status_code),\n            'aggregation_key': aggregation_key\n        })\n", "path": "checks.d/marathon.py"}], "after_files": [{"content": "# stdlib\nimport time\nfrom hashlib import md5\n\n# project\nfrom checks import AgentCheck\n\n# 3rd party\nimport simplejson as json\nimport requests\n\nclass Marathon(AgentCheck):\n    def check(self, instance):\n        if 'url' not in instance:\n            raise Exception('Marathon instance missing \"url\" value.')\n\n        # Load values from the instance config\n        url = instance['url']\n        instance_tags = instance.get('tags', [])\n        default_timeout = self.init_config.get('default_timeout', 5)\n        timeout = float(instance.get('timeout', default_timeout))\n\n        response = self.get_v2_apps(url, timeout)\n        if response is not None:\n            self.gauge('marathon.apps', len(response['apps']), tags=instance_tags)\n            for app in response['apps']:\n                tags = ['app_id:' + app['id'], 'version:' + app['version']] + instance_tags\n                for attr in ['taskRateLimit', 'instances', 'cpus', 'mem', 'tasksStaged', 'tasksRunning', 'backoffSeconds', 'backoffFactor']:\n                    if attr in app:\n                        self.gauge('marathon.' + attr, app[attr], tags=tags)\n                versions_reply = self.get_v2_app_versions(url, app['id'], timeout)\n                if versions_reply is not None:\n                    self.gauge('marathon.versions', len(versions_reply['versions']), tags=tags)\n\n    def get_v2_apps(self, url, timeout):\n        # Use a hash of the URL as an aggregation key\n        aggregation_key = md5(url).hexdigest()\n        try:\n            r = requests.get(url + \"/v2/apps\", timeout=timeout)\n        except requests.exceptions.Timeout:\n            # If there's a timeout\n            self.timeout_event(url, timeout, aggregation_key)\n            raise Exception(\"Timeout when hitting %s\" % url)\n\n        if r.status_code != 200:\n            self.status_code_event(url, r, aggregation_key)\n            raise Exception(\"Got %s when hitting %s\" % (r.status_code, url))\n\n        # Condition for request v1.x backward compatibility\n        if hasattr(r.json, '__call__'):\n            return r.json()\n        else:\n            return r.json\n\n    def get_v2_app_versions(self, url, app_id, timeout):\n        # Use a hash of the URL as an aggregation key\n        aggregation_key = md5(url).hexdigest()\n\n        try:\n            r = requests.get(url + \"/v2/apps/\" + app_id + \"/versions\", timeout=timeout)\n        except requests.exceptions.Timeout:\n            # If there's a timeout\n            self.timeout_event(url, timeout, aggregation_key)\n            self.warning(\"Timeout when hitting %s\" % url)\n            return None\n\n        if r.status_code != 200:\n            self.status_code_event(url, r, aggregation_key)\n            self.warning(\"Got %s when hitting %s\" % (r.status_code, url))\n            return None\n\n        return r.json()\n\n    def timeout_event(self, url, timeout, aggregation_key):\n        self.event({\n            'timestamp': int(time.time()),\n            'event_type': 'http_check',\n            'msg_title': 'URL timeout',\n            'msg_text': '%s timed out after %s seconds.' % (url, timeout),\n            'aggregation_key': aggregation_key\n        })\n\n    def status_code_event(self, url, r, aggregation_key):\n        self.event({\n            'timestamp': int(time.time()),\n            'event_type': 'http_check',\n            'msg_title': 'Invalid reponse code for %s' % url,\n            'msg_text': '%s returned a status of %s' % (url, r.status_code),\n            'aggregation_key': aggregation_key\n        })\n", "path": "checks.d/marathon.py"}]}