Exemple #1
0
    def test_transform_time_string(self):
        transform_result_1 = utils.transform_time_string('10S',
                                                         mode='to_second')
        transform_result_2 = utils.transform_time_string('2M',
                                                         mode='to_second')
        transform_result_3 = utils.transform_time_string('3H',
                                                         mode='to_second')
        transform_result_4 = utils.transform_time_string('1D',
                                                         mode='to_second')
        transform_result_5 = utils.transform_time_string('2W',
                                                         mode='to_second')

        transform_result_6 = utils.transform_time_string('10S',
                                                         mode='timedelta')
        transform_result_7 = utils.transform_time_string('2M',
                                                         mode='timedelta')
        transform_result_8 = utils.transform_time_string('3H',
                                                         mode='timedelta')
        transform_result_9 = utils.transform_time_string('1D',
                                                         mode='timedelta')
        transform_result_10 = utils.transform_time_string('2W',
                                                          mode='timedelta')

        self.assertEqual(transform_result_1, 10)
        self.assertEqual(transform_result_2, 2 * 60)
        self.assertEqual(transform_result_3, 3 * 60 * 60)
        self.assertEqual(transform_result_4, 1 * 24 * 60 * 60)
        self.assertEqual(transform_result_5, 2 * 7 * 24 * 60 * 60)

        self.assertEqual(transform_result_6, timedelta(seconds=10))
        self.assertEqual(transform_result_7, timedelta(minutes=2))
        self.assertEqual(transform_result_8, timedelta(hours=3))
        self.assertEqual(transform_result_9, timedelta(days=1))
        self.assertEqual(transform_result_10, timedelta(weeks=2))
Exemple #2
0
 def select_timeseries_by_timestamp(self, period):
     timeseries = []
     times = 0
     times_limit = 5
     while times < times_limit:
         try:
             get_last_timestamp_sql = "select timestamp from {table} order by timestamp desc limit 1"
             self._cur.execute(
                 get_last_timestamp_sql.format(table=self._table))
             last_timestamp = self._cur.fetchall()[0][0]
             time_interval = transform_time_string(period, mode='to_second')
             select_timestamp = last_timestamp - time_interval
             get_timeseries_sql = "select timestamp, value from {table} where timestamp >= '{select_timestamp}'"
             self._cur.execute(
                 get_timeseries_sql.format(
                     table=self._table, select_timestamp=select_timestamp))
             timeseries = self._cur.fetchall()
             if not timeseries:
                 logger.warn(
                     "get no timeseries from {table}', retry...".format(
                         table=self._table))
             else:
                 return timeseries
         except Exception as e:
             logger.exception(
                 'exception occur when get timeseries: {error}, retry...'.
                 format(error=str(e)),
                 exc_info=True)
             times += 1
             time.sleep(0.11)
     return timeseries
Exemple #3
0
 def apply(self, instance, args=None, kwargs=None):
     if instance in self._tasks:
         return False
     logger.info('add [{task}] in Monitor task......'.format(task=getattr(instance, 'metric_name')))
     interval = getattr(instance, 'forecast_interval')
     try:
         interval = transform_time_string(interval, mode='to_second')
     except ValueError as e:
         logger.error(e, exc_info=True)
         return
     timer = RepeatTimer(interval=interval, function=instance.run, args=args, kwargs=kwargs)
     self._tasks[instance] = timer
     return True
