#!/bin/python3
# -*- coding: utf-8 -*-
"""
使用方式:
python3 cpu_monitor.py 1 0.7
python3 cpu_monitor.py 5 0.7
python3 cpu_monitor.py 15 0.7
1 5 15分别表示负载1分钟内,5分钟内,15分钟内统计.只有这三个选择
0.7是计算峰值,可以随意修改。超过峰值,会打印告警,并且打印cpu占比前十的进程
"""
import sys
import os
import logging
from logging.handlers import TimedRotatingFileHandler

log_file_name = "/tmp/cpu_monitor.log"  # log输出文件名称
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')  # 定义日志输出格式(formatter)
logger = logging.getLogger('mylogger')  # 创建一个logger
logger.setLevel(logging.INFO)  # 设置logger级别
BACKUP_FILES_COUNT = 3
# 日志切割,TimedRotatingFileHandler
# # 创建一个TimedRotatingFileHandler,用于日志切割
handler = TimedRotatingFileHandler(filename=log_file_name, when='H',interval=5, backupCount=BACKUP_FILES_COUNT)
"""
# Calculate the real rollover interval, which is just the number of
# seconds between rollovers.  Also set the filename suffix used when
# a rollover occurs.  Current 'when' events supported:
# S - Seconds
# M - Minutes
# H - Hours
# D - Days
# midnight - roll over at midnight
# W{0-6} - roll over on a certain day; 0 - Monday
#
# Case of the 'when' specifier is not important; lower or upper case
# will work.
"""
handler.setLevel(logging.INFO) # 设置TimedRotatingFileHandler的log级别
handler.setFormatter(formatter)  # 给handler添加formatter
logger.addHandler(handler)  # logger添加上handler

# 输出到控制台,StreamHandler
ch = logging.StreamHandler()  # 创建一个StreamHandler,用于输出到控制台
ch.setLevel(logging.INFO)  # 设置StreamHandler的log级别
ch.setFormatter(formatter)  # 给handler添加formatter
logger.addHandler(ch)  # logger添加handler

Load_Average_type = 5  # 默认
TOP_Load_Average = 1.0  # 默认
if len(sys.argv) == 3:
    try:
        Load_Average_type = int(sys.argv[1])
        TOP_Load_Average = float(sys.argv[2])
    except Exception as e:
        print('参数错误, ./cpu_top_monitor.py Load_Average_type(1,5,15) TOP_Load_Average(0.7)')
        sys.exit(-1)

# cpu 负载
Load_Average_1 = os.popen("uptime | awk -F ': ' '{print $NF}' | awk -F ', ' '{print $1}'").read().strip()
Load_Average_5 = os.popen("uptime | awk -F ': ' '{print $NF}' | awk -F ', ' '{print $2}'").read().strip()
Load_Average_15 = os.popen("uptime | awk -F ': ' '{print $NF}' | awk -F ', ' '{print $3}'").read().strip()

# cpu核数
cpu_kernel_count = float(os.popen("grep 'model name' /proc/cpuinfo | wc -l").read().strip())

if Load_Average_type == 15:
    Load_Average_calc = float(Load_Average_15) / cpu_kernel_count

elif Load_Average_type == 5:
    Load_Average_calc = float(Load_Average_5) / cpu_kernel_count

else:
    Load_Average_calc = float(Load_Average_1) / cpu_kernel_count  # 默认

logger.info("Load_Average_1:{}".format(Load_Average_1))
logger.info("Load_Average_5:{}".format(Load_Average_5))
logger.info("Load_Average_15:{}".format(Load_Average_15))
logger.info("cpu_kernel_count:{}".format(cpu_kernel_count))
logger.info("参数,TOP负载:TOP_Load_Average:{}".format(TOP_Load_Average))
logger.info("实际负载Load_Average_calc[Load_Average/cpu_kernel_count]:{}".format(Load_Average_calc))

if Load_Average_calc >= TOP_Load_Average:
    logger.warning("Load_Average_{}超载告警!!!".format(Load_Average_type))
    str_to_file = "\nLoad_Average_{}超载告警!!!\n".format(Load_Average_type)
    str_to_file = str_to_file + "Load_Average_1: {}\nLoad_Average_5: {}\nLoad_Average_15: {}\n".format(Load_Average_1,
                                                                                                       Load_Average_5,
                                                                                                       Load_Average_15)
    str_to_file = str_to_file + "cpu_kernel_count: {}\nTOP_Load_Average: {}\nLoad_Average_calc: {}\n".format(
        cpu_kernel_count, TOP_Load_Average, Load_Average_calc)
    str_to_file = str_to_file + "\npid,pcpu,cmd\n"
    str_to_file = str_to_file + os.popen("ps -eo pid,pcpu,cmd | sort -r -n -k 2 | head -n 10").read()
    str_to_file = str_to_file + "\n\n"
    logger.warning(str_to_file)