首页 > 系统相关 >我们开发了一个强大的 shell 脚本用于收集系统内存信息

我们开发了一个强大的 shell 脚本用于收集系统内存信息

时间:2025-01-21 12:56:53浏览次数:3  
标签:INFO shell LOG 收集 信息 内存 FILE proc DIR

在 Linux 系统管理中,监控内存使用情况至关重要。我们开发了一个强大的 shell 脚本用于收集系统内存信息。

该脚本以 /bin/bash 为解释器,首先创建 /var/log/meminfo_collector.log 日志文件,若创建失败则记录错误并终止,以方便后续追踪调试。

接着根据当前日期在 /root/kylin_shell 下创建存储目录,形如 /root/kylin_shell/meminfos_<日期>。然后切换到 /tmp 并创建临时信息目录。

脚本会检查 pstop 等关键命令是否存在,若不存在则记录错误并终止。

信息收集是核心,它从 /proc 文件系统读取多类信息,如 /proc/vmstat 等,还添加了 /proc/swaps/proc/buddyinfo 以深入了解内存使用情况。使用 ps 命令多种选项收集进程信息,包括进程树及资源使用,对内存使用量前 10 的进程,会深入 /proc/<PID>/status 获取详细状态。

同时,利用 toppidstatsar 等命令从不同角度收集系统性能数据,如 top -b -n 1 提供实时进程信息,pidstat -u -p ALL 1 2 按 1 秒间隔采样进程 CPU 使用率,sar 命令收集不同性能指标,free -h 以可读格式展示内存使用,vmstat 1 2 提供虚拟内存统计。

收集完成后,将临时信息目录打包成包含系统运行和当前时间的压缩文件,移动到存储目录并删除临时目录。最后设置存储目录 755 权限。

该脚本可通过 crontab 定时执行,例如 */1 * * * * /path/to/save_meminfos.sh > /dev/null 2>&1,将输出重定向到 /dev/null,仅将重要信息存于日志文件。

使用时,将脚本保存为 save_meminfos.sh,添加执行权限并运行,也可按上述方式添加到 crontab。此脚本有助于系统管理员监控管理内存,分析数据优化性能,保障系统稳定运行,其日志方便问题排查。

#!/bin/bash

# 定义日志文件
LOG_FILE="/var/log/meminfo_collector.log"

# 检查并创建日志文件
touch $LOG_FILE
if [ $? -ne 0 ]; then
    echo "无法创建日志文件 $LOG_FILE" >> $LOG_FILE
    exit 1
fi

# 检查并创建存储目录
DATE=$(date +%Y%m%d)
SAVE_DIR="/root/kylin_shell/meminfos_${DATE}"
if [! -d $SAVE_DIR ]; then
    mkdir -p $SAVE_DIR >> $LOG_FILE 2>&1
    if [ $? -ne 0 ]; then
        echo "无法创建存储目录 $SAVE_DIR" >> $LOG_FILE
        exit 1
    fi
else
    echo "目录 $SAVE_DIR 已经存在" >> $LOG_FILE
fi

# 切换到 /tmp 目录
pushd /tmp >> $LOG_FILE 2>&1
if [ $? -ne 0 ]; then
    echo "无法切换到 /tmp 目录" >> $LOG_FILE
    exit 1
fi

# 定义要收集的文件列表
FILES=("/proc/vmstat" "/proc/zoneinfo" "/proc/meminfo" "/proc/slabinfo" "/proc/pagetypeinfo" "/proc/swaps" "/proc/buddyinfo")
INFO_DIR="meminfos_$(date +%H%M%S)"
mkdir -p $INFO_DIR >> $LOG_FILE 2>&1
if [ $? -ne 0 ]; then
    echo "无法创建信息目录 $INFO_DIR" >> $LOG_FILE
    exit 1
fi

# 检查所需命令是否存在
COMMANDS=("ps" "top" "pidstat" "sar" "free" "vmstat")
for cmd in "${COMMANDS[@]}"; do
    if! command -v $cmd >/dev/null 2>&1; then
        echo "$cmd 命令不存在,无法完成信息收集" >> $LOG_FILE
        exit 1
    fi
done

