def _get_hostname_metadata(self): """ Returns a dictionnary that contains hostname metadata. """ metadata = EC2.get_metadata(self.agentConfig) if metadata.get('hostname'): metadata['ec2-hostname'] = metadata.get('hostname') del metadata['hostname'] if self.agentConfig.get('hostname'): metadata['agent-hostname'] = self.agentConfig.get('hostname') else: try: metadata["socket-hostname"] = socket.gethostname() except Exception: pass try: metadata["socket-fqdn"] = socket.getfqdn() except Exception: pass metadata["hostname"] = self.hostname metadata["timezones"] = self._decode_tzname(time.tzname) # Add cloud provider aliases host_aliases = GCE.get_host_aliases(self.agentConfig) if host_aliases: metadata['host_aliases'] = host_aliases return metadata
def _set_agent_config_hostname(self, agentConfig): # Try to fetch instance Id from EC2 if not hostname has been set # in the config file. # DEPRECATED if agentConfig.get('hostname') is None and agentConfig.get('use_ec2_instance_id'): instanceId = EC2.get_instance_id(agentConfig) if instanceId is not None: log.info("Running on EC2, instanceId: %s" % instanceId) agentConfig['hostname'] = instanceId else: log.info('Not running on EC2, using hostname to identify this server') return agentConfig
def test_metadata(self): # Reset metadata just to be sure EC2.metadata = {} # Test gathering metadata from ec2 start = time.time() d = EC2.get_metadata({'collect_instance_metadata': True}) end = time.time() self.assertTrue(isinstance(d, types.DictType)) # Either we're on ec2 or we're not (at least 7 attributes expected) assert len(d) == 0 or len(d) >= 7, d if "instance-id" in d: assert d["instance-id"].startswith("i-"), d assert end - start <= 1.15, "It took %s seconds to get ec2 metadata" % (end-start)
def _populate_payload_metadata(self, payload, check_statuses, start_event=True): """ Periodically populate the payload with metadata related to the system, host, and/or checks. """ now = time.time() # Include system stats on first postback if start_event and self._is_first_run(): payload['systemStats'] = self.agentConfig.get('system_stats', {}) # Also post an event in the newsfeed payload['events']['System'] = [{ 'api_key': self.agentConfig['api_key'], 'host': self.hostname, 'timestamp': now, 'event_type':'Agent Startup', 'msg_text': 'Version %s' % get_version() }] # Periodically send the host metadata. if self._should_send_additional_data('host_metadata'): # gather metadata with gohai gohai_metadata = self._run_gohai_metadata() if gohai_metadata: payload['gohai'] = gohai_metadata payload['systemStats'] = get_system_stats( proc_path=self.agentConfig.get('procfs_path', '/proc').rstrip('/') ) payload['meta'] = self._get_hostname_metadata() self.hostname_metadata_cache = payload['meta'] # Add static tags from the configuration file host_tags = [] if self.agentConfig['tags'] is not None: host_tags.extend([unicode(tag.strip()) for tag in self.agentConfig['tags'].split(",")]) if self.agentConfig['collect_ec2_tags']: host_tags.extend(EC2.get_tags(self.agentConfig)) if host_tags: payload['host-tags']['system'] = host_tags # If required by the user, let's create the dd_check:xxx host tags if self.agentConfig['create_dd_check_tags']: app_tags_list = [DD_CHECK_TAG.format(c.name) for c in self.initialized_checks_d] app_tags_list.extend([DD_CHECK_TAG.format(cname) for cname in JMXFiles.get_jmx_appnames()]) if 'system' not in payload['host-tags']: payload['host-tags']['system'] = [] payload['host-tags']['system'].extend(app_tags_list) GCE_tags = GCE.get_tags(self.agentConfig) if GCE_tags is not None: payload['host-tags'][GCE.SOURCE_TYPE_NAME] = GCE_tags # Log the metadata on the first run if self._is_first_run(): log.info("Hostnames: %s, tags: %s" % (repr(self.hostname_metadata_cache), payload['host-tags'])) # Periodically send extra hosts metadata (vsphere) # Metadata of hosts that are not the host where the agent runs, not all the checks use # that external_host_tags = [] if self._should_send_additional_data('external_host_tags'): for check in self.initialized_checks_d: try: getter = getattr(check, 'get_external_host_tags') check_tags = getter() external_host_tags.extend(check_tags) except AttributeError: pass if external_host_tags: payload['external_host_tags'] = external_host_tags # Periodically send agent_checks metadata if self._should_send_additional_data('agent_checks'): # Add agent checks statuses and error/warning messages agent_checks = [] for check in check_statuses: if check.instance_statuses is not None: for i, instance_status in enumerate(check.instance_statuses): agent_checks.append( ( check.name, check.source_type_name, instance_status.instance_id, instance_status.status, # put error message or list of warning messages in the same field # it will be handled by the UI instance_status.error or instance_status.warnings or "", check.service_metadata[i] ) ) else: agent_checks.append( ( check.name, check.source_type_name, "initialization", check.status, repr(check.init_failed_error) ) ) payload['agent_checks'] = agent_checks payload['meta'] = self.hostname_metadata_cache # add hostname metadata
def get_hostname(config=None): """ Get the canonical host name this agent should identify as. This is the authoritative source of the host name for the agent. Tries, in order: * agent config (datadog.conf, "hostname:") * 'hostname -f' (on unix) * socket.gethostname() """ hostname = None # first, try the config if config is None: from config import get_config config = get_config(parse_args=True) config_hostname = config.get('hostname') if config_hostname and is_valid_hostname(config_hostname): return config_hostname # Try to get GCE instance name gce_hostname = GCE.get_hostname(config) if gce_hostname is not None: if is_valid_hostname(gce_hostname): return gce_hostname # Try to get the docker hostname if Platform.is_containerized(): # First we try from the Docker API docker_util = DockerUtil() docker_hostname = docker_util.get_hostname(use_default_gw=False) if docker_hostname is not None and is_valid_hostname(docker_hostname): hostname = docker_hostname elif Platform.is_k8s(): # Let's try from the kubelet kube_util = KubeUtil() _, kube_hostname = kube_util.get_node_info() if kube_hostname is not None and is_valid_hostname(kube_hostname): hostname = kube_hostname # then move on to os-specific detection if hostname is None: if Platform.is_unix() or Platform.is_solaris(): unix_hostname = _get_hostname_unix() if unix_hostname and is_valid_hostname(unix_hostname): hostname = unix_hostname # if we have an ec2 default hostname, see if there's an instance-id available if (Platform.is_ecs_instance()) or (hostname is not None and EC2.is_default(hostname)): instanceid = EC2.get_instance_id(config) if instanceid: hostname = instanceid # fall back on socket.gethostname(), socket.getfqdn() is too unreliable if hostname is None: try: socket_hostname = socket.gethostname() except socket.error: socket_hostname = None if socket_hostname and is_valid_hostname(socket_hostname): hostname = socket_hostname if hostname is None: log.critical('Unable to reliably determine host name. You can define one in datadog.conf or in your hosts file') raise Exception('Unable to reliably determine host name. You can define one in datadog.conf or in your hosts file') return hostname
def get_hostname(config=None): """ Get the canonical host name this agent should identify as. This is the authoritative source of the host name for the agent. Tries, in order: * agent config (datadog.conf, "hostname:") * 'hostname -f' (on unix) * socket.gethostname() """ hostname = None # first, try the config if config is None: from config import get_config config = get_config(parse_args=True) config_hostname = config.get('hostname') if config_hostname and is_valid_hostname(config_hostname): return config_hostname # Try to get GCE instance name gce_hostname = GCE.get_hostname(config) if gce_hostname is not None: if is_valid_hostname(gce_hostname): return gce_hostname # Try to get the docker hostname if Platform.is_containerized(): # First we try from the Docker API docker_util = DockerUtil() docker_hostname = docker_util.get_hostname(use_default_gw=False) if docker_hostname is not None and is_valid_hostname(docker_hostname): hostname = docker_hostname elif Platform.is_k8s(): # Let's try from the kubelet try: kube_util = KubeUtil() except Exception as ex: log.error("Couldn't instantiate the kubernetes client, " "getting the k8s hostname won't work. Error: %s" % str(ex)) else: _, kube_hostname = kube_util.get_node_info() if kube_hostname is not None and is_valid_hostname( kube_hostname): hostname = kube_hostname # then move on to os-specific detection if hostname is None: if Platform.is_unix() or Platform.is_solaris(): unix_hostname = _get_hostname_unix() if unix_hostname and is_valid_hostname(unix_hostname): hostname = unix_hostname # if we don't have a hostname, or we have an ec2 default hostname, # see if there's an instance-id available if not Platform.is_windows() and (hostname is None or Platform.is_ecs_instance() or EC2.is_default(hostname)): instanceid = EC2.get_instance_id(config) if instanceid: hostname = instanceid # fall back on socket.gethostname(), socket.getfqdn() is too unreliable if hostname is None: try: socket_hostname = socket.gethostname() except socket.error: socket_hostname = None if socket_hostname and is_valid_hostname(socket_hostname): hostname = socket_hostname if hostname is None: log.critical( 'Unable to reliably determine host name. You can define one in datadog.conf or in your hosts file' ) raise Exception( 'Unable to reliably determine host name. You can define one in datadog.conf or in your hosts file' ) return hostname
def test_is_default_hostname(self): for hostname in ['ip-172-31-16-235', 'domU-12-31-38-00-A4-A2', 'domU-12-31-39-02-14-35']: self.assertTrue(EC2.is_default(hostname)) for hostname in ['i-672d49da', 'localhost', 'robert.redf.org']: self.assertFalse(EC2.is_default(hostname))