def check_agent_parameter(config):
    """
    Check if the agent parameter is valid, if the parameter is valid, 
    then return parameters dict, otherwise exit process.
    :param config: config handler for config file.
    :return: agent parameters dict.
    """
    agent_parameters = {}
    url = ""
    try:
        host = config.get('server', 'host')
        listen_port = config.get('server', 'listen_port')
    except (NoOptionError, NoSectionError) as e:
        logger.error(e)
        sys.exit(0)
    else:
        agent_parameters['host'] = host
        agent_parameters['listen_port'] = listen_port

    default_agent_parameter_dicts = {
        'sink_timer_interval': '10S',
        'source_timer_interval': '10S',
        'channel_capacity': 1000
    }
    for parameter, default_value in default_agent_parameter_dicts.items():
        try:
            if parameter == 'channel_capacity':
                agent_parameter_value = config.getint('agent', parameter)
                agent_parameters[parameter] = agent_parameter_value
            else:
                agent_parameter_value = config.get('agent', parameter)
                agent_parameters[parameter] = transform_time_string(
                    agent_parameter_value, mode='to_second')
        except Exception as e:
            logger.error(
                "error occur when acquire {parameter}: {error}, use default_value: {default_value}"
                .format(parameter=parameter,
                        error=str(e),
                        default_value=default_value))
            agent_parameters[parameter] = default_agent_parameter_dicts[
                parameter]

    return agent_parameters
 def select_timeseries_by_timestamp(self, table, period):
     """
     Acquire all timeseries in a timedelta from the present.
     :param table: string, table name from database.
     :param period: string, name of timedelta from now, like '100S', '1H'.
     :return: list, timeseries dataset.
     """
     timeseries = []
     times = 0
     times_limit = 5
     while times < times_limit:
         try:
             get_last_timestamp_sql = "select timestamp from {table} order by timestamp desc limit 1"
             self._cur.execute(get_last_timestamp_sql.format(table=table))
             last_timestamp = self._cur.fetchall()[0][0]
             time_interval = transform_time_string(period, mode='to_second')
             select_timestamp = last_timestamp - time_interval
             get_timeseries_sql = "select timestamp, value from {table} where timestamp >= '{select_timestamp}'"
             self._cur.execute(
                 get_timeseries_sql.format(
                     table=table, select_timestamp=select_timestamp))
             timeseries = self._cur.fetchall()
             if not timeseries:
                 logger.warn(
                     "get no timeseries from {table}', retry...".format(
                         table=table))
             else:
                 return timeseries
         except Exception as e:
             logger.exception(
                 'exception occur when get timeseries: {error}, retry...'.
                 format(error=str(e)),
                 exc_info=True)
             times += 1
             time.sleep(0.11)
     return timeseries
Exemple #6
0
def start_agent(config_path):
    if not os.path.exists(config_path):
        logger.error(
            '{config_path} is not exist..'.format(config_path=config_path))
        return

    config = ConfigParser()
    config.read(config_path)

    if not config.has_section('agent') or not config.has_section('server'):
        logger.error(
            "do not has 'agent' or 'server' section in config file...")
        return

    if not config.has_option('server', 'host') or not config.has_option(
            'server', 'listen_port'):
        logger.error(
            "do not has 'host' or 'listen_port' in 'server' section...")
        return
    else:
        context = None
        if config.has_option('security', 'tls') and config.getboolean(
                'security', 'tls'):
            url = 'https://' + config.get('server', 'host') + ':' + config.get(
                'server', 'listen_port') + '/sink'
            try:
                agent_cert = os.path.realpath(
                    config.get('security', 'agent_cert'))
                agent_key = os.path.realpath(
                    config.get('security', 'agent_key'))
                ca = os.path.realpath(config.get('security', 'ca'))
            except NoOptionError as e:
                logger.error(e)
                return
            else:
                logger.info(agent_cert)
                logger.info(agent_key)
                logger.info(ca)
                ssl_certificate_status = check_certificate(agent_cert)
                ca_certificate_status = check_certificate(ca)
                if ssl_certificate_status['status'] == 'fail':
                    logger.error(
                        "error occur when check '{certificate}'.".format(
                            certificate=agent_cert))
                else:
                    if ssl_certificate_status['level'] == 'info':
                        logger.info(ssl_certificate_status['info'])
                    elif ssl_certificate_status['level'] == 'warn':
                        logger.warn(ssl_certificate_status['info'])
                    else:
                        logger.error(ssl_certificate_status['info'])
                        return

                if ca_certificate_status['status'] == 'fail':
                    logger.error(
                        "error occur when check '{certificate}'.".format(
                            certificate=ca))
                else:
                    if ca_certificate_status['level'] == 'info':
                        logger.info(ca_certificate_status['info'])
                    elif ca_certificate_status['level'] == 'warn':
                        logger.warn(ca_certificate_status['info'])
                    else:
                        logger.error(ca_certificate_status['info'])
                        return
                pw_file = os.path.join(os.path.dirname(config_path),
                                       'certificate/pwf')
                with open(pw_file, mode='r') as f:
                    pw = f.read().strip()

                context = ssl.create_default_context(ssl.Purpose.SERVER_AUTH,
                                                     cafile=ca)
                context.check_hostname = False
                context.load_cert_chain(certfile=agent_cert,
                                        keyfile=agent_key,
                                        password=pw)
        else:
            logger.warn(
                "detect not config 'ssl certificate', use 'http' instead.[advise use 'https']"
            )
            url = 'http://' + config.get('server', 'host') + ':' + config.get(
                'server', 'listen_port') + '/sink'

    default_agent_parameter_dicts = {
        'sink_timer_interval': '10S',
        'source_timer_interval': '10S',
        'channel_capacity': 1000
    }

    for parameter, default_value in default_agent_parameter_dicts.items():
        if not config.has_option('agent', parameter):
            logger.warn(
                "do not provide '{parameter}' in 'agent' section, use default '{default_value}'."
                .format(parameter=parameter,
                        default_value=default_agent_parameter_dicts[
                            'sink_timer_interval']))
            value = default_value
        else:
            value = config.get('agent', parameter)
        try:
            if parameter in ('sink_timer_interval', 'source_timer_interval'):
                globals()[parameter] = transform_time_string(value,
                                                             mode='to_second')
            if parameter == 'channel_capacity':
                globals()[parameter] = int(value)
        except Exception as e:
            logger.error(e)
            return

    chan = ChannelManager()
    source = DBSource()
    http_sink = HttpSink(interval=globals()['sink_timer_interval'],
                         url=url,
                         context=context)
    source.channel_manager = chan
    http_sink.channel_manager = chan

    for task_name, task_func in get_funcs(metric_task):
        source.add_task(name=task_name,
                        interval=globals()['source_timer_interval'],
                        task=task_func,
                        maxsize=globals()['channel_capacity'])
    source.start()
    http_sink.start()