# 收集 /proc 下的文件信息
for file in "${FILES[@]}"; do
    filename=$(basename $file)
    cat $file > $INFO_DIR/${filename} >> $LOG_FILE 2>&1
    if [ $? -ne 0 ]; then
        echo "无法将 $file 信息保存到 $INFO_DIR/${filename}" >> $LOG_FILE
        exit 1
    fi
done

# 收集 ps 信息
ps aux --sort=+rss > $INFO_DIR/ps_aux.txt >> $LOG_FILE 2>&1
if [ $? -ne 0 ]; then
    echo "无法保存 ps aux 信息" >> $LOG_FILE
    exit 1
fi
ps -eLo comm,pid,tid,psr,%cpu,%mem,rss,vsz,etimes > $INFO_DIR/ps_eLo.txt >> $LOG_FILE 2>&1
if [ $? -ne 0 ]; then
    echo "无法保存 ps -eLo 信息" >> $LOG_FILE
    exit 1
fi
ps axjf > $INFO_DIR/ps_axjf.txt >> $LOG_FILE 2>&1
if [ $? -ne 0 ]; then
    echo "无法保存 ps axjf 信息" >> $LOG_FILE
    exit 1
fi

# 收集 top 信息
top -b -n 1 > $INFO_DIR/top_info.txt >> $LOG_FILE 2>&1
if [ $? -ne 0 ]; then
    echo "无法保存 top 信息" >> $LOG_FILE
    exit 1
end

# 收集 pidstat 信息
pidstat -u -p ALL 1 2 > $INFO_DIR/pidstat_info.txt >> $LOG_FILE 2>&1
if [ $? -ne 0 ]; then
    echo "无法保存 pidstat 信息" >> $LOG_FILE
    exit 1
end

# 收集 sar 信息
sar -P ALL 1 2 > $INFO_DIR/sar_all_info.txt >> $LOG_FILE 2>&1
if [ $? -ne 0 ]; then
    echo "无法保存 sar -P ALL 信息" >> $LOG_FILE
    exit 1
end
sar -q 1 2 > $INFO_DIR/sar_q_info.txt >> $LOG_FILE 2>&1
if [ $? -ne 0 ]; then
    echo "无法保存 sar -q 信息" >> $LOG_FILE
    exit 1
end

# 收集 free 信息
free -h > $INFO_DIR/free_info.txt >> $LOG_FILE 2>&1
if [ $? -ne 0 ]; then
    echo "无法保存 free 信息" >> $LOG_FILE
    exit 1
end

# 收集 vmstat 信息
vmstat 1 2 > $INFO_DIR/vmstat_info.txt >> $LOG_FILE 2>&1
if [ $? -ne 0 ]; then
    echo "无法保存 vmstat 信息" >> $LOG_FILE
    exit 1
end

# 收集进程信息
mkdir -p $INFO_DIR/process_top10 >> $LOG_FILE 2>&1
if [ $? -ne 0 ]; then
    echo "无法创建进程信息目录 $INFO_DIR/process_top10" >> $LOG_FILE
    exit 1
end
for i in $(ps aux --sort=+rss|tail -n 10|awk '{print $2}'); do
    cat /proc/$i/status > $INFO_DIR/process_top10/proc_${i}_status.txt >> $LOG_FILE 2>&1
    if [ $? -ne 0 ]; then
        echo "无法保存进程 $i 的状态信息" >> $LOG_FILE
        exit 1
    end
end

# 打包文件
uptime_val=$(cat /proc/uptime | awk '{print $1}')
tar_filename="meminfos_${uptime_val}_$(date +%H%M%S).tar.gz"
tar zcvf $tar_filename $INFO_DIR >> $LOG_FILE 2>&1
if [ $? -ne 0 ]; then
    echo "无法将 $INFO_DIR 打包为 $tar_filename" >> $LOG_FILE
    exit 1
end

# 移动文件
mv $tar_filename $SAVE_DIR >> $LOG_FILE 2>&1
if [ $? -ne 0 ]; then
    echo "无法将 $tar_filename 移动到 $SAVE_DIR" >> $LOG_FILE
    exit 1
end

# 清理临时文件
rm -rf $INFO_DIR >> $LOG_FILE 2>&1
if [ $? -ne 0 ]; then
    echo "无法删除临时目录 $INFO_DIR" >> $LOG_FILE
    exit 1
end

