前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python2 进程扫描脚本 原

Python2 进程扫描脚本 原

作者头像
阿dai学长
发布2019-04-03 10:07:28
5180
发布2019-04-03 10:07:28
举报
文章被收录于专栏:阿dai_linux阿dai_linux

需求

因近期有开发人员在跑脚本时占用系统内存太多导致系统其它进程宕掉,所以需要对系统进程进行扫描监控,如果检测到占用系统内存大于5G的进程就直接kill掉,但是担心误杀,所以暂时只做扫描并记录日志,进行观察,脚本如下:

代码语言:javascript
复制
#!/usr/bin/env python2
# -*- coding:utf-8 -*-

# 扫描所有进程内存占用量

import os
import sys
import psutil
import subprocess
import time
import logging
import logging.config
import signal

# kill内存大于5G(5242880kb)的非root用户启动/cron进程

#获取pid和进程占用内存;注意:该命令需要对特殊字符进行脱意,如:引号——\"\"
cmd = "ps aux |egrep -iv \"root|USER|CROND|redis|mysql|rabbitmq|celery\" |awk '$6>5242880{print $0}'|awk '{print $2, $6}'"

# python之subprocess模块:https://docs.python.org/2/library/subprocess.html
# https://www.cnblogs.com/yyds/p/7288916.html
s = subprocess.Popen(cmd, stderr=subprocess.PIPE, stdout=subprocess.PIPE, shell=True)
lines, _ = s.communicate()

# python脚本中的日志输出
## 定义名为CONF的日志格式
CONF = {
    "version": 1,
    "formatters": {
        "simple": {
            "format": "%(asctime)s - %(name)s - %(levelname)s - %(message)s",
        },  #定义日志的前缀
    },

## 定义日志文件的属性
    "handlers": {
        "log_file": {
            "class": "logging.handlers.RotatingFileHandler",  #保持默认
            "level": "INFO",    #定义日志级别,INFO级别的日志由此输出
            "formatter": "simple",  #调用日志格式前缀
            "filename": "/tmp/process_mem_monitor.log",   #将日志输出到指定文件,不加该变量,日志将输出到终端
            "maxBytes": "1024000",     #定义日志文件大小
            "backupCount": 20,    #只保留最新的20个日志文件--类似于logrotate
            "encoding": "utf8",
        },

        ## 使用console可以将日志输出到当前终端
        "console": {
            "class": "logging.StreamHandler",  #默认
            "level": "DEBUG",  #定义日志级别,DEBUG级别日志将在此输出
            "formatter": "simple",
            "stream": "ext://sys.stdout"  #默认
        },
    },
    
    ## 日志过滤器
    "loggers": {
        "ps_logger": {
            "level": "INFO",
            #指定多个handlers,通过日志级别进行匹配,匹配到哪个handler就由哪种handler对应的格式输出日志
            "handlers": ["log_file", "console"],  
        },
    },

    ## 指定默认日志格式,即在未指定logger的时候使用该配置
    "root": {
        "level": "INFO",
        "handler": ["console"],
    },
}

# 调用日志配置
logging.config.dictConfig(CONF)

#指定日志过滤器
logger = logging.getLogger("ps_logger")


'''
#用于杀死进程
def kill(pid):
    try:
        a = os.kill(pid, signal.SIGKILL)
        # a = os.kill(pid, signal.9) # 与上等效
        print '已杀死pid为%s的进程!' % pid
    except OSError, e:
        print '没有如此进程!!!'
'''

# 通过pid获取进程信息
def process_stats():
    for line in lines.split('\n'):
        #时间戳
        t = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))
        #过滤line为空的情况
        if not line:
            continue
        #分别获取pid和内存使用量
        pid, mem = line.split(' ')
        pid = int(pid)  #格式转换
        try:
            #使用psutil模块,通过pid获取进程信息
            proc = psutil.Process(pid)
            mem = int(mem) / 1024 / 1024

            logger.info(u"pid: %d, process_name: %s, mem_ratio: %d, mem: %d, order: %s", pid, proc.name(), (proc.memory_percent()), mem"M", proc.exe())

        #如果进程已不存在,执行该命令
        except psutil.AccessDenied:
            print "psutil.AccessDenied"
            # kill(pid)


if __name__ == '__main__':
    process_stats()

注意:

  • 日志配置:
    • 如果只是做临时的数据收集,不需要配置logger,直接将日志print到终端,然后使用nohup或者“>>”重定向到指定文件即可
    • 日志文件的作用是做信息收集,配置好日志后需要配置logrotate对日志进行整理
  • 在python脚本中尽量不要使用shell,python本身有自己的包获取系统信息,如psutil;本次之所以使用shell是因为对python不够熟悉,没找到可以获取内存使用量的python包,所以才曲线救国。。。

(adsbygoogle = window.adsbygoogle || []).push({});

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018/05/02 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 需求
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档