☰
只用Python标准库搭建IP黑名单数据可观测性:ipblocklist统计stats与历史history机制详解
2026/10/23 17:40:07 网站建设 项目流程

【免费下载链接】ipblocklist

IP lists full of bad IPs - Updated every 2H

项目地址:https://gitcode.com/gh_mirrors/ip/ipblocklist
点击查看免费下载

开源项目 ipblocklist 是一个每 2 小时自动聚合更新的 IP 黑名单(inbound/outbound 双列表)项目。更难得的是,它没有引入任何第三方库,仅凭 Python 标准库和两个脚本,就为整条数据管道搭起了完整的数据可观测性:每次运行生成带时间戳的 stats 统计快照,再滚动聚合出每日趋势文件 history.json,让“黑名单规模变化”全程可见。本文带你完整拆解这套 stats 与 history 机制的设计与实现。

为什么 IP 黑名单需要数据可观测性?

ipblocklist 聚合了数十个外部威胁情报源(Spamhaus、blocklist.de、Tor 出口节点等),合并去重后产出两份名单:

文件用途当前规模
inbound.txt入站拦截:恶意扫描、爆破、僵尸网络来源 IP约 464 万行
outbound.txt出站拦截:C2 服务器、钓鱼站点等恶意目的地 IP约 9.2 万行

对于这种“数据来自几十家外部源、每 2 小时全量重算”的项目,可观测性回答的是三个关键问题:

  1. 📊每次更新抓到了多少数据?—— 有没有源悄悄失效、数据断崖下跌?
  2. ⏱️处理耗时多久?—— 性能是否退化?
  3. 📈名单总量趋势如何?—— 长期是在增长还是萎缩?

ipblocklist 的答案很朴素:用 JSON 快照 + 每日趋势两个文件,把答案写进仓库。项目 requirements.txt 里只有一行注释:

# No third-party dependencies — stdlib only (urllib, ipaddress, concurrent.futures)

也就是说,整条统计链路零第三方依赖,任何有 Python 的环境都能跑。

项目结构:3 个目录 + 2 个脚本看懂全局

ipblocklist/ ├── update_tables.py # 主更新脚本:抓取 → 过滤 → 输出名单 + stats 快照 ├── generate_history.py # 历史脚本:把 stats 快照聚合为 90 天每日趋势 ├── inbound.txt # 最终产出的入站黑名单 ├── outbound.txt # 最终产出的出站黑名单 ├── tables/ │ ├── inbound/ # 入站源清单与中间结果(ipv6.txt、networks.txt、single_ips.txt) │ └── outbound/ └── stats/ ├── stats_YYYYMMDD_HHMMSS.json # 每次更新的统计快照 ├── latest.json # 最近一次更新(永远是最新快照的副本) ├── history.json # 90 天每日趋势 └── archived/ # 历史快照归档(约 2600+ 个文件)

数据流向一目了然:

tables/inbound/urltable_inbound(源 URL 清单)→update_tables.py抓取解析 →inbound.txt/outbound.txt+stats/快照 →generate_history.py聚合 →stats/history.json

第一道防线:stats 统计快照的生成机制

一次更新产出 3 类数据文件

核心逻辑在 update_tables.py 的main()中。它先构建一个空的dashboard_data骨架,包含timestamp、execution_duration_seconds、inbound、outbound四个字段:

dashboard_data = { "timestamp": datetime.now(timezone.utc).isoformat(), "execution_duration_seconds": 0, "inbound": {}, "outbound": {} }

