博客
关于我
(12.1)实战项目:收集系统信息用于分析性能瓶颈
阅读量:398 次
发布时间:2019-03-05

本文共 7716 字,大约阅读时间需要 25 分钟。

1.select循环

select循环是一种在shell脚本中用户交互选择项的常用方法。与简单的echo读取不同,select循环可以让用户逐步输入选择,直到确定退出。

以下是一个典型的select循环示例:

#!/usr/bin/bash  PS3="Your choice is [5 for quit]:"  select choice in disk_partition filesystem cpu_load mem_util quit do  	case "$choice" in  		disk_partition)  			fdisk -l  			;;  		filesystem)  			df -h  			;;  		cpu_load)  			uptime  			;;  		mem_util)  			free -m  			;;  		quit)  			break  		;;  		*)  			echo "error"  			exit  	esac  done

执行效果如图所示:

$PS1,$PS2,$PS3的含义

在shell环境中,$PS1、$PS2和$PS3分别表示提示符的三个状态。默认情况下:

jiwangreal@ubuntu:~$ echo $PS1  [\e]0;\u@\h: \w\a\]${ debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]$

$PS3可以通过修改修改提示符,如下所示:

2.收集系统信息用于分析性能瓶颈完全版

该脚本旨在分析系统资源的性能瓶颈,功能包括:

  • 查看CPU利用率与负载(top、vmstat、sar)
  • 查看磁盘和inode利用率与I/O负载(df、iostat、iotop、sar、dstat)
  • 查看内存利用率(free、vmstat)
  • 查看TCP连接状态(netstat、ss)
  • 查看CPU和内存占用的前10个进程(top、ps)
  • 查看网络流量(ifconfig、iftop、iptraf)

脚本开始时会判断OS类型:

os_check(){  	if [ -e /etc/redhat-release ];then  		REDHAT=`cat /etc/redhat-release| cut -d' ' -f1`  	else  		DEBIAN=`cat /etc/issue|cut -d' ' -f1`  	fi  	if [ "$REDHAT" == "CentOS" -o "$REDHAT" == "Red" ];then  		P_M=yum  	elif [ "$DEBIAN" == "Ubuntu" -o "DEBIAN" == "ubuntu" ];then  		P_M=apt-get  	else  		OS not support  		exit 1  	fi  }

如果需要安装额外工具(如vmstat或iostat),脚本会自动判断并安装。

主循环体内,用户可以选择不同的选项进行分析:

