def __init__(self, *args, **kwargs): # `args` order is `name`, `init_config`, `agentConfig` (deprecated), `instances` self.metrics = defaultdict(list) self.instances = kwargs.get('instances', []) self.name = kwargs.get('name', '') self.init_config = kwargs.get('init_config', {}) self.agentConfig = kwargs.get('agentConfig', {}) self.warnings = [] if len(args) > 0: self.name = args[0] if len(args) > 1: self.init_config = args[1] if len(args) > 2: if len(args) > 3 or 'instances' in kwargs: # old-style init: the 3rd argument is `agentConfig` self.agentConfig = args[2] if len(args) > 3: self.instances = args[3] else: # new-style init: the 3rd argument is `instances` self.instances = args[2] self.hostname = datadog_agent.get_hostname() # `self.hostname` is deprecated, use `datadog_agent.get_hostname()` instead # the agent5 'AgentCheck' setup a log attribute. self.log = logging.getLogger('%s.%s' % (__name__, self.name)) # Set proxy settings self.proxies = get_requests_proxy(self.agentConfig) if not self.init_config: self._use_agent_proxy = True else: self._use_agent_proxy = _is_affirmative( self.init_config.get("use_agent_proxy", True)) self.default_integration_http_timeout = float(self.agentConfig.get('default_integration_http_timeout', 9)) self._deprecations = { 'increment': [ False, "DEPRECATION NOTICE: `AgentCheck.increment`/`AgentCheck.decrement` are deprecated, please use " + "`AgentCheck.gauge` or `AgentCheck.count` instead, with a different metric name", ], 'device_name': [ False, "DEPRECATION NOTICE: `device_name` is deprecated, please use a `device:` tag in the `tags` list instead", ], 'in_developer_mode': [ False, "DEPRECATION NOTICE: `in_developer_mode` is deprecated, please stop using it.", ], 'no_proxy': [ False, "DEPRECATION NOTICE: The `no_proxy` config option has been renamed " "to `skip_proxy` and will be removed in a future release.", ], }
def resolve_db_host(db_host): agent_hostname = datadog_agent.get_hostname() if not db_host or db_host in {'localhost', '127.0.0.1'}: return agent_hostname try: host_ip = socket.gethostbyname(db_host) except socket.gaierror as e: # could be connecting via a unix domain socket logger.debug( "failed to resolve DB host '%s' due to %r. falling back to agent hostname: %s", db_host, e, agent_hostname, ) return agent_hostname try: agent_host_ip = socket.gethostbyname(agent_hostname) if agent_host_ip == host_ip: return agent_hostname except socket.gaierror as e: logger.debug( "failed to resolve agent host '%s' due to socket.gaierror(%s). using DB host: %s", agent_hostname, e, db_host, ) return db_host
def get_iishost(self): inst_host = self.instance.get("host") if inst_host in [".", "localhost", "127.0.0.1", None]: # Use agent's hostname if connecting to local machine. iis_host = datadog_agent.get_hostname() else: iis_host = inst_host return "iis_host:{}".format(self.normalize_tag(iis_host))
def extract_hostname_for_event(server_uri): """Make a reasonable hostname for a replset membership event to mention.""" uri = urlsplit(server_uri) if '@' in uri.netloc: hostname = uri.netloc.split('@')[1].split(':')[0] else: hostname = uri.netloc.split(':')[0] if hostname == 'localhost': hostname = datadog_agent.get_hostname() return hostname
def __init__(self, *args, **kwargs): # type: (*Any, **Any) -> None """In general, you don't need to and you should not override anything from the base class except the :py:meth:`check` method but sometimes it might be useful for a Check to have its own constructor. When overriding `__init__` you have to remember that, depending on the configuration, the Agent might create several different Check instances and the method would be called as many times. Agent 6,7 signature: AgentCheck(name, init_config, instances) # instances contain only 1 instance AgentCheck.check(instance) Agent 8 signature: AgentCheck(name, init_config, instance) # one instance AgentCheck.check() # no more instance argument for check method :warning: when loading a Custom check, the Agent will inspect the module searching for a subclass of `AgentCheck`. If such a class exists but has been derived in turn, it'll be ignored - **you should never derive from an existing Check**. :param str name: the name of the check. :param dict init_config: the 'init_config' section of the configuration. :param list instances: a one-element list containing the instance options from the configuration file (a list is used to keep backward compatibility with older versions of the Agent). """ # NOTE: these variable assignments exist to ease type checking when eventually assigned as attributes. name = kwargs.get('name', '') init_config = kwargs.get('init_config', {}) agentConfig = kwargs.get('agentConfig', {}) instances = kwargs.get('instances', []) if len(args) > 0: name = args[0] if len(args) > 1: init_config = args[1] if len(args) > 2: # agent pass instances as tuple but in test we are usually using list, so we are testing for both if len(args) > 3 or not isinstance( args[2], (list, tuple)) or 'instances' in kwargs: # old-style init: the 3rd argument is `agentConfig` agentConfig = args[2] if len(args) > 3: instances = args[3] else: # new-style init: the 3rd argument is `instances` instances = args[2] # NOTE: Agent 6+ should pass exactly one instance... But we are not abiding by that rule on our side # everywhere just yet. It's complicated... See: https://github.com/DataDog/integrations-core/pull/5573 instance = instances[0] if instances else None self.check_id = '' self.name = name # type: str self.init_config = init_config # type: InitConfigType self.agentConfig = agentConfig # type: AgentConfigType self.instance = instance # type: Optional[InstanceType] self.instances = instances # type: List[InstanceType] self.warnings = [] # type: List[str] self.metrics = defaultdict(list) # type: DefaultDict[str, List[str]] # `self.hostname` is deprecated, use `datadog_agent.get_hostname()` instead self.hostname = datadog_agent.get_hostname() # type: str logger = logging.getLogger('{}.{}'.format(__name__, self.name)) self.log = CheckLoggingAdapter(logger, self) # TODO: Remove with Agent 5 # Set proxy settings self.proxies = self._get_requests_proxy() if not self.init_config: self._use_agent_proxy = True else: self._use_agent_proxy = is_affirmative( self.init_config.get('use_agent_proxy', True)) # TODO: Remove with Agent 5 self.default_integration_http_timeout = float( self.agentConfig.get('default_integration_http_timeout', 9)) self._deprecations = { 'increment': ( False, ('DEPRECATION NOTICE: `AgentCheck.increment`/`AgentCheck.decrement` are deprecated, please ' 'use `AgentCheck.gauge` or `AgentCheck.count` instead, with a different metric name' ), ), 'device_name': ( False, ('DEPRECATION NOTICE: `device_name` is deprecated, please use a `device:` ' 'tag in the `tags` list instead'), ), 'in_developer_mode': ( False, 'DEPRECATION NOTICE: `in_developer_mode` is deprecated, please stop using it.', ), 'no_proxy': ( False, ('DEPRECATION NOTICE: The `no_proxy` config option has been renamed ' 'to `skip_proxy` and will be removed in Agent version 6.13.'), ), 'service_tag': ( False, ('DEPRECATION NOTICE: The `service` tag is deprecated and has been renamed to `%s`. ' 'Set `disable_legacy_service_tag` to `true` to disable this warning. ' 'The default will become `true` and cannot be changed in Agent version 8.' ), ), } # type: Dict[str, Tuple[bool, str]] # Setup metric limits self.metric_limiter = self._get_metric_limiter(self.name, instance=self.instance) # Functions that will be called exactly once (if successful) before the first check run self.check_initializations = deque( [self.send_config_metadata]) # type: Deque[Callable[[], None]]
def __init__(self, *args, **kwargs): """In general, you don't need to and you should not override anything from the base class except the :py:meth:`check` method but sometimes it might be useful for a Check to have its own constructor. When overriding `__init__` you have to remember that, depending on the configuration, the Agent might create several different Check instances and the method would be called as many times. :warning: when loading a Custom check, the Agent will inspect the module searching for a subclass of `AgentCheck`. If such a class exists but has been derived in turn, it'll be ignored - **you should never derive from an existing Check**. :param str name: the name of the check. :param dict init_config: the 'init_config' section of the configuration. :param list instances: a one-element list containing the instance options from the configuration file (a list is used to keep backward compatibility with older versions of the Agent). """ self.metrics = defaultdict(list) self.check_id = '' self.instances = kwargs.get('instances', []) self.name = kwargs.get('name', '') self.init_config = kwargs.get('init_config', {}) self.agentConfig = kwargs.get('agentConfig', {}) self.warnings = [] self.metric_limiter = None if len(args) > 0: self.name = args[0] if len(args) > 1: self.init_config = args[1] if len(args) > 2: if len(args) > 3 or 'instances' in kwargs: # old-style init: the 3rd argument is `agentConfig` self.agentConfig = args[2] if len(args) > 3: self.instances = args[3] else: # new-style init: the 3rd argument is `instances` self.instances = args[2] # Agent 6+ will only have one instance self.instance = self.instances[0] if self.instances else None # `self.hostname` is deprecated, use `datadog_agent.get_hostname()` instead self.hostname = datadog_agent.get_hostname() # the agent5 'AgentCheck' setup a log attribute. self.log = logging.getLogger('{}.{}'.format(__name__, self.name)) # Provides logic to yield consistent network behavior based on user configuration. # Only new checks or checks on Agent 6.13+ can and should use this for HTTP requests. self._http = None # TODO: Remove with Agent 5 # Set proxy settings self.proxies = self._get_requests_proxy() if not self.init_config: self._use_agent_proxy = True else: self._use_agent_proxy = is_affirmative( self.init_config.get('use_agent_proxy', True)) # TODO: Remove with Agent 5 self.default_integration_http_timeout = float( self.agentConfig.get('default_integration_http_timeout', 9)) self._deprecations = { 'increment': [ False, ('DEPRECATION NOTICE: `AgentCheck.increment`/`AgentCheck.decrement` are deprecated, please ' 'use `AgentCheck.gauge` or `AgentCheck.count` instead, with a different metric name' ), ], 'device_name': [ False, ('DEPRECATION NOTICE: `device_name` is deprecated, please use a `device:` ' 'tag in the `tags` list instead'), ], 'in_developer_mode': [ False, 'DEPRECATION NOTICE: `in_developer_mode` is deprecated, please stop using it.', ], 'no_proxy': [ False, ('DEPRECATION NOTICE: The `no_proxy` config option has been renamed ' 'to `skip_proxy` and will be removed in Agent version 6.13.'), ], } # Setup metric limits try: metric_limit = self.instances[0].get('max_returned_metrics', self.DEFAULT_METRIC_LIMIT) # Do not allow to disable limiting if the class has set a non-zero default value if metric_limit == 0 and self.DEFAULT_METRIC_LIMIT > 0: metric_limit = self.DEFAULT_METRIC_LIMIT self.warning( 'Setting max_returned_metrics to zero is not allowed, reverting ' 'to the default of {} metrics'.format( self.DEFAULT_METRIC_LIMIT)) except Exception: metric_limit = self.DEFAULT_METRIC_LIMIT if metric_limit > 0: self.metric_limiter = Limiter(self.name, 'metrics', metric_limit, self.warning)
def __init__(self, *args, **kwargs): # type: (*Any, **Any) -> None """ - **name** (_str_) - the name of the check - **init_config** (_dict_) - the `init_config` section of the configuration. - **instance** (_List[dict]_) - a one-element list containing the instance options from the configuration file (a list is used to keep backward compatibility with older versions of the Agent). """ # NOTE: these variable assignments exist to ease type checking when eventually assigned as attributes. name = kwargs.get('name', '') init_config = kwargs.get('init_config', {}) agentConfig = kwargs.get('agentConfig', {}) instances = kwargs.get('instances', []) if len(args) > 0: name = args[0] if len(args) > 1: init_config = args[1] if len(args) > 2: # agent pass instances as tuple but in test we are usually using list, so we are testing for both if len(args) > 3 or not isinstance( args[2], (list, tuple)) or 'instances' in kwargs: # old-style init: the 3rd argument is `agentConfig` agentConfig = args[2] if len(args) > 3: instances = args[3] else: # new-style init: the 3rd argument is `instances` instances = args[2] # NOTE: Agent 6+ should pass exactly one instance... But we are not abiding by that rule on our side # everywhere just yet. It's complicated... See: https://github.com/DataDog/integrations-core/pull/5573 instance = instances[0] if instances else None self.check_id = '' self.name = name # type: str self.init_config = init_config # type: InitConfigType self.agentConfig = agentConfig # type: AgentConfigType self.instance = instance # type: InstanceType self.instances = instances # type: List[InstanceType] self.warnings = [] # type: List[str] self.metrics = defaultdict(list) # type: DefaultDict[str, List[str]] # `self.hostname` is deprecated, use `datadog_agent.get_hostname()` instead self.hostname = datadog_agent.get_hostname() # type: str logger = logging.getLogger('{}.{}'.format(__name__, self.name)) self.log = CheckLoggingAdapter(logger, self) # TODO: Remove with Agent 5 # Set proxy settings self.proxies = self._get_requests_proxy() if not self.init_config: self._use_agent_proxy = True else: self._use_agent_proxy = is_affirmative( self.init_config.get('use_agent_proxy', True)) # TODO: Remove with Agent 5 self.default_integration_http_timeout = float( self.agentConfig.get('default_integration_http_timeout', 9)) self._deprecations = { 'increment': ( False, ('DEPRECATION NOTICE: `AgentCheck.increment`/`AgentCheck.decrement` are deprecated, please ' 'use `AgentCheck.gauge` or `AgentCheck.count` instead, with a different metric name' ), ), 'device_name': ( False, ('DEPRECATION NOTICE: `device_name` is deprecated, please use a `device:` ' 'tag in the `tags` list instead'), ), 'in_developer_mode': ( False, 'DEPRECATION NOTICE: `in_developer_mode` is deprecated, please stop using it.', ), 'no_proxy': ( False, ('DEPRECATION NOTICE: The `no_proxy` config option has been renamed ' 'to `skip_proxy` and will be removed in a future release.'), ), 'service_tag': ( False, ('DEPRECATION NOTICE: The `service` tag is deprecated and has been renamed to `%s`. ' 'Set `disable_legacy_service_tag` to `true` to disable this warning. ' 'The default will become `true` and cannot be changed in Agent version 8.' ), ), } # type: Dict[str, Tuple[bool, str]] # Setup metric limits self.metric_limiter = self._get_metric_limiter(self.name, instance=self.instance) # Functions that will be called exactly once (if successful) before the first check run self.check_initializations = deque( [self.send_config_metadata]) # type: Deque[Callable[[], None]]
def check(self, _): # type: (Any) -> None self._hostname = datadog_agent.get_hostname() # Assert the health of the vCenter API by getting the version, and submit the service_check accordingly try: version_info = self.api.get_version() if self.is_metadata_collection_enabled(): self.set_metadata('version', version_info.version_str) except Exception: # Explicitly do not attach any host to the service checks. self.log.exception( "The vCenter API is not responding. The check will not run.") self.service_check(SERVICE_CHECK_NAME, AgentCheck.CRITICAL, tags=self.config.base_tags, hostname=None) raise else: self.service_check(SERVICE_CHECK_NAME, AgentCheck.OK, tags=self.config.base_tags, hostname=None) # Collect and submit events if self.config.should_collect_events: self.collect_events() if self.config.collect_events_only: return # Update the value of `max_query_metrics` if needed if self.config.is_historical(): try: vcenter_max_hist_metrics = self.api.get_max_query_metrics() if vcenter_max_hist_metrics < self.config.max_historical_metrics: self.log.warning( "The integration was configured with `max_query_metrics: %d` but your vCenter has a" "limit of %d which is lower. Ignoring your configuration in favor of the vCenter value." "To update the vCenter value, please update the `%s` field", self.config.max_historical_metrics, vcenter_max_hist_metrics, MAX_QUERY_METRICS_OPTION, ) self.config.max_historical_metrics = vcenter_max_hist_metrics except Exception: self.config.max_historical_metrics = DEFAULT_MAX_QUERY_METRICS self.log.info( "Could not fetch the value of %s, setting `max_historical_metrics` to %d.", MAX_QUERY_METRICS_OPTION, DEFAULT_MAX_QUERY_METRICS, ) pass # Refresh the metrics metadata cache if self.metrics_metadata_cache.is_expired(): with self.metrics_metadata_cache.update(): self.refresh_metrics_metadata_cache() # Refresh the infrastructure cache if self.infrastructure_cache.is_expired(): with self.infrastructure_cache.update(): self.refresh_infrastructure_cache() # Submit host tags as soon as we have fresh data self.submit_external_host_tags() # Submit the number of VMs that are monitored for resource_type in self.config.collected_resource_types: for mor in self.infrastructure_cache.get_mors(resource_type): mor_props = self.infrastructure_cache.get_mor_props(mor) # Explicitly do not attach any host to those metrics. resource_tags = mor_props.get('tags', []) self.count( '{}.count'.format(MOR_TYPE_AS_STRING[resource_type]), 1, tags=self.config.base_tags + resource_tags, hostname=None, ) # Creating a thread pool and starting metric collection self.log.debug("Starting metric collection in %d threads.", self.config.threads_count) self.collect_metrics_async() self.log.debug("Metric collection completed.")
def __init__(self, *args, **kwargs): """ args: `name`, `init_config`, `agentConfig` (deprecated), `instances` """ self.metrics = defaultdict(list) self.check_id = '' self.instances = kwargs.get('instances', []) self.name = kwargs.get('name', '') self.init_config = kwargs.get('init_config', {}) self.agentConfig = kwargs.get('agentConfig', {}) self.warnings = [] self.metric_limiter = None if len(args) > 0: self.name = args[0] if len(args) > 1: self.init_config = args[1] if len(args) > 2: if len(args) > 3 or 'instances' in kwargs: # old-style init: the 3rd argument is `agentConfig` self.agentConfig = args[2] if len(args) > 3: self.instances = args[3] else: # new-style init: the 3rd argument is `instances` self.instances = args[2] # Agent 6+ will only have one instance self.instance = self.instances[0] if self.instances else None # `self.hostname` is deprecated, use `datadog_agent.get_hostname()` instead self.hostname = datadog_agent.get_hostname() # the agent5 'AgentCheck' setup a log attribute. self.log = logging.getLogger('{}.{}'.format(__name__, self.name)) # Provides logic to yield consistent network behavior based on user configuration. # Only new checks or checks on Agent 6.13+ can and should use this for HTTP requests. self._http = None # TODO: Remove with Agent 5 # Set proxy settings self.proxies = self._get_requests_proxy() if not self.init_config: self._use_agent_proxy = True else: self._use_agent_proxy = is_affirmative(self.init_config.get('use_agent_proxy', True)) # TODO: Remove with Agent 5 self.default_integration_http_timeout = float(self.agentConfig.get('default_integration_http_timeout', 9)) self._deprecations = { 'increment': [ False, ( 'DEPRECATION NOTICE: `AgentCheck.increment`/`AgentCheck.decrement` are deprecated, please ' 'use `AgentCheck.gauge` or `AgentCheck.count` instead, with a different metric name' ), ], 'device_name': [ False, ( 'DEPRECATION NOTICE: `device_name` is deprecated, please use a `device:` ' 'tag in the `tags` list instead' ), ], 'in_developer_mode': [ False, 'DEPRECATION NOTICE: `in_developer_mode` is deprecated, please stop using it.', ], 'no_proxy': [ False, ( 'DEPRECATION NOTICE: The `no_proxy` config option has been renamed ' 'to `skip_proxy` and will be removed in Agent version 6.13.' ), ], } # Setup metric limits try: metric_limit = self.instances[0].get('max_returned_metrics', self.DEFAULT_METRIC_LIMIT) # Do not allow to disable limiting if the class has set a non-zero default value if metric_limit == 0 and self.DEFAULT_METRIC_LIMIT > 0: metric_limit = self.DEFAULT_METRIC_LIMIT self.warning( 'Setting max_returned_metrics to zero is not allowed, reverting ' 'to the default of {} metrics'.format(self.DEFAULT_METRIC_LIMIT) ) except Exception: metric_limit = self.DEFAULT_METRIC_LIMIT if metric_limit > 0: self.metric_limiter = Limiter(self.name, 'metrics', metric_limit, self.warning)
def __init__(self, *args, **kwargs): """ args: `name`, `init_config`, `agentConfig` (deprecated), `instances` """ self.metrics = defaultdict(list) self.check_id = b'' self.instances = kwargs.get('instances', []) self.name = kwargs.get('name', '') self.init_config = kwargs.get('init_config', {}) self.agentConfig = kwargs.get('agentConfig', {}) self.warnings = [] self.metric_limiter = None if len(args) > 0: self.name = args[0] if len(args) > 1: self.init_config = args[1] if len(args) > 2: if len(args) > 3 or 'instances' in kwargs: # old-style init: the 3rd argument is `agentConfig` self.agentConfig = args[2] if len(args) > 3: self.instances = args[3] else: # new-style init: the 3rd argument is `instances` self.instances = args[2] # Agent 6+ will only have one instance self.instance = self.instances[0] if self.instances else None # `self.hostname` is deprecated, use `datadog_agent.get_hostname()` instead self.hostname = datadog_agent.get_hostname() # the agent5 'AgentCheck' setup a log attribute. self.log = logging.getLogger('%s.%s' % (__name__, self.name)) # Set proxy settings self.proxies = self._get_requests_proxy() if not self.init_config: self._use_agent_proxy = True else: self._use_agent_proxy = is_affirmative( self.init_config.get("use_agent_proxy", True)) self.default_integration_http_timeout = float( self.agentConfig.get('default_integration_http_timeout', 9)) self._deprecations = { 'increment': [ False, "DEPRECATION NOTICE: `AgentCheck.increment`/`AgentCheck.decrement` are deprecated, please use " "`AgentCheck.gauge` or `AgentCheck.count` instead, with a different metric name", ], 'device_name': [ False, "DEPRECATION NOTICE: `device_name` is deprecated, please use a `device:` " "tag in the `tags` list instead", ], 'in_developer_mode': [ False, "DEPRECATION NOTICE: `in_developer_mode` is deprecated, please stop using it.", ], 'no_proxy': [ False, "DEPRECATION NOTICE: The `no_proxy` config option has been renamed " "to `skip_proxy` and will be removed in a future release.", ], } # Setup metric limits try: metric_limit = self.instances[0].get("max_returned_metrics", self.DEFAULT_METRIC_LIMIT) # Do not allow to disable limiting if the class has set a non-zero default value if metric_limit == 0 and self.DEFAULT_METRIC_LIMIT > 0: metric_limit = self.DEFAULT_METRIC_LIMIT self.warning( "Setting max_returned_metrics to zero is not allowed, " "reverting to the default of {} metrics".format( self.DEFAULT_METRIC_LIMIT)) except Exception: metric_limit = self.DEFAULT_METRIC_LIMIT if metric_limit > 0: self.metric_limiter = Limiter(self.name, "metrics", metric_limit, self.warning)
def test_get_hostname(self): self.assertEqual(datadog_agent.get_hostname(), "test.hostname")
def _get_debug_tags(self): return ['agent_hostname:{}'.format(datadog_agent.get_hostname())]
def agent_hostname(self): # type: () -> str if self._agent_hostname is None: self._agent_hostname = datadog_agent.get_hostname() return self._agent_hostname