prompt: 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()
  
  ```
  
golden_diff: 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)
  
verification_info: {"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"}]}