Skip to content

Instantly share code, notes, and snippets.

@Latezly
Created February 1, 2026 07:40
Show Gist options
  • Select an option

  • Save Latezly/fee9236e76c1b50f65262b0435d68cff to your computer and use it in GitHub Desktop.

Select an option

Save Latezly/fee9236e76c1b50f65262b0435d68cff to your computer and use it in GitHub Desktop.
prometheus_auto_scan
from concurrent.futures import ThreadPoolExecutor, as_completed
from loguru import logger
import json
import threading
import os
import requests
import re
import ipaddress
# ------------------------
# 局域网网段
# ------------------------
lan_subnets = ["192.168.0.0/24", "192.168.1.0/24"]
# ------------------------
# Cloudflare 凭据
# ------------------------
cf_token = ""
cf_zone_name = ""
# ------------------------
# 通用配置
# ------------------------
timeout = 1
retries = 3
retry_delay = 0.3
reload_url = "http://127.0.0.1:9090/-/reload"
logger.add("/etc/prometheus/scan_log/node_exporter_scan.log", rotation="1 MB", retention="7 days", encoding="utf-8", enqueue=True)
# ------------------------
# TCP 探测函数
# ------------------------
def tcp_check(host, port):
try:
r = requests.get(f"http://{host}:{port}/metrics", timeout=timeout)
if r.status_code != 200:
return False
text = r.text
return bool(re.search(r"^[a-zA-Z_:][a-zA-Z0-9_:]*\s", text, re.M))
except requests.RequestException:
return False
# ------------------------
# 通用端口扫描函数(局域网 + Cloudflare 共用)
# ------------------------
def scan_alive_hosts(hosts, port, label=""):
alive = []
lock = threading.Lock()
def worker(host):
if tcp_check(host, port):
with lock:
alive.append(f"{host}:{port}")
logger.info(f"✅ [{label}] 存活 {host}:{port}")
with ThreadPoolExecutor(max_workers=100) as executor:
futures = [executor.submit(worker, h) for h in hosts]
for _ in as_completed(futures):
pass
return sorted(alive)
# ------------------------
# 写 JSON 文件
# ------------------------
def write_targets_file(alive_list, output_path):
targets = [{"targets": alive_list}]
os.makedirs(os.path.dirname(output_path), exist_ok=True)
with open(output_path, "w") as f:
json.dump(targets, f, indent=2)
logger.info(f"📄 写入 {output_path},共 {len(alive_list)} 台")
# ------------------------
# 获取 Cloudflare 合规域名
# ------------------------
def fetch_cloudflare_target_domains():
headers = {
"Authorization": f"Bearer {cf_token}",
"Content-Type": "application/json"
}
# 获取 zone_id
zone_resp = requests.get(f"https://api.cloudflare.com/client/v4/zones?name={cf_zone_name}", headers=headers)
zone_resp.raise_for_status()
zone_id = zone_resp.json()["result"][0]["id"]
# 获取 DNS 记录
all_records = []
page = 1
while True:
dns_resp = requests.get(
f"https://api.cloudflare.com/client/v4/zones/{zone_id}/dns_records?page={page}&per_page=100",
headers=headers
)
dns_resp.raise_for_status()
result = dns_resp.json()["result"]
if not result:
break
all_records.extend(result)
page += 1
# 匹配规则
pattern = re.compile(r"^[a-z]{2}-[\w-]+\.latezly\.com$")
matched = [
record["name"]
for record in all_records
if record["type"] in ["A", "AAAA"] and pattern.match(record["name"])
]
logger.info(f"🌐 Cloudflare 匹配到 {len(matched)} 个域名")
return matched
# ------------------------
# 生成 IP 列表
# ------------------------
def generate_ip_list(subnets):
ip_list = []
for subnet in subnets:
network = ipaddress.ip_network(subnet, strict=False)
ip_list.extend(str(ip) for ip in network.hosts())
return ip_list
# ------------------------
# 主逻辑
# ------------------------
if __name__ == "__main__":
# 局域网 IP 列表
lan_subnets = lan_subnets
lan_hosts = generate_ip_list(lan_subnets)
# 局域网 Linux
alive_lan_linux = scan_alive_hosts(lan_hosts, 9100, "局域网 Linux")
write_targets_file(alive_lan_linux, "/etc/prometheus/targets/node_exporter_HomeLab_linux.json")
# 局域网 Windows
alive_lan_windows = scan_alive_hosts(lan_hosts, 9182, "局域网 Windows")
write_targets_file(alive_lan_windows, "/etc/prometheus/targets/node_exporter_HomeLab_windows.json")
# Cloudflare VPS 域名
cf_domains = fetch_cloudflare_target_domains()
alive_cf_vps = scan_alive_hosts(cf_domains, 9100, "VPS 域名")
write_targets_file(alive_cf_vps, "/etc/prometheus/targets/node_exporter_VPS_linux.json")
# Prometheus 热重载
try:
response = requests.post(reload_url)
if response.status_code == 200:
logger.success("🔁 Prometheus 配置热重载成功")
else:
logger.warning(f"⚠️ Prometheus 重载失败,状态码:{response.status_code}")
except Exception as e:
logger.error(f"❌ Prometheus 重载请求出错:{e}")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment