Bootstrap

Redis监控 Prometheus + redis_exporter + Grafana 一键部署脚本

此脚本实现将目标 Redis(ip:port)定义到脚本变量一键部署配置
脚本执行后只需自行添加 Grafana 的仪表盘
执行脚本前先仔细阅读脚本注释
脚本执行所需安装包可以用我打包好的链接1 链接2
(是官网的包方便使用,包放到/root目录下就可以 包名:Monitoring_packages.tar)
如果想自己在官网下也可以,脚本里有注释但注意需要访问外网
(别忘了注释掉脚本里的tar xf Monitoring_packages.tar)

脚本执行会生成一个.out文件
快速理解脚本可以阅读我的另一篇文章:文章链接
文章最后面附上了脚本执行效果图

#!/bin/bash
#########################################################
# Function :deploy redis monitoring                     #
# Platform :linux centos 7                              #
# Date     :2024-04-07                                  #
# Author   :TJ                                          #
# Contact  :[email protected]                     #
#########################################################
# Installation versions: Prometheus-2.45.2, node_exporter-1.7.0, redis_exporter-1.47.0, grafana-enterprise-8.5.2
# Note: Root permissions are required to execute this script.
# Note: Before executing the script, you must define the NIC_PORT, TARGETS, and REDIS_PASSWORD variables.
#   NIC_PORT
#       - Information about the network interface card of the local server (e.g., ens33).
#         Define the NIC_PORT variable to automatically obtain the local server IP for service configuration.
#   TARGETS
#       - Combination of IP addresses and port numbers for each node in the Redis cluster (e.g., ip:port).
#         Define the TARGETS variable to automatically configure the scraping of Redis instances.
#       - The TARGETS variable can only define nodes within the same cluster.
#         If monitoring nodes in different clusters, separate configuration is needed after script execution.
#   REDIS_PASSWORD
#       - Authentication password for the Redis cluster.
# Note: After executing the script, Prometheus, node_exporter, redis_exporter, and Grafana will start by default.
# Note: After execution, you can directly access Prometheus to view the status and scraping metrics of node_exporter, redis_exporter, and the Redis cluster.

# Define a custom action function to implement the general action function
success() {
  echo -en "\\033[60G[\\033[1;32m  OK  \\033[0;39m]\r"
  return 0
}

failure() {
  local rc=$?
  echo -en "\\033[60G[\\033[1;31mFAILED\\033[0;39m]\r"
  [ -x /bin/plymouth ] && /bin/plymouth --details
  return $rc
}

action() {
  local STRING rc

  STRING=$1
  echo -n "$STRING "
  shift
  "$@" && success $"$STRING" || failure $"$STRING"
  rc=$?
  echo
  return $rc
}

# Check if the command executes the function
if_success() {
        if [ $? -eq 0 ]; then
                action "$1" /bin/true
        else
                action "$2" /bin/false
                exit 1
        fi
}

#############################################################################
# defined variable
#############################################################################
# define the network card to get the local server ip
NIC_PORT=''
# service open port
PROMMETHEUS_PORT='9099'
NODE_EXPORTER_PORT='9100'
REDIS_EXPORTER_PORT='9121'
# darker identification and distinction between different monitoring tasks
REDIS_JOB_NAME=业务-机房-redis模式-用途
# define namespaces to group instances
NAMEESPACE=业务-机房-redis模式-用途
# the target redis to be crawled
TARGETS='50.50.50.100:7000
50.50.50.100:7001
50.50.50.100:7002
50.50.50.100:7003
50.50.50.100:7004
50.50.50.100:7005'
# redis authenticates passwords
REDIS_PASSWORD=''



