Python监控服务进程及自启动服务方法与实践

1. 需求概述

当我们在Windows Server环境中部署XX系统的实际应用中,往往会遇到一些运维管理的挑战。为了确保系统的持续稳定运行,特别是在服务程序因各种原因突然关闭的情况下,我们可以借助Python的强大生态系统来构建一个监控与自动重启的管理工具。

在这个场景中,我使用了psutil第三方库,它提供了跨平台的系统进程和系统利用率信息。结合apscheduler用于定时任务的管理,以及subprocess用于启动和监控服务程序,我打造了一个简单而有效的监控系统。

首先,我使用psutil来获取并筛选出系统中我们所关心的服务程序的进程。通过定时任务,我定期检查该进程是否在运行,如果不存在,那么就启动一个新的进程,确保服务不会因意外关闭而中断。

下面是一个简单的Python代码示例,演示了如何使用这些库来实现监控与自动重启:

import psutil
import subprocess
from apscheduler.schedulers.blocking import BlockingScheduler

# 设置服务程序的命令和路径
service_command = "py_monitor TestMonitor.py"
service_path = "D:/03study/Test/App"

def monitor_service():
    # 获取所有进程
    all_processes = psutil.process_iter(attrs=['pid', 'name'])

    # 检查服务程序是否在运行
    service_running = any(
        process.info['name'] == "python.exe"
        for process in all_processes
    )

    if not service_running:
        # 服务程序不存在,启动新的进程
        subprocess.Popen(service_command, cwd=service_path, shell=True)
        print("Service restarted.")

# 创建定时任务
scheduler = BlockingScheduler()
scheduler.add_job(monitor_service, 'interval', minutes=5)

try:
    print("Monitoring and auto-restarting service...")
    scheduler.start()
except KeyboardInterrupt:
    # 用户手动终止任务
    pass

注:此代码参考自chatgpt,在windows平台上,有些权限限制,process.cmdline()报错,去掉。

请注意,这只是一个简单的示例,实际中你可能需要根据具体情况进行更复杂的异常处理、日志记录等。此外,确保你的系统允许定时任务的执行,例如在Linux中,可以使用cron等工具。

2. python监控技术

2.1. Python在系统监控中的应用

系统监控是保证计算机系统正常运转的基础,也是运维工作的核心之一。Python在系统监控中的应用非常广泛,例如:

  • 监控进程和系统资源:Python可以通过内置的psutil模块来监控运行中的进程以及系统资源的使用情况,如CPU、内存、磁盘等。
  • 监控网络流量:Python可以通过scapy等第三方库来监控网络流量、分析流量内容、抓包等,有时还可以用来检测网络攻击。
  • 自定义监控:Python可以通过自定义实现各种监控项,如监控服务、网站、日志等,自定义监控项可以更贴合具体业务需求。例如,可以通过发送ping包来检测服务器是否能够正常响应。
  • 报警处理:Python可以将监控数据通过邮件、短信等方式发送给管理员,一旦监控数据异常,可以及时触发报警机制。这些报警机制可以在Python中用一些库来实现,如smtplib、email、twilio等。

用Python来编写脚本简化日常的运维工作是Python的一个重要用途。在Linux下,有许多系统命令可以让我们时刻监控系统运行的状态,如ps,top,free等等。要获取这些系统信息,Python可以通过subprocess模块调用并获取结果。但这样做显得很麻烦,尤其是要写很多解析代码。

在Python中获取系统信息的另一个好办法是使用psutil这个第三方 模块。顾名思义,psutil = process and system utilities,它不仅可以通过一两行代码实现系统监控,还可以跨平台使用,支持Linux/UNIX/OSX/Windows等,是系统管理员和运维小伙伴不可或缺的必备模块。

2.2. psutil

psutil是一个跨平台库,能够轻松实现获取系统运行的进程和系统运行的信息(包括CPU、内存、磁盘、网络等)。它主要用来做系统监控,性能分析,进程管理。它实现了同等命令行工具提供的功能,如ps、top、lsof、netstat、ifconfig、who、df、kill、free、nice、ionice、iostat、iotop、uptime、pidof、tty、taskset、pmap等。目前支持32位和64位的Linux、Windows、OS X、FreeBSD和Sun Solaris等操作系统.
在这里插入图片描述

