吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 1759|回复: 9
收起左侧

[其他原创] ansible实现内网纯命令行监控服务器资源,导出为MySQL数据

  [复制链接]
hades1998 发表于 2025-4-21 11:41
背景:纯内网环境无可用带图形化界面的主机,无浏览器工具,不部署zabbix等agent,需要实现监控服务器资源情况


实现:使用ansible,把监控脚本传到各个服务器上,然后每个服务器定时执行生成文件,再传回主服务器


监控脚本: usage.sh   (注意获取IP的部分 ip_address ,根据实际情况修改正则)
[Shell] 纯文本查看 复制代码
#!/bin/bash


check_ifconfig() {
    if ! command -v ifconfig &> /dev/null; then
        echo "Error: ifconfig command not found. Please install ifconfig."
        exit 1
    fi
	yum install -y net-tools
}


generate_count(){
# 设置日志文件路径
log_file="/home/ansible/count.log"

# 获取当前时间的小时部分
current_hour=$(date "+%H")

# 如果当前时间在0点之前,将执行次数重置为0
if [ "$current_hour" -lt "00" ]; then
  reset_execution_count=true
else
  reset_execution_count=false
fi
#echo "reset_execution_count :$reset_execution_count"

# 检查是否已存在日志文件,如果不存在则创建,并设置执行次数为0
if [ ! -e "$log_file" ]; then
  echo "my_variable: \"0\"" > "$log_file"
fi

# 从日志文件中读取执行次数
#read -r last_execution_count < "$log_file"
last_execution_count=$(awk -F'"' '{print $2}' "$log_file")
#echo "last_execution_count :$last_execution_count"

# 如果需要重置执行次数,则将执行次数设置为0
if [ "$reset_execution_count" = true ]; then
  new_execution_count=0
else
  # 否则,将执行次数加1
  new_execution_count=$(($last_execution_count + 1))
fi

#echo "new_execution_count :$new_execution_count"

# 将新的执行次数写入日志文件
echo "my_variable: \"${new_execution_count}\"" > "$log_file"

# 输出结果
#echo "日志文件已更新:my_variable: \"${new_execution_count}\""
}



# Function to convert bytes to terabytes with 2 decimal places
bytes_to_terabytes() {
    local bytes=$1
    awk -v bytes="$bytes" 'BEGIN { printf "%.2f", bytes / (1024 * 1024 * 1024) }'
   #awk -v bytes="$bytes" 'BEGIN { printf "%.2f", bytes / (1000 * 1000 * 1000) }'
}


# Function to convert bytes to terabytes with 2 decimal places
bytes_to_terabytes_df() {
    local bytes=$1
    #awk -v bytes="$bytes" 'BEGIN { printf "%.2f", bytes / (1024 * 1024 * 1024) }'
   awk -v bytes="$bytes" 'BEGIN { printf "%.2f", bytes / (1024 * 1024 * 1024 * 0.995) }'
}

# Function to convert bytes to terabytes with 2 decimal places
bytes_to_terabytes_mem() {
    local bytes=$1
    #awk -v bytes="$bytes" 'BEGIN { printf "%.2f", bytes / (1024 * 1024 * 1024 * 0.98) }'
   awk -v bytes="$bytes" 'BEGIN { printf "%.2f", bytes / (1000 * 1024 * 1024 * 0.98) }'
}

get_ip_address() {
    # Get the IP address of the system (assuming it is in the first line of the ifconfig output)
    ifconfig | grep -oP 'inet\s+\K[^\s]+' | head -n 1
}


# Function to get release version
get_release_version() {
    if [ -f /etc/os-release ]; then
        cat /etc/os-release | grep "PRETTY_NAME" | cut -d'"' -f2
    elif [ -f /etc/redhat-release ]; then
        cat /etc/redhat-release
    elif [ -f /etc/SuSE-release ]; then
        cat /etc/SuSE-release
    else
        echo "Unknown"
    fi
}

