备份任务通知

接上一篇【低成本方案,数据备份至阿里云oss】
完成了数据自动化备份,使用自动化任务虽然好,但是我们不希望每次都去看运行是否正常,软路由下的openwrt系统中有一个开源server酱定时任务通知,但免费的只能发送几次消息,我想实现类似的任务通知。

使用什么通知呢??? 邮件,微信,或是QQ,最终我选择了telegram,使用过telegram就知道telegram的机器人有多强大了

如何创建一个telegram机器人??

我看到这个过程有点匪夷所思

1.首先创建一个群组,然后在群组里面邀请一个名称为"BotFather"的机器人

2.发起邀请链接后我就可以和这个叫做BotFather"的机器人开始对话

3.然后你可以根据它的提示制造一个机器人(还得是外国人会玩)

创建群组

dc5fa1ff28cf4474cb4be4f6f6eb5db

邀请BotFather

9dd2426efb0dbd799bfc8edefa9677e

发送邀请链接

f78d71ef356009d06de82f9dca44564

接着bot的制造者就发来了对话

f09d911b622d882415b20d40bd61051

我们可以看到在消息中有一个/newbot的选择 点击创建机器人

根据对话可以创建一个机器人,最后会获得一个API 我们需要保存这个API

如果您已经创建了一个Telegram机器人并获得了API Token,您可以使用此Token从Linux服务器发送消息到任何与您的机器人进行对话的Telegram用户。以下是一个简单的方法,使用curl从Linux命令行发送消息:

获取Chat ID:

  • 首先,您需要知道要发送消息的Telegram用户或群组的Chat ID。
  • 与您的机器人开始对话(只需发送一个简单的消息,如"Hello",这一步不可少,多发送几次)。
  • 访问以下URL,替换

    YOUR_API_TOKEN

    为您的API Token:

    https://api.telegram.org/botYOUR_API_TOKEN/getUpdates
  • 在返回的JSON中,查找chat对象,它应该有一个id字段。这就是需要的Chat ID。
  1. 使用curl发送消息:

    • 使用以下命令发送消息,替换

      YOUR_API_TOKEN

      为您的API Token,

      YOUR_CHAT_ID

      为您刚刚获取的Chat ID,

      YOUR_MESSAGE

      为您想发送的消息内容:

      curl -X POST "https://api.telegram.org/botYOUR_API_TOKEN/sendMessage" -d "chat_id=YOUR_CHAT_ID&text=YOUR_MESSAGE"

这样,您就可以从Linux命令行发送Telegram消息了。

小结:

创建好机器人以后会有一个API我们需要保存这个API,接着需要获取Chat ID,获取Chat ID之前必须与创建好的机器人对话,我们在有了API 和chat id 就可以使用特定语法发送消息了

编写一个自动话脚本验证

send_info.sh

运行该脚本之前需要安装一下bc

bc 是一个在Linux和UNIX-like系统中的命令行计算器。它支持任意精度的数学库和代数。bc stands for "basic calculator"。

sudo apt update
sudo apt install bc

该脚本获取系统频率,内存使用情况以及硬盘使用情况 将消息发送出去

#!/bin/bash

TOKEN="这里填写你的TOKEN"
CHAT_ID="填写你的CHAT_ID"

# 获取CPU运行频率
CPU_FREQ_MHZ=$(lscpu | grep "MHz" | awk '{print $3}')
CPU_FREQ_GHZ=$(echo "scale=1; $CPU_FREQ_MHZ/1000" | bc)
CPU_MSG="CPU Frequency: $CPU_FREQ_GHZ GHz"

# 获取内存使用情况
MEM_USED=$(free -m | grep Mem | awk '{print $3}')
MEM_TOTAL=$(free -m | grep Mem | awk '{print $2}')
MEM_MSG="Memory Usage: ${MEM_USED}MB/${MEM_TOTAL}MB"

# 获取硬盘大小
DISK=$(df -h / | tail -1 | awk '{print $3 "/" $2}')
DISK_MSG="Disk Usage: $DISK"

# 组合消息
MESSAGE="$CPU_MSG%0A$MEM_MSG%0A$DISK_MSG"

# 发送到Telegram
curl -s -X POST "https://api.telegram.org/bot$TOKEN/sendMessage" -d "chat_id=$CHAT_ID&text=$MESSAGE" > /dev/null

给予脚本执行权限

chmod +x send_info.sh

执行该脚本:

./send_info.sh

不出意外就可以接收一次消息了

接下来写一个自动化脚本定时执行

telegram.sh

#!/bin/bash

# 获取当前脚本的目录
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

# 询问用户选择执行的时间单位
while true; do
    read -p "你想按照哪个时间单位发送消息? (1. 分钟 2. 小时 3. 天) " unit_choice
    case $unit_choice in
        1) unit="分钟"; cron_unit="*"; break ;;
        2) unit="小时"; cron_unit="hour"; break ;;
        3) unit="天"; cron_unit="day"; break ;;
        *) echo "错误: 请输入 1, 2 或 3。" ;;
    esac
