运维自动巡检脚本使用说明
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))