随后对 inbound/outbound 分别执行“抓取 → 排除 → 输出”,每处理完一条方向就填充对应分支(见 update_tables.py#L544-L566):

dashboard_data["inbound"] = { "sources": inbound_sources, # 每个源 URL 各自贡献的 IP 数量 "raw_total": sum(inbound_sources.values()), "unique_pre_collapse": len(inbound_ips), "stats": inbound_stats # 压缩后的细分统计 }

处理完成后,脚本按“时间戳文件 + latest.json”双写模式落盘(update_tables.py#L571-L579):

timestamp_str = datetime.now(timezone.utc).strftime('%Y%m%d_%H%M%S') with open(os.path.join(stats_dir, f"stats_{timestamp_str}.json"), 'w') as f: json.dump(dashboard_data, f, indent=4) with open(os.path.join(stats_dir, 'latest.json'), 'w') as f: json.dump(dashboard_data, f, indent=4)
文件角色特点
stats/stats_20261022_145311.json历史快照文件名自带 UTC 时间戳,每 2 小时新增一个
stats/latest.json最新快照固定路径,方便仪表盘/监控直接读取,无需 glob
stats/history.json每日趋势由第二个脚本聚合生成

这种“快照 + 最新指针”双写是标准库里实现观测数据发布的经典模式:历史数据不可变、最新数据零查找成本。

一份 stats 快照里到底记录了什么?

以 stats/latest.json 为例,一次真实更新的记录包括:

字段示例值观测价值
timestamp2026-10-22T14:43:11+00:00更新时刻(UTC)
execution_duration_seconds600.79本轮耗时,性能退化一眼可见
inbound.sources约 90 个 URL → 各自条数最细粒度:定位哪个源贡献多少
inbound.raw_total9108192原始抓到的总条数
inbound.unique_pre_collapse4646862去重排除后的唯一网络数
inbound.stats.total_optimized_count4646862最终优化输出的条目数
inbound.stats.top_metrics.total_ipv4_addresses_covered20356785覆盖的 IPv4 地址总数
inbound.stats.top_metrics.cidr_distribution{"32": 4381371, "24": 1035, ...}按前缀长度分布,反映名单“粒度”结构

其中sources字段最有排查价值:inbound.sources中每个源都记了独立条数,例如某源突然从数万条变成0(快照里确实存在"https://www.darklist.de/raw.php": 0这样的记录),就意味着该源失效,运维可以立即告警——这就是“源级数据质量监控”。

top_metrics则在 write_files() 中顺手计算:遍历压缩后的 IPv4 网络,累加num_addresses得到覆盖地址总数,并按prefixlen分桶得到 CIDR 分布,几乎零额外成本。

第二道防线:history 历史趋势的生成机制

90 天窗口 + 每日采样

generate_history.py 是一个可以独立运行的小脚本,generate_history()的文档注释写得很直白(generate_history.py#L20-L30):

Parses stats json files to generate a history of total_ipv4_addresses_covered for the last 3 months. Only keeps one entry (the latest) per day in the output JSON.

它的核心规则有三条:

  1. 扫描范围:同时扫stats/和stats/archived/两个目录,保证趋势完整;
  2. 90 天窗口:cutoff_date = datetime.now() - timedelta(days=90),早于截止日期的文件直接跳过(generate_history.py#L35);
  3. 每日只留一条:以YYYY-MM-DD为键写入daily_records字典,同一天的多次更新(每天约 12 次)后写的自然覆盖先写的,最终每天只保留最新一次快照的值。

提取的指标由extract_ipv4_covered()完成——把 inbound 与 outbound 的total_ipv4_addresses_covered相加(generate_history.py#L10-L17),并对 JSON 缺失做了try/except容错,坏文件只会打一条 Warning 而不会中断整个任务。

最终产出的 stats/history.json 是一个按日期排序的数组,每个元素只有 3 个字段:

{ "date": "2026-07-24T22:55:47", "timestamp": 1784933747.0, "total_ipv4_addresses_covered": 23921068 }

目前文件里已有约 90 天、440 行的记录,数值从 7 月底的 2392 万缓慢增长到 10 月下旬的 2422 万——这条曲线就是整个黑名单项目的“生命线指标”,任何断崖或异常跳变都会在图上无所遁形。

自动归档:让 stats 目录永远保持轻量

generate_history.py还有一个容易被忽略的职责——归档。它把stats/根目录下所有stats_开头的快照移动到stats/archived/(generate_history.py#L93-L100):

for filepath in files_to_archive: try: shutil.move(filepath, archive_dir) except Exception as e: print(f"Error moving {os.path.basename(filepath)}: {e}")

这带来了两个好处:

  • ✅目录干净:stats/根目录任意时刻只有最近一个周期(3 个左右)的快照 +latest.json+history.json,仓库浏览体验很好;
  • ✅历史不丢:archived/下已积累约 2600 个文件(每 2 小时一个 × 数周),趋势重建永远有据可查,单文件归档失败也只是打印错误而不影响其他文件。

值得注意的小细节:归档逻辑用shutil.move而非重命名,且对latest.json/history.json显式排除(ignored_files集合),避免把“指针文件”当数据文件处理。

快速上手:本地复现整套统计机制

由于零第三方依赖,复现整套 stats/history 流程只需要标准库。如果希望 clone 仓库:

git clone https://gitcode.com/gh_mirrors/ip/ipblocklist cd ipblocklist
步骤命令产物
1. 执行全量更新python update_tables.py更新 inbound.txt、outbound.txt,新增stats/stats_*.json并刷新 stats/latest.json
2. 生成每日趋势python generate_history.py重建 stats/history.json,旧快照移入stats/archived/
3. 调试排查python update_tables.py --debug输出 DEBUG 级日志;加--no-mp可关闭多进程便于断点

💡 说明:完整跑一次需要遍历几十家外部数据源并做大规模并集/排除计算(参考latest.json,官方单次约 10 分钟),本地体验建议直接阅读仓库中已生成的stats/文件来理解数据形态。

关键启示:标准库也能做出专业的数据可观测性

回顾 ipblocklist 的 stats 与 history 机制,可以提炼出 4 条可直接搬走的实践:

  1. 观测数据与业务数据同仓:统计快照直接随代码仓库提交,无需额外存储设施,git log天然就是数据变更审计日志;
  2. “时间戳快照 + latest.json 指针”双写:历史不可变、最新零成本读取,监控和仪表盘各取所需;
  3. 源级明细是排查的命脉:sources字段让“哪个数据源坏了”从猜谜变成查表;
  4. 趋势与明细分层:stats_*.json存全量细节(可按需归档),history.json只存每日单值,兼顾回溯深度与读取轻量。

整套机制只用了json、os、glob、shutil、datetime、concurrent.futures、ipaddress、urllib这些标准库模块,证明了数据可观测性不需要昂贵的技术栈——清晰的指标定义 + 可靠的落盘纪律,才是可观测性的核心。

【免费下载链接】ipblocklist

IP lists full of bad IPs - Updated every 2H

项目地址:https://gitcode.com/gh_mirrors/ip/ipblocklist
点击查看免费下载

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询