done

# 询问用户每隔多少时间单位发送消息
while true; do
    read -p "每隔多少$unit你想发送消息? " interval

    if [[ "$interval" =~ ^[0-9]+$ ]]; then
        case $cron_unit in
            "*") [[ $interval -ge 1 && $interval -le 59 ]] && break || echo "错误: 请输入一个在1到59之间的数字。" ;;
            "hour") [[ $interval -ge 1 && $interval -le 23 ]] && break || echo "错误: 请输入一个在1到23之间的数字。" ;;
            "day") [[ $interval -ge 1 && $interval -le 31 ]] && break || echo "错误: 请输入一个在1到31之间的数字。" ;;
        esac
    else
        echo "错误: 请输入一个有效的数字。"
    fi
done

# 根据用户选择的时间单位设置cron
case $cron_unit in
    "*") cron_time="*/$interval * * * *";;
    "hour") cron_time="0 */$interval * * *";;
    "day") cron_time="0 0 */$interval * *";;
esac

# 添加到cron
(crontab -l; echo "$cron_time $DIR/send_info.sh") | crontab -

echo "消息现在将每隔 $interval $unit 发送一次。"

给予脚本执行权限

chmod +x telegram.sh

执行该脚本:

./telegram.sh

image-20230917202053565

可以看到每隔一分钟机器人获取系统数据并发送了过来

image-20230917202103959

停止脚本

stop_telegram_sctipt.sh

#!/bin/bash

# 获取当前脚本的目录
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

# 从crontab中删除与send_message.sh相关的任务
crontab -l | grep -v "$DIR/send_info.sh" | crontab -

echo "已停止定时发送消息的任务。"

实际应用

我们需要每天在网站数据备份之后发送至阿里云oss,并将备份是否成功的消息发送到我的telegram

阿里云oss命令补充

查询存储桶的信息:使用ossutil的stat命令

ossutil stat oss://your_bucket_name

我的命令

ossutil stat oss://newbie-typora

image-20230917203645414

查询的数据是名为newbie-typora的OSS存储桶的元数据。以下是每个字段的解释:

  1. Name: 存储桶的名称,这里是newbie-typora
  2. Location: 存储桶所在的数据中心地域。这里是oss-cn-shenzhen,表示这个存储桶位于深圳。
  3. CreationDate: 存储桶的创建日期和时间。
  4. ExtranetEndpoint: 存储桶的外网访问点。您可以使用这个域名从互联网访问您的OSS存储桶。
  5. IntranetEndpoint: 存储桶的内网访问点。如果您在阿里云的VPC内有ECS实例,您可以使用这个域名在内网中访问您的OSS存储桶,这样可以节省数据传输费用。
  6. ACL: 存储桶的访问控制列表。这里是public-read,表示任何人都可以读取存储桶中的对象,但只有存储桶的拥有者可以写入。
  7. Owner: 存储桶的拥有者ID。
  8. StorageClass: 存储桶的存储类型。这里是Standard,表示这是标准存储。
  9. RedundancyType: 存储桶的冗余类型。这里是LRS,表示本地冗余存储。LRS会在同一数据中心内的多个设备上存储数据的多个副本。
  10. TransferAcceleration: 表示是否启用了OSS传输加速。这里是Disabled,表示未启用。
  11. CrossRegionReplication: 表示是否启用了跨地域复制。这里是Disabled,表示未启用。
  12. AccessMonitor: 表示是否启用了访问监控。这里是Disabled,表示未启用。

对于阿里云OSS,ossutil stat命令确实提供了存储桶的元数据,但它不直接提供存储桶的总大小。要获取存储桶的大小和对象数量,您需要使用ossutil du命令。

使用以下命令查询存储桶的大小和对象数量:

ossutil du oss://newbie-typora

这将返回存储桶的总大小(以字节为单位)和对象数量。

请注意,ossutil du可能需要一些时间来计算存储桶的大小,特别是当存储桶中有大量对象时。

image-20230917204245343

更多支持命令:https://help.aliyun.com/zh/oss/developer-reference/du?spm

ossutil du oss://newbie-typora --block-size GB