# Function to get detailed version number
get_detailed_version() {
    if [ -f /etc/debian_version ]; then
        cat /etc/debian_version
    elif [ -f /etc/redhat-release ]; then
        cat /etc/redhat-release
    elif [ -f /etc/alpine-release ]; then
        cat /etc/alpine-release
    elif [ -f /etc/SuSE-release ]; then
        cat /etc/SuSE-release
    # Add more distributions as needed
    else
        echo "Unknown"
    fi
}
# Function to get system information
get_system_info() {
	insertDate=$(date +"%Y-%m-%d %H:%M:%S")
    HOST_NAME=$(uname -n)
    KERNEL_VERSION=$(uname -r)
    RELEASE_VERSION=$(get_release_version)
    VERSION_NUMBER=$(get_detailed_version)
    ARCHITECTURE=$(uname -m)
	MAC=$(ip addr | grep -E 'inet 192\.168\.1\.[0-9]+' -B1 | grep -Eo 'link/ether [^ ]+' | awk '{print $2}')
    echo "#get system information ----------------------" >> ${filepath}/usage_${ip_address}_${currentDate}.sql
    echo "INSERT INTO system_info (ip_address,host_name, kernel_version, release_version, version_number, architecture,mac,insert_date) VALUES ('$ip_address','$HOST_NAME', '$KERNEL_VERSION', '$RELEASE_VERSION', '$VERSION_NUMBER', '$ARCHITECTURE','$MAC','$insertDate');" >> ${filepath}/usage_${ip_address}_${currentDate}.sql
}

get_cpu_usage() {
	insertDate=$(date +"%Y-%m-%d %H:%M:%S")
    #cpu的物理个数
    cpu_phy=`cat /proc/cpuinfo | grep "physical id" | wc -l`
    #echo "当前系统物理cpu为:$cpu_phy"
    #cpu的核心数
    cpu_core=`cat /proc/cpuinfo | grep "core" | wc -l`
    #echo "当前系统cpu核心数为:$cpu_core"
    #cpu的型号
    cpu_model=`cat /proc/cpuinfo | grep "model" | sed -n '2p' | awk -F : '{print $2}'`
    #echo "当前系统cpu型号是:$cpu_model"


    # Read the initial values from /proc/stat
    read -r cpu_user cpu_nice cpu_system cpu_idle cpu_iowait cpu_irq cpu_softirq <<< $(grep '^cpu ' /proc/stat | awk '{print $2, $3, $4, $5, $6, $7, $8}')

    # Sleep for a short duration
    sleep 5

    # Read the second set of values from /proc/stat
    read -r cpu_user2 cpu_nice2 cpu_system2 cpu_idle2 cpu_iowait2 cpu_irq2 cpu_softirq2 <<< $(grep '^cpu ' /proc/stat | awk '{print $2, $3, $4, $5, $6, $7, $8}')

    # Calculate CPU usage percentages
    total_first=$((cpu_user + cpu_nice + cpu_system + cpu_idle + cpu_iowait + cpu_irq + cpu_softirq))
    total_second=$((cpu_user2 + cpu_nice2 + cpu_system2 + cpu_idle2 + cpu_iowait2 + cpu_irq2 + cpu_softirq2))

    # Calculate the differences
    user_diff=$((cpu_user2 - cpu_user))
    nice_diff=$((cpu_nice2 - cpu_nice))
    system_diff=$((cpu_system2 - cpu_system))
    idle_diff=$((cpu_idle2 - cpu_idle))
    iowait_diff=$((cpu_iowait2 - cpu_iowait))
    irq_diff=$((cpu_irq2 - cpu_irq))
    softirq_diff=$((cpu_softirq2 - cpu_softirq))

    # Calculate the total CPU usage percentage
    total_diff=$((total_second - total_first))
    #cpu_usage=$((100 * (total_diff - idle_diff) / total_diff))
    cpu_usage=$(awk 'BEGIN{printf "%.2f",(('$total_diff' - '$idle_diff') / '$total_diff')*100}')
    #echo "CPU Usage: ${cpu_usage}%"
    echo "#get cpu information ----------------------" >> ${filepath}/usage_${ip_address}_${currentDate}.sql
    echo "INSERT INTO cpu_info (ip_address,host_name,cpu_physical, cpu_core, cpu_model, cpu_usage,insert_date) VALUES ('$ip_address','$hostname','$cpu_phy', '$cpu_core', '$cpu_model', '$cpu_usage','$insertDate');" >> ${filepath}/usage_${ip_address}_${currentDate}.sql
}