# confirm script execution conditions
Validate_and_Preparations() {
#############################################################################
# prepare the work, prepare the package, and create the installation directory
# because the packages are on github, you'll need to download them yourself and place them in the root directory
#   - prometheus-2.45.2.linux-amd64.tar.gz
#   - node_exporter-1.7.0.linux-amd64.tar.gz
#   - redis_exporter-v1.47.0.linux-amd64.tar.gz
#   - grafana-enterprise-8.5.2-1.x86_64.rpm
#############################################################################
cd /root
#URL="https://cdn1.easylink.cc/403fdm_Monitoring_packages.tar?e=1712827189&token=J_WyMIdhZtwb0E0QHWRqEfQrd5lVSWLffl9QxaxP:Tr0lBiPe73QCoMqYCaZuec8gxRQ="
#wget -O Monitoring_packages.tar "$URL" >/dev/null 2>&1
tar xf Monitoring_packages.tar
# download the prometheus-2.45.2.linux-amd64.tar.gz
#wget https://github.com/prometheus/prometheus/releases/download/v2.45.2/prometheus-2.45.2.linux-amd64.tar.gz
# download the node_exporter-1.7.0.linux-amd64.tar.gz
#wget https://github.com/prometheus/node_exporter/releases/download/v1.7.0/node_exporter-1.7.0.linux-amd64.tar.gz
# download the redis_exporter-v1.47.0.linux-amd64.tar.gz
#wget https://github.com/oliver006/redis_exporter/releases/download/v1.47.0/redis_exporter-v1.47.0.linux-amd64.tar.gz
# download the grafana-enterprise-8.5.2-1.x86_64.rpm
#wget https://dl.grafana.com/enterprise/release/grafana-enterprise-8.5.2-1.x86_64.rpm
FILES=(
"prometheus-2.45.2.linux-amd64.tar.gz"
"node_exporter-1.7.0.linux-amd64.tar.gz"
"redis_exporter-v1.47.0.linux-amd64.tar.gz"
"grafana-enterprise-8.5.2-1.x86_64.rpm")
for FILE in "${FILES[@]}"
do
    if [ ! -e "/root/$FILE" ];then
        echo "[ERROR] $FILE does NOT exist in root directory."
        exit 1
    fi
done
variables=(
"NIC_PORT"
"PROMMETHEUS_PORT"
"NODE_EXPORTER_PORT"
"REDIS_EXPORTER_PORT"
"REDIS_JOB_NAME"
"NAMEESPACE"
"TARGETS"
"REDIS_PASSWORD")
for var in "${variables[@]}"; do
    if [ -z "${!var}" ]; then
        echo "[ERROR] The variable $var is empty."
        exit 1
    fi
done
ip a | grep -w "^[0-9]" | awk -F '[ :]+' '{print $2}' | grep -w "$NIC_PORT" &>/dev/null || {
    echo "[ERROR] Network interface $NIC_PORT was not found." &&
    exit 1
}
# get the local server ip
LOCALHOST=$(ip a | grep -w $NIC_PORT | awk 'NR==2{print $2}' | awk -F "/" '{print $1}')
# creating an installation directory
if [ -d "/usr/local/prometheus" ]; then
    echo "[ERROR] The /usr/local/prometheus directory already exists."
    exit 1
else
    mkdir /usr/local/prometheus
fi
}
Validate_and_Preparations



