需求:单台服务器离线状态下,记录服务器24小时的资源占用情况,在出现偶发性程序崩溃问题时协助定位,单次问题排查(按需选择对应模块监控也行)。
思路:
不适用Prometheus等监控:
1、一个可以查询资源情况的脚本;
2、需要定时获取服务器资源信息;
3、需要日志记录有效信息。
资源查询脚本↓,记录到log,超过设定的阈值就会记录前几的进程(脚本可直接使用)
#!/bin/bash
# DeanL
timestamp=$(date +"%Y-%m-%d %H:%M:%S")
# 获取 CPU 使用率
cpu_usage=$(top -bn1 | grep "Cpu(s)" | awk '{print "CPU 使用率:" $2 + $4 "%"}')
# 获取内存使用情况
mem_usage=$(free -m | awk 'NR==2{printf "内存使用情况:已用 %sMB / 总计 %sMB (%.2f%%)\n", $3, $2, $3*100/$2 }')
# 判断 CPU 使用率是否超过 90%
cpu_percentage=$(top -bn1 | grep "Cpu(s)" | awk '{print $2 + $4}')
if (( $(echo "$cpu_percentage > 90" | bc -l) )); then
# 获取占用 CPU 最高的前五个进程,并加上换行符
highest_cpu_process=$(ps aux --sort=-%cpu | awk 'NR<=6 {if (NR>1) print "占用 CPU 第 " NR-1 " 的进程:" $11 " CPU 使用率:" $3 "%"}')
else
highest_cpu_process="CPU 使用率正常,不记录。"
fi
# 判断内存使用情况是否超过 90%
mem_percentage=$(free -m | awk 'NR==2{print $3/$2 * 100}')
if (( $(echo "$mem_percentage > 90" | bc -l) )); then
# 获取占用内存最高的前五个进程,并加上换行符
highest_mem_process=$(ps aux --sort=-%mem | awk 'NR<=6 {if (NR>1) print "占用内存第 " NR-1 " 的进程:" $11 " 内存使用率:" $4 "%"}')
else
highest_mem_process="内存使用率正常,不记录。"
fi
# 判断 GPU 显存使用率是否超过 95%(支持多张显卡)
if command -v nvidia-smi &> /dev/null
then
# 获取每张显卡的显存使用情况
gpu_usage=""; highest_gpu_process=""
num_gpus=$(nvidia-smi --list-gpus | wc -l) # 获取显卡数量
for gpu_index in $(seq 0 $((num_gpus - 1))) # 循环遍历所有显卡
do
# 获取每张显卡的显存使用情况
gpu_info=$(nvidia-smi --query-gpu=index,memory.total,memory.used --format=csv,noheader,nounits | sed -n "$((gpu_index + 1))p")
gpu_mem_percentage=$(echo "$gpu_info" | awk -F, '{print $3/$2 * 100}')
# 获取显存使用情况,并判断是否超过 95%
if (( $(echo "$gpu_mem_percentage > 95" | bc -l) )); then
highest_gpu_process+=$(nvidia-smi --query-compute-apps=pid,process_name,used_memory --format=csv,noheader | \
awk -v gpu_index="$gpu_index" '{print "GPU" gpu_index " 占用显存的进程:" $2 " 显存使用:" $3 "MiB"}')$'\n'
else
highest_gpu_process+="GPU$gpu_index 显存使用率正常,不记录。"$'\n'
fi
# 汇总显卡使用情况
gpu_usage+="GPU$gpu_index 显存使用:$gpu_info | "
done
else
gpu_usage="未检测到GPU或未安装驱动。"
highest_gpu_process="未检测到GPU。"
fi
# 输出到日志文件
echo -e "$timestamp - $cpu_usage | $mem_usage | $gpu_usage | $highest_cpu_process | $highest_mem_process | $highest_gpu_process" >> /home/get_resource_usage.log
EOF
# 日志样例
2024-11-06 14:02:00 - CPU 使用率:92.5% | 内存使用情况:已用 3400MB / 总计 8000MB (42.50%) | GPU0 使用率:35% 内存:2000MB / 4000MB |
占用 CPU 排名前 1 的进程:/usr/bin/python3 CPU 使用率:45.5%
占用 CPU 排名前 2 的进程:/usr/bin/java CPU 使用率:30.2%
占用 CPU 排名前 3 的进程:/bin/bash CPU 使用率:15.3%
占用 CPU 排名前 4 的进程:/usr/sbin/httpd CPU 使用率:10.5%
占用 CPU 排名前 5 的进程:/usr/bin/python3 CPU 使用率:9.1%
将任务加入到 crontab 中(脚本可根据自己的路径更改),每分钟执行一次,如果想要设定一周或者有限期间内脚本有效可以配合at命令进行设置!有需要可留言后续补充!
(crontab -l 2>/dev/null; echo "* * * * * /你的脚本路径/脚本名.sh") | crontab -
注:学而无境,共勉!@2024年11月6日