Exemple #7
0
def forecast(args):
    from detector.timeseries_algorithms import forecast_algorithm
    from detector.monitor import data_handler
    from utils import transform_time_string, SuppressStreamObject
    config = ConfigParser()
    config.read(config_path)
    display_table = PrettyTable()
    display_table.field_names = [
        'Metric name', 'Date range', 'Minimum', 'Maximum', 'Average'
    ]
    try:
        database_path = config.get('database', 'database_path')
        max_rows = int(config.get('database', 'max_rows'))
    except (NoSectionError, NoOptionError) as e:
        print("FATAL: {error}.".format(error=str(e)))
        return -1
    if not args.forecast_method:
        forecast_alg = forecast_algorithm('auto_arima')()
    else:
        forecast_alg = forecast_algorithm(args.forecast_method)()
    forecast_periods = str(
        transform_time_string(args.forecast_periods, mode='to_second')) + 'S'
    if not args.metric_name:
        with data_handler.DataHandler(database_path) as db:
            tables = db.get_all_tables()
            for table in tables:
                timeseries = db.get_timeseries(table=table, period=max_rows)
                with SuppressStreamObject():
                    forecast_alg.fit(timeseries=timeseries)
                    future_date, future_value = forecast_alg.forecast(
                        forecast_periods=forecast_periods)
                date_range = "{start_date}~{end_date}".format(
                    start_date=future_date[0], end_date=future_date[-1])
                minimum_forecast_value = min(future_value)
                maximum_forecast_value = max(future_value)
                average_value = sum(future_value) / len(future_value)
                display_table.add_row([
                    table, date_range, minimum_forecast_value,
                    maximum_forecast_value, average_value
                ])
    else:
        with data_handler.DataHandler(database_path) as db:
            timeseries = db.get_timeseries(table=args.metric_name,
                                           period=max_rows)
            with SuppressStreamObject():
                forecast_alg.fit(timeseries=timeseries)
                future_date, future_value = forecast_alg.forecast(
                    forecast_periods=forecast_periods)
            date_range = "{start_date}~{end_date}".format(
                start_date=future_date[0], end_date=future_date[-1])
            minimum_forecast_value = min(future_value)
            maximum_forecast_value = max(future_value)
            average_value = sum(future_value) / len(future_value)
            display_table.add_row([
                args.metric_name, date_range, minimum_forecast_value,
                maximum_forecast_value, average_value
            ])
            if args.save_path:
                if not os.path.exists(os.path.dirname(args.save_path)):
                    os.makedirs(os.path.dirname(args.save_path))
                with open(args.save_path, mode='w') as f:
                    for date, value in zip(future_date, future_value):
                        f.write(date + ',' + str(value) + '\n')
    print(display_table.get_string())