#############################################################################
# define the function, call the function installation
#############################################################################
# deploying prometheus-2.45.2
#############################################################################
deploying_prometheus() {
local success=true
cd /root
tar -zxvf prometheus-2.45.2.linux-amd64.tar.gz &>> /root/MonitorInstall.out || success=false
mv prometheus-2.45.2.linux-amd64 /usr/local/prometheus/prometheus-2.45.2 || success=false
# configuring prometheus
cat > /usr/local/prometheus/prometheus-2.45.2/prometheus.yml << EOF
global:
  scrape_interval: 15s
  evaluation_interval: 15s

alerting:
  alertmanagers:
    - static_configs:
        - targets:

rule_files:

scrape_configs:
  - job_name: 'prometheus_$PROMMETHEUS_PORT'

    static_configs:
      - targets: ["$LOCALHOST:$PROMMETHEUS_PORT"]

  - job_name: 'node_exporter_$NODE_EXPORTER_PORT'
    static_configs:
      - targets: ['$LOCALHOST:$NODE_EXPORTER_PORT']

  # redis exporter
  - job_name: 'redis_exporter_$REDIS_EXPORTER_PORT'
    static_configs:
      - targets: ['$LOCALHOST:$REDIS_EXPORTER_PORT']


  - job_name: '$REDIS_JOB_NAME'
    file_sd_configs:
      - files:
        - redis_exporter_conf/redis.json
    metrics_path: /scrape
    relabel_configs:
      - source_labels: [__address__]
        target_label: __param_target
      - source_labels: [__param_target]
        target_label: instance
      - target_label: __address__
        replacement: $LOCALHOST:$REDIS_EXPORTER_PORT
EOF
mkdir /usr/local/prometheus/prometheus-2.45.2/redis_exporter_conf
# configuring hot loading files
TARGETS_REDIS_FILE=/usr/local/prometheus/prometheus-2.45.2/redis_exporter_conf/redis.json
cat > $TARGETS_REDIS_FILE << EOF
[
  {
    "targets": [
    "labels": {"namespace": "$NAMEESPACE"}
  }
]
EOF
for IP_PORT in $TARGETS
do
    sed -i "3s|$| \"redis://$IP_PORT\",|" $TARGETS_REDIS_FILE
done
sed -i '3s|,$| ],|' $TARGETS_REDIS_FILE
# add prometheus start
cat > /usr/lib/systemd/system/prometheus.service << EOF
[Unit]
Description=https://prometheus.io
[Service]
Restart=on-failure
ExecStart=/usr/local/prometheus/prometheus-2.45.2/prometheus \
 --storage.tsdb.path=/usr/local/prometheus/prometheus-2.45.2/data \
 --config.file=/usr/local/prometheus/prometheus-2.45.2/prometheus.yml \
 --web.listen-address=:$PROMMETHEUS_PORT
[Install]
WantedBy=multi-user.target
EOF
# set prometheus to start on boot
systemctl enable prometheus.service
if [[ "$success" == false ]]; then
    return 1
  else
    return 0
fi
}



#############################################################################
# install node_exporter-1.7.0
#############################################################################
install_node_exporter() {
local success=true
cd /root
tar -zxvf node_exporter-1.7.0.linux-amd64.tar.gz &>> /root/MonitorInstall.out || success=false
# add node_exporter start
mv node_exporter-1.7.0.linux-amd64 /usr/local/prometheus/node_exporter-1.7.0 || success=false
cat > /usr/lib/systemd/system/node_exporter.service << EOF
[Unit]
Description=Prometheus node_exporter
[Service]
User=root
ExecStart=/usr/local/prometheus/node_exporter-1.7.0/node_exporter \
  --web.listen-address=:$NODE_EXPORTER_PORT
ExecStop=/usr/bin/killall node_exporter
[Install]
WantedBy=default.target
EOF
# set node_exporter to start on boot
systemctl enable node_exporter.service
if [[ "$success" == false ]]; then
    return 1
  else
    return 0
fi
}



#############################################################################
# install redis_exporter-v1.47.0
#############################################################################
install_redis_exporter() {
local success=true
cd /root
tar -zxvf redis_exporter-v1.47.0.linux-amd64.tar.gz &>> /root/MonitorInstall.out || success=false
mv redis_exporter-v1.47.0.linux-amd64 /usr/local/prometheus/redis_exporter-1.47.0 || success=false
mkdir /usr/local/prometheus/redis_exporter-1.47.0/{logs,password_file,script} || success=false
# Configure the redis exporter connection authentication file
REDIS_PASSWORD_FILE=/usr/local/prometheus/redis_exporter-1.47.0/password_file/redis-password.json
cat > $REDIS_PASSWORD_FILE << EOF
{
}
EOF
for IP_PORT in $TARGETS
do
    sed -i "1a\\
    \"redis://$IP_PORT\": \"$REDIS_PASSWORD\"," $REDIS_PASSWORD_FILE
done
sed -i 'x; ${s/,$//;p;x}; 1d' $REDIS_PASSWORD_FILE
# add redis_exporter start script
REDIS_EXPORTER_START_SCRIPT=/usr/local/prometheus/redis_exporter-1.47.0/script/redis_exporter-${REDIS_EXPORTER_PORT}.sh
REDIS_ADDR=$(echo $TARGETS | awk '{print $1}')
cat > $REDIS_EXPORTER_START_SCRIPT << EOF
#!/bin/bash

INSTALL_PATH=/usr/local/prometheus/redis_exporter-1.47.0
PASSWORD_FILE=\$INSTALL_PATH/password_file/redis-password.json
LOG_FILE=\$INSTALL_PATH/logs/redis-${REDIS_EXPORTER_PORT}.out

REDIS_ADDR=$REDIS_ADDR
PORT=$REDIS_EXPORTER_PORT

nohup \$INSTALL_PATH/redis_exporter \
 -redis.addr \$REDIS_ADDR \
 -redis.password-file \$PASSWORD_FILE \
 -web.listen-address :\$PORT \
 > \$LOG_FILE &
EOF
chmod +x $REDIS_EXPORTER_START_SCRIPT
# set redis_exporter to start on boot
echo "/bin/sh $REDIS_EXPORTER_START_SCRIPT" >> /etc/rc.d/rc.local
chmod +x /etc/rc.d/rc.local
if [[ "$success" == false ]]; then
    return 1
  else
    return 0
fi
}



#############################################################################
# install grafana
#############################################################################
install_grafana() {
local success=true
cd /root
yum install -y epel-release &>> /root/MonitorInstall.out || success=false
yum install -y jq &>> /root/MonitorInstall.out || success=false
yum install -y grafana-enterprise-8.5.2-1.x86_64.rpm &>> /root/MonitorInstall.out || success=false
# set grafana to start on boot
systemctl enable grafana-server.service
if [[ "$success" == false ]]; then
    return 1
  else
    return 0
fi
}


# reuse the split line
reuse() {
echo -e "\033[35m--------------------------------------------------------------------------------------------------------------\033[0m"
}
# Function to display spinning animation
display_spin_animation() {
    local i=0
    local str=""
    local arry=("\\" "|" "/" "-")

    while [ $i -le 100 ]; do
        let index=i%4
        let color=42 && let bg=32
        printf "\033[${color};${bg}m%-s\033[0m %d %c\r" "$str" "$i" "${arry[$index]}"
        usleep 240000
        let i=i+1 && str+="#"
    done
    echo ""
}
#############################################################################
# call function to perform the installation
#############################################################################
reuse
# prometheus
Text1="prometheus     install success."
Text2="prometheus     install failure."
deploying_prometheus
if_success "${Text1[*]}" "${Text2[*]}"
# node_exporter
Text3="node_exporter  install success."
Text4="node_exporter  install failure."
install_node_exporter
if_success "${Text3[*]}" "${Text4[*]}"
# redis_exporter
Text5="redis_exporter install success."
Text6="redis_exporter install failure."
install_redis_exporter
if_success "${Text5[*]}" "${Text6[*]}"
# grafana
Text7="grafana        install success."
Text8="grafana        install failure."
install_grafana
if_success "${Text7[*]}" "${Text8[*]}"
chown root.root -R /usr/local/prometheus



#############################################################################
# starting the service
#############################################################################
# prometheus
Text9="prometheus     start success."
Text10="prometheus     start failure."
systemctl start prometheus.service
if_success "${Text9[*]}" "${Text10[*]}"
# node_exporter
Text11="node_exporter  start success."
Text12="node_exporter  start failure."
systemctl start node_exporter.service
if_success "${Text11[*]}" "${Text12[*]}"
# redis_exporter
Text13="redis_exporter start success."
Text14="redis_exporter start failure."
/bin/sh $REDIS_EXPORTER_START_SCRIPT &>/dev/null
if_success "${Text13[*]}" "${Text14[*]}"
# grafana
Text15="grafana        start success."
Text16="grafana        start failure."
systemctl start grafana-server.service
if_success "${Text15[*]}" "${Text16[*]}"



#############################################################################
# echo
#############################################################################
Install_info() {
reuse
# prometheus-2.45.2
echo -e "\033[32mprometheus\033[0m
\033[33m  Version\033[0m : 2.45.2
\033[33m  Path\033[0m    : /usr/local/prometheus/prometheus-2.45.2
\033[33m  Port\033[0m    : $PROMMETHEUS_PORT
\033[33m  State\033[0m   : $(ps aux | grep -w '[p]rometheus-2.45.2' &>/dev/null &&
  echo -e "\033[1;32mup\033[0;39m" ||
  echo -e "\033[1;31mdonw\033[0;39m")
\033[33m  Start\033[0m   : systemctl start prometheus.service\n"
# node_exporter-1.7.0
echo -e "\033[32mnode_exporter\033[0m
\033[33m  Version\033[0m : 1.7.0
\033[33m  Path\033[0m    : /usr/local/prometheus/node_exporter-1.7.0
\033[33m  Port\033[0m    : $NODE_EXPORTER_PORT
\033[33m  State\033[0m   : $(ps aux | grep -w '[n]ode_exporter-1.7.0' &>/dev/null &&
  echo -e "\033[1;32mup\033[0;39m" ||
  echo -e "\033[1;31mdonw\033[0;39m")
\033[33m  Start\033[0m   : systemctl start node_exporter\n"
# redis_exporter-1.47.0
echo -e "\033[32mredis_exporter\033[0m
\033[33m  Version\033[0m : 1.47.0
\033[33m  Path\033[0m    : /usr/local/prometheus/redis_exporter-1.47.0
\033[33m  Port\033[0m    : $REDIS_EXPORTER_PORT
\033[33m  State\033[0m   : $(ps aux | grep -w '[r]edis_exporter-1.47.0' &>/dev/null &&
  echo -e "\033[1;32mup\033[0;39m" ||
  echo -e "\033[1;31mdonw\033[0;39m")
\033[33m  Start\033[0m   : /usr/local/prometheus/redis_exporter-1.47.0/script/redis_exporter-${REDIS_EXPORTER_PORT}.sh\n"
# grafana-8.5.2
echo -e "\033[32mgrafana\033[0m
\033[33m  Version\033[0m : 8.5.2
\033[33m  Path\033[0m    : /etc/grafana
\033[33m  Port\033[0m    : 3000
\033[33m  State\033[0m   : $(ps aux | grep -w '[g]rafana' &>/dev/null &&
  echo -e "\033[1;32mup\033[0;39m" ||
  echo -e "\033[1;31mdonw\033[0;39m")
\033[33m  Start\033[0m   : systemctl start grafana.service\n"
reuse
}
Install_info

#############################################################################
# The Job information status is printed
#############################################################################
Job_name_statu_info() {
sleep 1
display_spin_animation
reuse
PROMETHEUS_URL="http://${LOCALHOST}:${PROMMETHEUS_PORT}/api/v1/query"
# Get all the job
JOB_NAMES=$(curl -s "${PROMETHEUS_URL}" -H 'Content-Type: application/x-www-form-urlencoded' -d 'query=up&timeout=30s' | jq -r '.data.result[].metric | "\(.job)"' | sort | uniq)
# Iterate over each job name and query the status
for JOB in $JOB_NAMES; do
    echo -e "\033[2;33mQuerying status for job:\033[0;39m \033[1;33m${JOB}\033[0;39m" && sleep 2
    curl -s "$PROMETHEUS_URL" \
      -H 'Content-Type: application/x-www-form-urlencoded' \
      -d "query=up{job=\"$JOB\"}" | jq -r '.data.result[].metric' && sleep 2
done
reuse
}
Job_name_statu_info



Target_redis_connection_info() {
echo -e "\033[1;32mPrint instance connection status...\033[0;39m" && sleep 3
reuse
PROMETHEUS_API_URL="http://${LOCALHOST}:${PROMMETHEUS_PORT}"
# Queries all instances under the specified job
INSTANCES=$(curl -s "${PROMETHEUS_API_URL}/api/v1/targets?state=active" | \
          jq -r ".data.activeTargets[] | select(.labels.job == \"$REDIS_JOB_NAME\") | .discoveredLabels.__address__")
# Output the instance and the corresponding redis up metrics
for INSTANCE in $INSTANCES; do
    INSTANCE_ENCODED=$(echo "$INSTANCE" | jq -s -R -r @uri)
    ESCAPED_URL=$(echo "curl -s \"${PROMETHEUS_API_URL}/api/v1/query?query=redis_up{instance%3D%22${INSTANCE_ENCODED}}\"" | \
                sed -e 's/{/%7B/g' -e 's/%0A}/%22%7D/g')
    REDIS_UP=$(eval ${ESCAPED_URL} | jq -r '.data.result[0].value[1]')

    if [ "${REDIS_UP}" = "1" ]; then
        echo "Instance: ${INSTANCE}, redis_up: ${REDIS_UP}$(success)"
    elif [ "${REDIS_UP}" = "0" ]; then
        echo "Instance: ${INSTANCE}, redis_up: ${REDIS_UP}$(failure)"
    else
        echo "Instance: ${INSTANCE}, unexpected response: ${REDIS_UP}$(failure)"
    fi
done
}
Target_redis_connection_info
reuse



#############################################################################
# clear script residue
#############################################################################
clear_script_residue() {
cd /root
rm -f ./prometheus-2.45.2.linux-amd64.tar.gz
rm -f ./node_exporter-1.7.0.linux-amd64.tar.gz
rm -f ./redis_exporter-v1.47.0.linux-amd64.tar.gz
rm -f ./grafana-enterprise-8.5.2-1.x86_64.rpm
#rm -f ./Monitoring_packages.tar
}
clear_script_residue

在这里插入图片描述

;