用Python来编写脚本简化日常的运维工作是Python的一个重要用途。在Linux下,有许多系统命令可以让我们时刻监控系统运行的状态,如ps,top,free等等。要获取这些系统信息,Python可以通过subprocess模块调用并获取结果。但这样做显得很麻烦,尤其是要写很多解析代码。
接下来我们利用psutil来监控进程的cpu和内存负载,并将监控的数据定时push到监控系统中,这样就很方便我们每天登录到监控平台去查看业务进程的情况。
pip install psutil
# 监控代码如下 #!/usr/bin/env python # -*- coding:utf-8 -*- """ @Author: 风哥 @Mail: gujiwork@outlook.com @File:MonitorProcess.py @Time:2020/4/24 22:32 """ import psutil import re import requests import time import json MONITOR_API_URL = "http://localhost:2058/api/collector/push" APP_NAME = "Dzookeeper.log.dir=/data/apps/zookeeper-3.5.3-beta_2/bin/" MONITOR_TAG_NAME = "trip-corp-web" TIME_INTERVAL = 20 class MonitorProcessInfo(object): pid_number = None process = None @classmethod def __init__(cls, process_name): """ Get process ID number according to process name :param process_name: """ pids = psutil.process_iter() for pid in pids: # Find PID by process name ''' str_pid = str(pid) f = re.compile(process_name, re.I) if f.search(str_pid): global pid_number, process pid_number = int(str_pid.split('pid=')[1].split(',')[0]) process = psutil.Process(pid_number) ''' # Find PID based on process name CmdLine if process_name in ''.join(pid.cmdline()): global pid_number, process pid_number = pid.pid process = psutil.Process(pid_number) @classmethod def process_memory(cls): """ Get process memory usage :return: """ process_memory_percent = process.memory_percent() process_memory_info = process.memory_info() return process_memory_percent, process_memory_info.rss @classmethod def process_cpu(cls): """ Get the CPU usage of the process :return: """ process_cpu_percent = process.cpu_percent(interval=1.0) return process_cpu_percent @classmethod def process_io(cls): """ Get process IO status :return: """ process_io_count = process.io_counters() return process_io_count.read_bytes, process_io_count.write_bytes @classmethod def process_threads(cls): """ Get Process Threads :return: """ process_threads = process.num_threads() return process_threads class PushMonitorProcessInfo(MonitorProcessInfo): def __init__(self, process_name, tag_name): """Monitoring indicators - memory_rss : Memory size used by process - memory_percent: Percentage of process memory used - process_threads: Number of process threads - io_read_bytes: Process IO read operation - io_write_bytes: Process IO write operation - cpu_percent: Percentage of CPU used by process :param process_name: :param tag_name: """ # py3 super # super().__init__(process_name) """When super inherits the parent class in py2, the parent class needs to add the object attribute, MonitorProcessInfo (object), otherwise it will be thrown incorrectly TypeError: must be type, not classobj""" super(PushMonitorProcessInfo, self).__init__(process_name) cpu_percent = PushMonitorProcessInfo.process_cpu() memory_percent, memory_rss = PushMonitorProcessInfo.process_memory() io_read_bytes, io_write_bytes = PushMonitorProcessInfo.process_io() thread_number = PushMonitorProcessInfo.process_threads() pro_data = { "memory_rss": memory_rss, "memory_percent": memory_percent, "io_read_bytes": io_read_bytes, "io_write_bytes": io_write_bytes, "cpu_percent": cpu_percent, "threads": thread_number } payload = [] t = int(time.time()) for k, v in pro_data.items(): metric_data = { "metric": "process.%s" % k, "endpoint": "10.86.12.13", "tags": "tomcat_name=%s" % tag_name, "value": int(v), "timestamp": t, "step": TIME_INTERVAL } payload.append(metric_data) headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 \ (KHTML, like Gecko) Chrome/80.0.3987.122 Safari/537.36", "Content-Type": "application/json" } rsp = requests.post(url=MONITOR_API_URL, data=json.dumps(payload), headers=headers) print(rsp.text) while True: push_data = PushMonitorProcessInfo(APP_NAME, MONITOR_TAG_NAME) time.sleep(TIME_INTERVAL)
脚本以死循环方式每隔20秒将数据上报到监控平台,登陆监控平台就可以很愉快的查看图表了