We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Couchbase service check do not send tags on OK status
Missing a `tags=service_check_tags` on line:
https://github.com/DataDog/dd-agent/blob/master/checks.d/couchbase.py#L104

Pretty small fix.


--- 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/couchbase.py`
Content:
```
1 # stdlib
2 import re
3 
4 # 3rd party
5 import requests
6 
7 # project
8 from checks import AgentCheck
9 from util import headers
10 
11 # Constants
12 COUCHBASE_STATS_PATH = '/pools/default'
13 DEFAULT_TIMEOUT = 10
14 
15 
16 class Couchbase(AgentCheck):
17     """Extracts stats from Couchbase via its REST API
18     http://docs.couchbase.com/couchbase-manual-2.0/#using-the-rest-api
19     """
20     SERVICE_CHECK_NAME = 'couchbase.can_connect'
21 
22     def _create_metrics(self, data, tags=None):
23         storage_totals = data['stats']['storageTotals']
24         for key, storage_type in storage_totals.items():
25             for metric_name, val in storage_type.items():
26                 if val is not None:
27                     metric_name = '.'.join(['couchbase', key, self.camel_case_to_joined_lower(metric_name)])
28                     self.gauge(metric_name, val, tags=tags)
29 
30         for bucket_name, bucket_stats in data['buckets'].items():
31             for metric_name, val in bucket_stats.items():
32                 if val is not None:
33                     metric_name = '.'.join(['couchbase', 'by_bucket', self.camel_case_to_joined_lower(metric_name)])
34                     metric_tags = list(tags)
35                     metric_tags.append('bucket:%s' % bucket_name)
36                     self.gauge(metric_name, val[0], tags=metric_tags, device_name=bucket_name)
37 
38         for node_name, node_stats in data['nodes'].items():
39             for metric_name, val in node_stats['interestingStats'].items():
40                 if val is not None:
41                     metric_name = '.'.join(['couchbase', 'by_node', self.camel_case_to_joined_lower(metric_name)])
42                     metric_tags = list(tags)
43                     metric_tags.append('node:%s' % node_name)
44                     self.gauge(metric_name, val, tags=metric_tags, device_name=node_name)
45 
46 
47     def _get_stats(self, url, instance):
48         """ Hit a given URL and return the parsed json. """
49         self.log.debug('Fetching Couchbase stats at url: %s' % url)
50 
51         timeout = float(instance.get('timeout', DEFAULT_TIMEOUT))
52 
53         auth = None
54         if 'user' in instance and 'password' in instance:
55             auth = (instance['user'], instance['password'])
56 
57         r = requests.get(url, auth=auth, headers=headers(self.agentConfig),
58             timeout=timeout)
59         r.raise_for_status()
60         return r.json()
61 
62     def check(self, instance):
63         server = instance.get('server', None)
64         if server is None:
65             raise Exception("The server must be specified")
66         tags = instance.get('tags', [])
67         # Clean up tags in case there was a None entry in the instance
68         # e.g. if the yaml contains tags: but no actual tags
69         if tags is None:
70             tags = []
71         else:
72             tags = list(set(tags))
73         tags.append('instance:%s' % server)
74         data = self.get_data(server, instance)
75         self._create_metrics(data, tags=list(set(tags)))
76 
77     def get_data(self, server, instance):
78         # The dictionary to be returned.
79         couchbase = {
80             'stats': None,
81             'buckets': {},
82             'nodes': {}
83         }
84 
85         # build couchbase stats entry point
86         url = '%s%s' % (server, COUCHBASE_STATS_PATH)
87 
88         # Fetch initial stats and capture a service check based on response.
89         service_check_tags = ['instance:%s' % server]
90         try:
91             overall_stats = self._get_stats(url, instance)
92             # No overall stats? bail out now
93             if overall_stats is None:
94                 raise Exception("No data returned from couchbase endpoint: %s" % url)
95         except requests.exceptions.HTTPError as e:
96             self.service_check(self.SERVICE_CHECK_NAME, AgentCheck.CRITICAL,
97                 tags=service_check_tags, message=str(e.message))
98             raise
99         except Exception as e:
100             self.service_check(self.SERVICE_CHECK_NAME, AgentCheck.CRITICAL,
101                 tags=service_check_tags, message=str(e))
102             raise
103         else:
104             self.service_check(self.SERVICE_CHECK_NAME, AgentCheck.OK)
105 
106         couchbase['stats'] = overall_stats
107 
108         nodes = overall_stats['nodes']
109 
110         # Next, get all the nodes
111         if nodes is not None:
112             for node in nodes:
113                 couchbase['nodes'][node['hostname']] = node
114 
115         # Next, get all buckets .
116         endpoint = overall_stats['buckets']['uri']
117 
118         url = '%s%s' % (server, endpoint)
119         buckets = self._get_stats(url, instance)
120 
121         if buckets is not None:
122             for bucket in buckets:
123                 bucket_name = bucket['name']
124 
125                 # Fetch URI for the stats bucket
126                 endpoint = bucket['stats']['uri']
127                 url = '%s%s' % (server, endpoint)
128 
129                 try:
130                     bucket_stats = self._get_stats(url, instance)
131                 except requests.exceptions.HTTPError:
132                     url_backup = '%s/pools/nodes/buckets/%s/stats' % (server, bucket_name)
133                     bucket_stats = self._get_stats(url_backup, instance)
134 
135                 bucket_samples = bucket_stats['op']['samples']
136                 if bucket_samples is not None:
137                     couchbase['buckets'][bucket['name']] = bucket_samples
138 
139         return couchbase
140 
141     # Takes a camelCased variable and returns a joined_lower equivalent.
142     # Returns input if non-camelCase variable is detected.
143     def camel_case_to_joined_lower(self, variable):
144         # replace non-word with _
145         converted_variable = re.sub('\W+', '_', variable)
146 
147         # insert _ in front of capital letters and lowercase the string
148         converted_variable = re.sub('([A-Z])', '_\g<1>', converted_variable).lower()
149 
150         # remove duplicate _
151         converted_variable = re.sub('_+', '_', converted_variable)
152 
153         # handle special case of starting/ending underscores
154         converted_variable = re.sub('^_|_$', '', converted_variable)
155 
156         return converted_variable
157
```
--- 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/couchbase.py b/checks.d/couchbase.py
--- a/checks.d/couchbase.py
+++ b/checks.d/couchbase.py
@@ -101,7 +101,8 @@
                 tags=service_check_tags, message=str(e))
             raise
         else:
-            self.service_check(self.SERVICE_CHECK_NAME, AgentCheck.OK)
+            self.service_check(self.SERVICE_CHECK_NAME, AgentCheck.OK,
+                tags=service_check_tags)
 
         couchbase['stats'] = overall_stats

{"golden_diff": "diff --git a/checks.d/couchbase.py b/checks.d/couchbase.py\n--- a/checks.d/couchbase.py\n+++ b/checks.d/couchbase.py\n@@ -101,7 +101,8 @@\n                 tags=service_check_tags, message=str(e))\n             raise\n         else:\n-            self.service_check(self.SERVICE_CHECK_NAME, AgentCheck.OK)\n+            self.service_check(self.SERVICE_CHECK_NAME, AgentCheck.OK,\n+                tags=service_check_tags)\n \n         couchbase['stats'] = overall_stats\n", "issue": "Couchbase service check do not send tags on OK status\nMissing a `tags=service_check_tags` on line:\nhttps://github.com/DataDog/dd-agent/blob/master/checks.d/couchbase.py#L104\n\nPretty small fix.\n\n", "before_files": [{"content": "# stdlib\nimport re\n\n# 3rd party\nimport requests\n\n# project\nfrom checks import AgentCheck\nfrom util import headers\n\n# Constants\nCOUCHBASE_STATS_PATH = '/pools/default'\nDEFAULT_TIMEOUT = 10\n\n\nclass Couchbase(AgentCheck):\n    \"\"\"Extracts stats from Couchbase via its REST API\n    http://docs.couchbase.com/couchbase-manual-2.0/#using-the-rest-api\n    \"\"\"\n    SERVICE_CHECK_NAME = 'couchbase.can_connect'\n\n    def _create_metrics(self, data, tags=None):\n        storage_totals = data['stats']['storageTotals']\n        for key, storage_type in storage_totals.items():\n            for metric_name, val in storage_type.items():\n                if val is not None:\n                    metric_name = '.'.join(['couchbase', key, self.camel_case_to_joined_lower(metric_name)])\n                    self.gauge(metric_name, val, tags=tags)\n\n        for bucket_name, bucket_stats in data['buckets'].items():\n            for metric_name, val in bucket_stats.items():\n                if val is not None:\n                    metric_name = '.'.join(['couchbase', 'by_bucket', self.camel_case_to_joined_lower(metric_name)])\n                    metric_tags = list(tags)\n                    metric_tags.append('bucket:%s' % bucket_name)\n                    self.gauge(metric_name, val[0], tags=metric_tags, device_name=bucket_name)\n\n        for node_name, node_stats in data['nodes'].items():\n            for metric_name, val in node_stats['interestingStats'].items():\n                if val is not None:\n                    metric_name = '.'.join(['couchbase', 'by_node', self.camel_case_to_joined_lower(metric_name)])\n                    metric_tags = list(tags)\n                    metric_tags.append('node:%s' % node_name)\n                    self.gauge(metric_name, val, tags=metric_tags, device_name=node_name)\n\n\n    def _get_stats(self, url, instance):\n        \"\"\" Hit a given URL and return the parsed json. \"\"\"\n        self.log.debug('Fetching Couchbase stats at url: %s' % url)\n\n        timeout = float(instance.get('timeout', DEFAULT_TIMEOUT))\n\n        auth = None\n        if 'user' in instance and 'password' in instance:\n            auth = (instance['user'], instance['password'])\n\n        r = requests.get(url, auth=auth, headers=headers(self.agentConfig),\n            timeout=timeout)\n        r.raise_for_status()\n        return r.json()\n\n    def check(self, instance):\n        server = instance.get('server', None)\n        if server is None:\n            raise Exception(\"The server must be specified\")\n        tags = instance.get('tags', [])\n        # Clean up tags in case there was a None entry in the instance\n        # e.g. if the yaml contains tags: but no actual tags\n        if tags is None:\n            tags = []\n        else:\n            tags = list(set(tags))\n        tags.append('instance:%s' % server)\n        data = self.get_data(server, instance)\n        self._create_metrics(data, tags=list(set(tags)))\n\n    def get_data(self, server, instance):\n        # The dictionary to be returned.\n        couchbase = {\n            'stats': None,\n            'buckets': {},\n            'nodes': {}\n        }\n\n        # build couchbase stats entry point\n        url = '%s%s' % (server, COUCHBASE_STATS_PATH)\n\n        # Fetch initial stats and capture a service check based on response.\n        service_check_tags = ['instance:%s' % server]\n        try:\n            overall_stats = self._get_stats(url, instance)\n            # No overall stats? bail out now\n            if overall_stats is None:\n                raise Exception(\"No data returned from couchbase endpoint: %s\" % url)\n        except requests.exceptions.HTTPError as e:\n            self.service_check(self.SERVICE_CHECK_NAME, AgentCheck.CRITICAL,\n                tags=service_check_tags, message=str(e.message))\n            raise\n        except Exception as e:\n            self.service_check(self.SERVICE_CHECK_NAME, AgentCheck.CRITICAL,\n                tags=service_check_tags, message=str(e))\n            raise\n        else:\n            self.service_check(self.SERVICE_CHECK_NAME, AgentCheck.OK)\n\n        couchbase['stats'] = overall_stats\n\n        nodes = overall_stats['nodes']\n\n        # Next, get all the nodes\n        if nodes is not None:\n            for node in nodes:\n                couchbase['nodes'][node['hostname']] = node\n\n        # Next, get all buckets .\n        endpoint = overall_stats['buckets']['uri']\n\n        url = '%s%s' % (server, endpoint)\n        buckets = self._get_stats(url, instance)\n\n        if buckets is not None:\n            for bucket in buckets:\n                bucket_name = bucket['name']\n\n                # Fetch URI for the stats bucket\n                endpoint = bucket['stats']['uri']\n                url = '%s%s' % (server, endpoint)\n\n                try:\n                    bucket_stats = self._get_stats(url, instance)\n                except requests.exceptions.HTTPError:\n                    url_backup = '%s/pools/nodes/buckets/%s/stats' % (server, bucket_name)\n                    bucket_stats = self._get_stats(url_backup, instance)\n\n                bucket_samples = bucket_stats['op']['samples']\n                if bucket_samples is not None:\n                    couchbase['buckets'][bucket['name']] = bucket_samples\n\n        return couchbase\n\n    # Takes a camelCased variable and returns a joined_lower equivalent.\n    # Returns input if non-camelCase variable is detected.\n    def camel_case_to_joined_lower(self, variable):\n        # replace non-word with _\n        converted_variable = re.sub('\\W+', '_', variable)\n\n        # insert _ in front of capital letters and lowercase the string\n        converted_variable = re.sub('([A-Z])', '_\\g<1>', converted_variable).lower()\n\n        # remove duplicate _\n        converted_variable = re.sub('_+', '_', converted_variable)\n\n        # handle special case of starting/ending underscores\n        converted_variable = re.sub('^_|_$', '', converted_variable)\n\n        return converted_variable\n", "path": "checks.d/couchbase.py"}], "after_files": [{"content": "# stdlib\nimport re\n\n# 3rd party\nimport requests\n\n# project\nfrom checks import AgentCheck\nfrom util import headers\n\n# Constants\nCOUCHBASE_STATS_PATH = '/pools/default'\nDEFAULT_TIMEOUT = 10\n\n\nclass Couchbase(AgentCheck):\n    \"\"\"Extracts stats from Couchbase via its REST API\n    http://docs.couchbase.com/couchbase-manual-2.0/#using-the-rest-api\n    \"\"\"\n    SERVICE_CHECK_NAME = 'couchbase.can_connect'\n\n    def _create_metrics(self, data, tags=None):\n        storage_totals = data['stats']['storageTotals']\n        for key, storage_type in storage_totals.items():\n            for metric_name, val in storage_type.items():\n                if val is not None:\n                    metric_name = '.'.join(['couchbase', key, self.camel_case_to_joined_lower(metric_name)])\n                    self.gauge(metric_name, val, tags=tags)\n\n        for bucket_name, bucket_stats in data['buckets'].items():\n            for metric_name, val in bucket_stats.items():\n                if val is not None:\n                    metric_name = '.'.join(['couchbase', 'by_bucket', self.camel_case_to_joined_lower(metric_name)])\n                    metric_tags = list(tags)\n                    metric_tags.append('bucket:%s' % bucket_name)\n                    self.gauge(metric_name, val[0], tags=metric_tags, device_name=bucket_name)\n\n        for node_name, node_stats in data['nodes'].items():\n            for metric_name, val in node_stats['interestingStats'].items():\n                if val is not None:\n                    metric_name = '.'.join(['couchbase', 'by_node', self.camel_case_to_joined_lower(metric_name)])\n                    metric_tags = list(tags)\n                    metric_tags.append('node:%s' % node_name)\n                    self.gauge(metric_name, val, tags=metric_tags, device_name=node_name)\n\n\n    def _get_stats(self, url, instance):\n        \"\"\" Hit a given URL and return the parsed json. \"\"\"\n        self.log.debug('Fetching Couchbase stats at url: %s' % url)\n\n        timeout = float(instance.get('timeout', DEFAULT_TIMEOUT))\n\n        auth = None\n        if 'user' in instance and 'password' in instance:\n            auth = (instance['user'], instance['password'])\n\n        r = requests.get(url, auth=auth, headers=headers(self.agentConfig),\n            timeout=timeout)\n        r.raise_for_status()\n        return r.json()\n\n    def check(self, instance):\n        server = instance.get('server', None)\n        if server is None:\n            raise Exception(\"The server must be specified\")\n        tags = instance.get('tags', [])\n        # Clean up tags in case there was a None entry in the instance\n        # e.g. if the yaml contains tags: but no actual tags\n        if tags is None:\n            tags = []\n        else:\n            tags = list(set(tags))\n        tags.append('instance:%s' % server)\n        data = self.get_data(server, instance)\n        self._create_metrics(data, tags=list(set(tags)))\n\n    def get_data(self, server, instance):\n        # The dictionary to be returned.\n        couchbase = {\n            'stats': None,\n            'buckets': {},\n            'nodes': {}\n        }\n\n        # build couchbase stats entry point\n        url = '%s%s' % (server, COUCHBASE_STATS_PATH)\n\n        # Fetch initial stats and capture a service check based on response.\n        service_check_tags = ['instance:%s' % server]\n        try:\n            overall_stats = self._get_stats(url, instance)\n            # No overall stats? bail out now\n            if overall_stats is None:\n                raise Exception(\"No data returned from couchbase endpoint: %s\" % url)\n        except requests.exceptions.HTTPError as e:\n            self.service_check(self.SERVICE_CHECK_NAME, AgentCheck.CRITICAL,\n                tags=service_check_tags, message=str(e.message))\n            raise\n        except Exception as e:\n            self.service_check(self.SERVICE_CHECK_NAME, AgentCheck.CRITICAL,\n                tags=service_check_tags, message=str(e))\n            raise\n        else:\n            self.service_check(self.SERVICE_CHECK_NAME, AgentCheck.OK,\n                tags=service_check_tags)\n\n        couchbase['stats'] = overall_stats\n\n        nodes = overall_stats['nodes']\n\n        # Next, get all the nodes\n        if nodes is not None:\n            for node in nodes:\n                couchbase['nodes'][node['hostname']] = node\n\n        # Next, get all buckets .\n        endpoint = overall_stats['buckets']['uri']\n\n        url = '%s%s' % (server, endpoint)\n        buckets = self._get_stats(url, instance)\n\n        if buckets is not None:\n            for bucket in buckets:\n                bucket_name = bucket['name']\n\n                # Fetch URI for the stats bucket\n                endpoint = bucket['stats']['uri']\n                url = '%s%s' % (server, endpoint)\n\n                try:\n                    bucket_stats = self._get_stats(url, instance)\n                except requests.exceptions.HTTPError:\n                    url_backup = '%s/pools/nodes/buckets/%s/stats' % (server, bucket_name)\n                    bucket_stats = self._get_stats(url_backup, instance)\n\n                bucket_samples = bucket_stats['op']['samples']\n                if bucket_samples is not None:\n                    couchbase['buckets'][bucket['name']] = bucket_samples\n\n        return couchbase\n\n    # Takes a camelCased variable and returns a joined_lower equivalent.\n    # Returns input if non-camelCase variable is detected.\n    def camel_case_to_joined_lower(self, variable):\n        # replace non-word with _\n        converted_variable = re.sub('\\W+', '_', variable)\n\n        # insert _ in front of capital letters and lowercase the string\n        converted_variable = re.sub('([A-Z])', '_\\g<1>', converted_variable).lower()\n\n        # remove duplicate _\n        converted_variable = re.sub('_+', '_', converted_variable)\n\n        # handle special case of starting/ending underscores\n        converted_variable = re.sub('^_|_$', '', converted_variable)\n\n        return converted_variable\n", "path": "checks.d/couchbase.py"}]}