# 设置存储目录权限
chmod -R 755 $SAVE_DIR >> $LOG_FILE 2>&1
if [ $? -ne 0 ]; then
    echo "无法设置 $SAVE_DIR 权限" >> $LOG_FILE
    exit 1
end

# 输出完成信息
echo "内存信息收集完成,存储在 $SAVE_DIR/$tar_filename" >> $LOG_FILE

# 回到原目录
popd >> $LOG_FILE 2>&1
if [ $? -ne 0 ]; then
    echo "无法回到原目录" >> $LOG_FILE
    exit 1
end

脚本功能解释

  1. 日志文件创建与错误处理

    • 首先,脚本会尝试创建一个日志文件 /var/log/meminfo_collector.log,用于记录脚本的操作和可能出现的错误。如果创建失败,会将错误信息写入该文件并退出脚本,以确保后续的操作可以被追踪和调试。
  2. 存储目录操作

    • 根据当前日期生成存储目录 SAVE_DIR(例如 /root/kylin_shell/meminfos_20250121),如果该目录不存在,则创建它,同时将操作结果记录到日志文件中;如果目录已经存在,也会记录相应信息。
  3. 切换目录与信息目录创建

    • 切换到 /tmp 目录并创建一个以当前时分秒命名的信息目录 INFO_DIR(例如 meminfos_123456),用于临时存储收集到的信息。任何操作失败都会记录到日志文件并退出脚本。
  4. 命令检查

    • 检查 pstoppidstatsarfreevmstat 等命令是否存在,若不存在会记录错误信息并退出脚本,确保后续操作不会因缺少命令而中断。
  5. 信息收集

    • /proc
      

      文件系统收集多种信息:

      • /proc/vmstat/proc/zoneinfo/proc/meminfo/proc/slabinfo/proc/pagetypeinfo/proc/swaps/proc/buddyinfo 等文件中读取信息并存储到 INFO_DIR 下的相应文件中。

      • 使用

        ps
        

        命令收集进程信息:

        • ps aux --sort=+rss 按内存使用量对进程排序并保存结果。
        • ps -eLo comm,pid,tid,psr,%cpu,%mem,rss,vsz,etimes 收集更详细的进程信息,包括进程的命令、进程 ID、线程 ID、处理器编号、CPU 使用率、内存使用率、实际内存使用、虚拟内存大小和进程运行时间等。
        • ps axjf 输出进程树信息,有助于查看进程间的关系。
    • 使用 top -b -n 1 以批处理模式运行一次 top 命令,收集系统的实时进程信息。

    • 使用 pidstat -u -p ALL 1 2 收集进程的 CPU 使用率信息,每 1 秒采样一次,共采样 2 次。

    • 使用 sar -P ALL 1 2 收集每个 CPU 的性能数据,每 1 秒采样一次,共采样 2 次;sar -q 1 2 收集系统的平均负载信息,每 1 秒采样一次,共采样 2 次。

    • 使用 free -h 以人类可读的格式显示系统的内存使用情况。

    • 使用 vmstat 1 2 收集系统的虚拟内存统计信息,每 1 秒采样一次,共采样 2 次。

    • 对于内存使用量最大的前 10 个进程,收集它们的 /proc/<PID>/status 信息并存储在 process_top10 目录下。

  6. 文件打包、移动和清理

    • 使用 tar 命令将 INFO_DIR 目录打包成一个以系统运行时间和当前时间命名的压缩文件,例如 meminfos_12345.123456.tar.gz
    • 将打包文件移动到存储目录 SAVE_DIR 中,并将操作结果记录到日志文件。
    • 删除临时的 INFO_DIR 目录,避免残留临时文件。
  7. 权限设置和完成信息

    • 为存储目录 SAVE_DIR 及其内容设置 755 权限,以确保文件的安全性和可访问性。
    • 最后,将完成信息记录到日志文件中并回到原目录。

三、文章

《系统内存信息收集脚本的实现与优化》

在 Linux 系统管理和性能监控中,了解系统的内存使用情况是至关重要的。为了方便、全面且可靠地收集系统内存相关信息,我们开发了一个功能强大的 shell 脚本。这个脚本可以帮助系统管理员深入分析系统的内存使用模式、进程的内存消耗情况以及系统的性能表现,为性能优化和故障排除提供了有力的数据支持。

