当前位置:首页>python>Python工单驱动网络诊断:接到报障先跑一遍自动检查

Python工单驱动网络诊断:接到报障先跑一遍自动检查

  • 2026-09-27 16:24:43
Python工单驱动网络诊断:接到报障先跑一遍自动检查

运维工程师接到用户报障的时候,一般的流程是:问清楚是上不了网还是打不开某个系统、什么时候开始的、有没有改过什么。然后自己去测试:ping网关、ping目标、查DNS、traceroute……这些步骤其实每次都差不多。

与其每次手动重复,不如写一个脚本,输入目标IP或域名,自动跑完一整套诊断流程,生成一份报告。用Python实现不难,主要用到subprocess来调用系统命令:

importsubprocess
importsocket
importsys
fromdatetimeimportdatetime

defrun_cmd(cmd, timeout=5):
"""执行系统命令,返回输出内容,超时返回None"""
try:
result=subprocess.run(
cmd,
shell=True,
capture_output=True,
text=True,
timeout=timeout,
encoding='utf-8',
errors='ignore'
        )
returnresult.stdout.strip() ifresult.stdoutelseresult.stderr.strip()
exceptsubprocess.TimeoutExpired:
return"[超时]"
exceptExceptionase:
returnf"[错误: {e}]"

defdiagnose(target):
"""对目标执行完整网络诊断"""
print(f"\n{'='*60}")
print(f"网络诊断报告 - 目标: {target}")
print(f"诊断时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
print(f"{'='*60}\n")

# 1. DNS解析
print("【1. DNS解析测试】")
try:
ip=socket.gethostbyname(target)
print(f"  域名 {target} 解析成功 -> {ip}")
exceptsocket.gaierrorase:
print(f"  域名 {target} 解析失败: {e}")
print("  (无法解析,跳过后续IP层检查)\n")
return

# 2. Ping测试
print("\n【2. Ping测试(4次)】")
ping_result=run_cmd(f"ping -n 4 {target}", timeout=10)
# 取最后几行输出
lines=ping_result.split('\n')
forlineinlines[-5:]:
ifline.strip():
print(f"  {line}")

# 3. 端口检测
print("\n【3. 常用端口检测】")
ports= {22: "SSH", 23: "Telnet", 80: "HTTP", 443: "HTTPS",
3389: "RDP", 3306: "MySQL", 5432: "PostgreSQL"}
forport, serviceinports.items():
sock=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(1)
result=sock.connect_ex((target, port))
status="开放"ifresult==0else"关闭"
print(f"  {port}/tcp ({service}): {status}")
sock.close()

# 4. Traceroute
print("\n【4. Traceroute路径】")
trace_cmd="tracert -d -h 15"ifsys.platform=="win32"else"traceroute -m 15"
trace_result=run_cmd(f"{trace_cmd}{target}", timeout=15)
forlineintrace_result.split('\n')[:15]:
ifline.strip():
print(f"  {line}")

# 5. 汇总
print("\n【5. 初步判断】")
if"无法访问目标主机"inping_resultor"请求超时"inping_result:
print("  可能原因:")
print("  - 目标主机不在线或防火墙拦截了ICMP")
print("  - 网络路径存在丢包或阻塞")
print("  - 检查该IP在网络路径上是否有ACL拦截")
elif"来自 "inping_resultand"的回复: 字节="inping_result:
print("  基本连通性正常。")
if"开放"instr(ports):
print("  注意以下端口开放,请确认是否需要:")
else:
print("  所有检测端口均关闭,如业务不通请检查服务是否启动。")

print(f"\n{'='*60}")
print("诊断完成。如需进一步排查,请提供以上报告。\n")

if__name__=="__main__":
iflen(sys.argv) >1:
target=sys.argv[1]
else:
target=input("请输入要诊断的目标(IP或域名): ").strip()

iftarget:
diagnose(target)
else:
print("未输入目标,退出。")

运行效果:

============================================================
网络诊断报告 - 目标: www.example.com
诊断时间: 2025-05-14 10:30:15
============================================================

【1. DNS解析测试】
  域名 www.example.com 解析成功 -> 203.0.113.10

【2. Ping测试(4次)】
  正在 Ping www.example.com [203.0.113.10] 具有 32 字节的数据:
  来自 203.0.113.10 的回复: 字节=32 时间=15ms TTL=54
  来自 203.0.113.10 的回复: 字节=32 时间=14ms TTL=54
  来自 203.0.113.10 的回复: 字节=32 时间=15ms TTL=54
  来自 203.0.113.10 的回复: 字节=32 时间=14ms TTL=54

  www.example.com 的 Ping 统计信息:
    数据包: 已发送 = 4,已接收 = 4,丢失 = 0 (0% 丢失)

【3. 常用端口检测】
  22/tcp (SSH): 关闭
  23/tcp (Telnet): 关闭
  80/tcp (HTTP): 开放
  443/tcp (HTTPS): 开放
  ...

【4. Traceroute路径】
  1    <1 ms   <1 ms   <1 ms  192.168.1.1
  2     8 ms    7 ms    7 ms  10.0.0.1
  3    14 ms   15 ms   14 ms  203.0.113.10

============================================================
诊断完成。如需进一步排查,请提供以上报告。

实际工作中,用户报障的时候直接把这个报告发过来,比用户在电话里描述"网有点慢"有用得多。DNS解析成不成、Ping通不通、延迟多少毫秒、端口开没开、路由跳了几跳,全都一目了然。

有一点要提醒:Windows的ping命令参数是-n,Linux/macOS是-c。脚本里用sys.platform判断了操作系统,但traceroute的参数差异更大,Linux上默认是UDP方式探测,有些路由器会丢UDP包导致路径看起来不完整。Windows上的tracert用的是ICMP,跟实际路由更接近一点。混用两个系统的时候要注意这个差异。

诊断步骤还可以根据不同报障场景灵活组合。我把常见场景的对应检查项整理了一下:

报障场景优先检查项次优先
"网断了"Ping网关 → Ping外网 → DNS端口检测
"某个系统打不开"DNS解析 → Ping目标 → 端口检测Traceroute
"网速很慢"Ping延迟 → 端口检测Traceroute看跳数
"间歇性断线"多次Ping看丢包率 → TracerouteDNS解析一致性

这个脚本最方便的地方是,命令行传参就能用:python diagnose.py www.example.com,不需要交互输入,适合集成到工单系统里,用户报障的时候自动触发。

最新文章

随机文章