# Function to get disk information for each filesystem
get_disk_info() {
	insertDate=$(date +"%Y-%m-%d %H:%M:%S")
    all_capacity=0
    all_used=0
    all_unused=0
    echo "#get disk information ----------------------" >> ${filepath}/usage_${ip_address}_${currentDate}.sql
    df -T -B1 | sed 1d | egrep -v "tmpfs" | egrep -v "boot" > ${filepath}/tempfile
    while read -r filesystem type total_bytes used_bytes unused_bytes usage_percentage mount_point; do
        total_capacity=$(bytes_to_terabytes "$total_bytes")
        used_capacity=$(bytes_to_terabytes "$used_bytes")
        unused_capacity=$(bytes_to_terabytes "$unused_bytes")

        used_percentage=$(awk 'BEGIN{printf "%.2f",'$used_bytes'/'$total_bytes'*100}')
	#all_capacity=`expr $all_capacity+$total_bytes`
        all_capacity=$(($all_capacity + $total_bytes))
        all_used=$(($all_used + $used_bytes))
	all_unused=$(($all_unused + $unused_bytes))
	#echo "used_percentage: $used_percentage"
        #Output SQL insert statements for each disk
        echo "INSERT INTO disk_information (ip_address,host_name,mount_point,total_capacity, used_capacity, unused_capacity, usage_percentage,used_percentage,insert_date) VALUES ('$ip_address','$hostname','$mount_point',$total_capacity, $used_capacity, $unused_capacity, '$usage_percentage',$used_percentage,'$insertDate');" >> ${filepath}/usage_${ip_address}_${currentDate}.sql
    done <${filepath}/tempfile
    all_used_percentage=$(awk 'BEGIN{printf "%.2f",'$all_used'/'$all_capacity'*100}')
    all_capacity=$(bytes_to_terabytes "$all_capacity")
    all_used=$(bytes_to_terabytes "$all_used")
    all_unused=$(bytes_to_terabytes "$all_unused")
    #echo "all_capacity:$all_capacity ,all_used:$all_used,all_used_percentage:$all_used_percentage"
    #echo "all_capacity:$all_capacity ,all_used:$all_used,all_used_percentage:$all_used_percentage,all_unused:$all_unused"
    echo "INSERT INTO disk_information (ip_address,host_name,mount_point,total_capacity, used_capacity, unused_capacity,used_percentage,insert_date) VALUES ('$ip_address','$hostname','all',$all_capacity, $all_used, $all_unused,$all_used_percentage,'$insertDate');" >> ${filepath}/usage_${ip_address}_${currentDate}.sql
    rm -rf ${filepath}/tempfile
}

# Function to get disk type for each filesystem
get_disk_type() {
	insertDate=$(date +"%Y-%m-%d %H:%M:%S")
    echo "#get disk type ----------------------" >> ${filepath}/usage_${ip_address}_${currentDate}.sql
    lsblk -d -o name,rota | sed 1d > ${filepath}/tempdtfile
    while read -r name rota; do
        echo "INSERT INTO disk_type (ip_address,host_name,dfname,dftype,insert_date) VALUES ('$ip_address','$hostname','$name','$rota','$insertDate');" >> ${filepath}/usage_${ip_address}_${currentDate}.sql
    done <${filepath}/tempdtfile
   
    rm -rf ${filepath}/tempdtfile
}