2.3. 任务调度与启动服务程序

2.3.1 APScheduler

APScheduler是一个用于任务调度和定时任务管理的Python库。它提供了一个简单而灵活的方式来定义、调度和执行任务。

2.3.2. subprocess 模块

subprocess 模块允许我们启动一个新进程,并连接到它们的输入/输出/错误管道,从而获取返回值。

subprocess 模块首先推荐使用的是它的 run 方法,更高级的用法可以直接使用 Popen 接口。

run 方法语法格式如下:

	subprocess.run(args, *, stdin=None, input=None, stdout=None, stderr=None, capture_output=False, shell=False, cwd=None, timeout=None, check=False, encoding=None, errors=None, text=None, env=None, universal_newlines=None)
  • args:表示要执行的命令。必须是一个字符串,字符串参数列表。
  • stdin、stdout 和 stderr:子进程的标准输入、输出和错误。
  • timeout:设置命令超时时间。如果命令执行时间超时,子进程将被杀死,并弹出 TimeoutExpired 异常。
  • check:如果该参数设置为 True,并且进程退出状态码不是 0,则弹 出 CalledProcessError 异常。
  • encoding: 如果指定了该参数,则 stdin、stdout 和 stderr 可以接收字符串数据,并以该编码方式编码。否则只接收 bytes 类型的数据。
  • shell:如果该参数为 True,将通过操作系统的 shell 执行指定的命令。
  • returncode: 执行完子进程状态,通常返回状态为0则表明它已经运行完毕,若值为负值 “-N”,表明子进程被终。

3. 实践过程

3.1. psutil库的安装

pip install -i https://pypi.tuna.tsinghua.edu.cn/simple psutil

3.2. 常用方法

3.2.1. 获取系统信息示例

# coding:utf-8
import psutil
import datetime
import time

now_time = time.strftime('%Y-%m-%d-%H:%M:%S', time.localtime(time.time()))
print('当前时间', now_time)
# 获取系统启动时间
print("系统启动时间: %s" % datetime.datetime.fromtimestamp(psutil.boot_time()).strftime("%Y-%m-%d %H:%M:%S"))

print('----------------------------系统CPU信息---------------------------------------')
# 查看cpu物理个数的信息
print("物理CPU个数: %s" % psutil.cpu_count(logical=False))
# 查看cpu逻辑个数的信息
print("逻辑CPU个数: %s" % psutil.cpu_count(logical=True))
# cpu的使用率
cpu = (str(psutil.cpu_percent(1))) + '%'
print('当前1s内系统cup使用率: %s' % cpu)

print('----------------------------系统内存信息---------------------------------------')
# 查看内存信息
total = str(round(psutil.virtual_memory().total / (1024.0 * 1024.0 * 1024.0), 2))
free = str(round(psutil.virtual_memory().free / (1024.0 * 1024.0 * 1024.0), 2))
used = str(round(psutil.virtual_memory().used / (1024.0 * 1024.0 * 1024.0), 2))
memory = int(psutil.virtual_memory().total - psutil.virtual_memory().free) / float(psutil.virtual_memory().total)
print("物理总内存: %s G" % total)
print("已使用物理内存: %s G" % used)
print("剩余物理内存: %s G" % free)
print("物理内存使用率: %s %%" % int(memory * 100))

print('----------------------------系统用户信息---------------------------------------')
# 获取系统用户
users_count = len(psutil.users())
users_list = ", ".join([u.name for u in psutil.users()])
print("当前有 %s 个用户,分别是 %s" % (users_count, users_list))

print('----------------------------系统网卡信息---------------------------------------')
# 获取网卡信息,可以得到得到网卡属性,连接数,当前数据等信息
net = psutil.net_io_counters()
bytes_sent = '{0:.2f} Mb'.format(net.bytes_recv / 1024 / 1024)
bytes_recv = '{0:.2f} Mb'.format(net.bytes_sent / 1024 / 1024)
print("网卡接收数据 %s 网卡发送数据 %s" % (bytes_recv, bytes_sent))

