We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
[ssh] Multiple instances not differentiated
Any metrics sent through the ssh_check.py are not differentiated by instance. If multiple instances are running, the sftp.response_time metric will only be tagged with the host sending the metric: https://github.com/DataDog/dd-agent/blob/master/checks.d/ssh_check.py#L84


--- 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/ssh_check.py`
Content:
```
1 # stdlib
2 import time
3 import socket
4 # 3p
5 import paramiko
6 from collections import namedtuple
7 # project
8 from checks import AgentCheck
9 
10 class CheckSSH(AgentCheck):
11 
12     OPTIONS = [
13         ('host', True, None, str),
14         ('port', False, 22, int),
15         ('username', True, None, str),
16         ('password', False, None, str),
17         ('private_key_file', False, None, str),
18         ('sftp_check', False, True, bool),
19         ('add_missing_keys', False, False, bool),
20     ]
21 
22     Config = namedtuple('Config', [
23                 'host',
24                 'port',
25                 'username',
26                 'password',
27                 'private_key_file',
28                 'sftp_check',
29                 'add_missing_keys',
30             ]
31             )
32     def _load_conf(self, instance):
33         params = []
34         for option, required, default, expected_type in self.OPTIONS:
35             value = instance.get(option)
36             if required and (not value or type(value)) != expected_type :
37                 raise Exception("Please specify a valid {0}".format(option))
38 
39             if value is None or type(value) != expected_type:
40                 self.log.debug("Bad or missing value for {0} parameter. Using default".format(option))
41                 value = default
42 
43             params.append(value)
44         return self.Config._make(params)
45 
46     def check(self, instance):
47         conf = self._load_conf(instance)
48 
49         try:
50             private_key = paramiko.RSAKey.from_private_key_file (conf.private_key_file)
51         except Exception:
52             self.warning("Private key could not be found")
53             private_key = None
54 
55         client = paramiko.SSHClient()
56         if conf.add_missing_keys:
57             client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
58         client.load_system_host_keys()
59 
60         exception_message = None
61         #Service Availability to check status of SSH
62         try:
63             client.connect(conf.host, port=conf.port, username=conf.username, password=conf.password, pkey=private_key)
64             self.service_check('ssh.can_connect', AgentCheck.OK, message=exception_message)
65 
66         except Exception as e:
67             exception_message = str(e)
68             status = AgentCheck.CRITICAL
69             self.service_check('ssh.can_connect', status, message=exception_message)
70             if conf.sftp_check:
71                 self.service_check('sftp.can_connect', status, message=exception_message)
72             raise Exception (e)
73 
74         #Service Availability to check status of SFTP
75         if conf.sftp_check:
76             try:
77                 sftp = client.open_sftp()
78                 #Check response time of SFTP
79                 start_time = time.time()
80                 result = sftp.listdir('.')
81                 status = AgentCheck.OK
82                 end_time = time.time()
83                 time_taken = end_time - start_time
84                 self.gauge('sftp.response_time', time_taken)
85 
86             except Exception as e:
87                 exception_message = str(e)
88                 status = AgentCheck.CRITICAL
89 
90             if exception_message is None:
91                 exception_message = "No errors occured"
92 
93             self.service_check('sftp.can_connect', status, message=exception_message)
94
```
--- 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/ssh_check.py b/checks.d/ssh_check.py
--- a/checks.d/ssh_check.py
+++ b/checks.d/ssh_check.py
@@ -45,6 +45,7 @@
 
     def check(self, instance):
         conf = self._load_conf(instance)
+        tags = ["instance:{0}-{1}".format(conf.host, conf.port)] 
 
         try:
             private_key = paramiko.RSAKey.from_private_key_file (conf.private_key_file)
@@ -60,15 +61,19 @@
         exception_message = None
         #Service Availability to check status of SSH
         try:
-            client.connect(conf.host, port=conf.port, username=conf.username, password=conf.password, pkey=private_key)
-            self.service_check('ssh.can_connect', AgentCheck.OK, message=exception_message)
+            client.connect(conf.host, port=conf.port, username=conf.username,
+                password=conf.password, pkey=private_key)
+            self.service_check('ssh.can_connect', AgentCheck.OK,  tags=tags,
+                message=exception_message)
 
         except Exception as e:
             exception_message = str(e)
             status = AgentCheck.CRITICAL
-            self.service_check('ssh.can_connect', status, message=exception_message)
+            self.service_check('ssh.can_connect', status, tags=tags,
+                message=exception_message)
             if conf.sftp_check:
-                self.service_check('sftp.can_connect', status, message=exception_message)
+                self.service_check('sftp.can_connect', status, tags=tags,
+                    message=exception_message)
             raise Exception (e)
 
         #Service Availability to check status of SFTP
@@ -81,7 +86,7 @@
                 status = AgentCheck.OK
                 end_time = time.time()
                 time_taken = end_time - start_time
-                self.gauge('sftp.response_time', time_taken)
+                self.gauge('sftp.response_time', time_taken, tags=tags)
 
             except Exception as e:
                 exception_message = str(e)
@@ -90,4 +95,5 @@
             if exception_message is None:
                 exception_message = "No errors occured"
 
-            self.service_check('sftp.can_connect', status, message=exception_message)
+            self.service_check('sftp.can_connect', status, tags=tags,
+                message=exception_message)

{"golden_diff": "diff --git a/checks.d/ssh_check.py b/checks.d/ssh_check.py\n--- a/checks.d/ssh_check.py\n+++ b/checks.d/ssh_check.py\n@@ -45,6 +45,7 @@\n \n     def check(self, instance):\n         conf = self._load_conf(instance)\n+        tags = [\"instance:{0}-{1}\".format(conf.host, conf.port)] \n \n         try:\n             private_key = paramiko.RSAKey.from_private_key_file (conf.private_key_file)\n@@ -60,15 +61,19 @@\n         exception_message = None\n         #Service Availability to check status of SSH\n         try:\n-            client.connect(conf.host, port=conf.port, username=conf.username, password=conf.password, pkey=private_key)\n-            self.service_check('ssh.can_connect', AgentCheck.OK, message=exception_message)\n+            client.connect(conf.host, port=conf.port, username=conf.username,\n+                password=conf.password, pkey=private_key)\n+            self.service_check('ssh.can_connect', AgentCheck.OK,  tags=tags,\n+                message=exception_message)\n \n         except Exception as e:\n             exception_message = str(e)\n             status = AgentCheck.CRITICAL\n-            self.service_check('ssh.can_connect', status, message=exception_message)\n+            self.service_check('ssh.can_connect', status, tags=tags,\n+                message=exception_message)\n             if conf.sftp_check:\n-                self.service_check('sftp.can_connect', status, message=exception_message)\n+                self.service_check('sftp.can_connect', status, tags=tags,\n+                    message=exception_message)\n             raise Exception (e)\n \n         #Service Availability to check status of SFTP\n@@ -81,7 +86,7 @@\n                 status = AgentCheck.OK\n                 end_time = time.time()\n                 time_taken = end_time - start_time\n-                self.gauge('sftp.response_time', time_taken)\n+                self.gauge('sftp.response_time', time_taken, tags=tags)\n \n             except Exception as e:\n                 exception_message = str(e)\n@@ -90,4 +95,5 @@\n             if exception_message is None:\n                 exception_message = \"No errors occured\"\n \n-            self.service_check('sftp.can_connect', status, message=exception_message)\n+            self.service_check('sftp.can_connect', status, tags=tags,\n+                message=exception_message)\n", "issue": "[ssh] Multiple instances not differentiated\nAny metrics sent through the ssh_check.py are not differentiated by instance. If multiple instances are running, the sftp.response_time metric will only be tagged with the host sending the metric: https://github.com/DataDog/dd-agent/blob/master/checks.d/ssh_check.py#L84\n\n", "before_files": [{"content": "# stdlib\nimport time\nimport socket\n# 3p\nimport paramiko\nfrom collections import namedtuple\n# project\nfrom checks import AgentCheck\n\nclass CheckSSH(AgentCheck):\n\n    OPTIONS = [\n        ('host', True, None, str),\n        ('port', False, 22, int),\n        ('username', True, None, str),\n        ('password', False, None, str),\n        ('private_key_file', False, None, str),\n        ('sftp_check', False, True, bool),\n        ('add_missing_keys', False, False, bool),\n    ]\n\n    Config = namedtuple('Config', [\n                'host',\n                'port',\n                'username',\n                'password',\n                'private_key_file',\n                'sftp_check',\n                'add_missing_keys',\n            ]\n            )\n    def _load_conf(self, instance):\n        params = []\n        for option, required, default, expected_type in self.OPTIONS:\n            value = instance.get(option)\n            if required and (not value or type(value)) != expected_type :\n                raise Exception(\"Please specify a valid {0}\".format(option))\n\n            if value is None or type(value) != expected_type:\n                self.log.debug(\"Bad or missing value for {0} parameter. Using default\".format(option))\n                value = default\n\n            params.append(value)\n        return self.Config._make(params)\n\n    def check(self, instance):\n        conf = self._load_conf(instance)\n\n        try:\n            private_key = paramiko.RSAKey.from_private_key_file (conf.private_key_file)\n        except Exception:\n            self.warning(\"Private key could not be found\")\n            private_key = None\n\n        client = paramiko.SSHClient()\n        if conf.add_missing_keys:\n            client.set_missing_host_key_policy(paramiko.AutoAddPolicy())\n        client.load_system_host_keys()\n\n        exception_message = None\n        #Service Availability to check status of SSH\n        try:\n            client.connect(conf.host, port=conf.port, username=conf.username, password=conf.password, pkey=private_key)\n            self.service_check('ssh.can_connect', AgentCheck.OK, message=exception_message)\n\n        except Exception as e:\n            exception_message = str(e)\n            status = AgentCheck.CRITICAL\n            self.service_check('ssh.can_connect', status, message=exception_message)\n            if conf.sftp_check:\n                self.service_check('sftp.can_connect', status, message=exception_message)\n            raise Exception (e)\n\n        #Service Availability to check status of SFTP\n        if conf.sftp_check:\n            try:\n                sftp = client.open_sftp()\n                #Check response time of SFTP\n                start_time = time.time()\n                result = sftp.listdir('.')\n                status = AgentCheck.OK\n                end_time = time.time()\n                time_taken = end_time - start_time\n                self.gauge('sftp.response_time', time_taken)\n\n            except Exception as e:\n                exception_message = str(e)\n                status = AgentCheck.CRITICAL\n\n            if exception_message is None:\n                exception_message = \"No errors occured\"\n\n            self.service_check('sftp.can_connect', status, message=exception_message)\n", "path": "checks.d/ssh_check.py"}], "after_files": [{"content": "# stdlib\nimport time\nimport socket\n# 3p\nimport paramiko\nfrom collections import namedtuple\n# project\nfrom checks import AgentCheck\n\nclass CheckSSH(AgentCheck):\n\n    OPTIONS = [\n        ('host', True, None, str),\n        ('port', False, 22, int),\n        ('username', True, None, str),\n        ('password', False, None, str),\n        ('private_key_file', False, None, str),\n        ('sftp_check', False, True, bool),\n        ('add_missing_keys', False, False, bool),\n    ]\n\n    Config = namedtuple('Config', [\n                'host',\n                'port',\n                'username',\n                'password',\n                'private_key_file',\n                'sftp_check',\n                'add_missing_keys',\n            ]\n            )\n    def _load_conf(self, instance):\n        params = []\n        for option, required, default, expected_type in self.OPTIONS:\n            value = instance.get(option)\n            if required and (not value or type(value)) != expected_type :\n                raise Exception(\"Please specify a valid {0}\".format(option))\n\n            if value is None or type(value) != expected_type:\n                self.log.debug(\"Bad or missing value for {0} parameter. Using default\".format(option))\n                value = default\n\n            params.append(value)\n        return self.Config._make(params)\n\n    def check(self, instance):\n        conf = self._load_conf(instance)\n        tags = [\"instance:{0}-{1}\".format(conf.host, conf.port)] \n\n        try:\n            private_key = paramiko.RSAKey.from_private_key_file (conf.private_key_file)\n        except Exception:\n            self.warning(\"Private key could not be found\")\n            private_key = None\n\n        client = paramiko.SSHClient()\n        if conf.add_missing_keys:\n            client.set_missing_host_key_policy(paramiko.AutoAddPolicy())\n        client.load_system_host_keys()\n\n        exception_message = None\n        #Service Availability to check status of SSH\n        try:\n            client.connect(conf.host, port=conf.port, username=conf.username,\n                password=conf.password, pkey=private_key)\n            self.service_check('ssh.can_connect', AgentCheck.OK,  tags=tags,\n                message=exception_message)\n\n        except Exception as e:\n            exception_message = str(e)\n            status = AgentCheck.CRITICAL\n            self.service_check('ssh.can_connect', status, tags=tags,\n                message=exception_message)\n            if conf.sftp_check:\n                self.service_check('sftp.can_connect', status, tags=tags,\n                    message=exception_message)\n            raise Exception (e)\n\n        #Service Availability to check status of SFTP\n        if conf.sftp_check:\n            try:\n                sftp = client.open_sftp()\n                #Check response time of SFTP\n                start_time = time.time()\n                result = sftp.listdir('.')\n                status = AgentCheck.OK\n                end_time = time.time()\n                time_taken = end_time - start_time\n                self.gauge('sftp.response_time', time_taken, tags=tags)\n\n            except Exception as e:\n                exception_message = str(e)\n                status = AgentCheck.CRITICAL\n\n            if exception_message is None:\n                exception_message = \"No errors occured\"\n\n            self.service_check('sftp.can_connect', status, tags=tags,\n                message=exception_message)\n", "path": "checks.d/ssh_check.py"}]}