We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
[etcd] `/stats/leader` from a follower returns a 403
The `/stats/leader` endpoint is only available on the leader etcd host.
On the followers, it returns a 403: it is illegitimately logged as an exception in the agent and triggers a CRITICAL service check.

`#0[ERROR]: 'Http status code 403 on url http://localhost:4002/v2/stats/leader`

Full stacktrace: 

```
2015-06-17 16:41:46 UTC | ERROR | dd.collector | checks.etcd(__init__.py:678) | Check 'etcd' instance #0 failed
Traceback (most recent call last):
  File "/opt/datadog-agent/agent/checks/__init__.py", line 661, in run
    self.check(copy.deepcopy(instance))
  File "/opt/datadog-agent/agent/checks.d/etcd.py", line 114, in check
    leader_response = self._get_leader_metrics(url, timeout)
  File "/opt/datadog-agent/agent/checks.d/etcd.py", line 143, in _get_leader_metrics
    return self._get_json(url + "/v2/stats/leader", timeout)
  File "/opt/datadog-agent/agent/checks.d/etcd.py", line 159, in _get_json
    raise Exception("Http status code {0} on url {1}".format(r.status_code, url))
Exception: Http status code 403 on url http://localhost:4002/v2/stats/leader
```


--- 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/etcd.py`
Content:
```
1 # project
2 from checks import AgentCheck
3 from util import headers
4 
5 # 3rd party
6 import requests
7 
8 
9 class Etcd(AgentCheck):
10 
11     DEFAULT_TIMEOUT = 5
12 
13     SERVICE_CHECK_NAME = 'etcd.can_connect'
14 
15     STORE_RATES = {
16         'getsSuccess': 'etcd.store.gets.success',
17         'getsFail': 'etcd.store.gets.fail',
18         'setsSuccess': 'etcd.store.sets.success',
19         'setsFail': 'etcd.store.sets.fail',
20         'deleteSuccess': 'etcd.store.delete.success',
21         'deleteFail': 'etcd.store.delete.fail',
22         'updateSuccess': 'etcd.store.update.success',
23         'updateFail': 'etcd.store.update.fail',
24         'createSuccess': 'etcd.store.create.success',
25         'createFail': 'etcd.store.create.fail',
26         'compareAndSwapSuccess': 'etcd.store.compareandswap.success',
27         'compareAndSwapFail': 'etcd.store.compareandswap.fail',
28         'compareAndDeleteSuccess': 'etcd.store.compareanddelete.success',
29         'compareAndDeleteFail': 'etcd.store.compareanddelete.fail',
30         'expireCount': 'etcd.store.expire.count'
31     }
32 
33     STORE_GAUGES = {
34         'watchers': 'etcd.store.watchers'
35     }
36 
37     SELF_GAUGES = {
38         'sendPkgRate': 'etcd.self.send.pkgrate',
39         'sendBandwidthRate': 'etcd.self.send.bandwidthrate',
40         'recvPkgRate': 'etcd.self.recv.pkgrate',
41         'recvBandwidthRate': 'etcd.self.recv.bandwidthrate'
42     }
43 
44     SELF_RATES = {
45         'recvAppendRequestCnt': 'etcd.self.recv.appendrequest.count',
46         'sendAppendRequestCnt': 'etcd.self.send.appendrequest.count'
47     }
48 
49     LEADER_COUNTS = {
50         # Rates
51         'fail': 'etcd.leader.counts.fail',
52         'success': 'etcd.leader.counts.success',
53     }
54 
55     LEADER_LATENCY = {
56         # Gauges
57         'current': 'etcd.leader.latency.current',
58         'average': 'etcd.leader.latency.avg',
59         'minimum': 'etcd.leader.latency.min',
60         'maximum': 'etcd.leader.latency.max',
61         'standardDeviation': 'etcd.leader.latency.stddev',
62     }
63 
64     def check(self, instance):
65         if 'url' not in instance:
66             raise Exception('etcd instance missing "url" value.')
67 
68         # Load values from the instance config
69         url = instance['url']
70         instance_tags = instance.get('tags', [])
71         # Append the instance's URL in case there are more than one, that
72         # way they can tell the difference!
73         instance_tags.append("url:{0}".format(url))
74         timeout = float(instance.get('timeout', self.DEFAULT_TIMEOUT))
75         is_leader = False
76 
77         # Gather self metrics
78         self_response = self._get_self_metrics(url, timeout)
79         if self_response is not None:
80             if self_response['state'] == 'StateLeader':
81                 is_leader = True
82                 instance_tags.append('etcd_state:leader')
83             else:
84                 instance_tags.append('etcd_state:follower')
85 
86             for key in self.SELF_RATES:
87                 if key in self_response:
88                     self.rate(self.SELF_RATES[key], self_response[key], tags=instance_tags)
89                 else:
90                     self.log.warn("Missing key {0} in stats.".format(key))
91 
92             for key in self.SELF_GAUGES:
93                 if key in self_response:
94                     self.gauge(self.SELF_GAUGES[key], self_response[key], tags=instance_tags)
95                 else:
96                     self.log.warn("Missing key {0} in stats.".format(key))
97 
98         # Gather store metrics
99         store_response = self._get_store_metrics(url, timeout)
100         if store_response is not None:
101             for key in self.STORE_RATES:
102                 if key in store_response:
103                     self.rate(self.STORE_RATES[key], store_response[key], tags=instance_tags)
104                 else:
105                     self.log.warn("Missing key {0} in stats.".format(key))
106 
107             for key in self.STORE_GAUGES:
108                 if key in store_response:
109                     self.gauge(self.STORE_GAUGES[key], store_response[key], tags=instance_tags)
110                 else:
111                     self.log.warn("Missing key {0} in stats.".format(key))
112 
113         # Gather leader metrics
114         leader_response = self._get_leader_metrics(url, timeout)
115         if leader_response is not None and is_leader \
116                 and len(leader_response.get("followers", {})) > 0:
117             # Get the followers
118             followers = leader_response.get("followers")
119             for fol in followers:
120                 # counts
121                 for key in self.LEADER_COUNTS:
122                     self.rate(self.LEADER_COUNTS[key],
123                               followers[fol].get("counts").get(key),
124                               tags=instance_tags + ['follower:{0}'.format(fol)])
125                 # latency
126                 for key in self.LEADER_LATENCY:
127                     self.gauge(self.LEADER_LATENCY[key],
128                                followers[fol].get("latency").get(key),
129                                tags=instance_tags + ['follower:{0}'.format(fol)])
130 
131         # Service check
132         if self_response is not None and store_response is not None:
133             self.service_check(self.SERVICE_CHECK_NAME, AgentCheck.OK,
134                                tags=["url:{0}".format(url)])
135 
136     def _get_self_metrics(self, url, timeout):
137         return self._get_json(url + "/v2/stats/self", timeout)
138 
139     def _get_store_metrics(self, url, timeout):
140         return self._get_json(url + "/v2/stats/store", timeout)
141 
142     def _get_leader_metrics(self, url, timeout):
143         return self._get_json(url + "/v2/stats/leader", timeout)
144 
145     def _get_json(self, url, timeout):
146         try:
147             r = requests.get(url, timeout=timeout, headers=headers(self.agentConfig))
148         except requests.exceptions.Timeout:
149             # If there's a timeout
150             self.service_check(self.SERVICE_CHECK_NAME, AgentCheck.CRITICAL,
151                                message="Timeout when hitting %s" % url,
152                                tags=["url:{0}".format(url)])
153             raise
154 
155         if r.status_code != 200:
156             self.service_check(self.SERVICE_CHECK_NAME, AgentCheck.CRITICAL,
157                                message="Got %s when hitting %s" % (r.status_code, url),
158                                tags=["url:{0}".format(url)])
159             raise Exception("Http status code {0} on url {1}".format(r.status_code, url))
160 
161         return r.json()
162
```
--- 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()

```