print('-----------------------------系统磁盘信息---------------------------------------')
# 获取磁盘数据信息
io = psutil.disk_partitions()
print('系统当前所有的磁盘信息:{}'.format(io))
for i in io:
    try:
        o = psutil.disk_usage(i.device)
        print('磁盘名:{}'.format(i.device), end='\t')
        print("总容量:" + str(int(o.total / (1024.0 * 1024.0 * 1024.0))) + "G", end='\t')
        print("已用容量:" + str(int(o.used / (1024.0 * 1024.0 * 1024.0))) + "G", end='\t')
        print("可用容量:" + str(int(o.free / (1024.0 * 1024.0 * 1024.0))) + "G")
    except PermissionError:
        continue

print('-----------------------------系统进程信息-------------------------------------')
# 查看系统全部进程
for pid in psutil.pids():
    p = psutil.Process(pid)
    print("进程名 %-20s 内存利用率 %-18s 进程状态 %-10s 创建时间 %-10s " % (p.name(), p.memory_percent(), p.status(), p.create_time()))

输出结果截取片段:

在这里插入图片描述

3.2.2. 获取网络信息

获取主机名与IP地址

import socket
hostname = socket.gethostname()
print(hostname)
print(socket.gethostbyname(hostname))

3.3. 应用实践

import psutil
import time
import subprocess

import pytz
from apscheduler.schedulers.blocking import BlockingScheduler
from loguru import logger

# 按进程名称查询进行
def find_procs_by_name(name):
    #"Return a list of processes matching 'name'."
    ls = []
    for p in psutil.process_iter(['name']):
        if p.info['name'] == name:
            ls.append(p)
    return ls

# 监控进程列表
def monitorprocss():
    processname = [ 'pvforecast_py.exe',
                    'pvweather24_py.exe']
    cmdbat = ['D:\Python\PVMicrogrid\PVSystem\PVForecastAPScheduler.bat',
                'D:\Python\PVMicrogrid\PVSystem\PVAPScheduler.bat']
    
    processe_command = [('start ' + processname[0] + ' PVForecastAPScheduler.py','D:\Python\PVMicrogrid\PVSystem' ),
                        ('start ' + processname[1] + ' PVAPScheduler.py','D:\Python\PVMicrogrid\PVSystem'),
                        ('start ' + processname[2] + ' PVTrainAPScheduler.py','D:\Python\PVMicrogrid\PVSystem')]
    
    for i in range(len(processname)):
        ls = find_procs_by_name(processname[i])
        if len(ls)>0:
            p = ls[0]
            
            # 获取进程创建时间
            createtime = time.strftime('%Y-%m-%d %X', time.localtime(p.create_time())) 
            #print('进程创建时间:', createtime)          
            if p.is_running():
                # 获取该进程的内存利用率
                rate = p.memory_percent() 
                logger.info(processname[i] + ',该进程的内存利用率:' + str(round(rate,2)))
            else:
                # 杀掉进程
                p.terminate()
            
            logger.info(processname[i] + ',进程创建时间:' + createtime)    
            
        else:
            # 重新启动进行
            # 运行批处理文件,并获取返回值
            #result = subprocess.run(cmdbat[i], shell=True)
            print('启动服务程序:', processe_command[i][0])
            subprocess.Popen(processe_command[i][0], cwd=processe_command[i][1], shell=True)


if __name__ == '__main__':
    logger.add("MonitorProcess_{time}.log")
    print('监控程序开始运行!')
    #monitorprocss()
    scheduler = BlockingScheduler(timezone=pytz.timezone("Asia/Shanghai") )
     
    #scheduler.add_job(monitorprocss, 'cron', minute = '00,10,20,30,40,50', second='00', misfire_grace_time=60, id='job1')
    scheduler.add_job(monitorprocss, 'interval', minutes = 1, id='job1')

    try:
        scheduler.start()
    except (KeyboardInterrupt, SystemExit):
        pass    

4. 总结

