Linux服务器硬件资源采集脚本

使用Shell脚本采集Linux服务器CPU、内存、网卡、磁盘使用率,并将指标数据封装成JSON,通过UDP协议发送到指定服务

该指标采集脚本使用操作系统 crontab 定时任务每间隔五秒采集一次当前服务器的指标数据

#!/bin/bash

# 设置udp报文发送的IP和端口
sendip="192.168.0.20"
sendport="8888"

# 设置ifconfig命令的绝对路径
ifconfig=/usr/sbin/ifconfig

echo "----------------------------------- CPU -------------------------------------"
# 获取CPU使用率暂停时间(秒)
interval=1
# CPU核心
cpu_num=`cat /proc/stat | grep cpu[0-9] -c`

start_idle=()
start_total=()
cpu_rate=()


CPU_NUM=`grep "physical id" /proc/cpuinfo |sort |uniq |wc -l`	# /proc/cpuinfo CPU的相关配置信息
CPU_CORE_NUM=`grep "cores" /proc/cpuinfo |sort |uniq |awk '{print $4}'`
CPU_MODE=`grep "model name" /proc/cpuinfo |sort |uniq |awk -F: '{print $2}'`


cpu_info="{"
cpu_info=$cpu_info"\"cpu_num\":$CPU_NUM,"
cpu_info=$cpu_info"\"cpu_core_num\":$CPU_CORE_NUM,"
cpu_info=$cpu_info"\"cpu_mode\":\"$CPU_MODE\","

# 系统上下文切换次数 
ctxt=`cat /proc/stat | grep "ctxt" | awk '{print $2}'`
# 处于Runnable状态的进程个数
procs_running=`cat /proc/stat | grep "procs_running" | awk '{print $2}'`
# 处于等待I/O完成的进程个数
procs_blocked=`cat /proc/stat | grep "procs_blocked" | awk '{print $2}'`

cpu_info=$cpu_info"\"ctxt\":$ctxt,"
cpu_info=$cpu_info"\"procs_running\":$procs_running,"
cpu_info=$cpu_info"\"procs_blocked\":$procs_blocked,"

for((i=0;i<${cpu_num};i++))
{
	start=$(cat /proc/stat | grep "cpu$i" | awk '{print $2" "$3" "$4" "$5" "$6" "$7" "$8}')
	start_idle[$i]=$(echo ${start} | awk '{print $4}')
	start_total[$i]=$(echo ${start} | awk '{printf "%.f",$1+$2+$3+$4+$5+$6+$7}')
}
start=$(cat /proc/stat | grep "cpu " | awk '{print $2" "$3" "$4" "$5" "$6" "$7" "$8}')
start_idle[${cpu_num}]=$(echo ${start} | awk '{print $4}')
start_total[${cpu_num}]=$(echo ${start} | awk '{printf "%.f",$1+$2+$3+$4+$5+$6+$7}')
# 睡眠一段时间,计算与上次获取到的使用率差值
sleep ${interval}
# 循环所有的CPU核心,输出CPU使用率
cpu_usage_info="["
for((i=0;i<${cpu_num};i++))
{
	end=$(cat /proc/stat | grep "cpu$i" | awk '{print $2" "$3" "$4" "$5" "$6" "$7" "$8}')
	end_idle=$(echo ${end} | awk '{print $4}')
	end_total=$(echo ${end} | awk '{printf "%.f",$1+$2+$3+$4+$5+$6+$7}')
	idle=`expr ${end_idle} - ${start_idle[$i]}`
	total=`expr ${end_total} - ${start_total[$i]}`
	idle_normal=`expr ${idle} \* 100`
	cpu_usage=`expr ${idle_normal} / ${total}`
	cpu_rate[$i]=`expr 100 - ${cpu_usage}`
	# echo "CPU$i Rate : ${cpu_rate[$i]}%"
	# 拼接每个CPU的时间
	cpu_usage_info=$cpu_usage_info"{\"cpu_name\":\"cpu$i\", \"cpu_idle\":$idle, \"cpu_total\":$total, \"cpu_idle_normal\":$idle_normal, \"cpu_usage\":$cpu_usage, \"cpu_rate\":${cpu_rate[$i]}},"
}
end=$(cat /proc/stat | grep "cpu " | awk '{print $2" "$3" "$4" "$5" "$6" "$7" "$8}')
end_idle=$(echo ${end} | awk '{print $4}')
end_total=$(echo ${end} | awk '{printf "%.f",$1+$2+$3+$4+$5+$6+$7}')
idle=`expr ${end_idle} - ${start_idle[$i]}`
total=`expr ${end_total} - ${start_total[$i]}`
idle_normal=`expr ${idle} \* 100`
cpu_usage=`expr ${idle_normal} / ${total}`
cpu_rate[${cpu_num}]=`expr 100 - ${cpu_usage}`