使用了ossutil du命令并添加了--block-size GB选项来查询newbie-typora存储桶的大小和对象数量,并要求结果以GB为单位显示。以下是返回数据的解释:

  1. storage class: 这是对象的存储类型。在这里,所有对象都是Standard存储类型。
  2. object count: 这是存储桶中的对象数量。您的存储桶中有639个对象。
  3. sum size(byte): 这是存储桶中所有对象的总大小,以字节为单位。您的存储桶中的对象总共占用了403,562,526字节。
  4. total object count: 存储桶中的总对象数量,与上面的object count相同。
  5. total object sum size: 存储桶中所有对象的总大小,与上面的sum size(byte)相同。
  6. total part count: 这是存储桶中所有未完成的多部分上传的部分数量。在这里,这个数量是0,表示没有未完成的多部分上传。
  7. total part sum size: 这是存储桶中所有未完成的多部分上传的部分的总大小。这里的大小是0,与上面的total part count相符。
  8. total du size(GB): 这是存储桶的总大小,包括所有对象和所有未完成的多部分上传的部分,以GB为单位。在这里,这个大小是0.3758GB,这是上面的sum size(byte)转换成GB后的结果。
  9. 2.566311(s) elapsed: 这表示查询操作花费了2.566311秒。

由此我们可以获取阿里云oss的使用空间,以及可以计算出剩余空间

oss共占用了403,562,526字节  = 0.3758G  
实际使用0.3758G

我们会把阿里云oss的存储信息也发送出去

如何知道发送至阿里云的几种状态,更新,文件未改变,不需要更新,失败

image-20230917230343970

以上的图片:

第一行表示Successd 总数6 成功6 跳过6,也就是不需要更新

第二行表示Successd 总数7 成功7 更新1 跳过6 也就是表示上传成功

由此我们可以这么判断 successb表示状态成功,通过是否有upload字段来表示更新成功

三种状态:

Successd 同时存在 upload 更新成功
有Successd 没有upload  文件一致不需要更新
没有Successd就只能是失败了

由此我们通过识别这些字段来判断

再获取oss的使用空间,我们购买的空间40G也可以算出来未使用的空间

最终脚本:

判断同步阿里云oss的状态,获取oss的使用与未使用空间以及系统频率以及内存硬盘大小

send_info.sh

#!/bin/bash

TOKEN="6538532918:AAES46sC5prigXRx821fr9p51AEjXdSFbAE"
CHAT_ID="6118519649"

# 同步第一个文件夹到OSS
SITE_SYNC_OUTPUT=$(ossutil cp -r --update /www/backup/site oss://newbie-typora/typecho_backups/ 2>&1)
SITE_SYNC_STATUS=$?

# 同步第二个文件夹到OSS
DB_SYNC_OUTPUT=$(ossutil cp -r --update /www/backup/database oss://newbie-typora/typecho_backups/ 2>&1)
DB_SYNC_STATUS=$?

# 判断同步结果
if [[ $SITE_SYNC_OUTPUT == *"Succeed"* && ($SITE_SYNC_OUTPUT == *"upload"* || $DB_SYNC_OUTPUT == *"upload"*) ]]; then
    SYNC_MSG="File sync to OSS was successful."
elif [[ $SITE_SYNC_OUTPUT == *"Succeed"* && $SITE_SYNC_OUTPUT == *"skip"* && $DB_SYNC_OUTPUT == *"skip"* ]]; then
    SYNC_MSG="No new files need to be synchronized."
else
    SYNC_MSG="File sync to OSS failed."
fi

# 获取OSS的使用空间
OSS_USAGE_OUTPUT=$(ossutil du oss://newbie-typora --block-size GB)
OSS_USED=$(echo "$OSS_USAGE_OUTPUT" | grep -oP 'total du size\(GB\):\K[0-9.]+')
OSS_TOTAL=40
OSS_UNUSED=$(echo "$OSS_TOTAL - $OSS_USED" | bc)

# 获取CPU运行频率
CPU_FREQ_MHZ=$(lscpu | grep "MHz" | awk '{print $3}')
CPU_FREQ_GHZ=$(echo "scale=1; $CPU_FREQ_MHZ/1000" | bc)
CPU_MSG="CPU Frequency: $CPU_FREQ_GHZ GHz"

# 获取内存使用情况
MEM_USED=$(free -m | grep Mem | awk '{print $3}')
MEM_TOTAL=$(free -m | grep Mem | awk '{print $2}')
MEM_MSG="Memory Usage: ${MEM_USED}MB/${MEM_TOTAL}MB"

# 获取硬盘大小
DISK=$(df -h / | tail -1 | awk '{print $3 "/" $2}')
DISK_MSG="Disk Usage: $DISK"

# 组合消息
MESSAGE="$SYNC_MSG%0A$CPU_MSG%0A$MEM_MSG%0A$DISK_MSG%0AOSS Used: $OSS_USED GB%0AOSS Unused: $OSS_UNUSED GB"

# 发送到Telegram
curl -s -X POST "https://api.telegram.org/bot$TOKEN/sendMessage" -d "chat_id=$CHAT_ID&text=$MESSAGE" > /dev/null

image-20230917233303714

接下来就可以使用自动化脚本每天执行了,为了验证这几天我先频繁一点吧,一个小时发送一次消息到telegram

image-20230917233706327

网站的搭建与维护终于告一段落了,差不多用了三四天的时间,接下来该为就业准备了

如果觉得我的文章对你有用,请随意赞赏