使用python开发系统监控工具,能快速实现个性化需求,短小而且精悍。其中,服务程序自启动功能,可以替代“Windows环境中Python应用服务自启动及其监控解决方法“所描述多个启动批处理文件,直接使用此一个批处理文件”MonitorProcess.bat“,可以完全胜任。

@echo off
D:
cd D:\Python\PVMicrogrid\utils
start python Monitorprocess.py

部署代码buildw.bat修改为:

chcp 65001

copy D:\Python\PVMicrogrid\MonitorProcess.bat "%userprofile%\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup\MonitorProcess.bat"

注意:需要把…\Startup\MonitorProcess.bat文件加入安全防护白名单中。

通过这样的监控与自动重启工具,我们可以更好地保障应用服务系统的稳定性,及时应对各种潜在问题,确保服务始终处于可用状态。

参考:

肖永威. Windows环境中Python应用服务自启动及其监控解决方法. CSDN博客. 2023.11
习久性成. python第三方库psutil(process and system utilities)库详解:获取系统运行的进程和系统利用率(包括CPU、内存、磁盘、网络等)信息

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/182314.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Linux下载工具XDM下载安装与使用

Windows上IDM多线程下载非常强大,即能捕捉页面上的视频、图片、音频,又能作为浏览器下载器使用,但是IDM无法在Linux下使用,除非使用wine。不过我们可以在Linux中用XDM(Xtreme Download Manager)代替IDM。 1、XDM下载 Xtreme Dow…

线性回归中的函数求导

在线性回归中,函数求导是一个重要的数学工具,用于计算损失函数关于模型参数的导数。通过求导,我们可以找到最优的参数值,以实现更好的线性回归拟合。 本文将介绍线性回归的基本原理,以及如何通过函数求导来优化线性回…

C++设计模式之工厂模式(下)——抽象工厂模式

抽象工厂模式 介绍示例示例使用运行结果抽象工厂模式的优缺点优点缺点 总结 介绍 抽象工厂模式是一种创建型设计模式,它提供了一种封装一组相关或相互依赖对象的方式,而无需指定它们具体的类。它允许客户端使用抽象接口来创建一系列相关的对象&#xff…

Java常用类

目录 包装类 装箱和拆箱 包装类型和String的转换&#xff0c;包装类的常用方法 包装类 装箱和拆箱 package com.edu.wrapper;public class Interger01 {//演示int<-->Integer的装箱和拆箱//手动装箱int n1100;Integer integer new Integer(n1);Integer integer01 In…

UML建模图文详解教程01——Enterprise Architect的安装与使用

版权声明 本文原创作者&#xff1a;谷哥的小弟作者博客地址&#xff1a;http://blog.csdn.net/lfdfhl Enterprise Architect概述 官方网站&#xff1a;https://www.sparxsystems.cn/products/ea/&#xff1b;图示如下&#xff1a; Enterprise Architect是一个全功能的、基于…

【数据结构(四)】前缀、中缀、后缀表达式(逆波兰表达式)和逆波兰计算器的代码实现(2)

文章目录 1. 前缀表达式(波兰表达式)1.1. 前缀表达式的计算机求值 2. 中缀表达式3. 后缀表达式(逆波兰表达式)3.1. 后缀表达式的计算机求值3.2. 逆波兰计算器的实现 4. 中缀表达式 转 后缀表达式4.1. 思路分析4.2. 代码实现 5. 逆波兰计算器的完整版 1. 前缀表达式(波兰表达式)…

Django(十、中间件)

文章目录 一、中间件的介绍中间件有什么用中间件功能自定义中间中间件的顺序 一、中间件的介绍 中间件顾名思义&#xff0c;是介于request与response处理之间的一道处理过程&#xff0c;相对比较轻量级&#xff0c;并且在全局上改变django的输入与输出。因为改变的是全局&…

【精选】​​深度学习:构建卷积神经网络的表情识别系统(源码&教程)

1.研究背景与意义 随着社交媒体和在线通信的普及&#xff0c;人们越来越多地使用表情符号来表达情感和情绪。表情识别系统的发展成为一个重要的研究领域&#xff0c;旨在通过计算机自动识别和理解人类的表情&#xff0c;从而提高人机交互的效果和用户体验。 传统的表情识别方…