diff --git a/checks.d/etcd.py b/checks.d/etcd.py
--- a/checks.d/etcd.py
+++ b/checks.d/etcd.py
@@ -111,22 +111,22 @@
                     self.log.warn("Missing key {0} in stats.".format(key))
 
         # Gather leader metrics
-        leader_response = self._get_leader_metrics(url, timeout)
-        if leader_response is not None and is_leader \
-                and len(leader_response.get("followers", {})) > 0:
-            # Get the followers
-            followers = leader_response.get("followers")
-            for fol in followers:
-                # counts
-                for key in self.LEADER_COUNTS:
-                    self.rate(self.LEADER_COUNTS[key],
-                              followers[fol].get("counts").get(key),
-                              tags=instance_tags + ['follower:{0}'.format(fol)])
-                # latency
-                for key in self.LEADER_LATENCY:
-                    self.gauge(self.LEADER_LATENCY[key],
-                               followers[fol].get("latency").get(key),
-                               tags=instance_tags + ['follower:{0}'.format(fol)])
+        if is_leader:
+            leader_response = self._get_leader_metrics(url, timeout)
+            if leader_response is not None and len(leader_response.get("followers", {})) > 0:
+                # Get the followers
+                followers = leader_response.get("followers")
+                for fol in followers:
+                    # counts
+                    for key in self.LEADER_COUNTS:
+                        self.rate(self.LEADER_COUNTS[key],
+                                  followers[fol].get("counts").get(key),
+                                  tags=instance_tags + ['follower:{0}'.format(fol)])
+                    # latency
+                    for key in self.LEADER_LATENCY:
+                        self.gauge(self.LEADER_LATENCY[key],
+                                   followers[fol].get("latency").get(key),
+                                   tags=instance_tags + ['follower:{0}'.format(fol)])
 
         # Service check
         if self_response is not None and store_response is not None:

{"golden_diff": "diff --git a/checks.d/etcd.py b/checks.d/etcd.py\n--- a/checks.d/etcd.py\n+++ b/checks.d/etcd.py\n@@ -111,22 +111,22 @@\n                     self.log.warn(\"Missing key {0} in stats.\".format(key))\n \n         # Gather leader metrics\n-        leader_response = self._get_leader_metrics(url, timeout)\n-        if leader_response is not None and is_leader \\\n-                and len(leader_response.get(\"followers\", {})) > 0:\n-            # Get the followers\n-            followers = leader_response.get(\"followers\")\n-            for fol in followers:\n-                # counts\n-                for key in self.LEADER_COUNTS:\n-                    self.rate(self.LEADER_COUNTS[key],\n-                              followers[fol].get(\"counts\").get(key),\n-                              tags=instance_tags + ['follower:{0}'.format(fol)])\n-                # latency\n-                for key in self.LEADER_LATENCY:\n-                    self.gauge(self.LEADER_LATENCY[key],\n-                               followers[fol].get(\"latency\").get(key),\n-                               tags=instance_tags + ['follower:{0}'.format(fol)])\n+        if is_leader:\n+            leader_response = self._get_leader_metrics(url, timeout)\n+            if leader_response is not None and len(leader_response.get(\"followers\", {})) > 0:\n+                # Get the followers\n+                followers = leader_response.get(\"followers\")\n+                for fol in followers:\n+                    # counts\n+                    for key in self.LEADER_COUNTS:\n+                        self.rate(self.LEADER_COUNTS[key],\n+                                  followers[fol].get(\"counts\").get(key),\n+                                  tags=instance_tags + ['follower:{0}'.format(fol)])\n+                    # latency\n+                    for key in self.LEADER_LATENCY:\n+                        self.gauge(self.LEADER_LATENCY[key],\n+                                   followers[fol].get(\"latency\").get(key),\n+                                   tags=instance_tags + ['follower:{0}'.format(fol)])\n \n         # Service check\n         if self_response is not None and store_response is not None:\n", "issue": "[etcd] `/stats/leader` from a follower returns a 403\nThe `/stats/leader` endpoint is only available on the leader etcd host.\nOn the followers, it returns a 403: it is illegitimately logged as an exception in the agent and triggers a CRITICAL service check.\n\n`#0[ERROR]: 'Http status code 403 on url http://localhost:4002/v2/stats/leader`\n\nFull stacktrace: \n\n```\n2015-06-17 16:41:46 UTC | ERROR | dd.collector | checks.etcd(__init__.py:678) | Check 'etcd' instance #0 failed\nTraceback (most recent call last):\n  File \"/opt/datadog-agent/agent/checks/__init__.py\", line 661, in run\n    self.check(copy.deepcopy(instance))\n  File \"/opt/datadog-agent/agent/checks.d/etcd.py\", line 114, in check\n    leader_response = self._get_leader_metrics(url, timeout)\n  File \"/opt/datadog-agent/agent/checks.d/etcd.py\", line 143, in _get_leader_metrics\n    return self._get_json(url + \"/v2/stats/leader\", timeout)\n  File \"/opt/datadog-agent/agent/checks.d/etcd.py\", line 159, in _get_json\n    raise Exception(\"Http status code {0} on url {1}\".format(r.status_code, url))\nException: Http status code 403 on url http://localhost:4002/v2/stats/leader\n```\n\n", "before_files": [{"content": "# project\nfrom checks import AgentCheck\nfrom util import headers\n\n# 3rd party\nimport requests\n\n\nclass Etcd(AgentCheck):\n\n    DEFAULT_TIMEOUT = 5\n\n    SERVICE_CHECK_NAME = 'etcd.can_connect'\n\n    STORE_RATES = {\n        'getsSuccess': 'etcd.store.gets.success',\n        'getsFail': 'etcd.store.gets.fail',\n        'setsSuccess': 'etcd.store.sets.success',\n        'setsFail': 'etcd.store.sets.fail',\n        'deleteSuccess': 'etcd.store.delete.success',\n        'deleteFail': 'etcd.store.delete.fail',\n        'updateSuccess': 'etcd.store.update.success',\n        'updateFail': 'etcd.store.update.fail',\n        'createSuccess': 'etcd.store.create.success',\n        'createFail': 'etcd.store.create.fail',\n        'compareAndSwapSuccess': 'etcd.store.compareandswap.success',\n        'compareAndSwapFail': 'etcd.store.compareandswap.fail',\n        'compareAndDeleteSuccess': 'etcd.store.compareanddelete.success',\n        'compareAndDeleteFail': 'etcd.store.compareanddelete.fail',\n        'expireCount': 'etcd.store.expire.count'\n    }\n\n    STORE_GAUGES = {\n        'watchers': 'etcd.store.watchers'\n    }\n\n    SELF_GAUGES = {\n        'sendPkgRate': 'etcd.self.send.pkgrate',\n        'sendBandwidthRate': 'etcd.self.send.bandwidthrate',\n        'recvPkgRate': 'etcd.self.recv.pkgrate',\n        'recvBandwidthRate': 'etcd.self.recv.bandwidthrate'\n    }\n\n    SELF_RATES = {\n        'recvAppendRequestCnt': 'etcd.self.recv.appendrequest.count',\n        'sendAppendRequestCnt': 'etcd.self.send.appendrequest.count'\n    }\n\n    LEADER_COUNTS = {\n        # Rates\n        'fail': 'etcd.leader.counts.fail',\n        'success': 'etcd.leader.counts.success',\n    }\n\n    LEADER_LATENCY = {\n        # Gauges\n        'current': 'etcd.leader.latency.current',\n        'average': 'etcd.leader.latency.avg',\n        'minimum': 'etcd.leader.latency.min',\n        'maximum': 'etcd.leader.latency.max',\n        'standardDeviation': 'etcd.leader.latency.stddev',\n    }\n\n    def check(self, instance):\n        if 'url' not in instance:\n            raise Exception('etcd instance missing \"url\" value.')\n\n        # Load values from the instance config\n        url = instance['url']\n        instance_tags = instance.get('tags', [])\n        # Append the instance's URL in case there are more than one, that\n        # way they can tell the difference!\n        instance_tags.append(\"url:{0}\".format(url))\n        timeout = float(instance.get('timeout', self.DEFAULT_TIMEOUT))\n        is_leader = False\n\n        # Gather self metrics\n        self_response = self._get_self_metrics(url, timeout)\n        if self_response is not None:\n            if self_response['state'] == 'StateLeader':\n                is_leader = True\n                instance_tags.append('etcd_state:leader')\n            else:\n                instance_tags.append('etcd_state:follower')\n\n            for key in self.SELF_RATES:\n                if key in self_response:\n                    self.rate(self.SELF_RATES[key], self_response[key], tags=instance_tags)\n                else:\n                    self.log.warn(\"Missing key {0} in stats.\".format(key))\n\n            for key in self.SELF_GAUGES:\n                if key in self_response:\n                    self.gauge(self.SELF_GAUGES[key], self_response[key], tags=instance_tags)\n                else:\n                    self.log.warn(\"Missing key {0} in stats.\".format(key))\n\n        # Gather store metrics\n        store_response = self._get_store_metrics(url, timeout)\n        if store_response is not None:\n            for key in self.STORE_RATES:\n                if key in store_response:\n                    self.rate(self.STORE_RATES[key], store_response[key], tags=instance_tags)\n                else:\n                    self.log.warn(\"Missing key {0} in stats.\".format(key))\n\n            for key in self.STORE_GAUGES:\n                if key in store_response:\n                    self.gauge(self.STORE_GAUGES[key], store_response[key], tags=instance_tags)\n                else:\n                    self.log.warn(\"Missing key {0} in stats.\".format(key))\n\n        # Gather leader metrics\n        leader_response = self._get_leader_metrics(url, timeout)\n        if leader_response is not None and is_leader \\\n                and len(leader_response.get(\"followers\", {})) > 0:\n            # Get the followers\n            followers = leader_response.get(\"followers\")\n            for fol in followers:\n                # counts\n                for key in self.LEADER_COUNTS:\n                    self.rate(self.LEADER_COUNTS[key],\n                              followers[fol].get(\"counts\").get(key),\n                              tags=instance_tags + ['follower:{0}'.format(fol)])\n                # latency\n                for key in self.LEADER_LATENCY:\n                    self.gauge(self.LEADER_LATENCY[key],\n                               followers[fol].get(\"latency\").get(key),\n                               tags=instance_tags + ['follower:{0}'.format(fol)])\n\n        # Service check\n        if self_response is not None and store_response is not None:\n            self.service_check(self.SERVICE_CHECK_NAME, AgentCheck.OK,\n                               tags=[\"url:{0}\".format(url)])\n\n    def _get_self_metrics(self, url, timeout):\n        return self._get_json(url + \"/v2/stats/self\", timeout)\n\n    def _get_store_metrics(self, url, timeout):\n        return self._get_json(url + \"/v2/stats/store\", timeout)\n\n    def _get_leader_metrics(self, url, timeout):\n        return self._get_json(url + \"/v2/stats/leader\", timeout)\n\n    def _get_json(self, url, timeout):\n        try:\n            r = requests.get(url, timeout=timeout, headers=headers(self.agentConfig))\n        except requests.exceptions.Timeout:\n            # If there's a timeout\n            self.service_check(self.SERVICE_CHECK_NAME, AgentCheck.CRITICAL,\n                               message=\"Timeout when hitting %s\" % url,\n                               tags=[\"url:{0}\".format(url)])\n            raise\n\n        if r.status_code != 200:\n            self.service_check(self.SERVICE_CHECK_NAME, AgentCheck.CRITICAL,\n                               message=\"Got %s when hitting %s\" % (r.status_code, url),\n                               tags=[\"url:{0}\".format(url)])\n            raise Exception(\"Http status code {0} on url {1}\".format(r.status_code, url))\n\n        return r.json()\n", "path": "checks.d/etcd.py"}], "after_files": [{"content": "# project\nfrom checks import AgentCheck\nfrom util import headers\n\n# 3rd party\nimport requests\n\n\nclass Etcd(AgentCheck):\n\n    DEFAULT_TIMEOUT = 5\n\n    SERVICE_CHECK_NAME = 'etcd.can_connect'\n\n    STORE_RATES = {\n        'getsSuccess': 'etcd.store.gets.success',\n        'getsFail': 'etcd.store.gets.fail',\n        'setsSuccess': 'etcd.store.sets.success',\n        'setsFail': 'etcd.store.sets.fail',\n        'deleteSuccess': 'etcd.store.delete.success',\n        'deleteFail': 'etcd.store.delete.fail',\n        'updateSuccess': 'etcd.store.update.success',\n        'updateFail': 'etcd.store.update.fail',\n        'createSuccess': 'etcd.store.create.success',\n        'createFail': 'etcd.store.create.fail',\n        'compareAndSwapSuccess': 'etcd.store.compareandswap.success',\n        'compareAndSwapFail': 'etcd.store.compareandswap.fail',\n        'compareAndDeleteSuccess': 'etcd.store.compareanddelete.success',\n        'compareAndDeleteFail': 'etcd.store.compareanddelete.fail',\n        'expireCount': 'etcd.store.expire.count'\n    }\n\n    STORE_GAUGES = {\n        'watchers': 'etcd.store.watchers'\n    }\n\n    SELF_GAUGES = {\n        'sendPkgRate': 'etcd.self.send.pkgrate',\n        'sendBandwidthRate': 'etcd.self.send.bandwidthrate',\n        'recvPkgRate': 'etcd.self.recv.pkgrate',\n        'recvBandwidthRate': 'etcd.self.recv.bandwidthrate'\n    }\n\n    SELF_RATES = {\n        'recvAppendRequestCnt': 'etcd.self.recv.appendrequest.count',\n        'sendAppendRequestCnt': 'etcd.self.send.appendrequest.count'\n    }\n\n    LEADER_COUNTS = {\n        # Rates\n        'fail': 'etcd.leader.counts.fail',\n        'success': 'etcd.leader.counts.success',\n    }\n\n    LEADER_LATENCY = {\n        # Gauges\n        'current': 'etcd.leader.latency.current',\n        'average': 'etcd.leader.latency.avg',\n        'minimum': 'etcd.leader.latency.min',\n        'maximum': 'etcd.leader.latency.max',\n        'standardDeviation': 'etcd.leader.latency.stddev',\n    }\n\n    def check(self, instance):\n        if 'url' not in instance:\n            raise Exception('etcd instance missing \"url\" value.')\n\n        # Load values from the instance config\n        url = instance['url']\n        instance_tags = instance.get('tags', [])\n        # Append the instance's URL in case there are more than one, that\n        # way they can tell the difference!\n        instance_tags.append(\"url:{0}\".format(url))\n        timeout = float(instance.get('timeout', self.DEFAULT_TIMEOUT))\n        is_leader = False\n\n        # Gather self metrics\n        self_response = self._get_self_metrics(url, timeout)\n        if self_response is not None:\n            if self_response['state'] == 'StateLeader':\n                is_leader = True\n                instance_tags.append('etcd_state:leader')\n            else:\n                instance_tags.append('etcd_state:follower')\n\n            for key in self.SELF_RATES:\n                if key in self_response:\n                    self.rate(self.SELF_RATES[key], self_response[key], tags=instance_tags)\n                else:\n                    self.log.warn(\"Missing key {0} in stats.\".format(key))\n\n            for key in self.SELF_GAUGES:\n                if key in self_response:\n                    self.gauge(self.SELF_GAUGES[key], self_response[key], tags=instance_tags)\n                else:\n                    self.log.warn(\"Missing key {0} in stats.\".format(key))\n\n        # Gather store metrics\n        store_response = self._get_store_metrics(url, timeout)\n        if store_response is not None:\n            for key in self.STORE_RATES:\n                if key in store_response:\n                    self.rate(self.STORE_RATES[key], store_response[key], tags=instance_tags)\n                else:\n                    self.log.warn(\"Missing key {0} in stats.\".format(key))\n\n            for key in self.STORE_GAUGES:\n                if key in store_response:\n                    self.gauge(self.STORE_GAUGES[key], store_response[key], tags=instance_tags)\n                else:\n                    self.log.warn(\"Missing key {0} in stats.\".format(key))\n\n        # Gather leader metrics\n        if is_leader:\n            leader_response = self._get_leader_metrics(url, timeout)\n            if leader_response is not None and len(leader_response.get(\"followers\", {})) > 0:\n                # Get the followers\n                followers = leader_response.get(\"followers\")\n                for fol in followers:\n                    # counts\n                    for key in self.LEADER_COUNTS:\n                        self.rate(self.LEADER_COUNTS[key],\n                                  followers[fol].get(\"counts\").get(key),\n                                  tags=instance_tags + ['follower:{0}'.format(fol)])\n                    # latency\n                    for key in self.LEADER_LATENCY:\n                        self.gauge(self.LEADER_LATENCY[key],\n                                   followers[fol].get(\"latency\").get(key),\n                                   tags=instance_tags + ['follower:{0}'.format(fol)])\n\n        # Service check\n        if self_response is not None and store_response is not None:\n            self.service_check(self.SERVICE_CHECK_NAME, AgentCheck.OK,\n                               tags=[\"url:{0}\".format(url)])\n\n    def _get_self_metrics(self, url, timeout):\n        return self._get_json(url + \"/v2/stats/self\", timeout)\n\n    def _get_store_metrics(self, url, timeout):\n        return self._get_json(url + \"/v2/stats/store\", timeout)\n\n    def _get_leader_metrics(self, url, timeout):\n        return self._get_json(url + \"/v2/stats/leader\", timeout)\n\n    def _get_json(self, url, timeout):\n        try:\n            r = requests.get(url, timeout=timeout, headers=headers(self.agentConfig))\n        except requests.exceptions.Timeout:\n            # If there's a timeout\n            self.service_check(self.SERVICE_CHECK_NAME, AgentCheck.CRITICAL,\n                               message=\"Timeout when hitting %s\" % url,\n                               tags=[\"url:{0}\".format(url)])\n            raise\n\n        if r.status_code != 200:\n            self.service_check(self.SERVICE_CHECK_NAME, AgentCheck.CRITICAL,\n                               message=\"Got %s when hitting %s\" % (r.status_code, url),\n                               tags=[\"url:{0}\".format(url)])\n            raise Exception(\"Http status code {0} on url {1}\".format(r.status_code, url))\n\n        return r.json()\n", "path": "checks.d/etcd.py"}]}