feat: 添加网络监控项目核心功能

This commit is contained in:
楼湘缘
2026-03-06 11:26:35 +08:00
parent 85dc7cdd04
commit 4aea161fd5
11 changed files with 1294 additions and 0 deletions
+51
View File
@@ -0,0 +1,51 @@
# Python
__pycache__/
*.py[cod]
*$py.class
*.so
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
*.egg-info/
.installed.cfg
*.egg
# 虚拟环境
venv/
env/
ENV/
env.bak/
venv.bak/
# IDE
.vscode/
.idea/
*.swp
*.swo
*~
# 日志文件
logs/
*.log
# 配置文件(包含敏感信息)
# config.py
# 操作系统
.DS_Store
Thumbs.db
# 项目特定
.pytest_cache/
.coverage
htmlcov/
+241
View File
@@ -0,0 +1,241 @@
# 网络监控项目
一个功能完整的网络监控解决方案,持续监控指定IP地址的连接状态,当检测到连续无法连接超过设定阈值时自动执行关机操作。
## 功能特性
### 核心功能
- ✅ 持续监控指定IP地址的网络连接状态
- ✅ 可配置的延迟阈值和ping间隔
- ✅ 支持Windows、Linux和macOS系统
- ✅ 自动关机功能(网络断开后)
- ✅ 实时显示连接状态和日志
### 高级功能
- 📝 详细的日志记录系统
- 🔔 多种通知方式(控制台、桌面、邮件)
- 📊 会话统计和历史记录
- 🛠️ 完整的工具函数库
- 📦 模块化的项目结构
## 项目结构
```
network-monitor/
├── network_monitor.py # 核心监控器类
├── advanced_monitor.py # 高级监控器(带日志和通知)
├── logger.py # 日志记录模块
├── notifier.py # 通知模块
├── utils.py # 工具函数模块
├── config.py # 配置文件
├── setup.py # 项目初始化脚本
├── run_monitor.bat # Windows启动脚本
├── run_monitor.sh # Linux/Mac启动脚本
├── requirements.txt # Python依赖
├── .gitignore # Git忽略文件
└── README.md # 项目文档
```
## 快速开始
### 1. 环境要求
- Python 3.6 或更高版本
- 无需额外安装依赖(仅使用标准库)
- 可选:安装桌面通知库(见 requirements.txt
### 2. 初始化项目
```bash
# 运行初始化脚本
python setup.py
```
### 3. 运行监控器
#### Windows
```bash
# 使用启动脚本(推荐)
run_monitor.bat
# 或直接运行
python network_monitor.py
```
#### Linux/Mac
```bash
# 添加执行权限
chmod +x run_monitor.sh
# 使用启动脚本(推荐)
./run_monitor.sh
# 或直接运行
python3 network_monitor.py
```
### 4. 使用高级监控模式
```bash
# 基础模式
python network_monitor.py
# 高级模式(带日志和通知)
python advanced_monitor.py
```
## 使用方法
### 命令行参数
```bash
python network_monitor.py [IP地址] [延迟阈值] [Ping间隔]
```
**参数说明:**
- `IP地址`: 要监控的IP地址(默认: 8.8.8.8
- `延迟阈值`: 连续断开多少秒后关机(默认: 30)
- `Ping间隔`: 每隔多少秒执行一次ping(默认: 5)
**示例:**
```bash
# 使用默认配置
python network_monitor.py
# 监控内网网关,60秒后关机,每10秒ping一次
python network_monitor.py 192.168.1.1 60 10
# 高级模式
python advanced_monitor.py 192.168.1.1 45 5
```
### 修改配置
编辑 `config.py` 文件:
```python
# 目标IP地址
TARGET_IP = "8.8.8.8"
# 延迟阈值(秒)
DELAY_THRESHOLD = 30.0
# Ping检测间隔(秒)
PING_INTERVAL = 5.0
```
## 输出示例
```
[2026-03-05 10:30:00] 网络监控器已启动
[2026-03-05 10:30:00] 目标IP: 8.8.8.8
[2026-03-05 10:30:00] 延迟阈值: 30.0秒
[2026-03-05 10:30:00] Ping间隔: 5.0秒
[2026-03-05 10:30:00] 操作系统: Windows
------------------------------------------------------------
[2026-03-05 10:30:00] 开始监控网络连接...
[2026-03-05 10:30:00] 每 5.0 秒执行一次ping操作
------------------------------------------------------------
[2026-03-05 10:30:00] Ping #1 执行完成 → ✓ 连接正常
[2026-03-05 10:30:00] 等待 5.0 秒后执行下一次ping...
[2026-03-05 10:30:05] Ping #2 执行完成 → ✓ 连接正常
```
## 模块说明
### network_monitor.py
核心监控器类,提供基本的网络监控功能。
- `NetworkMonitor`: 主监控器类
- `ping_host()`: 执行ping操作
- `monitor()`: 启动监控循环
- `shutdown_system()`: 执行系统关机
### advanced_monitor.py
高级监控器,集成日志和通知功能。
- `AdvancedNetworkMonitor`: 继承自NetworkMonitor
- 自动记录所有ping操作
- 发送连接状态通知
- 生成详细的统计报告
### logger.py
日志记录模块,提供完整的日志功能。
- `Logger`: 日志记录器类
- 支持多种事件类型记录
- 自动保存历史日志
- 生成统计报告
### notifier.py
通知模块,支持多种通知方式。
- `NotificationManager`: 通知管理器
- `ConsoleNotifier`: 控制台通知
- `DesktopNotifier`: 桌面通知(需安装依赖)
- `EmailNotifier`: 邮件通知(需配置SMTP
### utils.py
工具函数模块,提供通用工具函数。
- IP地址验证
- 主机名解析
- 端口检测
- 数据格式化
## 注意事项
1. **谨慎使用**: 此脚本会在网络断开后执行自动关机,建议先在测试环境验证。
2. **管理员权限**: Windows上需要管理员权限执行关机命令。
3. **停止监控**: 按 `Ctrl+C` 可以安全停止监控程序。
4. **目标IP选择**: 建议使用可靠的公网IP(如8.8.8.8)或内网网关。
5. **日志目录**: 日志文件保存在 `logs/` 目录下,会自动清理旧日志。
## 扩展功能
### 启用桌面通知
```bash
# Windows
pip install win10toast
# Linux
pip install notify2
# macOS
pip install pync
```
然后在代码中设置 `enable_desktop=True`
### 配置邮件通知
```python
from notifier import EmailNotifier
email_notifier = EmailNotifier(
smtp_server="smtp.example.com",
smtp_port=587,
username="your@email.com",
password="your_password",
from_email="from@email.com",
to_email="to@email.com"
)
```
## 故障排除
### 问题: 无法执行关机命令
- Windows: 以管理员身份运行
- Linux/Mac: 检查用户权限
### 问题: ping失败
- 检查IP地址是否正确
- 检查网络连接
- 检查防火墙设置
### 问题: 依赖安装失败
- 使用 `pip install -r requirements.txt`
- 确保使用Python 3.6+
## 许可证
MIT License
## 贡献
欢迎提交问题和拉取请求!
+210
View File
@@ -0,0 +1,210 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
高级网络监控器
集成日志记录和通知功能
"""
import sys
import time
from datetime import datetime
from typing import Optional
from network_monitor import NetworkMonitor
from logger import Logger
from notifier import NotificationManager, ConsoleNotifier, DesktopNotifier
class AdvancedNetworkMonitor(NetworkMonitor):
"""高级网络监控器,继承自基础监控器"""
def __init__(self, target_ip: str, delay_threshold: float = 30.0,
ping_interval: float = 5.0, enable_logging: bool = True,
enable_notifications: bool = True):
"""
初始化高级网络监控器
Args:
target_ip: 要监控的IP地址
delay_threshold: 延迟阈值(秒)
ping_interval: ping检测间隔(秒)
enable_logging: 是否启用日志记录
enable_notifications: 是否启用通知
"""
super().__init__(target_ip, delay_threshold, ping_interval)
# 初始化日志记录器
self.enable_logging = enable_logging
if self.enable_logging:
self.logger = Logger()
print(f"[{self._get_timestamp()}] 日志记录已启用")
# 初始化通知管理器
self.enable_notifications = enable_notifications
if self.enable_notifications:
self.notification_manager = NotificationManager(
enable_console=True,
enable_desktop=False # 可设置为True启用桌面通知
)
print(f"[{self._get_timestamp()}] 通知功能已启用")
print("-" * 60)
def ping_host(self) -> bool:
"""执行ping操作并记录日志"""
start_time = time.time()
is_connected = super().ping_host()
latency = (time.time() - start_time) * 1000 # 转换为毫秒
if self.enable_logging:
self.logger.log_ping(is_connected, latency)
return is_connected
def shutdown_system(self):
"""执行系统关机操作并发送通知"""
print(f"\n[{self._get_timestamp()}] !!! 连续{self.delay_threshold}秒无法连接,准备关机 !!!")
if self.enable_logging:
self.logger.log_shutdown(
f"连续{self.delay_threshold}秒无法连接到 {self.target_ip}"
)
if self.enable_notifications:
self.notification_manager.notify_shutdown(
f"连续{self.delay_threshold}秒无法连接到 {self.target_ip}"
)
# 保存日志
if self.enable_logging:
log_file = self.logger.save_session()
print(f"[{self._get_timestamp()}] 日志已保存到: {log_file}")
# 执行关机
super().shutdown_system()
def monitor(self):
"""启动网络监控"""
print(f"[{self._get_timestamp()}] 开始高级监控...")
print(f"[{self._get_timestamp()}] 每 {self.ping_interval} 秒执行一次ping操作")
print("-" * 60)
consecutive_failures = 0
last_status = None
try:
while self.is_running:
# 执行ping操作
is_connected = self.ping_host()
# 显示ping结果
status_str = " → ✓ 连接正常" if is_connected else " → ✗ 连接失败"
print(status_str)
# 状态变化时额外输出日志和通知
if last_status != is_connected:
if not is_connected:
print(f"[{self._get_timestamp()}] 状态变化: 检测到连接失败")
if self.enable_logging:
self.logger.log_status_change("disconnected")
else:
print(f"[{self._get_timestamp()}] 状态变化: 连接已恢复")
if self.enable_logging:
self.logger.log_status_change("connected")
last_status = is_connected
if is_connected:
# 连接成功,重置失败计数
consecutive_failures = 0
self.failure_start_time = None
else:
# 连接失败
consecutive_failures += 1
if self.failure_start_time is None:
# 第一次失败,记录开始时间
self.failure_start_time = time.time()
print(f"[{self._get_timestamp()}] 开始记录连接失败时间")
else:
# 计算失败持续时间
failure_duration = time.time() - self.failure_start_time
remaining_time = self.delay_threshold - failure_duration
if remaining_time > 0:
print(f"[{self._get_timestamp()}] 连续失败: {consecutive_failures}次, "
f"已持续: {failure_duration:.1f}秒, "
f"剩余: {remaining_time:.1f}")
# 每隔一定时间发送通知
if int(failure_duration) % 10 == 0 and failure_duration > 0:
if self.enable_notifications:
self.notification_manager.notify_connection_lost(
self.target_ip, failure_duration
)
if failure_duration >= self.delay_threshold:
# 超过阈值,执行关机
self.shutdown_system()
self.is_running = False
break
# 按照设定的间隔等待下一次ping操作
print(f"[{self._get_timestamp()}] 等待 {self.ping_interval} 秒后执行下一次ping...")
time.sleep(self.ping_interval)
except KeyboardInterrupt:
print(f"\n[{self._get_timestamp()}] 用户中断,监控已停止")
print(f"[{self._get_timestamp()}] 总共执行了 {self.ping_count} 次ping操作")
# 显示统计信息
if self.enable_logging:
stats = self.logger.get_statistics()
print(f"[{self._get_timestamp()}] 统计信息:")
print(f" - 总ping次数: {stats['total_pings']}")
print(f" - 成功次数: {stats['successful_pings']}")
print(f" - 失败次数: {stats['failed_pings']}")
print(f" - 成功率: {stats['success_rate']}")
print(f" - 运行时长: {stats['session_duration']:.1f}")
# 保存日志
log_file = self.logger.save_session()
print(f"[{self._get_timestamp()}] 日志已保存到: {log_file}")
except Exception as e:
print(f"\n[{self._get_timestamp()}] 监控过程中发生错误: {e}")
print(f"[{self._get_timestamp()}] 总共执行了 {self.ping_count} 次ping操作")
def main():
"""主函数"""
# 可配置参数
CONFIG = {
"target_ip": "8.8.8.8", # 默认使用Google DNS
"delay_threshold": 30.0, # 延迟阈值(秒)
"ping_interval": 5.0, # Ping检测间隔(秒)
"enable_logging": True, # 启用日志记录
"enable_notifications": True # 启用通知
}
# 可以通过命令行参数覆盖配置
if len(sys.argv) > 1:
CONFIG["target_ip"] = sys.argv[1]
if len(sys.argv) > 2:
CONFIG["delay_threshold"] = float(sys.argv[2])
if len(sys.argv) > 3:
CONFIG["ping_interval"] = float(sys.argv[3])
# 创建并启动监控器
monitor = AdvancedNetworkMonitor(
target_ip=CONFIG["target_ip"],
delay_threshold=CONFIG["delay_threshold"],
ping_interval=CONFIG["ping_interval"],
enable_logging=CONFIG["enable_logging"],
enable_notifications=CONFIG["enable_notifications"]
)
monitor.monitor()
if __name__ == "__main__":
main()
+18
View File
@@ -0,0 +1,18 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
网络监控配置文件示例
在此处修改监控参数
"""
# 目标IP地址(支持IPv4和IPv6
TARGET_IP = "8.8.8.8"
# 延迟阈值(秒)
DELAY_THRESHOLD = 30.0
# Ping检测间隔(秒)
PING_INTERVAL = 5.0
# 可选参数(保留用于扩展)
MAX_RETRIES = 3
+167
View File
@@ -0,0 +1,167 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
日志记录器模块
负责记录网络监控的历史数据和异常事件
"""
import os
import json
from datetime import datetime
from typing import List, Dict, Any
from pathlib import Path
class Logger:
"""日志记录器类"""
def __init__(self, log_dir: str = "logs", max_log_files: int = 10):
"""
初始化日志记录器
Args:
log_dir: 日志文件存储目录
max_log_files: 最大保留的日志文件数量
"""
self.log_dir = Path(log_dir)
self.max_log_files = max_log_files
self.current_session_data: List[Dict[str, Any]] = []
self.session_start_time = datetime.now()
# 创建日志目录
self.log_dir.mkdir(parents=True, exist_ok=True)
# 清理旧日志文件
self._cleanup_old_logs()
def _get_log_filename(self) -> str:
"""生成日志文件名"""
timestamp = self.session_start_time.strftime("%Y%m%d_%H%M%S")
return f"network_monitor_{timestamp}.log"
def _cleanup_old_logs(self):
"""清理旧的日志文件,保留最近的max_log_files个"""
log_files = sorted(
self.log_dir.glob("network_monitor_*.log"),
key=lambda x: x.stat().st_mtime,
reverse=True
)
# 删除超出数量限制的旧日志文件
for old_log in log_files[self.max_log_files:]:
old_log.unlink()
def log_event(self, event_type: str, message: str, **kwargs):
"""
记录事件
Args:
event_type: 事件类型(ping, status_change, error等)
message: 事件描述
**kwargs: 额外的键值对数据
"""
event = {
"timestamp": datetime.now().isoformat(),
"type": event_type,
"message": message,
**kwargs
}
self.current_session_data.append(event)
def log_ping(self, success: bool, latency: float = 0.0):
"""
记录ping结果
Args:
success: ping是否成功
latency: 延迟时间(毫秒)
"""
self.log_event(
"ping",
"Ping操作完成" if success else "Ping操作失败",
success=success,
latency_ms=latency
)
def log_status_change(self, status: str, duration: float = None):
"""
记录状态变化
Args:
status: 状态(connected, disconnected
duration: 持续时间(秒)
"""
message = f"网络状态变化: {status}"
if duration is not None:
message += f" (持续{duration:.1f}秒)"
self.log_event(
"status_change",
message,
status=status,
duration_seconds=duration
)
def log_error(self, error_type: str, error_message: str):
"""
记录错误
Args:
error_type: 错误类型
error_message: 错误信息
"""
self.log_event(
"error",
f"{error_type}: {error_message}",
error_type=error_type
)
def log_shutdown(self, reason: str):
"""
记录关机事件
Args:
reason: 关机原因
"""
self.log_event(
"shutdown",
f"系统关机: {reason}",
reason=reason
)
def save_session(self):
"""保存当前会话的日志到文件"""
log_file = self.log_dir / self._get_log_filename()
session_summary = {
"session_start": self.session_start_time.isoformat(),
"session_end": datetime.now().isoformat(),
"total_events": len(self.current_session_data),
"events": self.current_session_data
}
with open(log_file, 'w', encoding='utf-8') as f:
json.dump(session_summary, f, ensure_ascii=False, indent=2)
return log_file
def get_statistics(self) -> Dict[str, Any]:
"""
获取当前会话的统计信息
Returns:
统计数据字典
"""
total_pings = sum(1 for event in self.current_session_data if event["type"] == "ping")
successful_pings = sum(
1 for event in self.current_session_data
if event["type"] == "ping" and event["success"]
)
return {
"total_pings": total_pings,
"successful_pings": successful_pings,
"failed_pings": total_pings - successful_pings,
"success_rate": f"{(successful_pings / total_pings * 100):.2f}%" if total_pings > 0 else "0%",
"session_duration": (datetime.now() - self.session_start_time).total_seconds()
}
+199
View File
@@ -0,0 +1,199 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
通知模块
负责在重要事件发生时发送通知
"""
import sys
import platform
from typing import Optional
from abc import ABC, abstractmethod
class Notifier(ABC):
"""通知器抽象基类"""
@abstractmethod
def send(self, title: str, message: str):
"""
发送通知
Args:
title: 通知标题
message: 通知内容
"""
pass
class ConsoleNotifier(Notifier):
"""控制台通知器"""
def send(self, title: str, message: str):
"""在控制台显示通知"""
separator = "=" * 60
print(f"\n{separator}")
print(f"{title}")
print(f"{message}")
print(f"{separator}\n")
class DesktopNotifier(Notifier):
"""桌面通知器"""
def __init__(self):
"""初始化桌面通知器"""
self.os_type = platform.system().lower()
self.enabled = True
# 尝试导入通知库
if self.os_type == "windows":
try:
import win10toast
self.toaster = win10toast.ToastNotifier()
except ImportError:
self.enabled = False
elif self.os_type == "linux":
try:
import notify2
notify2.init("网络监控器")
except ImportError:
self.enabled = False
elif self.os_type == "darwin":
try:
import pync
except ImportError:
self.enabled = False
def send(self, title: str, message: str):
"""发送桌面通知"""
if not self.enabled:
return
try:
if self.os_type == "windows":
self.toaster.show_notification(
title,
message,
duration=10
)
elif self.os_type == "linux":
import notify2
notification = notify2.Notification(title, message)
notification.show()
elif self.os_type == "darwin":
import pync
pync.notify(message, title=title)
except Exception as e:
print(f"发送桌面通知失败: {e}")
class EmailNotifier(Notifier):
"""邮件通知器(示例,需要配置SMTP"""
def __init__(self, smtp_server: str = None, smtp_port: int = None,
username: str = None, password: str = None,
from_email: str = None, to_email: str = None):
"""
初始化邮件通知器
Args:
smtp_server: SMTP服务器地址
smtp_port: SMTP端口
username: 用户名
password: 密码
from_email: 发件人邮箱
to_email: 收件人邮箱
"""
self.smtp_server = smtp_server
self.smtp_port = smtp_port
self.username = username
self.password = password
self.from_email = from_email
self.to_email = to_email
self.enabled = all([smtp_server, smtp_port, username, password, from_email, to_email])
def send(self, title: str, message: str):
"""发送邮件通知"""
if not self.enabled:
print("邮件通知未配置,跳过发送")
return
try:
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
# 创建邮件
msg = MIMEMultipart()
msg['From'] = self.from_email
msg['To'] = self.to_email
msg['Subject'] = title
# 添加邮件正文
msg.attach(MIMEText(message, 'plain', 'utf-8'))
# 发送邮件
with smtplib.SMTP(self.smtp_server, self.smtp_port) as server:
server.starttls()
server.login(self.username, self.password)
server.send_message(msg)
print(f"邮件通知已发送至 {self.to_email}")
except Exception as e:
print(f"发送邮件通知失败: {e}")
class NotificationManager:
"""通知管理器"""
def __init__(self, enable_console: bool = True, enable_desktop: bool = False):
"""
初始化通知管理器
Args:
enable_console: 是否启用控制台通知
enable_desktop: 是否启用桌面通知
"""
self.notifiers: list[Notifier] = []
if enable_console:
self.notifiers.append(ConsoleNotifier())
if enable_desktop:
self.notifiers.append(DesktopNotifier())
def add_notifier(self, notifier: Notifier):
"""
添加通知器
Args:
notifier: 通知器实例
"""
self.notifiers.append(notifier)
def notify(self, title: str, message: str):
"""
发送通知到所有通知器
Args:
title: 通知标题
message: 通知内容
"""
for notifier in self.notifiers:
notifier.send(title, message)
def notify_connection_lost(self, ip: str, duration: float):
"""通知连接丢失"""
self.notify(
"网络连接丢失",
f"无法连接到 {ip}\n已断开 {duration:.1f}"
)
def notify_shutdown(self, reason: str):
"""通知系统即将关机"""
self.notify(
"系统即将关机",
f"原因: {reason}\n请保存所有工作!"
)
+12
View File
@@ -0,0 +1,12 @@
# 网络监控项目依赖
# Python 3.6+ 仅使用标准库即可运行核心功能
# 可选依赖(用于桌面通知)
# Windows: pip install win10toast
win10toast==0.9
# Linux: pip install notify2
notify2==0.3.1
# macOS: pip install pync
pync==2.0.0
+69
View File
@@ -0,0 +1,69 @@
@echo off
REM Windows批处理脚本 - 启动网络监控器
echo ========================================
echo 网络监控器启动脚本
echo ========================================
echo.
REM 检查Python是否安装
python --version >nul 2>&1
if errorlevel 1 (
echo 错误: 未检测到Python,请先安装Python 3.6或更高版本
pause
exit /b 1
)
echo Python版本:
python --version
echo.
REM 检查是否有管理员权限(Windows关机需要)
net session >nul 2>&1
if errorlevel 1 (
echo 警告: 建议以管理员身份运行此脚本以确保关机功能正常工作
echo.
)
REM 选择运行模式
echo 请选择运行模式:
echo 1. 基础监控模式 (network_monitor.py)
echo 2. 高级监控模式 (advanced_monitor.py) - 带日志和通知
echo 3. 使用自定义参数
echo.
set /p choice="请输入选项 (1/2/3): "
if "%choice%"=="1" (
echo.
echo 启动基础监控模式...
echo.
python network_monitor.py
) else if "%choice%"=="2" (
echo.
echo 启动高级监控模式...
echo.
python advanced_monitor.py
) else if "%choice%"=="3" (
echo.
set /p target_ip="请输入目标IP地址 (默认: 8.8.8.8): "
if "%target_ip%"=="" set target_ip=8.8.8.8
set /p delay="请输入延迟阈值秒数 (默认: 30): "
if "%delay%"=="" set delay=30
set /p interval="请输入Ping间隔秒数 (默认: 5): "
if "%interval%"=="" set interval=5
echo.
echo 启动监控器: IP=%target_ip%, 延迟=%delay秒, 间隔=%interval秒
echo.
python network_monitor.py %target_ip% %delay% %interval%
) else (
echo 无效选项,使用默认启动...
python network_monitor.py
)
echo.
echo 监控已停止
pause
+64
View File
@@ -0,0 +1,64 @@
#!/bin/bash
# Linux/macOS Shell脚本 - 启动网络监控器
echo "========================================"
echo "网络监控器启动脚本"
echo "========================================"
echo ""
# 检查Python是否安装
if ! command -v python3 &> /dev/null; then
echo "错误: 未检测到Python3,请先安装Python 3.6或更高版本"
exit 1
fi
echo "Python版本:"
python3 --version
echo ""
# 选择运行模式
echo "请选择运行模式:"
echo "1. 基础监控模式 (network_monitor.py)"
echo "2. 高级监控模式 (advanced_monitor.py) - 带日志和通知"
echo "3. 使用自定义参数"
echo ""
read -p "请输入选项 (1/2/3): " choice
case $choice in
1)
echo ""
echo "启动基础监控模式..."
echo ""
python3 network_monitor.py
;;
2)
echo ""
echo "启动高级监控模式..."
echo ""
python3 advanced_monitor.py
;;
3)
echo ""
read -p "请输入目标IP地址 (默认: 8.8.8.8): " target_ip
target_ip=${target_ip:-8.8.8.8}
read -p "请输入延迟阈值秒数 (默认: 30): " delay
delay=${delay:-30}
read -p "请输入Ping间隔秒数 (默认: 5): " interval
interval=${interval:-5}
echo ""
echo "启动监控器: IP=$target_ip, 延迟=$delay秒, 间隔=$interval秒"
echo ""
python3 network_monitor.py "$target_ip" "$delay" "$interval"
;;
*)
echo "无效选项,使用默认启动..."
python3 network_monitor.py
;;
esac
echo ""
echo "监控已停止"
+102
View File
@@ -0,0 +1,102 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
项目设置脚本
用于初始化和配置项目
"""
import os
import sys
def create_directories():
"""创建必要的目录结构"""
directories = [
"logs",
"logs/backup",
"config",
]
for directory in directories:
os.makedirs(directory, exist_ok=True)
print(f"[OK] 创建目录: {directory}")
def create_example_config():
"""创建示例配置文件"""
example_config = """#!/usr/bin/env python3
# -*- coding: utf-8 -*-
\"\"\"
网络监控配置文件示例
在此处修改监控参数
\"\"\"
# 目标IP地址(支持IPv4和IPv6
TARGET_IP = "8.8.8.8"
# 延迟阈值(秒)
DELAY_THRESHOLD = 30.0
# Ping检测间隔(秒)
PING_INTERVAL = 5.0
# 可选参数(保留用于扩展)
MAX_RETRIES = 3
"""
config_file = "config/config_example.py"
with open(config_file, 'w', encoding='utf-8') as f:
f.write(example_config)
print(f"[OK] 创建示例配置: {config_file}")
def print_welcome_message():
"""打印欢迎信息"""
print("=" * 60)
print("网络监控项目 - 初始化设置")
print("=" * 60)
print()
def print_completion_message():
"""打印完成信息"""
print()
print("=" * 60)
print("项目初始化完成!")
print("=" * 60)
print()
print("快速开始:")
print(" Windows: run_monitor.bat")
print(" Linux/Mac: chmod +x run_monitor.sh && ./run_monitor.sh")
print()
print("或直接运行:")
print(" 基础模式: python network_monitor.py")
print(" 高级模式: python advanced_monitor.py")
print()
print("命令行参数:")
print(" python network_monitor.py <IP> <延迟阈值> <Ping间隔>")
print()
def main():
"""主函数"""
print_welcome_message()
# 创建目录结构
print("创建目录结构...")
create_directories()
# 创建示例配置
print()
print("创建示例配置文件...")
create_example_config()
print()
print("[OK] 所有设置完成!")
print_completion_message()
if __name__ == "__main__":
main()
+161
View File
@@ -0,0 +1,161 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
工具函数模块
提供项目所需的通用工具函数
"""
import socket
import re
from typing import Optional
def validate_ip_address(ip: str) -> bool:
"""
验证IP地址格式是否正确
Args:
ip: IP地址字符串
Returns:
bool: 如果IP地址格式正确返回True,否则返回False
"""
# IPv4正则表达式
ipv4_pattern = r'^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$'
# IPv6正则表达式(简化版)
ipv6_pattern = r'^(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$|^::$|^:(?::)+(?:[0-9a-fA-F]{1,4})?$'
return bool(re.match(ipv4_pattern, ip) or re.match(ipv6_pattern, ip))
def validate_hostname(hostname: str) -> bool:
"""
验证主机名格式是否正确
Args:
hostname: 主机名字符串
Returns:
bool: 如果主机名格式正确返回True,否则返回False
"""
if len(hostname) > 253:
return False
if hostname[-1] == ".":
hostname = hostname[:-1]
allowed = re.compile(r"^(?!-)[A-Z0-9-]{1,63}(?<!-)$", re.IGNORECASE)
return all(allowed.match(label) for label in hostname.split("."))
def resolve_hostname(hostname: str) -> Optional[str]:
"""
解析主机名为IP地址
Args:
hostname: 主机名
Returns:
IP地址字符串,解析失败返回None
"""
try:
ip_address = socket.gethostbyname(hostname)
return ip_address
except socket.gaierror:
return None
def is_port_open(host: str, port: int, timeout: float = 2.0) -> bool:
"""
检查指定主机的端口是否开放
Args:
host: 主机地址
port: 端口号
timeout: 超时时间(秒)
Returns:
bool: 端口开放返回True,否则返回False
"""
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(timeout)
result = sock.connect_ex((host, port))
sock.close()
return result == 0
except Exception:
return False
def format_bytes(bytes_size: int) -> str:
"""
格式化字节大小为可读字符串
Args:
bytes_size: 字节数
Returns:
格式化后的字符串
"""
for unit in ['B', 'KB', 'MB', 'GB', 'TB']:
if bytes_size < 1024.0:
return f"{bytes_size:.2f} {unit}"
bytes_size /= 1024.0
return f"{bytes_size:.2f} PB"
def format_duration(seconds: float) -> str:
"""
格式化时长为可读字符串
Args:
seconds: 秒数
Returns:
格式化后的字符串
"""
if seconds < 60:
return f"{seconds:.1f}"
elif seconds < 3600:
minutes = seconds / 60
return f"{minutes:.1f}分钟"
elif seconds < 86400:
hours = seconds / 3600
return f"{hours:.1f}小时"
else:
days = seconds / 86400
return f"{days:.1f}"
def safe_divide(numerator: float, denominator: float, default: float = 0.0) -> float:
"""
安全除法,避免除以零
Args:
numerator: 分子
denominator: 分母
default: 除零时的默认返回值
Returns:
除法结果或默认值
"""
try:
return numerator / denominator if denominator != 0 else default
except Exception:
return default
def clamp(value: float, min_value: float, max_value: float) -> float:
"""
将数值限制在指定范围内
Args:
value: 输入值
min_value: 最小值
max_value: 最大值
Returns:
限制后的值
"""
return max(min_value, min(value, max_value))