cpu_usage_info=$cpu_usage_info"{\"cpu_name\":\"cpu\", \"cpu_idle\":$idle, \"cpu_total\":$total, \"cpu_idle_normal\":$idle_normal, \"cpu_usage\":$cpu_usage, \"cpu_rate\":${cpu_rate[${cpu_num}]}}"
cpu_usage_info=$cpu_usage_info"]"

cpu_info=$cpu_info"\"cpu_usage_info\":$cpu_usage_info"
cpu_info=$cpu_info"}"

echo "----------------------------------- Memory -------------------------------------"

mem_total=$(free -m | sed -n '2p' | awk '{print $2}')
mem_used=$(free -m | sed -n '2p' | awk '{print $3}')
mem_free=$(free -m | sed -n '2p' | awk '{print $4}')
mem_shared=$(free -m | sed -n '2p' | awk '{print $5}')
mem_buff=$(free -m | sed -n '2p' | awk '{print $6}')
mem_cached=$(free -m | sed -n '2p' | awk '{print $7}')
mem_rate=`echo "scale=2;$mem_used/$mem_total" | bc | awk -F. '{print $2}'`

mem_info="{\"mem_total\":$mem_total, \"mem_used\":$mem_used, \"mem_free\":$mem_free, \"mem_shared\":$mem_shared, \"mem_buff\":$mem_buff, \"mem_cached\":$mem_cached, \"mem_rate\":$mem_rate, \"unit\": \"MB\"}"


echo "----------------------------------- Disk -------------------------------------"

disk_info="["
DISK_DEV=`df -hP | grep '^/dev/*' | cut -d' ' -f1 | sort`
for disk in $DISK_DEV
do 
	dev=`df -Ph | grep $disk | awk '{print $1}'`
	disk_size=`df -Ph | grep $disk | awk '{print $2}'`
	disk_used=`df -Ph | grep $disk | awk '{print $3}'`
	disk_free=`df -Ph | grep $disk | awk '{print $4}'`
	disk_rate=`df -Ph | grep $disk | awk '{print $5}'`
	disk_mount=`df -Ph | grep $disk | awk '{print $6}'`
	#echo -e "$disk:\tdisk_size:$disk_size\tused:$disk_used\tdisk_free:$disk_free\tdisk_rate:$disk_rate\tdisk_mount:$disk_mount"
	disk_obj_info="{\"name\":\"$disk\", \"disk_mount\":\"$disk_mount\", \"disk_size\":\"$disk_size\",\"disk_used\":\"$disk_used\",\"disk_free\":\"$disk_free\", \"disk_rate\":\"$disk_rate\"},"
	disk_info=$disk_info$disk_obj_info
done
# 截取disk_info最后一位的, 
disk_info="${disk_info: 0 : ${#disk_info}-1 }]"
echo $disk_info




echo "----------------------------------- Net -------------------------------------"
# 网卡流量采集
net_info="["
# 获取所有网卡设备
#ethn=(`$ifconfig | grep flags|awk '{print $1}'|sed 's/://g'`)
# 不替换网卡设备后面的冒号【:】,否则容易出现xxx-1 xxx的现象,无法区分是哪个网卡设备
ethn=(`$ifconfig | grep flags|awk '{print $1}'`)
# 如果指定网卡,直接使用指定网卡内容
if [ "$1" != "" ];
then
  ethn=("$1")
fi