该脚本以 /bin/bash 为解释器,在开始时,它会尝试创建一个日志文件 /var/log/meminfo_collector.log。这个日志文件是整个脚本的重要部分,它会记录脚本执行过程中的每一个重要步骤和可能出现的错误信息,方便后续的查看和分析。如果在创建日志文件时出现问题,脚本会立即终止并将错误信息记录在日志中,防止可能出现的错误操作被忽略。

接着,脚本会根据当前日期创建一个存储目录,存储目录位于 /root/kylin_shell 下,以 meminfos_<日期> 的形式命名,例如 /root/kylin_shell/meminfos_20250121。这有助于将不同日期的信息分类存储,方便查找和对比。

然后,脚本会切换到 /tmp 目录并创建一个临时信息目录,该目录的名称包含当前的时分秒,确保其唯一性。在进行信息收集之前,会检查一些常用的系统命令,如 pstoppidstatsarfreevmstat 是否存在,若这些命令不存在,脚本会在日志中记录错误信息并终止,因为这些命令是收集关键信息所必需的。

信息收集是该脚本的核心部分。它会从 /proc 文件系统中读取众多信息,这些 /proc 文件包含了系统运行时的内核数据,如 /proc/vmstat 提供了系统的虚拟内存统计信息,/proc/zoneinfo 展示了内存区域的信息,/proc/meminfo 包含了系统内存使用的总体信息等。此外,还收集了 /proc/swaps/proc/buddyinfo 这些额外的文件信息,/proc/swaps 可以让我们了解交换分区的使用情况,而 /proc/buddyinfo 则有助于我们查看内存碎片信息,这些信息对于理解系统的内存管理和性能优化都非常重要。

在进程信息收集方面,使用 ps 命令的多个选项,不仅能获取进程的常规信息,还能收集到进程的详细信息,包括进程的资源使用、线程信息以及进程树信息。例如,ps -eLo comm,pid,tid,psr,%cpu,%mem,rss,vsz,etimes 提供了进程的详细资源使用情况,ps axjf 展示了进程的层次结构,这对于分析进程之间的关系和资源分配非常有帮助。同时,对于内存使用量最高的前 10 个进程,会深入到它们的 /proc/<PID>/status 文件中,获取更详细的进程状态信息。

为了更全面地了解系统性能,使用 toppidstatsar 命令进行多维度的信息收集。top -b -n 1 可以提供系统实时的进程信息,pidstat -u -p ALL 1 2 能够以 1 秒为间隔采样 2 次进程的 CPU 使用率,sar -P ALL 1 2sar -q 1 2 分别从不同角度反映了系统的性能指标,而 free -h 以人类可读的方式展示系统的内存使用情况,vmstat 1 2 则从虚拟内存统计的角度提供系统性能数据。

收集完信息后,会将临时信息目录下的所有信息打包成一个压缩文件,文件名包含系统的运行时间和当前时间,确保每个打包文件都有独特的标识。随后将该压缩文件移动到存储目录中,并删除临时信息目录,避免占用 /tmp 空间。最后,为存储目录设置 755 权限,确保其内容可以被有权限的用户访问和管理。

该脚本还可以通过 crontab 进行定时执行,例如使用 */1 * * * * /path/to/save_meminfos.sh > /dev/null 2>&1 可以让脚本每分钟运行一次,这样系统管理员可以根据自己的需求设置不同的时间间隔,定期收集系统内存信息。通过将输出重定向到 /dev/null,避免在执行过程中产生过多的终端输出,仅将重要信息存储在日志文件中。

总的来说,这个脚本是一个全面、可靠且易于维护的系统内存信息收集工具,通过不断优化和扩展,它可以满足不同场景下的系统监控需求,为系统管理员提供丰富的信息资源,帮助他们更好地维护系统的性能和稳定性。

使用说明

  1. 将上述脚本保存为一个文件,例如 save_meminfos.sh
  2. 确保该脚本有执行权限,可以使用 chmod +x save_meminfos.sh 命令添加权限。
  3. 运行脚本可以直接使用 ./save_meminfos.sh
  4. 可以将脚本添加到 crontab 中进行定时执行,将 /path/to/save_meminfos.sh 替换为实际脚本的存储路径,例如:
