Python实现Linux服务器自动巡检脚本
作者:小码哥
概述
最近抽时间写了一个自动巡检脚本,只需配置服务器ip、用户名、密码即可实现服务器自动巡检,巡检日志以txt文件输出,免去了挨个敲命令巡检的麻烦,脚本比较简单可拉去代码进行二次开发。可以加上定时任务和巡检报告发送邮箱功能,实现完全托管。
源码
以下是完整代码:
#!/usr/bin/python3
from netmiko.huawei.huawei import HuaweiSSH
import os
from datetime import datetime
import smtplib
from email.mime.text import MIMEText
from email.header import Header
from email.mime.multipart import MIMEMultipart
CMD_STR = 'cmd_str'
CMD_NAME = 'name'
IP = 'ip'
USER_NAME = 'username'
PASSWORD = 'password'
# email config
smtp_host = '你的邮箱发送付服务地址'
smtp_port = 25
smtp_email = '你的发送邮箱号'
# 用户名,默认为发件人邮箱前缀
smtp_user ='你的发送邮箱号'
# 密码(注意,某些邮箱需要为SMTP服务单独设置授权码,详情查看相关帮助)
smtp_password = '你的发送邮箱密码'
class ServerMaintenance:
net_connect = None
curr_dir = os.getcwd()
fo = None
file_name = None
email_files = []
# 建立服务器连接
def Connect_HuaweiSSH(self, _ip, _user_name, _pw):
try:
S5720 = {
'device_type': 'huawei',
'ip': _ip,
'username': _user_name,
'password': _pw,
}
# 实例化HuaweiSSH
net_connect = HuaweiSSH(**S5720)
self.net_connect = net_connect
except:
print("连接" + _ip + "错误")
# 运行指令
def execute(self, cmd_str, cmd_name):
result = self.net_connect.send_command(cmd_str)
print(result)
self.printFile('\n-------------------------任务【' + cmd_name + '】开始巡查 -------------------------\n')
self.printFile(result)
self.printFile('\n-------------------------任务【' + cmd_name + '】结束巡查 -------------------------\n')
return result
# 关闭连接
def disconnect(self):
self.net_connect.disconnect()
print("连接断开" + self.net_connect)
# 文件写入
def printFile(self, txt):
self.fo.write(txt)
# 发送邮箱
def sendEmail(self):
msg = MIMEMultipart()
msg['From'] = Header("master", 'utf-8')
msg['To'] = Header('13693567027@163.com', 'utf-8')
subject = 'Test Email'
msg['Subject'] = Header(subject, 'utf-8')
# 邮件正文内容
content = ''
for filename in self.email_files:
content+=filename+'\n'
# 邮件附件
att = MIMEText(open(filename+'.txt', 'rb').read(), 'base64', 'utf-8')
att['Content-Type'] = 'application/octet-stream' # 指定文件格式
att["Content-Disposition"] = 'attachment; filename="服务器巡检报告.txt"'
msg.attach(att)
msg.attach(MIMEText(content, 'plain', 'utf-8'))
try:
# # 创建安全连接,使用SMTP_SSL连接SMTP服务器
smtp_client = smtplib.SMTP(smtp_host) # 实例化对象
smtp_client.connect(smtp_host, smtp_port) # 连接163邮箱服务器,端口号为25
# # 向服务器标识用户身份
smtp_client.login(smtp_user, smtp_password)
# 发送邮件
smtp_client.sendmail(smtp_user, '13693567027@163.com', msg.as_string())
print("邮件发送成功")
except smtplib.SMTPException as e:
print("Error: 无法发送邮件 ", e)
# 关闭SMTP连接
smtp_client.quit()
def run(self,commands,hosts):
for host in hosts:
self.file_name = "服务器巡查_" + host[IP] + '_' + datetime.now().strftime(format="%Y年%m月%d日%H时%M分%S秒")
self.email_files.append(self.file_name)
self.fo = open(self.file_name + ".txt", 'w+', encoding='utf-8')
self.Connect_HuaweiSSH(host[IP], host[USER_NAME], host[PASSWORD])
self.printFile(
'\n================================主机开始巡检: ' + host[IP] + '================================\n')
for command in commands:
self.execute(command[CMD_STR], command[CMD_NAME])
self.printFile(
'\n================================主机巡检结束: ' + host[IP] + '================================\n')
commands = [
{CMD_STR: "ps -ef |grep java", CMD_NAME: "运行中的应用"},
{CMD_STR: "docker ps", CMD_NAME: "运行中的容器"},
{CMD_STR: "df -TH", CMD_NAME: "磁盘空间"},
{CMD_STR: "free -h", CMD_NAME: "内存"},
{CMD_STR: "ps -ef", CMD_NAME: "进程"},
{CMD_STR: "crontab -l", CMD_NAME: "定时任务"},
{CMD_STR: "cat /var/log/messages|grep ERROR && dmesg |grep ERROR", CMD_NAME: "操作系统日志"},
{CMD_STR: "date", CMD_NAME: "操作系统时间"},
{CMD_STR: "firewall-cmd --list-all", CMD_NAME: "防火墙"},
{CMD_STR: "dmidecode -t system", CMD_NAME: "服务器型号"},
{CMD_STR: "uname -a && uname -r", CMD_NAME: "操作系统与内核"},
{CMD_STR: "last", CMD_NAME: "用户登录日志"},
]
hosts = [
{IP: '你的服务器ip', USER_NAME: '你的服务器账号', PASSWORD: '你的服务器密码'}
]
serverMain = ServerMaintenance()
serverMain.run(commands,hosts)
serverMain.sendEmail()Linux系统巡检常用命令
1、查看服务器型号: dmidecode grep Product Name 或者 dmidecode -t system 或者 dmidecode -t1 或者dmidecodegrep“Product"
2、查看主板的序列号: dmidecode grep Serial Number 或者 dmidecode -t system|grep Serial Number
3、统-查看服务器SN序列号和型号: dmidecode grep “System lnformation” -A9 egrepManufacturer/Product Serial!
4、查看内核/操作系统: uname-a/r
5、查看操作系统版本: head -n ]/etc/issue #是数字1不是字母L查看centos操作系统版本: cat /etc/centos-release
查看版本: cat /proc/version #类似uname -r
6、查看CPU信息 (型号): cat/proc/cpuinfolgrep namelcut-f2 -d:|unig -c
7、查看物理CPU个数: cat /proc/cpuinfol grep“physicalid” sort uniql wc -l
8、查看每个物理CPU中core的个数(即核数): cat /proc/cpuinfo grep “cpu cores”|uniq
9、查看逻辑CPU的个数: cat /proc/cpuinfolgrep“processor”]wc-
10、查看内存信息: cat /proc/meminfo或者free 命令 或者cat /proc/meminfo grep MemTota查看内存信息: dmidecode -t memory 或者dmidecode -t memory|grep
- 查看内存总量: grep MemTotal /proc/meminfo
- 查看空闲内存量: grep MemFree /proc/meminfo
11、查看所有swap分区的信息: cat /proc/swaps
查看内存使用量和交换区使用量: free-m
12、查看磁盘信息: fdisk - 或者fdisk -grep Disk
查看各分区使用情况: df -h
13、列出所有启动的系统服务: chkconfig - list|grep on
14、查看磁盘IO的性能:iostat -x 10
15、列出所有PCI设备: Ispci -tv
- 列出所有USB设备: lsusb -tv
- 列出加载的内核模块: lsmod
- 查看pci设备的信息: cat /proc/pci
16、列出所有USB设备的linux系统信息命令:Isusb -tv
17、查看计算机名: hostname
18、查看指定目录的大小: du -sh< 目录名>
19、查看系统运行时间、用户数、负载: uptime
查看系统负载: cat /proc/loadavg
20、查看所有用户的定时任务: crontab -
21、查看挂接的分区状态: mount|column -t
22、查看所有网络接口的属性: ifconfig
23、查看防火墙设置:iptables -L
24、查看路由表: route -n
25、查看所有监听端口: netstat -Intp
26、查看所有已经建立的连接: netstat -antp
查看网络统计信息: netstat -s
27、查看设备io端口: cat /proc/ioports
29、查看中断: cat /proc/interrupts
30、查看环境变量:env
31、查看所有进程:ps -ef
实时显示进程状态: top
32、查看活动用户: who
33、查看看磁盘参数(仅适用于IDE设备): hdparm -i/dev/hda
查看启动时IDE设备检测状况: dmesg|grepIDE
34、查看指定用户信息: id< 用户名>
35、查看用户登录日志: last
36、查看系统所有用户: cut -d:f1 /etc/passwd
37、查看系统所有组: cut -d: -f1 /etc/group
38、安全检查: cat /etc/passwd cat /etc/group
39、查看DB2数据库的表空间详情: db2 list tablespaces show detail
40、日志查看:
- dmesg<目录/日志文件>
- cat /var <目录/日志文件>
- tail -f <目录/日志文件>/var/log/message 系统启动后的信息和错误日志,是Red Hat Linux中最常用的日志之-/var/log/secure 与安全相关的日志信息
- /var/log/maillog 与邮件相关的日志信息
- /var/log/cron 与定时任务相关的日志信息
- /var/log/spooler 与UUCP和news设备相关的日志信息
- /var/log/boot.log 守护进程启动和停止相关的日志消息
方法补充
Linux-Python运维自动巡检脚本
1.使用说明
createTime: 2022-12-21
createBy: lln
createInfo:
检查服务器磁盘、内存、网络、docker容器等信息,以json格式输出至同目录下的report文件夹中,便于运维人员查看。
环境说明
Centos版本 >=7
Python2版本 >=2.6 (兼容python3)
使用步骤
1、将脚本文件linuxOpsStartUp.py放入任意目录下
2、执行 python linuxOpsStartUp.py 命令,进行服务器信息检查,检查结果输出至同目录下report文件夹中。
检查结果示例
[
{
"最后启动": [
"15:08 "
],
"发行版本": [
"CentOS Linux release 7.9.2009 (Core)"
],
"当前时间": [
"2022-12-20 17:50:13"
],
"系统": [
"GNU/Linux"
],
"时区信息": [
"Tue, 20 Dec 2022 17:50:13 +0800"
],
"运行时间": [
"2022-12-20 17:50:13"
],
"内核": [
"3.10.0-1160.6.1.el7.x86_64"
],
"主机名": [
"localhost.localdomain"
]
},
{
"物理CPU个数": [
"1"
],
"CPU架构": [
"x86_64"
],
"每CPU核心数": [
"4"
],
"CPU型号": [
"Intel(R) Core(TM) i5-6400 CPU @ 2.70GHz"
],
"逻辑CPU个数": [
"4"
]
},
{
"内存总览": [
" total used free shared buff/cache available",
"Mem: 15G 9.2G 307M 783M 5.9G 5.1G",
"Swap: 7.8G 237M 7.6G"
]
},
{
"索引总量(MB)": 1125058,
"硬盘使用量(GB)": 1060,
"磁盘总览": [
"文件系统 容量 已用 可用 已用% 挂载点",
"devtmpfs 7.8G 0 7.8G 0% /dev",
"tmpfs 7.8G 0 7.8G 0% /dev/shm",
"tmpfs 7.8G 732M 7.1G 10% /run",
"tmpfs 7.8G 0 7.8G 0% /sys/fs/cgroup",
"/dev/mapper/centos-root 50G 31G 20G 62% /",
"/dev/sda2 1014M 188M 827M 19% /boot",
"/dev/sda1 200M 12M 189M 6% /boot/efi",
"/dev/mapper/centos-home 2.0T 38G 2.0T 2% /home",
"tmpfs 1.6G 0 1.6G 0% /run/user/0"
],
"硬盘总量(GB)": 3726,
"硬盘使用比例(%)": "28.46%",
"索引剩余量(MB)": 1095859,
"索引使用量(MB)": 29198,
"硬盘空余量(GB)": 2665,
"索引使用比例(%)": "2.60%"
},
{
"IP": [
"enp3s0 192.168.11.127/24,br-1849b047c9dd 172.19.0.1/16,docker0 172.17.0.1/16,br-7e3fcfcbbbdf 172.18.0.1/16,br-e9753d63540c 172.20.0.1/16"
],
"GATEWAY": [
"192.168.11.1"
],
"DNS": [
"223.5.5.5"
]
},
{
"空密码用户": [
"test"
],
"所有用户名": [
"root",
"bin",
"daemon",
"ntp"
]
},
{
"jdk信息": [
"openjdk version \"1.8.0_275\"",
"OpenJDK Runtime Environment (build 1.8.0_275-b01)",
"OpenJDK 64-Bit Server VM (build 25.275-b01, mixed mode)"
]
},
{
"防火墙状态": [
"not running"
]
},
{
"ssh开启状态": [
"active"
],
"ssh运行情况": [
"tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1062/sshd ",
"tcp 0 0 192.168.11.127:22 192.168.11.194:50779 ESTABLISHED 10513/sshd: root@pt ",
"tcp 0 0 192.168.11.127:22 192.168.11.194:52458 ESTABLISHED 17626/sshd: root@no ",
"tcp6 0 0 :::22 :::* LISTEN 1062/sshd "
]
},
{
"ntp运行情况": [
"active"
]
},
{
"docker-compose version": [
"docker-compose version 1.29.2, build unknown"
],
"docker version": [
"Docker version 20.10.0, build 7287ab3"
],
"docket stats": [
"CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS",
"d36c48b5c621 sinfcloud-rabbitmq 1.31% 122.7MiB / 15.47GiB 0.77% 3.78GB / 4.09GB 63.2MB / 2.58MB 29",
"40db1a93ec2d linux-command 0.00% 144KiB / 15.47GiB 0.00% 62.1kB / 1.3MB 1.44MB / 0B 1"
]
}
]
脚本完整代码
# -*- coding: utf-8 -*-
"""
linux 自动化脚本
# @Time: 2022/11/4 10:20
# @Author: lln
# @File: linuxOpsStartUp.py
"""
import json
import os
import platform
import time
def runCommand(command):
"""
执行命令,将所有读到的数据去除空行
:param command: 命令
:return: 去除空行后的命令
"""
lines = os.popen(command).readlines()
res = []
for line in lines:
res.append(line.replace('\n', ''))
return res
def getSystemInfo():
"""
使用内置库获取系统信息
"""
res = {
"操作系统名称及版本号": platform.platform(),
"操作系统版本号": platform.version(),
"操作系统的位数": platform.architecture(),
"计算机类型": platform.machine(),
"网络名称": platform.node(),
"处理器信息": platform.processor(),
}
return res
def getSystemStatus():
"""
系统信息,仅支持centos进行查询
"""
# 系统
OS = runCommand("uname -o")
# 发行版本
Release = runCommand("cat /etc/redhat-release 2>/dev/null")
# 内核
Kernel = runCommand("uname -r")
# 主机名
Hostname = runCommand("uname -n")
# 当前时间
LocalTime = runCommand("date +'%F %T'")
# 最后启动
LastReboot = runCommand("who -b | awk '{print $3,$4}'")
# 运行时间
Uptime = runCommand("date +'%F %T'")
# 当前时区信息
time_zone = runCommand("date -R")
res = {
"系统": OS,
"发行版本": Release,
"内核": Kernel,
"主机名": Hostname,
"当前时间": LocalTime,
"最后启动": LastReboot,
"运行时间": Uptime,
"时区信息": time_zone
}
return res
def getCpuStatus():
"""
CPU信息
"""
# 物理CPU个数
physical_cpus = runCommand("grep 'physical id' /proc/cpuinfo| sort | uniq | wc -l")
# 逻辑CPU个数
virt_cpus = runCommand("grep 'processor' /proc/cpuinfo | wc -l")
# 每CPU核心数
cpu_kernels = runCommand("grep 'cores' /proc/cpuinfo|uniq| awk -F ': ' '{print $2}'")
# CPU型号
cpu_type = runCommand("grep 'model name' /proc/cpuinfo | awk -F ': ' '{print $2}' | sort | uniq")
# CPU架构
cpu_arch = runCommand("uname -m")
res = {
'物理CPU个数': physical_cpus,
'逻辑CPU个数': virt_cpus,
'每CPU核心数': cpu_kernels,
'CPU型号': cpu_type,
'CPU架构': cpu_arch
}
return res
def getMemStatus():
"""
内存信息
"""
# 总内存
MemTotal = runCommand("grep MemTotal /proc/meminfo| awk '{print $2}'")
MemTotal_Num = map(float, MemTotal)[0]
# 可用内存
MemFree = runCommand("grep MemFree /proc/meminfo| awk '{print $2}'")
MemFree_Num = map(float, MemFree)[0]
# 比例
Proportion = '{:.4%}'.format(MemFree_Num / MemTotal_Num)
res = {
'总内存(GB)': '{:.5}'.format(float(MemTotal_Num / 1024 / 1024)),
'可用内存(GB)': '{:.5}'.format(float(MemFree_Num / 1024 / 1024)),
'已用比例(%)': Proportion
}
return res
def getMemStatusSimple():
MemTotal = runCommand("free -h")
res = {
'内存总览': MemTotal
}
return res
def getDiskStatus():
"""
磁盘检查
"""
# 生成临时数据记录文件
# os.popen("df -TP | sed '1d' | awk '$2!='tmpfs'{print}'")
# os.popen("df -hTP | sed 's/Mounted on/Mounted/'> /tmp/disk")
# 硬盘总量
DiskAllInfo = runCommand("df -h | grep -v docker")
DiskTotal = runCommand("df -TP | sed '1d' | awk '$2!='tmpfs'{print}'| awk '{total+=$3}END{print total}'")
DiskTotalNum = int(DiskTotal[0])
# 硬盘使用量
DiskUsed = runCommand("df -TP | sed '1d' | awk '$2!='tmpfs'{print}'| awk '{total+=$4}END{print total}'")
DiskUsedNum = int(DiskUsed[0])
# 硬盘空余量
DiskFree = DiskTotalNum - DiskUsedNum
# 硬盘使用比例
DiskUsedPercent = '{:.2%}'.format(DiskUsedNum / DiskTotalNum)
# 索引总量
InodeTotal = runCommand("df -iTP | sed '1d' | awk '$2!='tmpfs'{print}' | awk '{total+=$3}END{print total}' ")
InodeTotal_Num = int(InodeTotal[0])
# 索引使用量
InodeUsed = runCommand("df -iTP | sed '1d' | awk '$2!='tmpfs'{print}' | awk '{total+=$4}END{print total}' ")
InodeUsed_Num = int(InodeUsed[0])
# 索引剩余量
InodeFree = InodeTotal_Num - InodeUsed_Num
# 索引使用比例
InodePercent = '{:.2%}'.format(InodeUsed_Num / InodeTotal_Num)
res = {
'磁盘总览': DiskAllInfo,
'硬盘总量(GB)': int(DiskTotalNum / 1024 / 1024),
'硬盘使用量(GB)': int(DiskUsedNum / 1024 / 1024),
'硬盘空余量(GB)': int(DiskFree / 1024 / 1024),
'硬盘使用比例(%)': DiskUsedPercent,
'索引总量(MB)': int(InodeTotal_Num / 1021),
'索引使用量(MB)': int(InodeUsed_Num / 1021),
'索引剩余量(MB)': int(InodeFree / 1021),
'索引使用比例(%)': InodePercent,
}
return res
def getNetworkStatus():
"""
网络检查
"""
GATEWAY = runCommand("ip route | grep default | awk '{print $3}'")
DNS = runCommand("grep nameserver /etc/resolv.conf| grep -v '#' | awk '{print $2}' | tr '\n' ',' | sed 's/,$//'")
IP = runCommand(
"ip -f inet addr | grep -v 127.0.0.1 | grep inet | awk '{print $NF,$2}' | tr '\n' ',' | sed 's/,$//'")
# TODO 语句有问题会报错,sed的错误,需要检查下执行情况
# MAC = runCommand("ip link | grep -v 'LOOPBACK\|loopback' | awk '{print $2}' | sed 'N;s/\n//' | tr '\n' ',' | sed 's/,$//'")
res = {
'GATEWAY': GATEWAY,
'DNS': DNS,
'IP': IP
# 'MAC': MAC
}
return res
def getUserStatus():
"""
所有用户和空密码用户
"""
all_user = runCommand("awk -F':' '{ print $1}' /etc/passwd")
empty_passwd_user = runCommand("getent shadow | grep -Po '^[^:]*(?=::)'")
res = {
'所有用户名': all_user,
'空密码用户': empty_passwd_user
}
return res
def getJdkStatus():
"""
jdk信息
"""
jdkInfo = runCommand("java -version 2>&1")
res = {
'jdk信息': jdkInfo
}
return res
def getFirewallStatus():
"""
防火墙
"""
firewall = runCommand("firewall-cmd --state 2>&1")
# 兼容 ubuntu 防火墙命令报错 sh: not found 特殊处理
for info in firewall:
if "not found" in info:
firewall = runCommand("ufw status")
res = {
'防火墙状态': firewall
}
return res
def sshStatus():
"""
ssh 检查
"""
sshActive = runCommand("systemctl is-active sshd.service")
sshNetstat = runCommand("sudo netstat -atlunp | grep sshd")
res = {
'ssh开启状态': sshActive,
'ssh运行情况': sshNetstat
}
return res
def ntpStatus():
"""
ntp 检查
"""
ntpActive = runCommand("systemctl is-active ntpd")
res = {
'ntp运行情况': ntpActive
}
return res
def dockerStatus():
"""
docker 检查
"""
dk_version = runCommand("docker -v")
dk_stats = []
for info in dk_version:
if "version" not in info:
dk_version = "未安装docker"
else:
lines = os.popen(
"docker stats --all --no-stream").readlines()
for line in lines:
dk_stats.append(line.replace('\n', ''))
dp_version = runCommand("docker-compose --version")
for info in dp_version:
if "version" not in info:
dp_version = "未安装docker-compose"
res = {
'docker version': dk_version,
'docker-compose version': dp_version,
'docker stats': dk_stats
}
return res
def createReportFile(name, text):
"""
创建report的txt文件,并写入数据
"""
report_dir = os.getcwd() + os.sep + "report" + os.sep
# 判断当前路径是否存在,没有则创建new文件夹
if not os.path.exists(report_dir):
os.makedirs(report_dir)
# 在当前py文件所在路径下的new文件中创建txt
report_file = report_dir + name + '.txt'
# 打开文件,open()函数用于打开一个文件,创建一个file对象,相关的方法才可以调用它进行读写。
file = open(report_file, 'w')
# 写入内容信息
file.write(text)
file.close()
print('report_file create success', report_file)
def printSinfcloud():
print("+------------------------------------------------+")
print("| 欢迎使用SinfCloud自动巡检工具 |")
print("| ____ _ __ ____ _ _ |")
print("|/ ___|(_)_ __ / _|/ ___| | ___ _ _ __| | |")
print("|\___ \| | _ \| |_| | | |/ _ \| | | |/ _ | |")
print("| ___) | | | | | _| |___| | (_) | |_| | (_| | |")
print("||____/|_|_| |_|_| \____|_|\___/ \__,_|\__,_| |")
print("| |")
print("+------------------------------------------------+")
if __name__ == '__main__':
printSinfcloud()
outputFileName = time.strftime('%Y-%m-%d', time.localtime(time.time())) + "_report"
report = list()
report.append(getSystemInfo())
report.append(getSystemStatus())
report.append(getCpuStatus())
report.append(getMemStatusSimple())
report.append(getDiskStatus())
report.append(getNetworkStatus())
report.append(getUserStatus())
report.append(getJdkStatus())
report.append(getFirewallStatus())
report.append(sshStatus())
report.append(ntpStatus())
report.append(dockerStatus())
createReportFile(outputFileName,
json.dumps(report, sort_keys=True, indent=4, separators=(',', ':'), ensure_ascii=False))到此这篇关于Python实现Linux服务器自动巡检脚本的文章就介绍到这了,更多相关Python Linux自动巡检内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