while true:do  	select input in cpu_load disk_load disk_use disk_inode mem_use tcp_status cpu_top10 mem_top10 traffic quit do  		case $input in  			cpu_load)  				# CPU利用率与负载  				i=1  				while [[ $i -le 3 ]];do  					echo -e "\033[32m 参考值${i}\033[0m"  					UTIL=`vmstat | awk '{if(NR==3) print 100-$15"%"}'`  					USER=`vmstat | awk '{if(NR==3) print $13"%"}'`  					SYS=`vmstat | awk '{if(NR==3) print $14"%"}'`  					IOWAIT=`vmstat | awk '{if(NR==3) print $16"%"}'`  					echo "Utile: $UTIL"  					echo "User user:$USER"  					echo "System use: $SYS"  					echo "I/O wait: $IOWAIT"  					let i++  					sleep 1  				done  				echo "--------------------------"  				break  			;;  			disk_load)  				# 硬盘I/O负载  				i=1  				while [[ $i -le 3 ]];do  					echo -e "\033[32m 参考值${i}\033[0m"  					UTIL=`iostat -x -k | awk '/^[v|s]/{OFS=": ";print $1,$NF"%"}'`  					READ=`iostat -x -k | awk '/^[v|s]/{OFS=": ";print $1,$6"KB"}'`  					WRITE=`iostat -x -k | awk '/^[v|s]/{OFS=": ";print $1,$7"KB"}'`  					IOWAIT=`vmstat | awk '{if(NR==3) print $16"%"}}'`  					echo -e "Util:"  					echo -e "${UTIL}"  					echo "I/O wait: $IOWAIT"  					echo "I/O Wait: $IOWAIT"  					echo "Read/s: \n$READ"  					echo "Write/s: \n$WRITE"  					i=$(($i+1))  					sleep 1  				done  				echo "--------------------------"  				break  			;;  			disk_use)  				# 硬盘利用率  				DISK_LOG=/tmp/disk_use.tmp  				DISK_TOTAL=`fdisk -l | awk '/^Disk.*bytes/ && /\/dev/{printf $2" ";printf "%d", $3;print "GB"}'`  				USE_RATE=`df -h | awk '/^\/dev/{print int($5)}'`  				for i in $USE_RATE;do  					if [ $i -gt 90 ];then  						PART=`df -h|awk '{if(int($5) === ''$i'') print $6}'`  						echo "$PART = ${i}%" >> $DISK_LOG  					fi  				done  				echo "--------------------------"  				echo -e "Dick toltal:\n${DISK_TOTAL}"  				if [ -f $DISK_LOG ];then  					echo "--------------------------"  					cat $DISK_LOG  					echo "--------------------------"  					rm -f $DISK_LOG  				else  					echo "--------------------------"  					echo "Disk use rate no than 90% of the partition"  					echo "--------------------------"  				fi  				break  			;;  			disk_inode)  				# 硬盘inode利用率  				INODE_LOG=/tmp/inode_use.tmp  				INODE_USE=`df -i | awk '/^\dev/{print int($5)}'`  				for i in $INODE_USE;do  					if [ $i -gt 90 ];then  						PART=`df -h|awk '{if(int($5) == ''$i'') print $6}'`  						echo "$PART = ${i}%" >> $INODE_LOG  					fi  				done  				if [ -f $INODE_LOG ];then  					echo "--------------------------"  					cat $INODE_LOG  					echo "--------------------------"  					rm -f $INODE_LOG  				else  					echo "--------------------------"  					echo "Disk use rate no than 90% of the partition"  					echo "--------------------------"  				fi  				break  			;;  			mem_use)  				# 内存利用率  				MEM_TOTAL=`free -m|awk '{if(NR==2)printf "%.1f" ,$2/1024} END{print "G"}'`  				USE=`free -m|awk '{if(NR==2)printf "%.1f" ,$3/1024} END{print "G"}'`  				FREE=`free -m|awk '{if(NR==2)printf "%.1f" ,$4/1024} END{print "G"}'`  				CACHE=`free -m|awk '{if(NR==2)printf "%.1f" ,$6/1024} END{print "G"}'`  				echo -e "Total: $MEM_TOTAL"  				echo -e "Use:$USE"  				echo -e "Free : $FREE"  				echo -e "Cache: $CACHE"  				echo "--------------------------"  				break  			;;  			tcp_status)  				# 网络连接状态  				COUNT=`ss -ant|awk '!/State/{status[$1]++}END{for(i in status) print i,status[i]}'`  				echo -e "TCP connection status:\n$COUNT"  				echo "--------------------------"  				break  			;;  			cpu_top10)  				# 占用CPU高的前10个进程  				CPU_LOG=/tmp/cpu_top.tmp  				i=1  				while [[ $i -le 3 ]];do  					ps aux|awk '{if(($3>0.1)){   {printf "PID:" $2  "CPU: " $3 "%--->"}for(i=11;i<=NF;i++)if((i==NF))printf $i"\n";else printf $i}}'|sort -k4 -nr|head -10 >> $CPU_LOG  					if [[ -n `cat $CPU_LOG` ]];then  						echo -e "\033[32m 参考值${i}\033[0m"  						cat $CPU_LOG  						>> $CPU_LOG ## 将文件清空  					else  						echo "No process using the CPU"  						break  					fi  					let i++  					sleep 1  				done  				echo "--------------------------"  				break  			;;  			mem_top10)  				# 占用内存高的前10个进程  				MEM_LOG=/tmp/mem_top.tmp  				i=1  				while [[ $i -le 3 ]];do  					ps aux|awk '{if(($3>0.1)){   {printf "PID:" $2  "MEM: " $4 "%--->"}for(i=11;i<=NF;i++)if((i==NF))printf $i"\n";else printf $i}}'|sort -k4 -nr|head -10 >> $MEM_LOG  					if [[ -n `cat $MEM_LOG` ]];then  						echo -e "\033[32m 参考值${i}\033[0m"  						cat $MEM_LOG  						>> $MEM_LOG ## 将文件清空  					else  						echo "No process using the Memory"  						break  					fi  					let i++  					sleep 1  				done  				echo "--------------------------"  				break  			;;  			traffic)  				# 查看网络流量  				while true;do  					read -p "Please enter the network card name(eth[0-9]) or em[0-9]: " eth  					if [ `ifconfig`| grep -c "\<$eth\>" -eq 1 ];then  						break  					else  						echo "Input format error or Do not have the card name,please input again"  					fi  					echo "--------------------------"  					echo -e "In ------- Out"  					i=1  					while [[ $i -le 3 ]];do  						OLS_IN=`ifconfig $eth |awk -F'[: ]+' '{/bytes/if(NR==8) print $4;else if(NR==5)print $6}'`  						OLS_OUT=`ifconfig $eth |awk -F'[: ]+' '{/bytes/if(NR==8) print $9;else if(NR==7)print $6}'`  						NEW_IN=`ifconfig $eth |awk -F'[: ]+' '{/bytes/if(NR==8) print $4;else if(NR==5)print $6}'`  						NEW_OUT=`ifconfig $eth |awk -F'[: ]+' '{/bytes/if(NR==8) print $9;else if(NR==7)print $6}'`  						IN=`awk 'BEGIN{printf "%.1f\n",'$((${   NEW_IN}-${   OLD_IN}))'/1024/128}'`  						OUT=`awk 'BEGIN{printf "%.1f\n",'$((${   NEW_OUT}-${   OLD_OUT}))'/1024/128}'`  						echo "${IN}MB/s ${OUT}MB/s"  						i=$(($i+1))  						sleep 1  					done  					echo "--------------------------"  					break  				done  			;;  			quit)  				exit 0  			;;  			*)  				echo "--------------------------"  				echo "Please enter the number"  				echo "--------------------------"  				break  			;;  			esac  		done  	done

