metrics copy.py 16.1 KB
from datetime import datetime, timedelta

from sqlalchemy.sql.functions import func
from .models import MonitorLog, db
from sqlalchemy import and_
from app.util.component.ApiTemplate import ApiTemplate


class Api(ApiTemplate):
    api_name = "统计指标"

    def process(self):

        # 返回结果
        res = {}
        res["data"] = {}
        logs = []
        try:
            server = self.para.get("server")  # server
            # metrics_type = self.para.get("metrics_type")
            grain = self.para.get("grain")
            count = int(self.para.get("count"))
            start_time = self.para.get("start")
            to_time = self.para.get("to")

            cur_now = datetime.now()
            start_datetime = datetime.strptime(start_time, "%Y-%m-%d %H:%M:%S")
            end_datetime = datetime.strptime(to_time, "%Y-%m-%d %H:%M:%S")

            if grain == "day":
                # 粒度是一天
                format = "%Y-%m-%d"
                logs = db.session.query(MonitorLog.date_stamp.label("key"), func.avg(MonitorLog.cpu_usage).label("cpu_usage"),
                                        func.avg(MonitorLog.total_mem).label(
                                            "total_mem"),
                                        func.avg(MonitorLog.available_mem).label(
                                            "available_mem"),
                                        func.avg(MonitorLog.used_mem).label(
                                            "used_mem"),
                                        func.avg(MonitorLog.disk).label(
                                            "disk"),
                                        func.avg(MonitorLog.disk_usage).label(
                                            "disk_usage"),
                                        func.avg(MonitorLog.net_recv).label(
                                            "net_recv"),
                                        func.avg(MonitorLog.net_send).label("net_send")).filter(and_(
                                            MonitorLog.date_stamp <= end_datetime.strftime(
                                                format),
                                            MonitorLog.date_stamp > start_datetime.strftime(
                                                format),
                                            MonitorLog.server == server)).group_by(MonitorLog.date_stamp).order_by(MonitorLog.date_stamp.asc()).all()

                keys = []
                keys_map = {}
                while start_datetime <= end_datetime:
                    keys.append(self.get_monitor_log(
                        start_datetime.strftime('%Y-%m-%d')))
                    keys_map[start_datetime.strftime('%Y-%m-%d')] = len(keys)-1
                    start_datetime += timedelta(days=1)

                res["data"] = self.get_result(logs, keys, keys_map)
            elif grain == "minu_five":
                # 粒度是5分钟
                cur_minu = int(end_datetime.strftime("%M")) % 5
                logs = db.session.query(MonitorLog.hour_stamp.label("hour_stamp"),
                                        MonitorLog.f_minu_stamp.label(
                                            "minu_stamp"),
                                        func.avg(MonitorLog.cpu_usage).label(
                                            "cpu_usage"),
                                        func.avg(MonitorLog.total_mem).label(
                                            "total_mem"),
                                        func.avg(MonitorLog.available_mem).label(
                                            "available_mem"),
                                        func.avg(MonitorLog.used_mem).label(
                                            "used_mem"),
                                        func.avg(MonitorLog.disk).label(
                                            "disk"),
                                        func.avg(MonitorLog.disk_usage).label(
                                            "disk_usage"),
                                        func.avg(MonitorLog.net_recv).label(
                                            "net_recv"),
                                        func.avg(MonitorLog.net_send).label("net_send")).filter(and_(
                                            MonitorLog.time_stamp <= "{}:00".format(
                                                end_datetime.strftime("%Y-%m-%d %H:%M")),
                                            MonitorLog.time_stamp >= "{}:00".format(
                                                start_datetime.strftime("%Y-%m-%d %H:%M")),
                                            MonitorLog.server == server)).group_by(MonitorLog.date_stamp, MonitorLog.hour_stamp, MonitorLog.f_minu_stamp).order_by(
                    MonitorLog.hour_stamp.asc(), MonitorLog.f_minu_stamp.asc()).all()

                keys = []
                keys_map = {}
                while start_datetime <= end_datetime:
                    key = start_datetime.strftime('%H:%M')
                    keys.append(self.get_monitor_log(key))
                    keys_map[key] = len(keys)-1
                    start_datetime += timedelta(minutes=5)

                logs = list(map(lambda log:
                                {"key": "%02d:%02d" % (log.hour_stamp, log.minu_stamp*5+cur_minu),
                                    "cpu_usage": log.cpu_usage, "total_mem": log.total_mem,
                                    "available_mem": log.available_mem, "used_mem": log.used_mem, "disk": log.disk, "disk_usage": log.disk_usage,
                                    "net_recv": log.net_recv, "net_send": log.net_send},
                                logs))

                res["data"] = self.get_result_from_list(logs, keys, keys_map)
            elif grain == "minu_ten":
                # 粒度是10分钟
                cur_minu = int(end_datetime.strftime("%M")) % 10
                logs = db.session.query(MonitorLog.hour_stamp.label("hour_stamp"),
                                        MonitorLog.d_minu_stamp.label(
                                            "minu_stamp"),
                                        func.avg(MonitorLog.cpu_usage).label(
                                            "cpu_usage"),
                                        func.avg(MonitorLog.total_mem).label(
                                            "total_mem"),
                                        func.avg(MonitorLog.available_mem).label(
                                            "available_mem"),
                                        func.avg(MonitorLog.used_mem).label(
                                            "used_mem"),
                                        func.avg(MonitorLog.disk).label(
                                            "disk"),
                                        func.avg(MonitorLog.disk_usage).label(
                                            "disk_usage"),
                                        func.avg(MonitorLog.net_recv).label(
                                            "net_recv"),
                                        func.avg(MonitorLog.net_send).label("net_send")).filter(and_(
                                            MonitorLog.time_stamp <= "{}:00".format(
                                                end_datetime.strftime("%Y-%m-%d %H:%M")),
                                            MonitorLog.time_stamp >= "{}:00".format(
                                                start_datetime.strftime("%Y-%m-%d %H:%M")),
                                            MonitorLog.server == server)).group_by(MonitorLog.date_stamp,
                                                                                   MonitorLog.hour_stamp,
                                                                                   MonitorLog.d_minu_stamp).order_by(MonitorLog.hour_stamp.asc(), MonitorLog.d_minu_stamp.asc()).all()
                keys = []
                keys_map = {}
                while start_datetime <= end_datetime:
                    key = start_datetime.strftime('%H:%M')
                    keys.append(self.get_monitor_log(key))
                    keys_map[key] = len(keys)-1
                    start_datetime += timedelta(minutes=10)

                logs = list(map(lambda log:
                                {"key": "%02d:%02d" % (log.hour_stamp, log.minu_stamp*10+cur_minu),
                                    "cpu_usage": log.cpu_usage, "total_mem": log.total_mem,
                                    "available_mem": log.available_mem, "used_mem": log.used_mem, "disk": log.disk, "disk_usage": log.disk_usage,
                                    "net_recv": log.net_recv, "net_send": log.net_send},
                                logs))

                res["data"] = self.get_result_from_list(logs, keys, keys_map)
            elif grain == "hour":
                # 粒度是一小时
                logs = db.session.query(MonitorLog.hour_stamp.label("key"), func.avg(MonitorLog.cpu_usage).label("cpu_usage"),
                                        func.avg(MonitorLog.total_mem).label(
                                            "total_mem"),
                                        func.avg(MonitorLog.available_mem).label(
                                            "available_mem"),
                                        func.avg(MonitorLog.used_mem).label(
                                            "used_mem"),
                                        func.avg(MonitorLog.disk).label(
                                            "disk"),
                                        func.avg(MonitorLog.disk_usage).label(
                                            "disk_usage"),
                                        func.avg(MonitorLog.net_recv).label(
                                            "net_recv"),
                                        func.avg(MonitorLog.net_send).label("net_send")).filter(and_(
                                            MonitorLog.time_stamp <= "{}:59:59".format(
                                                end_datetime.strftime("%Y-%m-%d %H")),
                                            MonitorLog.time_stamp >= "{}:59:59".format(
                                                start_datetime.strftime("%Y-%m-%d %H")),
                                            MonitorLog.server == server)).group_by(MonitorLog.hour_stamp).order_by(MonitorLog.hour_stamp.asc()).all()
                keys = []
                keys_map = {}
                while start_datetime <= end_datetime:
                    key = int(start_datetime.strftime('%H'))
                    keys.append(self.get_monitor_log("%02d时" % key))
                    keys_map[str(key)] = len(keys)-1
                    start_datetime += timedelta(hours=1)

                res["data"] = self.get_result(logs, keys, keys_map)
            else:
                # 按分钟统计
                logs = db.session.query(MonitorLog.hour_stamp.label("hour_stamp"), MonitorLog.minu_stamp.label("minu_stamp"), func.avg(MonitorLog.cpu_usage).label("cpu_usage"),
                                        func.avg(MonitorLog.total_mem).label(
                                            "total_mem"),
                                        func.avg(MonitorLog.available_mem).label(
                                            "available_mem"),
                                        func.avg(MonitorLog.used_mem).label("used_mem"),
                                        func.avg(MonitorLog.disk).label(
                                            "disk"),
                                        func.avg(MonitorLog.disk_usage).label(
                                            "disk_usage"),
                                        func.avg(MonitorLog.net_recv).label(
                                            "net_recv"),
                                        func.avg(MonitorLog.net_send).label("net_send")).filter(and_(
                                            MonitorLog.time_stamp <= end_datetime.strftime("%Y-%m-%d %H:%M:%S"),
                                            MonitorLog.time_stamp >= start_datetime.strftime("%Y-%m-%d %H:%M:%S"),
                                            MonitorLog.server == server)).group_by(MonitorLog.hour_stamp, MonitorLog.minu_stamp).order_by(
                                                MonitorLog.hour_stamp.asc(), MonitorLog.minu_stamp.asc()).all()
                keys = []
                keys_map = {}
                while start_datetime <= end_datetime:
                    key = start_datetime.strftime('%H:%M')
                    keys.append(self.get_monitor_log(key))
                    keys_map[key] = len(keys)-1
                    start_datetime += timedelta(minutes=1)

                logs = list(map(lambda log:
                                {"key": "%02d:%02d" % (log.hour_stamp, log.minu_stamp),
                                    "cpu_usage": log.cpu_usage, "total_mem": log.total_mem,
                                    "available_mem": log.available_mem, "used_mem": log.used_mem, "disk": log.disk, "disk_usage": log.disk_usage,
                                    "net_recv": log.net_recv, "net_send": log.net_send},
                                logs))

                res["data"] = self.get_result_from_list(logs, keys, keys_map)
            res["result"] = True
        except Exception as e:
            raise e
        return res

    api_doc = {
        "tags": ["监控接口"],
        "parameters": [
            {"name": "server",
             "in": "query",
             "type": "string",
             "description": "服务器地址"},
            {"name": "grain",
             "in": "query",
             "type": "string",
             "description": "指标粒度:minu:分钟,minu_five:5分钟,minu_ten:10分钟,hour:1小时,day:每天"},
            {"name": "count",
             "in": "query",
             "type": "string",
             "description": "个数"},
            {"name": "to",
             "in": "query",
             "type": "string",
             "description": "查询终止时间"},
            {"name": "start",
             "in": "query",
             "type": "string",
             "description": "查询起始时间"}
        ],
        "responses": {
            200: {
                "schema": {
                    "properties": {
                    }
                }
            }
        }
    }

    def get_monitor_log(self, key):
        return {"key": key,
                "cpu_usage": None, "total_mem": None,
                "available_mem": None, "used_mem": None, "disk": None, "disk_usage": None,
                "net_recv": None, "net_send": None}

    def get_result(self, logs, keys, keys_map):
        keys_map_key=keys_map.keys()
        for log in logs:
            if  str(log.key) in  keys_map_key:
                tmp = keys[keys_map[str(log.key)]]
                if tmp != None:
                    tmp['cpu_usage'] = log.cpu_usage
                    tmp['total_mem'] = log.total_mem
                    tmp['available_mem'] = log.available_mem
                    tmp['used_mem'] = log.used_mem
                    tmp['disk'] = log.disk
                    tmp['disk_usage'] = log.disk_usage
                    tmp['net_recv'] = log.net_recv
                    tmp['net_send'] = log.net_send
        return keys

    def get_result_from_list(self, logs, keys, keys_map):
        keys_map_key=keys_map.keys()
        for log in logs:
            if  str(log["key"]) in  keys_map_key:
                tmp = keys[keys_map[str(log["key"])]]
                if tmp != None:
                    tmp['cpu_usage'] = log["cpu_usage"]
                    tmp['total_mem'] = log["total_mem"]
                    tmp['available_mem'] = log["available_mem"]
                    tmp['used_mem'] = log["used_mem"]
                    tmp['disk'] = log["disk"]
                    tmp['disk_usage'] = log["disk_usage"]
                    tmp['net_recv'] = log["net_recv"]
                    tmp['net_send'] = log["net_send"]
        return keys