#!/usr/bin/env	bash
# author: Edison Y
# PATH设置


# 定义颜色样式
cat > style.html << EOF
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <style>
    .info { color: #00FF00; }
    .warning { color: #FFFF00; }
    .error { color: #FF0000; }
    .blue { color: #0000FF; }
  </style>
</head>
<body>
EOF

# 将日志输出重定向到HTML文件
{
    #echo "<p class='blue'>关键配置文件检查：</p>"
    
        # 获取JVM参数
    checkJVM(){
        jvm_params=$(ps aux | grep dhr.war | grep -v grep | awk '{for(i=1;i<=NF;i++) if($i ~ /^-Xmx/) print $i}')
        jvm_max=${jvm_params#-Xmx}

        # 获取系统内存信息(KB)
        total_mem=$(free | grep Mem | awk '{print $2}')
        free_mem=$(free | grep Mem | awk '{print $4}')

        # 转换为GB进行比较
        total_gb=$(echo "scale=1; $total_mem/1024/1024" | bc)
        free_gb=$(echo "scale=1; $free_mem/1024/1024" | bc)
        jvm_gb=${jvm_max%[gG]}

        echo "<p class='blue'>JVM配置及内存检查:</p>"
        echo "<p>总内存: ${total_gb}GB</p>" 
        echo "<p>可用内存: ${free_gb}GB</p>"
        echo "<p>当前JVM最大堆内存: ${jvm_gb}GB</p>"
        # 建议JVM内存设置为总内存的50%-75%
        suggested_min=$(echo "scale=0; $total_gb * 0.5 / 1" | bc)
        suggested_max=$(echo "scale=0; $total_gb * 0.75 / 1" | bc)

        echo -e "\nJVM内存配置建议:"
        if (( $(echo "$jvm_gb < $suggested_min" | bc -l) )); then
            echo "<p class='blue'>当前JVM内存配置偏小，建议调整为${suggested_min}GB - ${suggested_max}GB之间，具体建议详情参考如下文档</p>"
            echo "<a class="error" href="https://www.yuque.com/xiaolangua/xinshili2022/uuk9sgci5bgq5sic?singleDoc#" target="_blank">dhr2.0JVM参考配置建议</a>"
        elif (( $(echo "$jvm_gb > $suggested_max" | bc -l) )); then
            echo "<p class='blue'>当前JVM内存配置偏大，建议调整为${suggested_min}GB - ${suggested_max}GB之间，具体建议详情参考如下文档</p>"
            echo "<a class="error" href="https://www.yuque.com/xiaolangua/xinshili2022/uuk9sgci5bgq5sic?singleDoc#" target="_blank">dhr2.0JVM参考配置建议</a>"
        else
            echo "<p class='info'>当前JVM内存配置在合理范围内</p>" 
        fi

        if (( $(echo "$free_gb < 2" | bc -l) )); then
            echo "<p class='error'>可用内存警告: 系统可用内存不足2GB，建议检查内存使用情况</p>"
        fi
    }

    checkCFG(){
        echo -e "<p class='blue'> \ncfg配置文件比较结果: </p>"
        if [ ! -f "$cfg_file1" ]; then
            echo "<p class='error'>文件不存在: $cfg_file1 </p>"
            exit 1
        fi

        if [ ! -f "$cfg_file2" ]; then
            echo "<p class='error'>文件不存在: $cfg_file2 </p>"
            exit 1
        fi

        if cmp -s "$cfg_file1" "$cfg_file2"; then
            echo "<p class='info'>cfg.properties配置文件内容完全一致</p>"
        else
            echo "<p class='error'>cfg.properties配置文件内容不一致,差异如下:</p>"
            diff "$cfg_file1" "$cfg_file2" | while read line; do
                echo "<p> $line </p>"
            done
            echo "<p class='error'>建议使用 $cfg_file2 覆盖 $cfg_file1</p>"
        fi
    }

    checkServer(){
        echo -e "<p class='blue'> \ntomcat配置文件比较结果: </p>"
        if [ ! -f "$server_file1" ]; then
            echo "<p class='error'>文件不存在: $sever_file1 </p>"
            exit 1
        fi

        if [ ! -f "$server_file2" ]; then
            echo "<p class='error'>文件不存在: $server_file2 </p>"
            exit 1
        fi

        if cmp -s "$server_file1" "$server_file2"; then
            echo "<p class='info'>tomcat.properties配置文件内容完全一致</p>"
        else
            echo "<p class='error'>tomcat.properties配置文件内容不一致,差异如下:</p>"
            diff "$server_file1" "$server_file2" | while read line; do
                echo "<p> $line </p>"
            done
            echo "<p class='error'>建议使用 $server_file2 覆盖 $server_file1 </p>"
        fi
    
    }

    checkProcess(){
        echo "<hr>"
        echo -e "<p class='blue'> \n内存占用TOP3进程: </p>"
        ps aux --sort=-%mem | head -4 | tail -3 | while read user pid cpu mem vsz rss tty stat start time cmd; do
            echo "<p> 进程: $cmd </p>"
            echo "<p>内存使用率: $mem% </p>"
            echo "<p>PID: $pid </p>"
        done
    }

    checkCPU(){
        echo "<hr>"
        echo -e "<p class='blue'> \nCPU使用TOP3进程: </p>"
        cpu_usage=$(top -bn1 | grep "Cpu(s)" | awk '{print $2}')
        echo "<p>CPU使用率: ${cpu_usage}%</p>"
        
        echo -e "<p> \nCPU占用TOP3进程: </p>"
        ps aux --sort=-%cpu | head -4 | tail -3 | while read user pid cpu mem vsz rss tty stat start time cmd; do
            echo "<p>进程: $cmd </p>"
            echo "<p>CPU使用率: $cpu% </p>"
            echo "<p>PID: $pid </p>"
        done
    }

    checkFileHandles(){
        echo "<hr>"
        echo -e "<p class='blue'> \n文件句柄数限制检查: </p>"
        current_limit=$(ulimit -n)
        if [ "$current_limit" -eq 1024 ]; then
            echo "<p class='error'>当前文件句柄数限制为 $current_limit, 建议修改为65536</p>"
            echo "<p class='error'>可通过修改 /etc/security/limits.conf 文件来调整限制，具体建议详情参考如下文档</p>"
            echo "<a class="error" href="https://www.yuque.com/xiaolangua/xinshili2022/oncseh5g2c7iux5z?singleDoc#" target="_blank">dhr2.0服务器句柄数限制修改</a>"
        else
            echo "<p class='info'>当前文件句柄数限制为 $current_limit</p>"
        fi
    }

    checkDiskSpace(){
        echo "<hr>"
        echo -e "<p class='blue'> \n磁盘空间使用情况: </p>"
        df -h | grep -vE '^Filesystem|tmpfs|cdrom' | while read filesystem size used avail use mounted; do
            usage=${use%\%}
            if [ "$usage" -gt 80 ]; then
                echo "<p class='error'>警告: $mounted 分区使用率为 $use</p>"
                echo "<p class='error'>总空间: $size, 已使用: $used, 可用: $avail</p>"
            else
                echo "<p class='info'>$mounted 分区使用率为 $use</p>"
                echo "<p>总空间: $size, 已使用: $used, 可用: $avail</p>"
            fi
        done
    }

    checkMongoDB(){
        echo "<hr>"
        echo -e "<p class='blue'> \nMongoDB检查: </p>"
        
        # 查找mongodb相关进程并提取路径
        mongo_path=$(ps aux | grep -E 'mongodb|mongodb6' | grep -v grep | awk '{print $11}' | head -1)
        
        if [ -n "$mongo_path" ]; then
            # 使用sed提取路径中包含mongodb或mongodb6的部分，包括mongodb/mongodb6本身
            install_path=$(echo "$mongo_path" | sed 's/\(.*mongodb6\?\).*/\1/')
            if [ -n "$install_path" ]; then
                echo "<p>MongoDB安装路径: $install_path</p>"
                # 检查data_bak目录下的备份文件大小，端口，日志文件
                data_bak_path="${install_path}/data_bak"
                if [ -d "$data_bak_path" ]; then

                    # 检查MongoDB日志文件大小
                    log_path="${install_path}/logs"
                    if [ -d "$log_path" ]; then
                        echo "<p>MongoDB日志存放路径: $log_path </p>"
                        echo "<p>MongoDB日志文件大小检查:</p>"
                        find "$log_path" -type f -name "*.log" -exec du -m {} \; | while read size file; do
                            if [ "$size" -gt 300 ]; then
                                echo "<p class='error'>警告: 日志文件 ${file##*/} 大小为 ${size}MB,超过300MB,建议及时清理该文件，具体操作建议参考如下文档MongoDB部分</p>"
                                echo "<a class="error" href="https://www.yuque.com/xiaolangua/xinshili2022/iya3qduww07c5cb9?singleDoc#" target="_blank">dhr2.0数据库服务日志清理</a>"
                            else
                                echo "<p class='info'>日志文件 ${file##*/} 大小为 ${size}MB</p>"
                            fi
                        done
                        
                    else
                        echo "<p class='error'>日志目录 ${log_path} 不存在</p>"
                    fi

                    mongo_port=$(grep port $install_path/bin/mongod.cfg )
                        echo "<p class='info'> MongoDB端口 $mongo_port </p>"

                    du -sh "${data_bak_path}" 2>/dev/null | while read size file; do
                        echo "<p>MongoDB备份路径: ${file} </p>"
                        echo "<p class='info'>MongoDB总备份文件大小: ${size} </p>"
                    done

                    echo "<p>数据备份目录大小统计:</p>"
                    du -sh "${data_bak_path}"/* 2>/dev/null | while read size file; do
                        echo "<p>文件: ${file##*/}</p>"
                        echo "<p>大小: ${size}</p>"                        
                    done

                else
                    echo "<p class='error'>数据备份目录 ${data_bak_path} 不存在</p>"
                fi
            else
                echo "<p class='error'>未能从进程路径中提取MongoDB安装路径</p>"
            fi
        else
            echo "<p class='error'>未检测到MongoDB相关进程</p>"
        fi
    }

    # 检查PostgreSQL状态
    checkPostgreSQL(){
        echo "<hr>"
        echo "<p class='blue'>PostgreSQL检查:</p>"
        # 查找PostgreSQL进程
        pg_path=$(ps aux | grep /postgresql15 | grep -v grep | awk '{print $11}' | head -1)

        if [ -n "$pg_path" ]; then
            # 提取PostgreSQL安装路径
            install_path=$(echo "$pg_path" | sed 's/\(.*postgresql.*15\).*/\1/')
            if [ -n "$install_path" ]; then
                echo "<p>PostgreSQL安装路径: $install_path</p>"
                
                # 检查备份目录
                data_bak_path="${install_path}/data_bak"
                if [ -d "$data_bak_path" ]; then
                    # 检查日志文件
                    log_path="${install_path}/data/pg_log"
                    # 统计日志目录下所有日志文件总大小
                    if [ -d "$log_path" ]; then
                        echo "<p>PostgreSQL日志存放路径: $log_path </p>"
                        total_log_size=$(find "$log_path" -type f -name "*.log" -exec du -m {} \; | awk '{sum += $1} END {print sum}')
                        if [ -n "$total_log_size" ] && [ "$total_log_size" -gt 300 ]; then
                            echo "<p class='error'>警告: 日志目录总大小为 ${total_log_size}MB, 超过300MB, 建议及时清理日志文件，具体操作建议参考如下文档PostgreSQL部分</p>"
                            echo "<a class="error" href="https://www.yuque.com/xiaolangua/xinshili2022/iya3qduww07c5cb9?singleDoc#" target="_blank">dhr2.0数据库服务日志清理</a>"
                        else
                            echo "<p class='info'>日志目录总大小为 ${total_log_size}MB</p>"
                        fi
                    else
                        echo "<p class='error'>日志目录 ${log_path} 不存在</p>"
                    fi

                    # 检查PostgreSQL端口
                    pg_port=$(grep 'port =' ${install_path}/data/postgresql.conf | grep -v ^# | awk '{print $3}')
                    echo "<p class='info'>PostgreSQL端口: $pg_port</p>"

                    # 检查备份文件大小
                    du -sh "${data_bak_path}" 2>/dev/null | while read size file; do
                        echo "<p>PostgreSQL备份路径: ${file}</p>"
                        echo "<p class='info'>PostgreSQL总备份文件大小: ${size}</p>"
                    done

                    echo "<p>数据备份目录大小统计:</p>"
                    du -sh "${data_bak_path}"/* 2>/dev/null | while read size file; do
                        echo "<p>文件: ${file##*/}</p>"
                        echo "<p>大小: ${size}</p>"
                    done
                else
                    echo "<p class='error'>数据备份目录 ${data_bak_path} 不存在</p>"
                fi
            else
                echo "<p class='error'>未能从进程路径中提取PostgreSQL安装路径</p>"
            fi
        else
            echo "<p class='error'>未检测到PostgreSQL相关进程</p>"
        fi
    }

    # 检查磁盘挂载点和使用情况
    checkDiskMounts(){
        echo "<hr>"
        echo "<p class='blue'>挂载磁盘检查:</p>"
        
        # 检查/etc/fstab文件是否存在
        if [ ! -f "/etc/fstab" ]; then
            echo "<p class='error'>/etc/fstab文件不存在</p>"
            return
        fi

        echo "<p>fstab中配置的挂载点:</p>"
        
        # 从fstab中获取挂载点信息(排除注释行和swap)
        grep -v '^#' /etc/fstab | grep -v "swap" | while read -r device mountpoint fstype options dump fsck; do
            if [ -n "$mountpoint" ] && [ "$mountpoint" != "none" ]; then
                echo "<p>挂载点: $mountpoint</p>"
                
                # 获取该挂载点的磁盘使用情况
                df -h "$mountpoint" 2>/dev/null | tail -n 1 | while read filesystem size used avail use_percent mounted_on; do
                    echo "<p>文件系统: $filesystem</p>"
                    echo "<p>总大小: $size</p>"
                    echo "<p>已使用: $used</p>"
                    echo "<p>可用: $avail</p>"
                    echo "<p>使用率: $use_percent</p>"
                    
                    # 如果使用率超过80%，显示警告
                    use_percent_num=${use_percent%\%}
                    if [ "$use_percent_num" -gt 80 ]; then
                        echo "<p class='warning'>警告: 挂载点 $mountpoint 使用率超过80%</p>"
                    fi
                done
                echo "<hr>"
            fi
        done
    }

    main(){

        #sleep 1
        #checkCFG

        #sleep 1
        #checkServer

        #sleep 1
        #html 分割线 <hr>
        #echo "<hr>"
        #checkJVM

        sleep 1
        checkProcess

        sleep 1
        checkCPU
        
        sleep 1
        checkFileHandles

        sleep 1
        checkMongoDB

        sleep 1
        checkPostgreSQL

        sleep 1
        checkDiskMounts
        
        sleep 1

    }

    main

    echo "</body></html>"
} > log.html

# 合并样式和日志内容
cat style.html log.html > DBReport.html
rm style.html log.html

echo -e "\033[34m请从 $PWD 路径下载DBReport.html文件到本地,使用浏览器打开查看巡检结果\033[0m"

