Пример #1
0
    def decide(self, app_metrics_summary):
        """
        The decision-maker of the autoscaler.
        :param app_metrics_summary: dict of app definitions and metrics
        :return: None
        """
        self.logger.info("Decision process beginning.")

        app_scale_recommendations = {}
        for app, metrics_summary in app_metrics_summary.items():
            app_def = ApplicationDefinition(
                metrics_summary.get("application_definition"))
            rm = RulesManager(app_def)
            if rm.is_app_participating():
                vote = 0
                scale_factor = 0
                cpu = metrics_summary.get("cpu_avg_usage")
                mem = metrics_summary.get("memory_avg_usage")
                metrics = dict(cpu=cpu, mem=mem)

                rm.trigger_rules(metrics)

                if rm.last_triggered_criteria:
                    scale_factor = int(
                        rm.last_triggered_criteria.get("scale_factor"))
                    vote = 1 if scale_factor > 0 else -1

                app_scale_recommendations[app] = dict(
                    vote=vote,
                    checksum=app_def.version,
                    timestamp=datetime.now(),
                    rule=rm.last_triggered_rule)
                info_msg = "{app_name}: vote: {vote} ; scale_factor requested: {scale_factor}"
                self.logger.info(
                    info_msg.format(app_name=app_def.app_name,
                                    vote=vote,
                                    scale_factor=scale_factor))
                # Check if app is participating
                # Check if app is ready
                # Check if app instances is greater than or equal to min and less than max

                if (rm.is_app_ready() and rm.is_app_within_min_or_max()
                        and rm.last_triggered_criteria):
                    tolerance_reached = self.hm.tolerance_reached(
                        app, rm.last_triggered_criteria.get("tolerance"), vote)
                    within_backoff = self.hm.within_backoff(
                        app, rm.last_triggered_criteria.get("backoff"), vote)

                    if vote is not IDLE and tolerance_reached and not within_backoff:
                        self.logger.info("{app}: Decision made: Scale.".format(
                            app=app_def.app_name))
                        app_scale_recommendations[app]["decision"] = vote
                        self.scale(app_def, rm)
                    elif vote == IDLE:
                        app_scale_recommendations[app]["decision"] = IDLE
                        self.logger.info(
                            "{app}: Decision made: No Change.".format(
                                app=app_def.app_name))

        self.hm.add_to_perf_tail(app_scale_recommendations)
Пример #2
0
    def update_autoscaler_metrics(self, stats):
        """
        * Number of participating applications
        * Total min instances
        * Total max instances
        * Total number of currently running instances (only participating applications)
        * Number of currently running instances per application
        * Number of scale up events
        * Number of scale down events
        * Number of flap detection events
        :param stats: dict object containing all application metric information specific to this polling event
        :return:
        """
        participating_applications = [{
            "app":
            app,
            "current_instances":
            int(items["application_definition"]["instances"]),
            "min_instances":
            int(items["application_definition"]["labels"]["min_instances"]),
            "max_instances":
            int(items["application_definition"]["labels"]["max_instances"])
        } for app, items in stats.items() if ApplicationDefinition(
            items["application_definition"]).is_app_participating]

        # total_participating_applications = len(participating_applications)
        # total_min_instances = sum([app["min_instances"] for app in participating_applications])
        # total_max_instances = sum([app["max_instances"] for app in participating_applications])
        # total_current_instances = sum([app["current_instances"] for app in participating_applications])

        [
            self.datadog_client.send_counter_event(
                app["app"],
                "marathon_autoscaler.counters.min_instances",
                points=app["min_instances"])
            for app in participating_applications
        ]
        [
            self.datadog_client.send_counter_event(
                app["app"],
                "marathon_autoscaler.counters.max_instances",
                points=app["max_instances"])
            for app in participating_applications
        ]
        [
            self.datadog_client.send_counter_event(
                app["app"],
                "marathon_autoscaler.counters.current_instances",
                points=app["current_instances"])
            for app in participating_applications
        ]
Пример #3
0
def rules_mgr(testsettings, app_def):
    _rules_mgr = RulesManager(app_def=ApplicationDefinition(app_def))
    assert (type(_rules_mgr) is RulesManager)
    return _rules_mgr