# 先采集网卡内的上行和下行流量信息
ethns=${#ethn[@]}
for ((i=0;i<${ethns};i++))
{
	RX_pre=$(cat /proc/net/dev | grep ${ethn[$i]} | sed 's/:/ /g' | awk '{print $2}')
	TX_pre=$(cat /proc/net/dev | grep ${ethn[$i]} | sed 's/:/ /g' | awk '{print $10}')
	# 睡眠1秒,计算网卡速率的差值
	sleep ${interval}
	RX_next=$(cat /proc/net/dev | grep ${ethn[$i]} | sed 's/:/ /g' | awk '{print $2}')
	TX_next=$(cat /proc/net/dev | grep ${ethn[$i]} | sed 's/:/ /g' | awk '{print $10}')
	
	# 获取上行和下行的带宽
	# rx receive  接收,下行流量
	# tx transmit 发送,上行流量
	RX=$((${RX_next}-${RX_pre}))
	TX=$((${TX_next}-${TX_pre}))
	
	# 计算bps
	
	
	RXMbps=$(echo $RX | awk '{print $1*8/1048576 }')
	TXMbps=$(echo $TX | awk '{print $1*8/1048576 }')
	RXKbps=$(echo $RX | awk '{print $1*8/1024 }')
	TXKbps=$(echo $TX | awk '{print $1*8/1024 }')
	# 实际Byte(字节)
	RXBYTE=$(printf %.2f $RX)
	TXBYTE=$(printf %.2f $TX)
	
	RXKB=$(echo $RX | awk '{print $1/1024 }')
	TXKB=$(echo $TX | awk '{print $1/1024 }')
	RXMB=$(echo $RX | awk '{print $1/1048576 }')
	TXMB=$(echo $TX | awk '{print $1/1048576 }')
	
	device=`echo ${ethn[$i]}|sed 's/://g'`
	device_ip=`ifconfig $device |grep "inet "|awk '{print $2}'`
	
	net_info=$net_info"{\"device\":\"${device}\", \"device_ip\":\"$device_ip\", \"RXMbps\":$RXMbps, \"TXMbps\":$TXMbps, \"RXKbps\":$RXKbps, \"TXKbps\":$TXKbps, \"RXByte\":$RXBYTE, \"TXByte\":$TXBYTE, \"RXKByte\":$RXKB, \"TXKByte\":$TXKB, \"RXMByte\":$RXMB, \"TXMByte\":$TXMB},"
}
net_info="${net_info: 0 : ${#net_info}-1 }]"

# 指标采集时间, 取当前操作系统的时间
collect_time=`date +%Y%m%d%H%M%S`

sendmsg="{\"cpu_info\":$cpu_info, \"mem_info\":$mem_info, \"disk_info\":$disk_info, \"net_info\": $net_info, \"collect_time\": $collect_time }"
echo $sendmsg

#echo $sendmsg > /dev/udp/sendip/$sendport
# 使用nc命令发送udp数据报到数据采集服务器 -4 使用IPv4,-u 使用udp数据报
echo $sendmsg | nc -4u  $sendip $sendport

-----------------------------------------------------------------------------------------------------------------------------------
----------------------------------------------------------  代码分割线  -----------------------------------------------------------
-----------------------------------------------------------------------------------------------------------------------------------
# !!!!下方代码写到操作系统的crontab文件中!!!!
# 每5秒钟调度一次当前脚本,由于linux定时机制是以分开始,所以采用下面每分钟间隔5秒执行一次硬件信息采集(脚本路径和名字根据自己的实际文件写)
*/1 * * * * sleep 5  && /opt/project/monitor/monitor.sh
*/1 * * * * sleep 10 && /opt/project/monitor/monitor.sh
*/1 * * * * sleep 15 && /opt/project/monitor/monitor.sh
*/1 * * * * sleep 20 && /opt/project/monitor/monitor.sh
*/1 * * * * sleep 25 && /opt/project/monitor/monitor.sh
*/1 * * * * sleep 30 && /opt/project/monitor/monitor.sh
*/1 * * * * sleep 35 && /opt/project/monitor/monitor.sh
*/1 * * * * sleep 40 && /opt/project/monitor/monitor.sh
*/1 * * * * sleep 45 && /opt/project/monitor/monitor.sh
*/1 * * * * sleep 50 && /opt/project/monitor/monitor.sh
*/1 * * * * sleep 55 && /opt/project/monitor/monitor.sh
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值