Java之《ATM自动取款机》(面向对象)

《JAVA编程基础》项目说明 一、项目名称&#xff1a; 基于JAVA控制台版本银行自动取款机 项目要求&#xff1a; 实现银行自动取款机的以下基本操作功能&#xff1a;读卡、取款、查询。&#xff08;自动取款机中转账、修改密码不作要求&#xff09; 具体要求&#xff1a; 读卡…

github批量仓库克隆,git clone某个用户的所有仓库

利用github的api工具&#xff0c; 首先拿到用户名为kevin的所有仓库的url&#xff1a; curl "https://api.github.com/users/kevin/repos?per_page100&&page1" | grep -w clone_url >clone.txt过滤一下&#xff1a; grep -o https://[^"]* clone…

Vue学习笔记-Object.defineproperty函数

文章目录 前文提要Object.defineProperty作用Object.defineProperty参数使用例图getter&#xff0c;也就是get函数setter&#xff0c;也就是set函数 前文提要 本人仅做个人学习记录&#xff0c;如有错误&#xff0c;请多包涵 Object.defineProperty作用 当在js中声明了一个变…

老鸟总结,软件测试工程师职业发展规划路线,入门到冲击大厂...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 1、测试工程师发展…

1999-2021年地级市城镇居民人均消费性支出数据

1999-2021年地级市城镇居民人均消费性支出数据 1、时间&#xff1a;1999-2021年 2、指标&#xff1a;城镇居民人均消费性支出 3、范围&#xff1a;290个地级市 4、来源&#xff1a;城市年鉴、地级市统计公报 5、指标解释&#xff1a; 城镇居民人均消费性支出&#xff1a;指…

JavaScript基础—引入方式、注释和结束符、输入和输出、变量、常量、数据类型、检测数据类型、类型转换、综合案例—用户订单信息

版本说明 当前版本号[20231123]。 版本修改说明20231123初版 目录 文章目录 版本说明目录JavaScript 基础 - 第1天介绍引入方式内部方式外部形式 注释和结束符单行注释多行注释 结束符输入和输出输出输入 变量声明赋值变量初始化更新变量 关键字变量名命名规则 常量数据类型…

java--权限修饰符

1.什么是权限修饰符 就是是用来限制类中的成员(成员变量、成员方法、构造器、代码块...)能够被访问的范围。 2.权限修饰符有几种&#xff1f;各自的作用是什么&#xff1f; private<缺省<protected<public(范围由小到大)

【成功案例】7日ROI超65%!注册率超85%!雷霆网络 联手 NetMarvel 实现效果翻倍增长!

雷霆网络旗下多款角色扮演手游在国内长期霸占买量榜前列&#xff0c;而这股“买量大户”的风依旧吹到了海外&#xff0c;其中《地下城堡3》依靠买量在境外业务收入上增长明显&#xff0c;目前市场潜力巨大。 然而&#xff0c;面对竞争激烈的PRG游戏出海局面&#xff0c;打开市…

PyTorch包

进入PyTorch的官网&#xff1a; pytorch GitHub 点击GitHub&#xff1a; 进入PyTorch的主目录&#xff1a; 进入Vision reference&#xff1a; detection&#xff1a; 这就是我们在训练过程中会使用到的文件了&#xff1a;

如何下载OpenJDK及其源码

如果想下载 OpenJDK&#xff0c;存在以下几种办法&#xff1a; 最简单的办法是去 OpenJDK 官网&#xff0c;这里能下载 JDK9 及其以上的版本&#xff0c;还有 JDK 源码所在的 github 地址。 第二种方法是使用 IDEA 下载&#xff0c;位置在 File->Project Structure->SD…

R数据分析:集成学习方法之随机生存森林的原理和做法,实例解析

很久很久以前给大家写过决策树&#xff0c;非常简单明了的算法。今天给大家写随机&#xff08;生存&#xff09;森林&#xff0c;随机森林是集成了很多个决策数的集成模型。像随机森林这样将很多个基本学习器集合起来形成一个更加强大的学习器的这么一种集成思想还是非常好的。…
最新文章