文章目录
- 一、python 程序后台自启
- 二、对 Linux 服务器的监控
- 三、以表格形式终端输出
一、python 程序后台自启
查询某个服务是否在后台运行
#!/usr/bin/env pythonimport subprocess
import datetime
import re
import sys
import os
res = subprocess.Popen("id root",stdout=subprocess.PIPE,shell=True)
output_lines=res.stdout.readlines()
for line in output_lines:
if not re.search("ma", line): # 若是没有找到该服务,执行以下
line = line.strip()
dt=datetime.datetime.now()
fp=open('/root/check_ma_group/check_ma.txt','a')
fp.write('root in ma group at %s\n' % dt.strftime('%Y-%m-%d %H:%M:%S'))
fp.close()
subprocess.Popen("/usr/sbin/usermod -G ma root",shell=True)
else:
pass# -*- coding: utf-8 -*-
#!/usr/bin/python
import os
import subprocess
res = subprocess.Popen('ps -ef | grep python',stdout=subprocess.PIPE,shell=True)
attn=res.stdout.readlines()
counts=len(attn) #获取关于 python 的进程个数
print counts
if counts<10: #当进程不够正常运行的个数时,说明某程式退出了
os.system('python /home/weblogic/test.py') #启动程序
利用python的logging模块来记录日志,利用subprocess模块来和系统交互执行命令,检测到子程序结束运行之后,重新开启子程序。
# -*- coding: UTF-8 -*-import os
import subprocess
import logging
from logging.handlers import RotatingFileHandler
class Config:
LOG_PATH_FILE = "./my_service_mgr.log"
LOG_MODE = 'a'
LOG_MAX_SIZE = 10 * 1024 * 1024 # 10M per file
LOG_MAX_FILES = 10 # 10 Files: my_service_mgr.log.1, printmy_service_mgrlog.2, ...
LOG_LEVEL = logging.DEBUG
LOG_FORMAT = "%(asctime)s %(levelname)-10s[%(filename)s:%(lineno)d(%(funcName)s)] %(message)s"
cfg = Config()
handler = RotatingFileHandler(cfg.LOG_PATH_FILE, cfg.LOG_MODE, cfg.LOG_MAX_SIZE, cfg.LOG_MAX_FILES)
formatter = logging.Formatter(cfg.LOG_FORMAT)
handler.setFormatter(formatter)
Logger = logging.getLogger()
Logger.setLevel(cfg.LOG_LEVEL)
Logger.addHandler(handler)
pid = os.getpid()
def print_error(s):
print('\033[31m[%d: ERROR] %s\033[31;m' % (pid, s))
def print_info(s):
print('\033[32m[%d: INFO] %s\033[32;m' % (pid, s))
def print_warning(s):
print('\033[33m[%d: WARNING] %s\033[33;m' % (pid, s))
def start_child_proc(command, merged):
try:
if command is None:
raise OSError("Invalid command")
child = None
if merged is True:
child = subprocess.Popen(command,
stderr=subprocess.STDOUT, # 表示子进程的标准错误也输出到标准输出
stdout=subprocess.PIPE # 表示需要创建一个新的管道
)
else:
child = subprocess.Popen(command)
return child
except subprocess.CalledProcessError:
pass # 处理调用的可执行文件中的错误
except OSError:
raise OSError("Failed to run command!")
def run_forever(command):
print_info("start child process with command: " + ' '.join(command))
Logger.info("start child process with command: " + ' '.join(command))
failover = 0
merged = False
child = start_child_proc(command, merged)
while True:
while child.poll() != None:
failover = failover + 1
print_warning("child process shutdown with return code: " + str(child.returncode))
Logger.critical("child process shutdown with return code: " + str(child.returncode))
print_warning("restart child process again, times=%d" % failover)
Logger.info("restart child process again, times=%d" % failover)
child = start_child_proc(command, merged)
# 读取子进程stdout并记录它
out, err = child.communicate()
returncode = child.returncode
if returncode != 0:
for errorline in err.splitlines():
Logger.info(errorline)
else:
Logger.info("execute child process failed")
if __name__ == "__main__":
run_forever(['scrapy', 'crawl', 'CNSubAllInd'])
Logger.exception("!!!should never run to this!!!")
二、对 Linux 服务器的监控
工作原理:基于/proc 文件系统
Linux 系统为管理员提供了非常好的方法,使其可以在系统运行时更改内核,而不需要重新引导内核系统,这是通过/proc 虚拟文件系统实现的。/proc 文件虚拟系统是一种内核和内核模块用来向进程(process)发送信息的机制(所以叫做“/proc”),这个伪文件系统允许与内核内部数据结构交互,获取有关进程的有用信息,在运行中(on the fly)改变设置(通过改变内核参数)。与其他文件系统不同,/proc 存在于内存而不是硬盘中。proc 文件系统提供的信息如下:
- 进程信息:系统中的任何一个进程,在 proc 的子目录中都有一个同名的进程 ID,可以找到 cmdline、mem、root、stat、statm,以及 status。某些信息只有超级用户可见,例如进程根目录。每一个单独含有现有进程信息的进程有一些可用的专门链接,系统中的任何一个进程都有一个单独的自链接指向进程信息,其用处就是从进程中获取命令行信息。
- 系统信息:如果需要了解整个系统信息中也可以从/proc/stat 中获得,其中包括 CPU 占用情况、磁盘空间、内存对换、中断等。
- CPU 信息:利用/proc/CPUinfo 文件可以获得中央处理器的当前准确信息。
- 负载信息:/proc/loadavg 文件包含系统负载信息。
- 系统内存信息:/proc/meminfo 文件包含系统内存的详细信息,其中显示物理内存的数量、可用交换空间的数量,以及空闲内存的数量等。
/proc 目录中的主要文件的说明
文件或目录名称
描 述
apm
高级电源管理信息
cmdline
这个文件给出了内核启动的命令行
CPUinfo
中央处理器信息
devices
可以用到的设备(块设备/字符设备)
dma
显示当前使用的 DMA 通道
filesystems
核心配置的文件系统
ioports
当前使用的 I/O 端口
interrupts
这个文件的每一行都有一个保留的中断
kcore
系统物理内存映像
kmsg
核心输出的消息,被送到日志文件
mdstat
这个文件包含了由 md 设备驱动程序控制的 RAID 设备信息
loadavg
系统平均负载均衡
meminfo
存储器使用信息,包括物理内存和交换内存
modules
这个文件给出可加载内核模块的信息。lsmod 程序用这些信息显示有关模块的名称,大小,使用数目方面的信息
net
网络协议状态信息
partitions
系统识别的分区表
pci
pci 设备信息
scsi
scsi 设备信息
self
到查看/proc 程序进程目录的符号连接
stat
这个文件包含的信息有 CPU 利用率,磁盘,内存页,内存对换,全部中断,接触开关以及赏赐自举时间
swaps
显示的是交换分区的使用情况
uptime
这个文件给出自从上次系统自举以来的秒数,以及其中有多少秒处于空闲
version
这个文件只有一行内容,说明正在运行的内核版本。可以用标准的编程方法进行分析获得所需的系统信息
OrderedDict 是一个字典子类,可以记住其内容增加的顺序,方便遍历
#!/usr/bin/env Pythonfrom __future__ import print_function
from collections import OrderedDict
import pprint,os
# CPU(中央处理器)监测
def CPUinfo():
'''
读取/proc/CPUinfo 中的信息,返回 list,每核心一个 dict。
CPU_info['proc0']={...}
CPU_info['proc1']={...}
'''
CPUinfo=OrderedDict()
procinfo=OrderedDict()
nprocs = 0
with open('/proc/CPUinfo') as f:
for line in f:
if not line.strip():
# end of one processor
CPUinfo['proc%s' % nprocs] = procinfo
nprocs=nprocs+1
# Reset
procinfo=OrderedDict()
else:
if len(line.split(':')) == 2:
procinfo[line.split(':')[0].strip()] = line.split(':')[1].strip()
else:
procinfo[line.split(':')[0].strip()] = ''
return CPUinfo
# 系统负载监测
def load_stat():
loadavg = {}
f = open("/proc/loadavg")
con = f.read().split()
f.close()
loadavg['lavg_1']=con[0]
loadavg['lavg_5']=con[1]
loadavg['lavg_15']=con[2]
loadavg['nr']=con[3]
loadavg['last_pid']=con[4]
return loadavg
# 对于内存信息的获取
def meminfo():
''' Return the information in /proc/meminfo
as a dictionary '''
meminfo=OrderedDict()
with open('/proc/meminfo') as f:
for line in f:
meminfo[line.split(':')[0]] = line.split(':')[1].strip()
return meminfo
if __name__=='__main__':
CPUinfo = CPUinfo()
for processor in CPUinfo.keys():
print(CPUinfo[processor]['model name'])
loadavg = load_stat()
print(loadavg['lavg_15'])
meminfo = meminfo()
print('Total memory: {0}'.format(meminfo['MemTotal']))
print('Free memory: {0}'.format(meminfo['MemFree']))
对于网络接口的监测
#!/usr/bin/env Pythonimport time
import sys
if len(sys.argv) > 1:
INTERFACE = sys.argv[1]
else:
INTERFACE = 'eth0'
STATS = []
print ('Interface:',INTERFACE)
def rx():
ifstat = open('/proc/net/dev').readlines()
for interface in ifstat:
if INTERFACE in interface:
stat = float(interface.split()[1])
STATS[0:] = [stat]
def tx():
ifstat = open('/proc/net/dev').readlines()
for interface in ifstat:
if INTERFACE in interface:
stat = float(interface.split()[9])
STATS[1:] = [stat]
print('In Out')
rx()
tx()
while True:
time.sleep(1)
rxstat_o = list(STATS)
rx()
tx()
RX = float(STATS[0])
RX_O = rxstat_o[0]
TX = float(STATS[1])
TX_O = rxstat_o[1]
RX_RATE = round((RX - RX_O)/1024/1024,3)
TX_RATE = round((TX - TX_O)/1024/1024,3)
print (RX_RATE ,'MB ',TX_RATE ,'MB')
三、以表格形式终端输出
照着这个图,可以发现几个关键的实现点
鸣谢:
https://www.ibm.com/developerworks/cn/linux/1312_caojh_pythonlinux/#icomments