# Function to get memory information
# Function to get memory information
get_memory_info1() {
    insertDate=$(date +"%Y-%m-%d %H:%M:%S")
    #total_memory=$(free -b | awk '/Mem:/ {print $2}')
    total_memory=$(bytes_to_terabytes "$(free -b | awk '/Mem:/ {print $2}')")
    #used_memory=$(free -g | awk '/Mem:/ {print $3}')
    used_memory=$(bytes_to_terabytes "$(free -b | awk '/Mem:/ {print $3}')")
    #unused_memory=$(free -g | awk '/Mem:/ {print $4}')
    unused_memory=$(bytes_to_terabytes "$(free -b | awk '/Mem:/ {print $4}')")
    memory_usage_percentage=$(awk -v used="$used_memory" -v total="$total_memory" 'BEGIN { printf "%.2f", used / total * 100 }')

    # Output SQL insert statement for memory
     echo "#get memory information ----------------------" >> ${filepath}/usage_${ip_address}_${currentDate}.sql
     echo "INSERT INTO memory_information (ip_address,host_name,total_memory, used_memory, unused_memory, memory_usage_percentage,insert_date) VALUES ('$ip_address','$hostname',$total_memory, $used_memory, $unused_memory, $memory_usage_percentage,'$insertDate');" >> ${filepath}/usage_${ip_address}_${currentDate}.sql
}

get_memory_info() {
	insertDate=$(date +"%Y-%m-%d %H:%M:%S")
    #total_memory=$(free -b | awk '/Mem:/ {print $2}')
    total_memory=$(bytes_to_terabytes_mem "$(free -b | awk '/Mem:/ {print $2}')")
    #unused_memory=$(free -g | awk '/Mem:/ {print $4}')
    unused_memory=$(bytes_to_terabytes_mem "$(free -b | awk '/Mem:/ {print $4}')")
	
	#used_memory=$(free -g | awk '/Mem:/ {print $3}')
    #used_memory=$(bytes_to_terabytes_mem "$(free -b | awk '/Mem:/ {print $3}')")
    used_memory=$(awk 'BEGIN {printf "%.2f",('$total_memory' - '$unused_memory')}')	
	
    memory_usage_percentage=$(awk -v used="$used_memory" -v total="$total_memory" 'BEGIN { printf "%.2f", used / total * 100 }')

    # Output SQL insert statement for memory
     echo "#get memory information ----------------------" >> ${filepath}/usage_${ip_address}_${currentDate}.sql
     echo "INSERT INTO memory_information (ip_address,host_name,total_memory, used_memory, unused_memory, memory_usage_percentage,insert_date) VALUES ('$ip_address','$hostname',$total_memory, $used_memory, $unused_memory, $memory_usage_percentage,'$insertDate');" >> ${filepath}/usage_${ip_address}_${currentDate}.sql
}


main() {
#ip_address=$(get_ip_address)
#注意修改获取ip地址的命令,可能获取到多个ip,需要根据情况修改
ip_address=$(ip addr | awk '/inet 192.168.1.[0-9]+\/24 / {split($2, a, "/"); print a[1]}')
currentDate=$(date +"%Y%m%d%H%M%S")
filepath=/home/ansible
hostname=$(uname -n)
# Output SQL statements for disk information
get_disk_info

# Output SQL statement for memory information
get_memory_info

get_system_info

get_cpu_usage

get_disk_type
}
declare -g ip_address
declare -g currentDate
declare -g filepath
declare -g hostname
main








ansible 脚本:  usageAll.yml
[Plain Text] 纯文本查看 复制代码
---
- name: Create Local Directory with Current Date
  hosts: groups
  gather_facts: true

  vars:
    local_base_directory: "/home/staryea/temp/ansibleResult/usageResult"
    ip: "{{ ansible_default_ipv4.address }}"
    current_date: "{{ ansible_date_time.date | regex_replace('-', '') }}"
# The system time of each server is inconsistent. Therefore, datetime cannot be used
    current_datetime: "{{ ansible_date_time.date | regex_replace('-', '') }}{{ ansible_date_time.hour }}{{ ansible_date_time.minute }}"
    pattern_rule: "usage_*_{{ current_date }}*.sql"  # Adjust the pattern rule based on your files