#crontab -e
*/1 * * * * /path/to/save_meminfos.sh > /dev/null 2>&1

标签:INFO,shell,LOG,收集,信息,内存,FILE,proc,DIR
From: https://blog.csdn.net/qq_40797754/article/details/145281481

相关文章

  • finalshell远程连接Centos虚拟机配置固定ip地址
    为虚拟机Centos的远程连接软件Finalshell或者xshell等软件配置固定ip地址提示:然后全点确定,就好了,这里就不演示了输入指令vim/etc/sysconfig/network-scripts/ifcfg-ens33BOOTPROTO=static#将ip设置为静态IPADDR="192.168.142.130"#静态ip地址,这个130是在0-254......
  • 基于goland的WebShell检测设计于研究
    摘要随着互联网在我们生活中被广泛应用到社交、金融、行政以及办公等领域,网络安全的问题也越来越被重视。WebShell的本质是一种Web应用脚本程序,由于其可以通过HTTP协议的方式对服务器进行控制,故常被黑客用于植入到被入侵的系统中,严重威胁到主机的安全。本文针对现有的WebSh......
  • 内存字符串有关问题
    问题一:#include<iostream>#include<cstdint>#include<cstring>usingnamespacestd;typedefstructdata{charhwid[4];charsip[4];charrev[4];}Data;intmain(){Datastdata;memset(&stdata,0,sizeof(stdata));......
  • Java类加载机制与JVM运行时数据区各逻辑内存区域与JDK的版本相关差异浅谈
    Java类加载机制与JVM运行时数据区各逻辑内存区域与JDK的版本相关差异浅谈 【摘要】JVM(JavaVirtualMachine)作为Java研发人员工作的每天都会接触到的虚拟机,其运行机制与底层原理想必大家都略知一二,今天我将从初学者的角度出发,结合甲骨文官方的技术文档,对部分Java虚拟机的相关......
  • finalshell远程连接Centos虚拟机配置固定ip地址
    为虚拟机Centos的远程连接软件Finalshell或者xshell等软件配置固定ip地址提示:然后全点确定,就好了,这里就不演示了输入指令vim/etc/sysconfig/network-scripts/ifcfg-ens33BOOTPROTO=static#将ip设置为静态IPADDR="192.168.142.130"#静态ip地址,这个130是在0-254......
  • Shell SpringBoot 操作
    通过shell脚本来操作SpringBoot,检查程序是否在运行,启动程序,停止程序,重启程序,输出程序状态#!/bin/bash#这里可替换为你自己的执行程序,其他代码无需更改APP_NAME="$2"APP_DIR=/application#APP_DIR=`pwd`#使用说明,用来提示输入参数usage(){echo"Usage:shxxx.sh[......
  • 02内存结构篇(D2_剖析运行数据区)
    目录学习前言一、程序计数器1.作用2.存储的数据3.异常三、Java虚拟机栈1.栈帧1.1.局部变量表存储内容存储容量其他1.2.操作数栈作用存储内容存储容量1.3.动态连接1.4.方法返回1.5.附加信息2.栈异常四、本地方法栈1.本地方法1.1.什么是本地......
  • 02内存结构篇(D1_自动内存管理)
    目录一、内存管理1.C/C++程序员2.Java程序员二、运行时数据区1.程序计数器2.Java虚拟机栈3.本地方法栈4.Java堆5.方法区运行时常量池三、Hotspot运行时数据区四、分配JVM内存空间分配堆的大小分配方法区的大小分配线程空间的大小一、内存管理1.C/C......
  • Java几种常见的内存溢出及其解决方法
    java.lang.OutOfMemoryError:Javaheapspacejava.lang.OutOfMemoryError:GCoverheadlimitexceededjava.lang.OutOfMemoryError:Unabletocreatenewnativethreadjava.lang.StackOverflowError微信扫码查看:JAVA基础之内存机制.pptx......
  • 第八章(下) 内存管理系统
    第八章(下)内存管理系统本文是对《操作系统真象还原》第八章学习的笔记,欢迎大家一起交流。在上一节中,我们实现了位图的定义以及相关操作,这节中我们要继续完善内存管理系统,最终实现malloc函数,拆分成两个步骤就是内存池的初始化以及内存分配的实现。内存池的初始化本节我们将规划......