def run_check(name, path=None): """ Test custom checks on Windows. """ # Read the config file confd_path = path or os.path.join(get_confd_path(get_os()), "%s.yaml" % name) try: f = open(confd_path) except IOError: raise Exception("Unable to open configuration at %s" % confd_path) config_str = f.read() f.close() # Run the check check, instances = get_check(name, config_str) if not instances: raise Exception("YAML configuration returned no instances.") for instance in instances: check.check(instance) if check.has_events(): print "Events:\n" pprint(check.get_events(), indent=4) print "Metrics:\n" pprint(check.get_metrics(), indent=4)
def __init__(self, agentConfig, emitters, systemStats): self.emit_duration = None self.agentConfig = agentConfig # system stats is generated by config.get_system_stats self.agentConfig["system_stats"] = systemStats # agent config is used during checks, system_stats can be accessed through the config self.os = get_os() self.plugins = None self.emitters = emitters self.metadata_interval = int(agentConfig.get("metadata_interval", 10 * 60)) self.metadata_start = time.time() socket.setdefaulttimeout(15) self.run_count = 0 self.continue_running = True self.metadata_cache = None self.initialized_checks_d = [] self.init_failed_checks_d = [] # Unix System Checks self._unix_system_checks = { "disk": u.Disk(log), "io": u.IO(log), "load": u.Load(log), "memory": u.Memory(log), "processes": u.Processes(log), "cpu": u.Cpu(log), } # Win32 System `Checks self._win32_system_checks = { "disk": w32.Disk(log), "io": w32.IO(log), "proc": w32.Processes(log), "memory": w32.Memory(log), "network": w32.Network(log), "cpu": w32.Cpu(log), } # Old-style metric checks self._ganglia = Ganglia(log) self._dogstream = Dogstreams.init(log, self.agentConfig) self._ddforwarder = DdForwarder(log, self.agentConfig) # Agent Metrics self._agent_metrics = CollectorMetrics(log) self._metrics_checks = [] # Custom metric checks for module_spec in [s.strip() for s in self.agentConfig.get("custom_checks", "").split(",")]: if len(module_spec) == 0: continue try: self._metrics_checks.append(modules.load(module_spec, "Check")(log)) log.info("Registered custom check %s" % module_spec) log.warning( "Old format custom checks are deprecated. They should be moved to the checks.d interface as old custom checks will be removed in a next version" ) except Exception, e: log.exception("Unable to load custom check module %s" % module_spec)
def load_check(name, config, agentConfig): checksd_path = get_checksd_path(get_os()) if checksd_path not in sys.path: sys.path.append(checksd_path) check_module = __import__(name) check_class = None classes = inspect.getmembers(check_module, inspect.isclass) for _, clsmember in classes: if clsmember == AgentCheck: continue if issubclass(clsmember, AgentCheck): check_class = clsmember if AgentCheck in clsmember.__bases__: continue else: break if check_class is None: raise Exception("Unable to import check %s. Missing a class that inherits AgentCheck" % name) init_config = config.get('init_config', {}) instances = config.get('instances') agentConfig['checksd_hostname'] = get_hostname(agentConfig) # init the check class try: return check_class(name, init_config=init_config, agentConfig=agentConfig, instances=instances) except Exception as e: raise Exception("Check is using old API, {0}".format(e))
def load_check(name, config, agentConfig, is_sdk=False): if not is_sdk: checksd_path = get_checksd_path(get_os()) # find (in checksd_path) and load the check module fd, filename, desc = imp.find_module(name, [checksd_path]) check_module = imp.load_module(name, fd, filename, desc) else: check_module = __import__("check") check_class = None classes = inspect.getmembers(check_module, inspect.isclass) for _, clsmember in classes: if clsmember == AgentCheck: continue if issubclass(clsmember, AgentCheck): check_class = clsmember if AgentCheck in clsmember.__bases__: continue else: break if check_class is None: raise Exception("Unable to import check %s. Missing a class that inherits AgentCheck" % name) init_config = config.get('init_config', {}) instances = config.get('instances') agentConfig['checksd_hostname'] = get_hostname(agentConfig) # init the check class try: return check_class(name, init_config=init_config, agentConfig=agentConfig, instances=instances) except TypeError as e: raise Exception("Check is using old API, {0}".format(e)) except Exception: raise
def get_check(name, config_str): from checks import AgentCheck checksd_path = get_checksd_path(get_os()) if checksd_path not in sys.path: sys.path.append(checksd_path) check_module = __import__(name) check_class = None classes = inspect.getmembers(check_module, inspect.isclass) max_hierarchy_len = 0 for name, clsmember in classes: if AgentCheck in clsmember.__bases__: check_class = clsmember break class_hierarchy = inspect.getmro(clsmember) if AgentCheck in class_hierarchy: if len(class_hierarchy) > max_hierarchy_len: max_hierarchy_len = len(class_hierarchy) check_class = clsmember if check_class is None: raise Exception("Unable to import check %s. Missing a class that inherits AgentCheck" % name) agentConfig = { 'version': '0.1', 'api_key': 'tota' } return check_class.from_yaml(yaml_text=config_str, check_name=name, agentConfig=agentConfig)
def run_check(name, path=None): from tests.common import get_check # Read the config file confd_path = path or os.path.join(get_confd_path(get_os()), '%s.yaml' % name) try: f = open(confd_path) except IOError: raise Exception('Unable to open configuration at %s' % confd_path) config_str = f.read() f.close() # Run the check check, instances = get_check(name, config_str) if not instances: raise Exception('YAML configuration returned no instances.') for instance in instances: check.check(instance) if check.has_events(): print "Events:\n" pprint(check.get_events(), indent=4) print "Metrics:\n" pprint(check.get_metrics(), indent=4)
def get_config_path(cfg_path=None, os_name=None): # Check if there's an override and if it exists if cfg_path is not None and os.path.exists(cfg_path): return cfg_path # Check if there's a config stored in the current agent directory try: path = os.path.realpath(__file__) path = os.path.dirname(path) return _config_path(path) except PathNotFound as e: pass if os_name is None: os_name = get_os() # Check for an OS-specific path, continue on not-found exceptions bad_path = '' try: if os_name == 'windows': return _windows_config_path() elif os_name == 'mac': return _mac_config_path() else: return _unix_config_path() except PathNotFound as e: if len(e.args) > 0: bad_path = e.args[0] # If all searches fail, exit the agent with an error sys.stderr.write("Please supply a configuration file at %s or in the directory where " "the Agent is currently deployed.\n" % bad_path) sys.exit(3)
def load_check_directory(agentConfig, hostname): ''' Return the initialized checks from checks.d, and a mapping of checks that failed to initialize. Only checks that have a configuration file in conf.d will be returned. ''' from checks import AgentCheck, AGENT_METRICS_CHECK_NAME initialized_checks = {} init_failed_checks = {} deprecated_checks = {} agentConfig['checksd_hostname'] = hostname deprecated_configs_enabled = [v for k,v in OLD_STYLE_PARAMETERS if len([l for l in agentConfig if l.startswith(k)]) > 0] for deprecated_config in deprecated_configs_enabled: msg = "Configuring %s in datadog.conf is not supported anymore. Please use conf.d" % deprecated_config deprecated_checks[deprecated_config] = {'error': msg, 'traceback': None} log.error(msg) osname = get_os() checks_paths = [glob.glob(os.path.join(agentConfig['additional_checksd'], '*.py'))] try: checksd_path = get_checksd_path(osname) checks_paths.append(glob.glob(os.path.join(checksd_path, '*.py'))) except PathNotFound, e: log.error(e.args[0]) sys.exit(3)
def load_check(agentConfig, hostname, checkname): """Same logic as load_check_directory except it loads one specific check""" agentConfig['checksd_hostname'] = hostname osname = get_os() checks_places = get_checks_places(osname, agentConfig) for config_path in _file_configs_paths(osname, agentConfig): check_name = _conf_path_to_check_name(config_path) if check_name == checkname: conf_is_valid, check_config, invalid_check = _load_file_config(config_path, check_name, agentConfig) if invalid_check and not conf_is_valid: return invalid_check # try to load the check and return the result load_success, load_failure = load_check_from_places(check_config, check_name, checks_places, agentConfig) return load_success.values()[0] or load_failure # the check was not found, try with service discovery for check_name, service_disco_check_config in _service_disco_configs(agentConfig).iteritems(): if check_name == checkname: sd_init_config, sd_instances = service_disco_check_config check_config = {'init_config': sd_init_config, 'instances': sd_instances} # try to load the check and return the result load_success, load_failure = load_check_from_places(check_config, check_name, checks_places, agentConfig) return load_success.values()[0] or load_failure return None
def load_check(name, config, agentConfig): checksd_path = get_checksd_path(get_os()) if checksd_path not in sys.path: sys.path.append(checksd_path) check_module = __import__(name) check_class = None classes = inspect.getmembers(check_module, inspect.isclass) for name, clsmember in classes: if clsmember == AgentCheck: continue if issubclass(clsmember, AgentCheck): check_class = clsmember if AgentCheck in clsmember.__bases__: continue else: break if check_class is None: raise Exception("Unable to import check %s. Missing a class that inherits AgentCheck" % name) init_config = config.get("init_config", None) instances = config.get("instances") # init the check class try: return check_class(name, init_config=init_config, agentConfig=agentConfig, instances=instances) except: # Backwards compatitiblity for old checks that don't support the # instances argument. c = check_class(name, init_config=init_config, agentConfig=agentConfig) c.instances = instances return c
def get_checksd_path(osname=None): if not osname: osname = get_os() if osname == 'windows': return _windows_checksd_path() else: return _unix_checksd_path()
def __init__(self, agentConfig, emitters, systemStats): self.emit_duration = None self.agentConfig = agentConfig # system stats is generated by config.get_system_stats self.agentConfig['system_stats'] = systemStats # agent config is used during checks, system_stats can be accessed through the config self.os = get_os() self.plugins = None self.emitters = emitters self.metadata_interval = int(agentConfig.get('metadata_interval', 10 * 60)) self.metadata_start = time.time() socket.setdefaulttimeout(15) self.run_count = 0 self.continue_running = True self.metadata_cache = None self.checks_d = [] # Unix System Checks self._unix_system_checks = { 'disk': u.Disk(log), 'io': u.IO(log), 'load': u.Load(log), 'memory': u.Memory(log), 'processes': u.Processes(log), 'cpu': u.Cpu(log) } # Win32 System `Checks self._win32_system_checks = { 'disk': w32.Disk(log), 'io': w32.IO(log), 'proc': w32.Processes(log), 'memory': w32.Memory(log), 'network': w32.Network(log), 'cpu': w32.Cpu(log) } # Old-style metric checks self._ganglia = Ganglia(log) self._cassandra = Cassandra() self._dogstream = Dogstreams.init(log, self.agentConfig) self._ddforwarder = DdForwarder(log, self.agentConfig) # Agent Metrics self._agent_metrics = CollectorMetrics(log) # Metric Checks self._metrics_checks = [ Memcache(log), ] # Custom metric checks for module_spec in [s.strip() for s in self.agentConfig.get('custom_checks', '').split(',')]: if len(module_spec) == 0: continue try: self._metrics_checks.append(modules.load(module_spec, 'Check')(log)) log.info("Registered custom check %s" % module_spec) except Exception, e: log.exception('Unable to load custom check module %s' % module_spec)
def init(config_path=None): agentConfig = get_config(parse_args=False, cfg_path=config_path) osname = get_os() try: confd_path = get_confd_path(osname) except PathNotFound, e: log.error("No conf.d folder found at '%s' or in the directory where" "the Agent is currently deployed.\n" % e.args[0])
def initialize_logging(logger_name): try: logging_config = get_logging_config() logging.basicConfig( format=get_log_format(logger_name), level=logging_config['log_level'] or logging.INFO, ) log_file = logging_config.get('%s_log_file' % logger_name) if log_file is not None and not logging_config['disable_file_logging']: # make sure the log directory is writeable # NOTE: the entire directory needs to be writable so that rotation works if os.access(os.path.dirname(log_file), os.R_OK | os.W_OK): file_handler = logging.handlers.RotatingFileHandler(log_file, maxBytes=LOGGING_MAX_BYTES, backupCount=1) formatter = logging.Formatter(get_log_format(logger_name), get_log_date_format()) file_handler.setFormatter(formatter) root_log = logging.getLogger() root_log.addHandler(file_handler) else: sys.stderr.write("Log file is unwritable: '%s'\n" % log_file) # set up syslog if logging_config['log_to_syslog']: try: from logging.handlers import SysLogHandler if logging_config['syslog_host'] is not None and logging_config['syslog_port'] is not None: sys_log_addr = (logging_config['syslog_host'], logging_config['syslog_port']) else: sys_log_addr = "/dev/log" # Special-case BSDs if Platform.is_darwin(): sys_log_addr = "/var/run/syslog" elif Platform.is_freebsd(): sys_log_addr = "/var/run/log" handler = SysLogHandler(address=sys_log_addr, facility=SysLogHandler.LOG_DAEMON) handler.setFormatter(logging.Formatter(get_syslog_format(logger_name), get_log_date_format())) root_log = logging.getLogger() root_log.addHandler(handler) except Exception, e: sys.stderr.write("Error setting up syslog: '%s'\n" % str(e)) traceback.print_exc() # Setting up logging in the event viewer for windows if get_os() == 'windows' and logging_config['log_to_event_viewer']: try: from logging.handlers import NTEventLogHandler nt_event_handler = NTEventLogHandler(logger_name, get_win32service_file('windows', 'win32service.pyd'), 'Application') nt_event_handler.setFormatter(logging.Formatter(get_syslog_format(logger_name), get_log_date_format())) nt_event_handler.setLevel(logging.ERROR) app_log = logging.getLogger(logger_name) app_log.addHandler(nt_event_handler) except Exception, e: sys.stderr.write("Error setting up Event viewer logging: '%s'\n" % str(e)) traceback.print_exc()
def get_checksd_path(osname=None): if not osname: osname = get_os() if osname == "windows": return _windows_checksd_path() elif osname == "mac": return _mac_checksd_path() else: return _unix_checksd_path()
def initialize_logging(logger_name): try: if get_os() == 'windows': logging.config.fileConfig(get_config_path()) else: logging_config = get_logging_config() logging.basicConfig( format=get_log_format(logger_name), level=logging_config['log_level'] or logging.INFO, ) # set up file loggers log_file = logging_config.get('%s_log_file' % logger_name) if log_file is not None and not logging_config['disable_file_logging']: # make sure the log directory is writeable # NOTE: the entire directory needs to be writable so that rotation works if os.access(os.path.dirname(log_file), os.R_OK | os.W_OK): file_handler = logging.handlers.RotatingFileHandler(log_file, maxBytes=LOGGING_MAX_BYTES, backupCount=1) file_handler.setFormatter(logging.Formatter(get_log_format(logger_name))) root_log = logging.getLogger() root_log.addHandler(file_handler) else: sys.stderr.write("Log file is unwritable: '%s'\n" % log_file) # set up syslog if logging_config['log_to_syslog']: try: from logging.handlers import SysLogHandler if logging_config['syslog_host'] is not None and logging_config['syslog_port'] is not None: sys_log_addr = (logging_config['syslog_host'], logging_config['syslog_port']) else: sys_log_addr = "/dev/log" # Special-case macs if sys.platform == 'darwin': sys_log_addr = "/var/run/syslog" handler = SysLogHandler(address=sys_log_addr, facility=SysLogHandler.LOG_DAEMON) handler.setFormatter(logging.Formatter(get_syslog_format(logger_name))) root_log = logging.getLogger() root_log.addHandler(handler) except Exception, e: sys.stderr.write("Error setting up syslog: '%s'\n" % str(e)) traceback.print_exc() except Exception, e: sys.stderr.write("Couldn't initialize logging: %s\n" % str(e)) traceback.print_exc() # if config fails entirely, enable basic stdout logging as a fallback logging.basicConfig( format=get_log_format(logger_name), level=logging.INFO, )
def get_confd_path(osname=None): if not osname: osname = get_os() bad_path = '' if osname == 'windows': try: return _windows_confd_path() except PathNotFound, e: if len(e.args) > 0: bad_path = e.args[0]
def get_sdk_integrations_path(osname=None): if not osname: osname = get_os() if osname in ['windows', 'mac']: raise PathNotFound() cur_path = os.path.dirname(os.path.realpath(__file__)) path = os.path.join(cur_path, '..', SDK_INTEGRATIONS_DIR) if os.path.exists(path): return path raise PathNotFound(path)
def get_3rd_party_path(osname=None): if not osname: osname = get_os() if osname in ['windows', 'mac']: raise PathNotFound() cur_path = os.path.dirname(os.path.realpath(__file__)) path = os.path.join(cur_path, '../3rd-party') if os.path.exists(path): return path raise PathNotFound(path)
def load_class(check_name, class_name): """ Retrieve a class with the given name among the given check module. """ checksd_path = get_checksd_path(get_os()) check_module = __import__(check_name) classes = inspect.getmembers(check_module, inspect.isclass) for name, clsmember in classes: if name == class_name: return clsmember raise Exception(u"Unable to import class {0} from the check module.".format(class_name))
def __init__(self, agentConfig, hostname): multiprocessing.Process.__init__(self, name='jmxfetch') self.config = agentConfig self.is_enabled = True self.hostname = hostname osname = get_os() try: confd_path = get_confd_path(osname) except PathNotFound, e: log.error("No conf.d folder found at '%s' or in the directory where" "the Agent is currently deployed.\n" % e.args[0])
def get_logging_config(cfg_path=None): logging_config = { 'log_level': None, 'collector_log_file': '/var/log/datadog/collector.log', 'forwarder_log_file': '/var/log/datadog/forwarder.log', 'dogstatsd_log_file': '/var/log/datadog/dogstatsd.log', 'pup_log_file': '/var/log/datadog/pup.log', 'log_to_syslog': True, 'syslog_host': None, 'syslog_port': None, } config_path = get_config_path(cfg_path, os_name=get_os()) config = ConfigParser.ConfigParser() config.readfp(skip_leading_wsp(open(config_path))) if config.has_section('handlers') or config.has_section('loggers') or config.has_section('formatters'): sys.stderr.write("Python logging config is no longer supported and will be ignored.\nTo configure logging, update the logging portion of 'datadog.conf' to match:\n 'https://github.com/DataDog/dd-agent/blob/master/datadog.conf.example'.\n") for option in logging_config: if config.has_option('Main', option): logging_config[option] = config.get('Main', option) levels = { 'CRITICAL': logging.CRITICAL, 'DEBUG': logging.DEBUG, 'ERROR': logging.ERROR, 'FATAL': logging.FATAL, 'INFO': logging.INFO, 'WARN': logging.WARN, 'WARNING': logging.WARNING, } if config.has_option('Main', 'log_level'): logging_config['log_level'] = levels.get(config.get('Main', 'log_level')) if config.has_option('Main', 'log_to_syslog'): logging_config['log_to_syslog'] = config.get('Main', 'log_to_syslog').strip().lower() in ['yes', 'true', 1] if config.has_option('Main', 'syslog_host'): host = config.get('Main', 'syslog_host').strip() if host: logging_config['syslog_host'] = host else: logging_config['syslog_host'] = None if config.has_option('Main', 'syslog_port'): port = config.get('Main', 'syslog_port').strip() try: logging_config['syslog_port'] = int(port) except: logging_config['syslog_port'] = None return logging_config
def get_confd_path(osname=None): if not osname: osname = get_os() bad_path = '' try: if osname == 'windows': return _windows_confd_path() elif osname == 'mac': return _mac_confd_path() else: return _unix_confd_path() except PathNotFound, e: if len(e.args) > 0: bad_path = e.args[0]
def __init__(self, agentConfig, hostname): multiprocessing.Process.__init__(self, name='jmxfetch') self.config = agentConfig self.hostname = hostname try: osname = get_os() confd_path = get_confd_path(osname) self.jmx_daemon = JMXFetch(confd_path, agentConfig) self.jmx_daemon.configure() self.is_enabled = self.jmx_daemon.should_run() except PathNotFound: self.is_enabled = False
def kill_subprocess(process_obj): try: process_obj.terminate() except AttributeError: # py < 2.6 doesn't support process.terminate() if get_os() == 'windows': import ctypes PROCESS_TERMINATE = 1 handle = ctypes.windll.kernel32.OpenProcess(PROCESS_TERMINATE, False, process_obj.pid) ctypes.windll.kernel32.TerminateProcess(handle, -1) ctypes.windll.kernel32.CloseHandle(handle) else: os.kill(process_obj.pid, signal.SIGKILL)
def get_config_path(cfg_path=None, os_name=None): # Check if there's an override and if it exists if cfg_path is not None and os.path.exists(cfg_path): return cfg_path if os_name is None: os_name = get_os() # Check for an OS-specific path, continue on not-found exceptions bad_path = '' if os_name == 'windows': try: return _windows_config_path() except PathNotFound, e: if len(e.args) > 0: bad_path = e.args[0]
def get_check(name, config_str): checksd_path = get_checksd_path(get_os()) if checksd_path not in sys.path: sys.path.append(checksd_path) check_module = __import__(name) check_class = None classes = inspect.getmembers(check_module, inspect.isclass) for name, clsmember in classes: if AgentCheck in clsmember.__bases__: check_class = clsmember break if check_class is None: raise Exception("Unable to import check %s. Missing a class that inherits AgentCheck" % name) agentConfig = {"version": "0.1", "api_key": "tota"} return check_class.from_yaml(yaml_text=config_str, check_name=name, agentConfig=agentConfig)
def load_check_directory(agentConfig): ''' Return the initialized checks from checks.d, and a mapping of checks that failed to initialize. Only checks that have a configuration file in conf.d will be returned. ''' from checks import AgentCheck initialized_checks = {} init_failed_checks = {} osname = get_os() checks_paths = [glob.glob(os.path.join(agentConfig['additional_checksd'], '*.py'))] try: checksd_path = get_checksd_path(osname) checks_paths.append(glob.glob(os.path.join(checksd_path, '*.py'))) except PathNotFound, e: log.error(e.args[0]) sys.exit(3)
def is_running(cls): try: pid = JMXFetch.pid_file.get_pid() if pid is None: return False except Exception: return False if get_os() != 'windows': try: os.kill(pid, 0) # os.kill(pid, 0) will throw an exception if pid is not running # and won't do anything otherwise # It doesn't work on windows as signal.CTRL_C_EVENT is 0, it would quit the process return True except Exception, e: if "Errno 3" not in str(e): log.debug("Couldn't determine if JMXFetch is running. We suppose it's not. %s" % str(e)) return False
def get_check_class(name): checksd_path = get_checksd_path(get_os()) if checksd_path not in sys.path: sys.path.append(checksd_path) check_module = __import__(name) check_class = None classes = inspect.getmembers(check_module, inspect.isclass) for _, clsmember in classes: if clsmember == AgentCheck: continue if issubclass(clsmember, AgentCheck): check_class = clsmember if AgentCheck in clsmember.__bases__: continue else: break return check_class
def get_checks(): checks = {} conf_d_directory = get_confd_path(get_os()) for filename in sorted(os.listdir(conf_d_directory)): module_name, ext = osp.splitext(filename) if filename.split('.')[0] in EXCLUDED_WINDOWS_CHECKS: continue if ext not in ('.yaml', '.example', '.disabled'): continue agent_check = AgentCheck(filename, ext, conf_d_directory) if (agent_check.enabled or agent_check.module_name not in checks or (not agent_check.is_example and not checks[agent_check.module_name].enabled)): checks[agent_check.module_name] = agent_check checks_list = checks.values() checks_list.sort(key=lambda c: c.module_name) return checks_list
def register(p_repo, p_isJSON): [repo_type, name, url, package, key, repo_filter] = get_repo(p_repo, p_isJSON) if util.get_os() in YUM_LIST: repo_pkg = url + "/" + package util.run_sudo("yum install -y " + repo_pkg, True, p_isJSON) return 0 ## APT ################ a_file = "/etc/apt/sources.list.d/pgdg.list" a_repo = "http://apt.postgresql.org/pub/repos/apt/" cmd = '"deb ' + a_repo + ' ' + p_repo + ' main" > ' + a_file util.run_sudo("sh -c 'echo " + cmd + "'", True, p_isJSON) a_key = "https://www.postgresql.org/media/keys/ACCC4CF8.asc" cmd = "wget --quiet -O - " + a_key + " | sudo apt-key add -" util.run_sudo(cmd, True, p_isJSON) util.run_sudo("apt-get update", True, p_isJSON) return 0
def get_config_path(cfg_path=None, os_name=None): # Check if there's an override and if it exists if cfg_path is not None and os.path.exists(cfg_path): return cfg_path if os_name is None: os_name = get_os() # Check for an OS-specific path, continue on not-found exceptions bad_path = '' try: if os_name == 'windows': return _windows_config_path() elif os_name == 'mac': return _mac_config_path() else: return _unix_config_path() except PathNotFound, e: if len(e.args) > 0: bad_path = e.args[0]
def load_check_directory(agentConfig): ''' Return the initialized checks from checks.d, and a mapping of checks that failed to initialize. Only checks that have a configuration file in conf.d will be returned. ''' from checks import AgentCheck initialized_checks = {} init_failed_checks = {} osname = get_os() checks_paths = [ glob.glob(os.path.join(agentConfig['additional_checksd'], '*.py')) ] try: checksd_path = get_checksd_path(osname) checks_paths.append(glob.glob(os.path.join(checksd_path, '*.py'))) except PathNotFound, e: log.error(e.args[0]) sys.exit(3)
def get_check(name, config_str): checksd_path = get_checksd_path(get_os()) if checksd_path not in sys.path: sys.path.append(checksd_path) check_module = __import__(name) check_class = None classes = inspect.getmembers(check_module, inspect.isclass) for name, clsmember in classes: if AgentCheck in clsmember.__bases__: check_class = clsmember break if check_class is None: raise Exception("Unable to import check %s. Missing a class that inherits AgentCheck" % name) agentConfig = { 'version': '0.1', 'api_key': 'tota' } return check_class.from_yaml(yaml_text=config_str, check_name=name, agentConfig=agentConfig)
def load_check(name, config, agentConfig): if not _is_sdk(): checksd_path = get_checksd_path(get_os()) # find (in checksd_path) and load the check module fd, filename, desc = imp.find_module(name, [checksd_path]) check_module = imp.load_module(name, fd, filename, desc) else: check_module = __import__("check") check_class = None classes = inspect.getmembers(check_module, inspect.isclass) for _, clsmember in classes: if clsmember == AgentCheck: continue if issubclass(clsmember, AgentCheck): check_class = clsmember if AgentCheck in clsmember.__bases__: continue else: break if check_class is None: raise Exception( "Unable to import check %s. Missing a class that inherits AgentCheck" % name) init_config = config.get('init_config', {}) instances = config.get('instances') agentConfig['checksd_hostname'] = get_hostname(agentConfig) # init the check class try: return check_class(name, init_config=init_config, agentConfig=agentConfig, instances=instances) except TypeError as e: raise Exception("Check is using old API, {0}".format(e)) except Exception: raise
def run_check(name, path=None): confd_path = path or os.path.join(get_confd_path(get_os()), '%s.yaml' % name) try: f = open(confd_path) except IOError: raise Exception('Unable to open configuration at %s' % confd_path) config_str = f.read() f.close() check, instances = get_check(name, config_str) if not instances: raise Exception('YAML configuration returned no instances.') for instance in instances: check.check(instance) if check.has_events(): print "Events:\n" pprint(check.get_events(), indent=4) print "Metrics:\n" pprint(check.get_metrics(), indent=4)
def get_confd_path(osname=None): try: cur_path = os.path.dirname(os.path.realpath(__file__)) return _confd_path(cur_path) except PathNotFound as e: pass if not osname: osname = get_os() bad_path = '' try: if osname == 'windows': return _windows_confd_path() elif osname == 'mac': return _mac_confd_path() else: return _unix_confd_path() except PathNotFound as e: if len(e.args) > 0: bad_path = e.args[0] raise PathNotFound(bad_path)
def load_check(name, config, agentConfig): checksd_path = get_checksd_path(get_os()) if checksd_path not in sys.path: sys.path.append(checksd_path) check_module = __import__(name) check_class = None classes = inspect.getmembers(check_module, inspect.isclass) for name, clsmember in classes: if clsmember == AgentCheck: continue if issubclass(clsmember, AgentCheck): check_class = clsmember if AgentCheck in clsmember.__bases__: continue else: break if check_class is None: raise Exception( "Unable to import check %s. Missing a class that inherits AgentCheck" % name) init_config = config.get('init_config', None) instances = config.get('instances') agentConfig['checksd_hostname'] = get_hostname(agentConfig) # init the check class try: return check_class(name, init_config=init_config, agentConfig=agentConfig, instances=instances) except: # Backwards compatitiblity for old checks that don't support the # instances argument. c = check_class(name, init_config=init_config, agentConfig=agentConfig) c.instances = instances return c
def build_ot_python_backend_executable(backend_exec_path): print(script_tag + "Build procedure started.") print(script_tag + "Checking for OS.") os_type = util.get_os() print(script_tag + "Building OT-App Backend for %s." % os_type) print(script_tag + "Project directory is: %s" % project_root_dir) print(script_tag + "Script working directory: %s" % os.getcwd()) # TODO: Check that app frontend assets have been moved to print(script_tag + "Removing PyInstaller old temp directories.") remove_pyinstaller_temps() print(script_tag + "Running PyInstaller process.") success = pyinstaller_build() if not success: print(script_tab + "Removing PyInstaller recent temp directories.") remove_pyinstaller_temps() raise SystemExit(script_tab + "Exiting as there was an error in the " "PyInstaller execution.") print(script_tag + "Removing old OT-App Backend executable directory.") if os.path.isfile(backend_exec_path): os.remove(backend_exec_path) print(script_tag + "Moving executable folder to backend-dist.") success = move_executable_folder(backend_exec_path) if not success: print(script_tab + "Removing PyInstaller recent temp directories.") remove_pyinstaller_temps() raise SystemExit(script_tab + "Exiting now as there was an error in " "the PyInstaller execution.") print(script_tag + "Removing PyInstaller recent temp directories.") remove_pyinstaller_temps()
def load_check_directory(agentConfig, hostname): ''' Return the initialized checks from checks.d, and a mapping of checks that failed to initialize. Only checks that have a configuration file in conf.d will be returned. ''' from checks import AGENT_METRICS_CHECK_NAME initialized_checks = {} init_failed_checks = {} deprecated_checks = {} agentConfig['checksd_hostname'] = hostname # the TRACE_CONFIG flag is used by the configcheck to trace config object loading and # where they come from (service discovery, auto configuration or configuration file). if agentConfig.get(TRACE_CONFIG): configs_and_sources = { # check_name: (config_source, config) } deprecated_configs_enabled = [v for k, v in OLD_STYLE_PARAMETERS if len([l for l in agentConfig if l.startswith(k)]) > 0] for deprecated_config in deprecated_configs_enabled: msg = "Configuring %s in datadog.conf is not supported anymore. Please use conf.d" % deprecated_config deprecated_checks[deprecated_config] = {'error': msg, 'traceback': None} log.error(msg) osname = get_os() checks_paths = get_checks_paths(agentConfig, osname) # this can happen if check.d is not found if checks_paths is None: log.error('Check directory not found, exiting. The agent is likely misconfigured.') sys.exit(3) try: confd_path = get_confd_path(osname) except PathNotFound, e: log.error("No conf.d folder found at '%s' or in the directory where " "the Agent is currently deployed.\n" % e.args[0]) sys.exit(3)
def build_electron_app(): print(script_tag + "Running electron-builder process.") platform_type = util.get_os() process_args = [ which("build"), os.path.join(project_root_dir, "app"), "--{}".format(platform_type), "--{}".format(util.get_arch()), ] print(process_args) if platform_type in {'mac'}: electron_builder_process = subprocess.Popen(process_args) elif platform_type in {'win', 'linux'}: electron_builder_process = subprocess.Popen(process_args, shell=True) electron_builder_process.communicate() if electron_builder_process.returncode != 0: raise SystemExit(script_tag + 'Failed to properly build electron app') print(script_tab + 'electron-builder process completed successfully')
def validate_os(p_isJSON): os = util.get_os() if (os in YUM_LIST) or (os in APT_LIST): return util.exit_message("OS '" + os + "' not supported for this command.", 1, p_isJSON)
def get_apt_repo_file_name(): rf_prefix = "/var/lib/apt/lists/apt.postgresql.org_pub_repos_apt_dists_" rf_suffix = "_main_binary-amd64_Packages" return (rf_prefix + util.get_os() + "-pgdg" + rf_suffix)
def get_config(parse_args=True, cfg_path=None, options=None): if parse_args: options, _ = get_parsed_args() # General config agentConfig = { 'check_freq': DEFAULT_CHECK_FREQUENCY, 'dogstatsd_port': 8125, 'dogstatsd_target': 'http://localhost:17123', 'graphite_listen_port': None, 'hostname': None, 'listen_port': None, 'tags': None, 'use_ec2_instance_id': False, # DEPRECATED 'version': get_version(), 'watchdog': True, 'additional_checksd': '/etc/sd-agent/checks.d/', 'bind_host': get_default_bind_host(), 'statsd_metric_namespace': None, 'utf8_decoding': False } if Platform.is_mac(): agentConfig['additional_checksd'] = '/usr/local/etc/sd-agent/checks.d/' # Config handling try: # Find the right config file path = os.path.realpath(__file__) path = os.path.dirname(path) config_path = get_config_path(cfg_path, os_name=get_os()) config = ConfigParser.ConfigParser() config.readfp(skip_leading_wsp(open(config_path))) # bulk import for option in config.options('Main'): agentConfig[option] = config.get('Main', option) # Store developer mode setting in the agentConfig if config.has_option('Main', 'developer_mode'): agentConfig['developer_mode'] = _is_affirmative( config.get('Main', 'developer_mode')) # Allow an override with the --profile option if options is not None and options.profile: agentConfig['developer_mode'] = True # # Core config # # FIXME unnecessarily complex if config.has_option('Main', 'sd_account'): agentConfig['sd_account'] = config.get('Main', 'sd_account') agentConfig['use_forwarder'] = False if options is not None and options.use_forwarder: listen_port = 17124 if config.has_option('Main', 'listen_port'): listen_port = int(config.get('Main', 'listen_port')) agentConfig['sd_url'] = "http://" + agentConfig[ 'bind_host'] + ":" + str(listen_port) agentConfig['use_forwarder'] = True elif options is not None and not options.disable_sd and options.sd_url: agentConfig['sd_url'] = options.sd_url elif config.has_option('Main', 'sd_url'): agentConfig['sd_url'] = config.get('Main', 'sd_url') else: # Default agent URL agentConfig['sd_url'] = "https://" + agentConfig[ 'sd_account'] + ".agent.serverdensity.io" if agentConfig['sd_url'].endswith('/'): agentConfig['sd_url'] = agentConfig['sd_url'][:-1] # Extra checks.d path # the linux directory is set by default if config.has_option('Main', 'additional_checksd'): agentConfig['additional_checksd'] = config.get( 'Main', 'additional_checksd') elif get_os() == 'windows': # default windows location common_path = _windows_commondata_path() agentConfig['additional_checksd'] = os.path.join( common_path, 'ServerDensity', 'checks.d') if config.has_option('Main', 'use_dogstatsd'): agentConfig['use_dogstatsd'] = config.get( 'Main', 'use_dogstatsd').lower() in ("yes", "true") else: agentConfig['use_dogstatsd'] = True # Service discovery if config.has_option('Main', 'service_discovery_backend'): try: additional_config = extract_agent_config(config) agentConfig.update(additional_config) except: log.error('Failed to load the agent configuration related to ' 'service discovery. It will not be used.') # Concerns only Windows if config.has_option('Main', 'use_web_info_page'): agentConfig['use_web_info_page'] = config.get( 'Main', 'use_web_info_page').lower() in ("yes", "true") else: agentConfig['use_web_info_page'] = True # Which agent key to use agentConfig['agent_key'] = config.get('Main', 'agent_key') # local traffic only? Default to no agentConfig['non_local_traffic'] = False if config.has_option('Main', 'non_local_traffic'): agentConfig['non_local_traffic'] = config.get( 'Main', 'non_local_traffic').lower() in ("yes", "true") # DEPRECATED if config.has_option('Main', 'use_ec2_instance_id'): use_ec2_instance_id = config.get('Main', 'use_ec2_instance_id') # translate yes into True, the rest into False agentConfig['use_ec2_instance_id'] = ( use_ec2_instance_id.lower() == 'yes') if config.has_option('Main', 'check_freq'): try: agentConfig['check_freq'] = int( config.get('Main', 'check_freq')) except Exception: pass # Custom histogram aggregate/percentile metrics if config.has_option('Main', 'histogram_aggregates'): agentConfig['histogram_aggregates'] = get_histogram_aggregates( config.get('Main', 'histogram_aggregates')) if config.has_option('Main', 'histogram_percentiles'): agentConfig['histogram_percentiles'] = get_histogram_percentiles( config.get('Main', 'histogram_percentiles')) # Disable Watchdog (optionally) if config.has_option('Main', 'watchdog'): if config.get('Main', 'watchdog').lower() in ('no', 'false'): agentConfig['watchdog'] = False # Optional graphite listener if config.has_option('Main', 'graphite_listen_port'): agentConfig['graphite_listen_port'] = \ int(config.get('Main', 'graphite_listen_port')) else: agentConfig['graphite_listen_port'] = None # Dogstatsd config dogstatsd_defaults = { 'dogstatsd_port': 8125, 'dogstatsd_target': 'http://' + agentConfig['bind_host'] + ':17123', } for key, value in dogstatsd_defaults.iteritems(): if config.has_option('Main', key): agentConfig[key] = config.get('Main', key) else: agentConfig[key] = value # Create app:xxx tags based on monitored apps agentConfig['create_dd_check_tags'] = config.has_option('Main', 'create_dd_check_tags') and \ _is_affirmative(config.get('Main', 'create_dd_check_tags')) # Forwarding to external statsd server if config.has_option('Main', 'statsd_forward_host'): agentConfig['statsd_forward_host'] = config.get( 'Main', 'statsd_forward_host') if config.has_option('Main', 'statsd_forward_port'): agentConfig['statsd_forward_port'] = int( config.get('Main', 'statsd_forward_port')) # optionally send dogstatsd data directly to the agent. if config.has_option('Main', 'dogstatsd_use_ddurl'): if _is_affirmative(config.get('Main', 'dogstatsd_use_ddurl')): agentConfig['dogstatsd_target'] = agentConfig['sd_url'] # Optional config # FIXME not the prettiest code ever... if config.has_option('Main', 'use_mount'): agentConfig['use_mount'] = _is_affirmative( config.get('Main', 'use_mount')) if options is not None and options.autorestart: agentConfig['autorestart'] = True elif config.has_option('Main', 'autorestart'): agentConfig['autorestart'] = _is_affirmative( config.get('Main', 'autorestart')) if config.has_option('Main', 'check_timings'): agentConfig['check_timings'] = _is_affirmative( config.get('Main', 'check_timings')) if config.has_option('Main', 'exclude_process_args'): agentConfig['exclude_process_args'] = _is_affirmative( config.get('Main', 'exclude_process_args')) try: filter_device_re = config.get('Main', 'device_blacklist_re') agentConfig['device_blacklist_re'] = re.compile(filter_device_re) except ConfigParser.NoOptionError: pass if config.has_option("Main", "nagios_perf_cfg"): agentConfig["nagios_perf_cfg"] = config.get( "Main", "nagios_perf_cfg") if config.has_option("Main", "use_curl_http_client"): agentConfig["use_curl_http_client"] = _is_affirmative( config.get("Main", "use_curl_http_client")) else: # Default to False as there are some issues with the curl client and ELB agentConfig["use_curl_http_client"] = False if config.has_section('WMI'): agentConfig['WMI'] = {} for key, value in config.items('WMI'): agentConfig['WMI'][key] = value if (config.has_option("Main", "limit_memory_consumption") and config.get("Main", "limit_memory_consumption") is not None): agentConfig["limit_memory_consumption"] = int( config.get("Main", "limit_memory_consumption")) else: agentConfig["limit_memory_consumption"] = None if config.has_option("Main", "skip_ssl_validation"): agentConfig["skip_ssl_validation"] = _is_affirmative( config.get("Main", "skip_ssl_validation")) agentConfig["collect_instance_metadata"] = True if config.has_option("Main", "collect_instance_metadata"): agentConfig["collect_instance_metadata"] = _is_affirmative( config.get("Main", "collect_instance_metadata")) agentConfig["proxy_forbid_method_switch"] = False if config.has_option("Main", "proxy_forbid_method_switch"): agentConfig["proxy_forbid_method_switch"] = _is_affirmative( config.get("Main", "proxy_forbid_method_switch")) agentConfig["collect_ec2_tags"] = False if config.has_option("Main", "collect_ec2_tags"): agentConfig["collect_ec2_tags"] = _is_affirmative( config.get("Main", "collect_ec2_tags")) agentConfig["utf8_decoding"] = False if config.has_option("Main", "utf8_decoding"): agentConfig["utf8_decoding"] = _is_affirmative( config.get("Main", "utf8_decoding")) agentConfig["gce_updated_hostname"] = False if config.has_option("Main", "gce_updated_hostname"): agentConfig["gce_updated_hostname"] = _is_affirmative( config.get("Main", "gce_updated_hostname")) except ConfigParser.NoSectionError, e: sys.stderr.write('Config file not found or incorrectly formatted.\n') sys.exit(2)
def initialize_logging(logger_name): try: logging_config = get_logging_config() logging.basicConfig( format=get_log_format(logger_name), level=logging_config['log_level'] or logging.INFO, ) log_file = logging_config.get('%s_log_file' % logger_name) if log_file is not None and not logging_config['disable_file_logging']: # make sure the log directory is writeable # NOTE: the entire directory needs to be writable so that rotation works if os.access(os.path.dirname(log_file), os.R_OK | os.W_OK): file_handler = logging.handlers.RotatingFileHandler( log_file, maxBytes=LOGGING_MAX_BYTES, backupCount=1) formatter = logging.Formatter(get_log_format(logger_name), get_log_date_format()) file_handler.setFormatter(formatter) root_log = logging.getLogger() root_log.addHandler(file_handler) else: sys.stderr.write("Log file is unwritable: '%s'\n" % log_file) # set up syslog if logging_config['log_to_syslog']: try: from logging.handlers import SysLogHandler if logging_config['syslog_host'] is not None and logging_config[ 'syslog_port'] is not None: sys_log_addr = (logging_config['syslog_host'], logging_config['syslog_port']) else: sys_log_addr = "/dev/log" # Special-case BSDs if Platform.is_darwin(): sys_log_addr = "/var/run/syslog" elif Platform.is_freebsd(): sys_log_addr = "/var/run/log" handler = SysLogHandler(address=sys_log_addr, facility=SysLogHandler.LOG_DAEMON) handler.setFormatter( logging.Formatter(get_syslog_format(logger_name), get_log_date_format())) root_log = logging.getLogger() root_log.addHandler(handler) except Exception, e: sys.stderr.write("Error setting up syslog: '%s'\n" % str(e)) traceback.print_exc() # Setting up logging in the event viewer for windows if get_os() == 'windows' and logging_config['log_to_event_viewer']: try: from logging.handlers import NTEventLogHandler nt_event_handler = NTEventLogHandler( logger_name, get_win32service_file('windows', 'win32service.pyd'), 'Application') nt_event_handler.setFormatter( logging.Formatter(get_syslog_format(logger_name), get_log_date_format())) nt_event_handler.setLevel(logging.ERROR) app_log = logging.getLogger(logger_name) app_log.addHandler(nt_event_handler) except Exception, e: sys.stderr.write( "Error setting up Event viewer logging: '%s'\n" % str(e)) traceback.print_exc()
def get_logging_config(cfg_path=None): system_os = get_os() logging_config = { 'log_level': None, 'log_to_event_viewer': False, 'log_to_syslog': False, 'syslog_host': None, 'syslog_port': None, } if system_os == 'windows': logging_config['windows_collector_log_file'] = os.path.join( _windows_commondata_path(), 'ServerDensity', 'logs', 'collector.log') logging_config['windows_forwarder_log_file'] = os.path.join( _windows_commondata_path(), 'ServerDensity', 'logs', 'forwarder.log') logging_config['windows_dogstatsd_log_file'] = os.path.join( _windows_commondata_path(), 'ServerDensity', 'logs', 'dogstatsd.log') logging_config['jmxfetch_log_file'] = os.path.join( _windows_commondata_path(), 'ServerDensity', 'logs', 'jmxfetch.log') else: logging_config[ 'collector_log_file'] = '/var/log/sd-agent/collector.log' logging_config[ 'forwarder_log_file'] = '/var/log/sd-agent/forwarder.log' logging_config[ 'dogstatsd_log_file'] = '/var/log/sd-agent/dogstatsd.log' logging_config['jmxfetch_log_file'] = '/var/log/sd-agent/jmxfetch.log' logging_config['go-metro_log_file'] = '/var/log/sd-agent/go-metro.log' logging_config['log_to_syslog'] = True config_path = get_config_path(cfg_path, os_name=system_os) config = ConfigParser.ConfigParser() config.readfp(skip_leading_wsp(open(config_path))) if config.has_section('handlers') or config.has_section( 'loggers') or config.has_section('formatters'): if system_os == 'windows': config_example_file = "https://github.com/serverdensity/sd-agent/blob/master/packaging/sd-agent/win32/install_files/config_win32.conf" else: config_example_file = "https://github.com/serverdensity/sd-agent/blob/master/config.cfg.example" sys.stderr.write( """Python logging config is no longer supported and will be ignored. To configure logging, update the logging portion of 'config.cfg' to match: '%s'. """ % config_example_file) for option in logging_config: if config.has_option('Main', option): logging_config[option] = config.get('Main', option) levels = { 'CRITICAL': logging.CRITICAL, 'DEBUG': logging.DEBUG, 'ERROR': logging.ERROR, 'FATAL': logging.FATAL, 'INFO': logging.INFO, 'WARN': logging.WARN, 'WARNING': logging.WARNING, } if config.has_option('Main', 'log_level'): logging_config['log_level'] = levels.get( config.get('Main', 'log_level')) if config.has_option('Main', 'log_to_syslog'): logging_config['log_to_syslog'] = config.get( 'Main', 'log_to_syslog').strip().lower() in ['yes', 'true', 1] if config.has_option('Main', 'log_to_event_viewer'): logging_config['log_to_event_viewer'] = config.get( 'Main', 'log_to_event_viewer').strip().lower() in ['yes', 'true', 1] if config.has_option('Main', 'syslog_host'): host = config.get('Main', 'syslog_host').strip() if host: logging_config['syslog_host'] = host else: logging_config['syslog_host'] = None if config.has_option('Main', 'syslog_port'): port = config.get('Main', 'syslog_port').strip() try: logging_config['syslog_port'] = int(port) except Exception: logging_config['syslog_port'] = None if config.has_option('Main', 'disable_file_logging'): logging_config['disable_file_logging'] = config.get( 'Main', 'disable_file_logging').strip().lower() in ['yes', 'true', 1] else: logging_config['disable_file_logging'] = False return logging_config
def get_log_format(logger_name): if get_os() != 'windows': return '%%(asctime)s | %%(levelname)s | sd.%s | %%(name)s(%%(filename)s:%%(lineno)s) | %%(message)s' % logger_name return '%(asctime)s | %(levelname)s | %(name)s(%(filename)s:%(lineno)s) | %(message)s'
print "#" * 80 print "JMX tool to be used to help configuring your JMX checks." print "See http://docs.datadoghq.com/integrations/java/ for more information" print "#" * 80 print "\n" print "You have to specify one of the following command:" for command, desc in JMX_LIST_COMMANDS.iteritems(): print " - %s [OPTIONAL: LIST OF CHECKS]: %s" % (command, desc) print "Example: sudo /etc/init.d/datadog-agent jmx list_matching_attributes tomcat jmx solr" print "\n" else: jmx_command = args[1] checks_list = args[2:] confd_directory = get_confd_path(get_os()) should_run = JMXFetch.init(confd_directory, agentConfig, get_logging_config(), 15, jmx_command, checks_list, reporter="console") if not should_run: print "Couldn't find any valid JMX configuration in your conf.d directory: %s" % confd_directory print "Have you enabled any JMX check ?" print "If you think it's not normal please get in touch with Datadog Support" return 0
def get_config_path(cfg_path=None, os_name=None): # Check if there's an override and if it exists if cfg_path is not None and os.path.exists(cfg_path): return cfg_path # Check if there's a config stored in the current agent directory try: path = os.path.realpath(__file__) path = os.path.dirname(path) return _config_path(path) except PathNotFound, e: pass if os_name is None: os_name = get_os() # Check for an OS-specific path, continue on not-found exceptions bad_path = '' try: if os_name == 'windows': return _windows_config_path() elif os_name == 'mac': return _mac_config_path() else: return _unix_config_path() except PathNotFound, e: if len(e.args) > 0: bad_path = e.args[0] # If all searches fail, exit the agent with an error
def get_config(parse_args=True, cfg_path=None, options=None): if parse_args: options, _ = get_parsed_args() # General config agentConfig = { 'check_freq': DEFAULT_CHECK_FREQUENCY, 'dogstatsd_port': 8125, 'dogstatsd_target': 'http://localhost:17123', 'graphite_listen_port': None, 'hostname': None, 'listen_port': None, 'tags': None, 'use_ec2_instance_id': False, # DEPRECATED 'version': get_version(), 'watchdog': True, 'additional_checksd': '/etc/dd-agent/checks.d/', 'bind_host': get_default_bind_host(), 'statsd_metric_namespace': None, 'utf8_decoding': False } if Platform.is_mac(): agentConfig['additional_checksd'] = '/opt/datadog-agent/etc/checks.d' # Config handling try: # Find the right config file path = os.path.realpath(__file__) path = os.path.dirname(path) config_path = get_config_path(cfg_path, os_name=get_os()) config = ConfigParser.ConfigParser() config.readfp(skip_leading_wsp(open(config_path))) # bulk import for option in config.options('Main'): agentConfig[option] = config.get('Main', option) # Store developer mode setting in the agentConfig if config.has_option('Main', 'developer_mode'): agentConfig['developer_mode'] = _is_affirmative( config.get('Main', 'developer_mode')) # Allow an override with the --profile option if options is not None and options.profile: agentConfig['developer_mode'] = True # # Core config #ap if not config.has_option('Main', 'api_key'): log.warning(u"No API key was found. Aborting.") sys.exit(2) if not config.has_option('Main', 'dd_url'): log.warning(u"No dd_url was found. Aborting.") sys.exit(2) # Endpoints dd_url = clean_dd_url(config.get('Main', 'dd_url')) api_key = config.get('Main', 'api_key').strip() # For collector and dogstatsd agentConfig['api_key'] = api_key agentConfig['dd_url'] = dd_url # multiple endpoints if config.has_option('Main', 'other_dd_urls'): other_dd_urls = map(clean_dd_url, config.get('Main', 'other_dd_urls').split(',')) else: other_dd_urls = [] if config.has_option('Main', 'other_api_keys'): other_api_keys = map( lambda x: x.strip(), config.get('Main', 'other_api_keys').split(',')) else: other_api_keys = [] # Forwarder endpoints logic # endpoints is: # { # 'https://app.datadoghq.com': ['api_key_abc', 'api_key_def'], # 'https://app.example.com': ['api_key_xyz'] # } endpoints = {dd_url: [api_key]} if len(other_dd_urls) == 0: endpoints[dd_url] += other_api_keys else: assert len(other_dd_urls) == len( other_api_keys), 'Please provide one api_key for each url' for i, other_dd_url in enumerate(other_dd_urls): endpoints[other_dd_url] = endpoints.get( other_dd_url, []) + [other_api_keys[i]] agentConfig['endpoints'] = endpoints # Forwarder or not forwarder agentConfig[ 'use_forwarder'] = options is not None and options.use_forwarder if agentConfig['use_forwarder']: listen_port = 17123 if config.has_option('Main', 'listen_port'): listen_port = int(config.get('Main', 'listen_port')) agentConfig['dd_url'] = "http://{}:{}".format( agentConfig['bind_host'], listen_port) # FIXME: Legacy dd_url command line switch elif options is not None and options.dd_url is not None: agentConfig['dd_url'] = options.dd_url # Forwarder timeout agentConfig['forwarder_timeout'] = 20 if config.has_option('Main', 'forwarder_timeout'): agentConfig['forwarder_timeout'] = int( config.get('Main', 'forwarder_timeout')) # Extra checks.d path # the linux directory is set by default if config.has_option('Main', 'additional_checksd'): agentConfig['additional_checksd'] = config.get( 'Main', 'additional_checksd') elif get_os() == 'windows': # default windows location common_path = _windows_commondata_path() agentConfig['additional_checksd'] = os.path.join( common_path, 'Datadog', 'checks.d') if config.has_option('Main', 'use_dogstatsd'): agentConfig['use_dogstatsd'] = config.get( 'Main', 'use_dogstatsd').lower() in ("yes", "true") else: agentConfig['use_dogstatsd'] = True # Service discovery if config.has_option('Main', 'service_discovery_backend'): try: additional_config = extract_agent_config(config) agentConfig.update(additional_config) except: log.error('Failed to load the agent configuration related to ' 'service discovery. It will not be used.') # Concerns only Windows if config.has_option('Main', 'use_web_info_page'): agentConfig['use_web_info_page'] = config.get( 'Main', 'use_web_info_page').lower() in ("yes", "true") else: agentConfig['use_web_info_page'] = True # local traffic only? Default to no agentConfig['non_local_traffic'] = False if config.has_option('Main', 'non_local_traffic'): agentConfig['non_local_traffic'] = config.get( 'Main', 'non_local_traffic').lower() in ("yes", "true") # DEPRECATED if config.has_option('Main', 'use_ec2_instance_id'): use_ec2_instance_id = config.get('Main', 'use_ec2_instance_id') # translate yes into True, the rest into False agentConfig['use_ec2_instance_id'] = ( use_ec2_instance_id.lower() == 'yes') if config.has_option('Main', 'check_freq'): try: agentConfig['check_freq'] = int( config.get('Main', 'check_freq')) except Exception: pass # Custom histogram aggregate/percentile metrics if config.has_option('Main', 'histogram_aggregates'): agentConfig['histogram_aggregates'] = get_histogram_aggregates( config.get('Main', 'histogram_aggregates')) if config.has_option('Main', 'histogram_percentiles'): agentConfig['histogram_percentiles'] = get_histogram_percentiles( config.get('Main', 'histogram_percentiles')) # Disable Watchdog (optionally) if config.has_option('Main', 'watchdog'): if config.get('Main', 'watchdog').lower() in ('no', 'false'): agentConfig['watchdog'] = False # Optional graphite listener if config.has_option('Main', 'graphite_listen_port'): agentConfig['graphite_listen_port'] = \ int(config.get('Main', 'graphite_listen_port')) else: agentConfig['graphite_listen_port'] = None # Dogstatsd config dogstatsd_defaults = { 'dogstatsd_port': 8125, 'dogstatsd_target': 'http://' + agentConfig['bind_host'] + ':17123', } for key, value in dogstatsd_defaults.iteritems(): if config.has_option('Main', key): agentConfig[key] = config.get('Main', key) else: agentConfig[key] = value # Create app:xxx tags based on monitored apps agentConfig['create_dd_check_tags'] = config.has_option('Main', 'create_dd_check_tags') and \ _is_affirmative(config.get('Main', 'create_dd_check_tags')) # Forwarding to external statsd server if config.has_option('Main', 'statsd_forward_host'): agentConfig['statsd_forward_host'] = config.get( 'Main', 'statsd_forward_host') if config.has_option('Main', 'statsd_forward_port'): agentConfig['statsd_forward_port'] = int( config.get('Main', 'statsd_forward_port')) # optionally send dogstatsd data directly to the agent. if config.has_option('Main', 'dogstatsd_use_ddurl'): if _is_affirmative(config.get('Main', 'dogstatsd_use_ddurl')): agentConfig['dogstatsd_target'] = agentConfig['dd_url'] # Optional config # FIXME not the prettiest code ever... if config.has_option('Main', 'use_mount'): agentConfig['use_mount'] = _is_affirmative( config.get('Main', 'use_mount')) if options is not None and options.autorestart: agentConfig['autorestart'] = True elif config.has_option('Main', 'autorestart'): agentConfig['autorestart'] = _is_affirmative( config.get('Main', 'autorestart')) if config.has_option('Main', 'check_timings'): agentConfig['check_timings'] = _is_affirmative( config.get('Main', 'check_timings')) if config.has_option('Main', 'exclude_process_args'): agentConfig['exclude_process_args'] = _is_affirmative( config.get('Main', 'exclude_process_args')) try: filter_device_re = config.get('Main', 'device_blacklist_re') agentConfig['device_blacklist_re'] = re.compile(filter_device_re) except ConfigParser.NoOptionError: pass if config.has_option('datadog', 'ddforwarder_log'): agentConfig['has_datadog'] = True # Dogstream config if config.has_option("Main", "dogstream_log"): # Older version, single log support log_path = config.get("Main", "dogstream_log") if config.has_option("Main", "dogstream_line_parser"): agentConfig["dogstreams"] = ':'.join( [log_path, config.get("Main", "dogstream_line_parser")]) else: agentConfig["dogstreams"] = log_path elif config.has_option("Main", "dogstreams"): agentConfig["dogstreams"] = config.get("Main", "dogstreams") if config.has_option("Main", "nagios_perf_cfg"): agentConfig["nagios_perf_cfg"] = config.get( "Main", "nagios_perf_cfg") if config.has_option("Main", "use_curl_http_client"): agentConfig["use_curl_http_client"] = _is_affirmative( config.get("Main", "use_curl_http_client")) else: # Default to False as there are some issues with the curl client and ELB agentConfig["use_curl_http_client"] = False if config.has_section('WMI'): agentConfig['WMI'] = {} for key, value in config.items('WMI'): agentConfig['WMI'][key] = value if (config.has_option("Main", "limit_memory_consumption") and config.get("Main", "limit_memory_consumption") is not None): agentConfig["limit_memory_consumption"] = int( config.get("Main", "limit_memory_consumption")) else: agentConfig["limit_memory_consumption"] = None if config.has_option("Main", "skip_ssl_validation"): agentConfig["skip_ssl_validation"] = _is_affirmative( config.get("Main", "skip_ssl_validation")) agentConfig["collect_instance_metadata"] = True if config.has_option("Main", "collect_instance_metadata"): agentConfig["collect_instance_metadata"] = _is_affirmative( config.get("Main", "collect_instance_metadata")) agentConfig["proxy_forbid_method_switch"] = False if config.has_option("Main", "proxy_forbid_method_switch"): agentConfig["proxy_forbid_method_switch"] = _is_affirmative( config.get("Main", "proxy_forbid_method_switch")) agentConfig["collect_ec2_tags"] = False if config.has_option("Main", "collect_ec2_tags"): agentConfig["collect_ec2_tags"] = _is_affirmative( config.get("Main", "collect_ec2_tags")) agentConfig["utf8_decoding"] = False if config.has_option("Main", "utf8_decoding"): agentConfig["utf8_decoding"] = _is_affirmative( config.get("Main", "utf8_decoding")) agentConfig["gce_updated_hostname"] = False if config.has_option("Main", "gce_updated_hostname"): agentConfig["gce_updated_hostname"] = _is_affirmative( config.get("Main", "gce_updated_hostname")) except ConfigParser.NoSectionError as e: sys.stderr.write('Config file not found or incorrectly formatted.\n') sys.exit(2) except ConfigParser.ParsingError as e: sys.stderr.write('Config file not found or incorrectly formatted.\n') sys.exit(2) except ConfigParser.NoOptionError as e: sys.stderr.write( 'There are some items missing from your config file, but nothing fatal [%s]' % e) # Storing proxy settings in the agentConfig agentConfig['proxy_settings'] = get_proxy(agentConfig) if agentConfig.get('ca_certs', None) is None: agentConfig['ssl_certificate'] = get_ssl_certificate( get_os(), 'datadog-cert.pem') else: agentConfig['ssl_certificate'] = agentConfig['ca_certs'] return agentConfig
def __init__(self, agentConfig, emitters, systemStats, hostname): self.emit_duration = None self.agentConfig = agentConfig self.hostname = hostname # system stats is generated by config.get_system_stats self.agentConfig['system_stats'] = systemStats # agent config is used during checks, system_stats can be accessed through the config self.os = get_os() self.plugins = None self.emitters = emitters self.check_timings = agentConfig.get('check_timings') self.push_times = { 'host_metadata': { 'start': time.time(), 'interval': int(agentConfig.get('metadata_interval', 4 * 60 * 60)) }, 'external_host_tags': { 'start': time.time() - 3 * 60, # Wait for the checks to init 'interval': int(agentConfig.get('external_host_tags', 5 * 60)) }, 'agent_checks': { 'start': time.time(), 'interval': int(agentConfig.get('agent_checks_interval', 10 * 60)) }, 'processes': { 'start': time.time(), 'interval': int(agentConfig.get('processes_interval', 60)) } } socket.setdefaulttimeout(15) self.run_count = 0 self.continue_running = True self.hostname_metadata_cache = None self.initialized_checks_d = [] self.init_failed_checks_d = {} # Unix System Checks self._unix_system_checks = { 'io': u.IO(log), 'load': u.Load(log), 'memory': u.Memory(log), 'processes': u.Processes(log), 'cpu': u.Cpu(log), 'system': u.System(log) } # Win32 System `Checks self._win32_system_checks = { 'io': w32.IO(log), 'proc': w32.Processes(log), 'memory': w32.Memory(log), 'network': w32.Network(log), 'cpu': w32.Cpu(log), 'system': w32.System(log) } # Old-style metric checks self._ganglia = Ganglia(log) self._dogstream = Dogstreams.init(log, self.agentConfig) self._ddforwarder = DdForwarder(log, self.agentConfig) # Agent performance metrics check self._agent_metrics = None self._metrics_checks = [] # Custom metric checks for module_spec in [s.strip() for s in self.agentConfig.get('custom_checks', '').split(',')]: if len(module_spec) == 0: continue try: self._metrics_checks.append(modules.load(module_spec, 'Check')(log)) log.info("Registered custom check %s" % module_spec) log.warning("Old format custom checks are deprecated. They should be moved to the checks.d interface as old custom checks will be removed in a next version") except Exception: log.exception('Unable to load custom check module %s' % module_spec)
def __init__(self, agentConfig, emitters, systemStats): self.emit_duration = None self.agentConfig = agentConfig # system stats is generated by config.get_system_stats self.agentConfig['system_stats'] = systemStats # agent config is used during checks, system_stats can be accessed through the config self.os = get_os() self.plugins = None self.emitters = emitters self.metadata_interval = int( agentConfig.get('metadata_interval', 10 * 60)) self.metadata_start = time.time() socket.setdefaulttimeout(15) self.run_count = 0 self.continue_running = True self.metadata_cache = None self.initialized_checks_d = [] self.init_failed_checks_d = [] # Unix System Checks self._unix_system_checks = { 'disk': u.Disk(log), 'io': u.IO(log), 'load': u.Load(log), 'memory': u.Memory(log), 'processes': u.Processes(log), 'cpu': u.Cpu(log) } # Win32 System `Checks self._win32_system_checks = { 'disk': w32.Disk(log), 'io': w32.IO(log), 'proc': w32.Processes(log), 'memory': w32.Memory(log), 'network': w32.Network(log), 'cpu': w32.Cpu(log) } # Old-style metric checks self._ganglia = Ganglia(log) self._cassandra = Cassandra() self._dogstream = Dogstreams.init(log, self.agentConfig) self._ddforwarder = DdForwarder(log, self.agentConfig) # Agent Metrics self._agent_metrics = CollectorMetrics(log) self._metrics_checks = [] # Custom metric checks for module_spec in [ s.strip() for s in self.agentConfig.get('custom_checks', '').split(',') ]: if len(module_spec) == 0: continue try: self._metrics_checks.append( modules.load(module_spec, 'Check')(log)) log.info("Registered custom check %s" % module_spec) except Exception, e: log.exception('Unable to load custom check module %s' % module_spec)
def list_packages(p_repo, p_SHOWDUPS, p_isJSON, p_isEXTRA): if not is_repo(p_repo, p_isJSON): util.exit_message(p_repo + " is not a valid REPO.", 1, p_isJSON) [repo_type, name, url, package, key, pkg_filter] = get_repo(p_repo, p_isJSON) if not is_installed(p_repo): util.exit_message(p_repo + " is not registered.", 1, p_isJSON) options = "" if p_SHOWDUPS: options = "--showduplicates" if util.get_os() in APT_LIST: return list_apt_packages(p_repo, p_isJSON) os = util.get_os() if os == "el6": cmd = "yum list all | grep " + p_repo else: cmd = "yum repo-pkgs " + p_repo + " list " + options cmd = cmd + " | awk '" ## filter package list unless asked to show --extra or --test kount = 0 if not p_isEXTRA: for p in pkg_filter: kount = kount + 1 ps = "/" + p.replace('.', '\.') + "/" if kount > 1: cmd = cmd + " || " + ps else: cmd = cmd + ps cmd = "sudo " + cmd + " { print }' | awk '!/debug/ && !/docs/ { print }'" outp = util.getoutput(cmd) my_logger.info("\n$ " + cmd + "\n\n" + str(outp)) repoList = [] for line in outp.splitlines(): data = line.split() if len(data) != 3: continue repoDict = {} p1 = data[0].find('.') pkg_nm = data[0][0:p1] p2 = data[1].find('.rhel') if p2 > 0: pkg_ver = data[1][0:p2] else: pkg_ver = data[1] status = "" if data[2].startswith("@"): status = "Installed" repoDict['component'] = pkg_nm repoDict['version'] = pkg_ver repoDict['status'] = status if pkg_nm > "": repoList.append(repoDict) keys = ['component', 'version', 'status'] headers = ['Component', 'Version', 'Status'] if p_isJSON: print(json.dumps(repoList, sort_keys=True, indent=2)) else: print(api.format_data_to_table(repoList, keys, headers)) return (0)
def load_check_directory(agentConfig, hostname): ''' Return the initialized checks from checks.d, and a mapping of checks that failed to initialize. Only checks that have a configuration file in conf.d will be returned. ''' from checks import AGENT_METRICS_CHECK_NAME initialized_checks = {} init_failed_checks = {} deprecated_checks = {} agentConfig['checksd_hostname'] = hostname osname = get_os() # the TRACE_CONFIG flag is used by the configcheck to trace config object loading and # where they come from (service discovery, auto config or config file) if agentConfig.get(TRACE_CONFIG): configs_and_sources = { # check_name: (config_source, config) } deprecated_checks.update(_deprecated_configs(agentConfig)) checks_places = get_checks_places(osname, agentConfig) for config_path in _file_configs_paths(osname, agentConfig): # '/etc/dd-agent/checks.d/my_check.py' -> 'my_check' check_name = _conf_path_to_check_name(config_path) conf_is_valid, check_config, invalid_check = _load_file_config( config_path, check_name, agentConfig) init_failed_checks.update(invalid_check) if not conf_is_valid: continue if agentConfig.get(TRACE_CONFIG): configs_and_sources[check_name] = (CONFIG_FROM_FILE, check_config) # load the check load_success, load_failure = load_check_from_places( check_config, check_name, checks_places, agentConfig) initialized_checks.update(load_success) init_failed_checks.update(load_failure) for check_name, service_disco_check_config in _service_disco_configs( agentConfig).iteritems(): # ignore this config from service disco if the check has been loaded through a file config if check_name in initialized_checks or check_name in init_failed_checks: continue # if TRACE_CONFIG is set, service_disco_check_config looks like: # (config_src, (sd_init_config, sd_instances)) instead of # (sd_init_config, sd_instances) if agentConfig.get(TRACE_CONFIG): sd_init_config, sd_instances = service_disco_check_config[1] configs_and_sources[check_name] = (service_disco_check_config[0], { 'init_config': sd_init_config, 'instances': sd_instances }) else: sd_init_config, sd_instances = service_disco_check_config check_config = { 'init_config': sd_init_config, 'instances': sd_instances } # load the check load_success, load_failure = load_check_from_places( check_config, check_name, checks_places, agentConfig) initialized_checks.update(load_success) init_failed_checks.update(load_failure) init_failed_checks.update(deprecated_checks) log.info('initialized checks.d checks: %s' % [ k for k in initialized_checks.keys() if k != AGENT_METRICS_CHECK_NAME ]) log.info('initialization failed checks.d checks: %s' % init_failed_checks.keys()) if agentConfig.get(TRACE_CONFIG): return configs_and_sources return { 'initialized_checks': initialized_checks.values(), 'init_failed_checks': init_failed_checks, }
def get_pgdg_base(p_ver, p_isJSON): basedir = None ver = p_ver svcname = None datadir = None port = None logdir = None to_devnull = " >/dev/null 2>&1" ####### (1) PGHOME ############################## if util.get_os() in YUM_LIST: basedir = "/usr/pgsql-" + ver else: basedir = "/usr/lib/postgresql/" + ver pgbin = basedir + "/bin/postgres" if not os.path.isfile(pgbin): print(" PGHOME could not be located at " + pgbin) return ("1111111") ###### (2) Service Control File ################# if util.get_os() in APT_LIST: svcname = "postgresql" else: svcname = "postgresql-" + ver if util.is_systemd(): sysdir = util.get_systemd_dir() svcfile = sysdir + "/" + svcname + ".service" else: sysdir = "/etc/init.d" svcfile = sysdir + "/" + svcname if not os.path.isfile(svcfile): print("ERROR: ServiceFile not found (" + svcfile + ")") return ("2222222") ###### (3) DATADIR ############################### if util.get_os() in YUM_LIST: datadir = "/var/lib/pgsql/" + ver + "/data" else: datadir = "/var/lib/postgresql/" + ver + "/main" cmd = "sudo ls " + datadir rc = os.system(cmd + to_devnull) if rc != 0: print("ERROR: DataDir not found (" + datadir + ")") return ("3333333") ##### LOOK FOR PORT #################### pidfile = datadir + "/postmaster.pid" cmd = "sudo ls " + pidfile rc = os.system(cmd + to_devnull) if rc == 0: cmd = "sudo cat " + pidfile + " | sed -n '4p'" port = util.getoutput(cmd) else: port = "1" ##### LOOK FOR LOGDIR ################## if util.get_os() in APT_LIST: logdir = "/var/log/postgresql" else: logdir = datadir + "/pg_log" cmd = "sudo ls " + logdir rc = os.system(cmd + to_devnull) if rc != 0: logdir = "" return ([basedir, ver, svcname, svcfile, datadir, port, logdir])
def main(): options, args = get_parsed_args() agentConfig = get_config(options=options) autorestart = agentConfig.get('autorestart', False) COMMANDS = [ 'start', 'stop', 'restart', 'foreground', 'status', 'info', 'check', 'configcheck', 'jmx', ] if len(args) < 1: sys.stderr.write("Usage: %s %s\n" % (sys.argv[0], "|".join(COMMANDS))) return 2 command = args[0] if command not in COMMANDS: sys.stderr.write("Unknown command: %s\n" % command) return 3 pid_file = PidFile('dd-agent') if options.clean: pid_file.clean() agent = Agent(pid_file.get_path(), autorestart) if command in START_COMMANDS: log.info('Agent version %s' % get_version()) if 'start' == command: log.info('Start daemon') agent.start() elif 'stop' == command: log.info('Stop daemon') agent.stop() elif 'restart' == command: log.info('Restart daemon') agent.restart() elif 'status' == command: agent.status() elif 'info' == command: return agent.info(verbose=options.verbose) elif 'foreground' == command: logging.info('Running in foreground') if autorestart: # Set-up the supervisor callbacks and fork it. logging.info('Running Agent with auto-restart ON') def child_func(): agent.run() def parent_func(): agent.start_event = False AgentSupervisor.start(parent_func, child_func) else: # Run in the standard foreground. agent.run(config=agentConfig) elif 'check' == command: check_name = args[1] try: import checks.collector # Try the old-style check first print getattr(checks.collector, check_name)(log).check(agentConfig) except Exception: # If not an old-style check, try checks.d checks = load_check_directory(agentConfig) for check in checks['initialized_checks']: if check.name == check_name: check.run() print check.get_metrics() print check.get_events() if len(args) == 3 and args[2] == 'check_rate': print "Running 2nd iteration to capture rate metrics" time.sleep(1) check.run() print check.get_metrics() print check.get_events() elif 'configcheck' == command or 'configtest' == command: osname = get_os() all_valid = True for conf_path in glob.glob( os.path.join(get_confd_path(osname), "*.yaml")): basename = os.path.basename(conf_path) try: check_yaml(conf_path) except Exception, e: all_valid = False print "%s contains errors:\n %s" % (basename, e) else: print "%s is valid" % basename if all_valid: print "All yaml files passed. You can now run the Datadog agent." return 0 else: print( "Fix the invalid yaml files above in order to start the Datadog agent. " "A useful external tool for yaml parsing can be found at " "http://yaml-online-parser.appspot.com/") return 1