脚本还支持自定义日志文件清空功能,便于持续监控系统状态。

关于脚本中的NR==3处理原因:

在vmstat命令输出中,NR表示当前的行数。由于vmstat通常显示5行,其中第3行包含了重要的系统状态信息(如CPU利用率、用户、系统、I/O等)。因此,脚本中使用NR==3来处理这行数据,以获取具体的性能指标。

关于文件利用率的解释:

每个文件会分配一个inode存储文件的元数据,而实际的文件内容则以块的形式存储在磁盘的数据区。无论是文件的元数据还是实际数据,都会占用磁盘空间。当inode或块都满的时候,磁盘空间就被利用满了。

grep -c的作用:

grep -c是grep命令的一个选项,它用于统计匹配项的数量。如果没有匹配项,grep -c会返回0;如果有匹配项,返回匹配的数量。

为啥要除以128?

网络带宽通常以Mbit/s为单位表示,但实际上可能需要除以8转换成标准的单位(如KB/s或B/s)。例如,家里的1M带宽实际上等于1024Kbit/s,而一个Byte等于8bit。因此,在计算网络流量时,通常需要将流量除以8来得到更标准的单位。

转载地址:http://xufzz.baihongyu.com/

你可能感兴趣的文章
OpenCV与AI深度学习 | 十分钟掌握Pytorch搭建神经网络的流程
查看>>
OpenCV与AI深度学习 | 基于GAN的零缺陷样本产品表面缺陷检测
查看>>
OpenCV与AI深度学习 | 基于OpenCV和深度学习预测年龄和性别
查看>>
OpenCV与AI深度学习 | 基于OpenCV实现模糊检测 / 自动对焦
查看>>
OpenCV与AI深度学习 | 基于Python和OpenCV将图像转为ASCII艺术效果
查看>>
OpenCV与AI深度学习 | 基于PyTorch实现Faster RCNN目标检测
查看>>
OpenCV与AI深度学习 | 基于PyTorch语义分割实现洪水识别(数据集 + 源码)
查看>>
OpenCV与AI深度学习 | 基于YOLO11的车体部件检测与分割
查看>>
OpenCV与AI深度学习 | 基于YoloV11自定义数据集实现车辆事故检测(有源码,建议收藏!)
查看>>
OpenCV与AI深度学习 | 基于YOLOv8 + BotSORT实现球员和足球检测与跟踪 (步骤 + 源码)
查看>>
OpenCV与AI深度学习 | 基于YOLOv8实现高级目标检测和区域计数
查看>>
OpenCV与AI深度学习 | 基于YOLOv8的停车对齐检测
查看>>
OpenCV与AI深度学习 | 基于YoloV8的药丸/片剂类型识别
查看>>
OpenCV与AI深度学习 | 基于YOLO和EasyOCR从视频中识别车牌
查看>>
OpenCV与AI深度学习 | 基于图像处理的火焰检测算法(颜色+边缘)
查看>>
OpenCV与AI深度学习 | 基于拉普拉斯金字塔实现图像融合(步骤 + 代码)
查看>>
OpenCV与AI深度学习 | 基于机器视觉的磁瓦表面缺陷检测方案
查看>>
OpenCV与AI深度学习 | 基于深度学习的轮胎缺陷检测系统
查看>>
OpenCV与AI深度学习 | 如何使用YOLO-World做目标检测
查看>>
OpenCV与AI深度学习 | 如何使用YOLOv9分割图像中的对象
查看>>