#    pattern_rule1: "usage_*_*.sql"
    local_directory: "{{ local_base_directory }}/{{ current_date }}"

  tasks:
    - name: Execute the script on the remote machine
      command: /home/ansible/usage.sh
      register: script_result
      ignore_errors: true  # Ignore errors if the script returns a non-zero exit code

    - name: Check if local directory exists
      stat:
        path: "{{ local_directory }}"
      register: dir_stat
      delegate_to: localhost
      run_once: true

    - name: Create local directory if it doesn't exist
      file:
        path: "{{ local_directory }}"
        state: directory
        mode: "0755"
      when: dir_stat.stat.exists == false
      delegate_to: localhost
      run_once: true

   # from remote fetch file
    - name: find remote files
      find:
        paths: /home/ansible/
        patterns: "{{ pattern_rule }}"
        age : -10m
      register: file_name

    - name: copy remote file
      fetch:
        src: "{{ item.path }}"
        dest: "{{ local_directory }}/"   # 本地ansible机器存放日志的目录
        flat: yes
      with_items: "{{ file_name.files }}"

#   merge all usage file
    - name: Gather a list of files matching the pattern
      find:
        paths: "{{ local_directory }}"
        patterns: "{{ pattern_rule }}"
        age : -10m
      register: found_files
      delegate_to: localhost
      run_once: true

    - name: Assemble files into a single file
      assemble:
        src: "{{ local_directory }}"
        dest: "{{ local_base_directory }}/allserver/usage_allserver_{{ current_date }}.sql"
      when: found_files.matched > 0  # Only run if files are found
      delegate_to: localhost
      run_once: true

#   rename allserver merge file
    - name: stat merge file
      stat: path="{{ local_base_directory }}/allserver/usage_allserver_{{ current_date }}.sql"
      register: file_stat
      delegate_to: localhost
      run_once: true
          
    - name: rename merge file use move
      command: mv {{ local_base_directory }}/allserver/usage_allserver_{{ current_date }}.sql {{ local_base_directory }}/allserver/usage_allserver_{{ current_datetime }}.sql
      when: file_stat.stat.exists
      delegate_to: localhost
      run_once: true

#  delete local usage file
    - name: find local today usage file
      find:
        paths: "{{ local_directory }}"
        patterns: "{{ pattern_rule }}"
      register: files_to_delete
      delegate_to: localhost
      run_once: true

    - name: remove local today usage file
      file:
        path: "{{ item.path }}"
        state: absent
      with_items: "{{ files_to_delete.files }}"
      delegate_to: localhost
      run_once: true

#    - name: 调试输出文件模式
#      debug:
#        var: pattern_rule




最后输出问SQL文件,表的创建文件也在附件中。


巡检相关.zip

5.19 KB, 下载次数: 21, 下载积分: 吾爱币 -1 CB

免费评分

参与人数 3吾爱币 +9 热心值 +2 收起 理由
苏紫方璇 + 7 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
lcg2014 + 1 能不能直接集中在一个网页上显示?
psliwei + 1 + 1 努力学习

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

onetwo888 发表于 2025-4-21 15:53

很实用,谢谢大佬!!!
boshi6319 发表于 2025-4-21 16:47
fanliansuo1 发表于 2025-4-21 18:43
lcg2014 发表于 2025-4-21 22:53
能不能直接显示在网页?
 楼主| hades1998 发表于 2025-4-22 09:30
lcg2014 发表于 2025-4-21 22:53
能不能直接显示在网页?

就是没有图形化和浏览器才用的这个,网页的话推荐直接部署hertzbeat 这一类的监控系统,这个也不需要agent,只需要部署在一台主服务上就行
lcg2014 发表于 2025-4-22 17:26
hades1998 发表于 2025-4-22 09:30
就是没有图形化和浏览器才用的这个,网页的话推荐直接部署hertzbeat 这一类的监控系统,这个也不需要agen ...

sql写到mysql,在启动web服务,把mysql内容在客户端显示就行。导出excel也行。hertzbeat太重了
renzhiming1216 发表于 2025-4-22 17:50
很实用运维人用得上!
 楼主| hades1998 发表于 2025-4-24 09:38
lcg2014 发表于 2025-4-22 17:26
sql写到mysql,在启动web服务,把mysql内容在客户端显示就行。导出excel也行。hertzbeat太重了

可以,找时间写一个页面
lcg2014 发表于 2025-4-24 14:59
hades1998 发表于 2025-4-24 09:38
可以,找时间写一个页面

主打一个轻量级自研自主可控
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - 52pojie.cn ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2026-4-18 06:58

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表