概述
smokeping 是一个开源免费的监控网络性能的工具,功能例如 ping、dig、echoping、curl 、dns等,绘制图形使用了 RRDtools 。
本文使用 docker 部署,操作比较简单,最主要的是收集全国各运营商的监测 IP ,以及维护这些 IP 的可用性,这里使用 Python 检测测试 IP 的可用性,并自动生成配置文件。
Smokeping 应用部署与配置
创建数据目录
# 创建存放smokeping数据的目录 mkdir -p /data/smokeping/config mkdir -p /data/smokeping/data
启动容器
docker create \ --name=smokeping \ -e PUID=1000 \ -e PGID=1000 \ -e TZ=Asia/Shanghai \ -p 80:80 \ -v /path/to/smokeping/config:/config \ -v /path/to/smokeping/data:/data \ --restart unless-stopped \ linuxserver/smokeping
修改检测时间间隔
这部分是修改 RRD 数据库的配置
vim /data/smokeping/config/Database *** Database *** step = 120 pings = 20 # 表示每 120 秒执行 20 次ping操作
修改 Targets 文件
Targets 是 ping 测试的目标对象,日常修改主要是这个,我们这里通过 Python 检测测试 IP 的可用性,并自动生成配置文件
Python 处理 Targets 文件
收集测试 IP
我主要是从 ipip.net收集的
收集全国电信、联通、移动的测试 IP
收集国外的测试 IP
将收集好的 IP 放到数据库
我用的是 PostgreSQL ,新建两张表,分别是 ip_test、ip_test_international
表结构如下图所示
收集完成后,记得备份 table,可使用如下 SQL 语句
create table ip_test as table backup_ip_test; create table ip_test_international as table backup_ip_test_international;
代码如下
将对代码分段解释其作用
使用到的模块的解释
# 导入所需的模块 import os import smtplib import datetime import psycopg2 from pypinyin import lazy_pinyin from email.utils import formataddr from email.mime.text import MIMEText
-
OS:执行 ping 操作
smtplib、email 相关模块:发送邮件使用
psycopg2:操作 PostgreSQL 数据库
Pypinyin:将汉字转换为拼音
定义一个邮件的列表
mail_down_ip_body = []
操作IP数据库,测试不通的设置为 is down
def ping_ip(): # 用 os.system ping 太慢了,可以优化一下,使用 python 封装 icmp,并使用多线程 conn = psycopg2.connect(dbname="数据库名称", user="数据库用户名", password="数据库密码", host="填写数据库地址", port="5432") cursor = conn.cursor() # 为节省时间,这里就不合并到一起了 cursor.execute("select china_unicom from ip_test;") ip_list_unicom = cursor.fetchall() for i in ip_list_unicom: response = os.system('ping -c 8 ' + i[0]) if response == 0: print(i[0], 'is up') else: print(i[0], 'is down') cursor.execute("select state, city from ip_test where china_unicom = (%s) and china_unicom != 'is down';", (i[0],)) china_unicom_down_name = cursor.fetchall() for z in china_unicom_down_name: mail_down_ip_body.append(('联通', z[0].rstrip() + z[1].rstrip(), i[0].rstrip())) cursor.execute("update ip_test set china_unicom = 'is down' where china_unicom = (%s);", (i[0],)) cursor.execute("select china_mobile from ip_test;") ip_list_mobile = cursor.fetchall() for i in ip_list_mobile: response = os.system('ping -c 8 ' + i[0]) if response == 0: print(i[0], 'is up') else: print(i[0], 'is down') cursor.execute("select state, city from ip_test where china_mobile = (%s) and china_mobile != 'is down';", (i[0],))