1052 lines
56 KiB
Markdown
1052 lines
56 KiB
Markdown
# MY Network Monitoring System
|
||
|
||
## Обзор Системы Мониторинга
|
||
|
||
MY Network Monitoring System представляет собой комплексную систему мониторинга с ASCII-арт интерфейсом в хакерском стиле, API endpoints для мониторинга, веб-интерфейс и интеграцию с Telegram ботом.
|
||
|
||
## ASCII-арт Интерфейс в Хакерском Стиле
|
||
|
||
### 1. Terminal Dashboard
|
||
|
||
```python
|
||
class HackerStyleTerminalUI:
|
||
def __init__(self):
|
||
self.screen_width = 120
|
||
self.screen_height = 40
|
||
self.refresh_rate = 1.0 # секунды
|
||
|
||
def render_main_dashboard(self, node_status: dict) -> str:
|
||
"""Главная панель мониторинга"""
|
||
|
||
ascii_art = f"""
|
||
╔════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╗
|
||
║ ███╗ ███╗██╗ ██╗ ███╗ ██╗███████╗████████╗██╗ ██╗ ██████╗ ██████╗ ██╗ ██╗ ║
|
||
║ ████╗ ████║╚██╗ ██╔╝ ████╗ ██║██╔════╝╚══██╔══╝██║ ██║██╔═══██╗██╔══██╗██║ ██╔╝ ║
|
||
║ ██╔████╔██║ ╚████╔╝ ██╔██╗ ██║█████╗ ██║ ██║ █╗ ██║██║ ██║██████╔╝█████╔╝ ║
|
||
║ ██║╚██╔╝██║ ╚██╔╝ ██║╚██╗██║██╔══╝ ██║ ██║███╗██║██║ ██║██╔══██╗██╔═██╗ ║
|
||
║ ██║ ╚═╝ ██║ ██║ ██║ ╚████║███████╗ ██║ ╚███╔███╔╝╚██████╔╝██║ ██║██║ ██╗ ║
|
||
║ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═══╝╚══════╝ ╚═╝ ╚══╝╚══╝ ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═╝ ║
|
||
║ ║
|
||
║ Node ID: {node_status['node_id'][:16]}... Status: {self.get_status_indicator(node_status)} ║
|
||
║ Uptime: {self.format_uptime(node_status['uptime'])} Network: ONLINE ║
|
||
╠════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╣
|
||
║ ┌─ NETWORK STATUS ─────────────────────┐ ┌─ CONTENT METRICS ──────────────────┐ ┌─ SYSTEM RESOURCES ──────────────┐ ║
|
||
║ │ Peers Connected: {node_status['peer_count']:>3} │ │ Total Content: {node_status['content_count']:>6} │ │ CPU Usage: {self.render_bar(node_status['cpu_usage'], 10)} │ ║
|
||
║ │ Active Connections: {node_status.get('active_connections', 0):>3} │ │ Synced Today: {node_status.get('synced_today', 0):>7} │ │ Memory: {self.render_bar(node_status['memory_usage'], 13)} │ ║
|
||
║ │ Network Bandwidth: {node_status.get('bandwidth', '0 MB/s'):>8} │ │ Replication Rate: {node_status.get('replication_rate', '0/s'):>4} │ │ Disk: {self.render_bar(node_status['disk_usage'], 15)} │ ║
|
||
║ │ Consensus Participation: {node_status.get('consensus_rate', '0%'):>3} │ │ Failed Syncs: {node_status.get('failed_syncs', 0):>6} │ │ Network I/O: {node_status.get('network_io', '0 KB/s'):>8} │ ║
|
||
║ └─────────────────────────────────────┘ └────────────────────────────────────┘ └─────────────────────────────────┘ ║
|
||
║ ║
|
||
║ ┌─ RECENT ACTIVITY ────────────────────────────────────────────────────────────────────────────────────────────┐ ║
|
||
║ │ {self.format_recent_activities(node_status.get('recent_activities', []))} │ ║
|
||
║ └──────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ ║
|
||
║ ║
|
||
║ ┌─ PEER CONNECTIONS ───────────────────────────────────────────────────────────────────────────────────────────┐ ║
|
||
║ │ {self.format_peer_connections(node_status.get('peer_connections', []))} │ ║
|
||
║ └──────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ ║
|
||
║ ║
|
||
║ Commands: [S]ync | [P]eers | [C]ontent | [L]ogs | [Q]uit Last Update: {datetime.now().strftime('%H:%M:%S')} ║
|
||
╚════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╝
|
||
"""
|
||
return ascii_art
|
||
|
||
def render_bar(self, percentage: float, width: int) -> str:
|
||
"""Рендер прогресс-бара в ASCII"""
|
||
filled_width = int((percentage / 100) * width)
|
||
bar = "█" * filled_width + "░" * (width - filled_width)
|
||
return f"{bar} {percentage:>5.1f}%"
|
||
|
||
def get_status_indicator(self, node_status: dict) -> str:
|
||
"""Индикатор статуса ноды"""
|
||
if node_status.get('is_healthy', True):
|
||
return "🟢 HEALTHY"
|
||
elif node_status.get('has_warnings', False):
|
||
return "🟡 WARNING"
|
||
else:
|
||
return "🔴 CRITICAL"
|
||
```
|
||
|
||
### 2. Network Topology Visualization
|
||
|
||
```python
|
||
def render_network_topology(self, network_data: dict) -> str:
|
||
"""ASCII визуализация топологии сети"""
|
||
|
||
topology_art = f"""
|
||
┌─ MY NETWORK TOPOLOGY ──────────────────────────────────────────────────────────────────────────────────┐
|
||
│ │
|
||
│ ┌─────────────┐ │
|
||
│ ┌──│ Bootstrap-1 │──┐ │
|
||
│ │ └─────────────┘ │ │
|
||
│ │ │ │
|
||
│ ┌─────────────┴──┐ ┌──┴─────────────┐ │
|
||
│ │ Regional-EU │ │ Regional-US │ │
|
||
│ └─────────────┬──┘ └──┬─────────────┘ │
|
||
│ │ │ │
|
||
│ ┌────────────────────────┼─────────────────┼────────────────────────┐ │
|
||
│ │ │ │ │ │
|
||
│ ┌────▼───┐ ┌───▼───┐ ┌───▼───┐ ┌───▼────┐ │
|
||
│ │ Node-A │────────────────│ Node-B│─────────│ Node-C│────────────────│ Node-D │ │
|
||
│ └────────┘ └───────┘ └───────┘ └────────┘ │
|
||
│ │ │ │ │ │
|
||
│ │ ┌──────────────┴─────────────────┴──────────────┐ │ │
|
||
│ │ │ │ │ │
|
||
│ ┌────▼───┐ ┌───▼───┐ ┌───▼───┐ ┌───▼────┐ │
|
||
│ │ Node-E │ │ Node-F│ │ Node-G│ │ Node-H │ │
|
||
│ └────────┘ └───────┘ └───────┘ └────────┘ │
|
||
│ │
|
||
│ Legend: ━━━ High Bandwidth │ ─── Standard │ ╬╬╬ Consensus Link │ ░░░ Sync Active │
|
||
│ │
|
||
│ Network Stats: │
|
||
│ • Total Nodes: {network_data.get('total_nodes', 0)} │
|
||
│ • Active Connections: {network_data.get('active_connections', 0)} │
|
||
│ • Average Latency: {network_data.get('avg_latency', '0ms')} │
|
||
│ • Network Health: {network_data.get('health_score', '0%')} │
|
||
└────────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||
"""
|
||
return topology_art
|
||
|
||
def render_matrix_rain_effect(self) -> str:
|
||
"""Matrix-style rain effect для заставки"""
|
||
|
||
matrix_art = """
|
||
╔═══════════════════════════════════════════════════════════════════════════════════════════════════╗
|
||
║ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ║
|
||
║ ░█░█░░█░░█░░░█░█░░█░░█░░░█░█░░█░░█░░░█░█░░█░░█░░░█░█░░█░░█░░░█░█░░█░░█░░░█░█░░█░░█░░░█░█░░█░ ║
|
||
║ ░░█░░░░█░░█░░░░█░░░░█░░█░░░░█░░░░█░░█░░░░█░░░░█░░█░░░░█░░░░█░░█░░░░█░░░░█░░█░░░░█░░░░█░░█░░░░█░ ║
|
||
║ █░░█░█░░█░░█░█░░█░█░░█░░█░█░░█░█░░█░░█░█░░█░█░░█░░█░█░░█░█░░█░░█░█░░█░█░░█░░█░█░░█░█░░█░░█░█░ ║
|
||
║ ░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░ ║
|
||
║ ░░█░█░░█░░█░░░█░█░░█░░█░░░█░█░░█░░█░░░█░█░░█░░█░░░█░█░░█░░█░░░█░█░░█░░█░░░█░█░░█░░█░░░█░█░░█░ ║
|
||
║ ║
|
||
║ ╔══════════════════════════════════════════╗ ║
|
||
║ ║ INITIALIZING MY NETWORK MONITORING... ║ ║
|
||
║ ║ ║ ║
|
||
║ ║ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓░░░░░░░░░░░░░░░░░░ ║ ║
|
||
║ ║ ║ ║
|
||
║ ║ Loading quantum encryption protocols... ║ ║
|
||
║ ║ Establishing secure P2P connections... ║ ║
|
||
║ ║ Synchronizing with blockchain nodes... ║ ║
|
||
║ ╚══════════════════════════════════════════╝ ║
|
||
║ ║
|
||
║ ░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░ ║
|
||
║ ░░█░█░░█░░█░░░█░█░░█░░█░░░█░█░░█░░█░░░█░█░░█░░█░░░█░█░░█░░█░░░█░█░░█░░█░░░█░█░░█░░█░░░█░█░░█░ ║
|
||
║ █░░█░█░░█░░█░█░░█░█░░█░░█░█░░█░█░░█░░█░█░░█░█░░█░░█░█░░█░█░░█░░█░█░░█░█░░█░░█░█░░█░█░░█░░█░█░ ║
|
||
║ ░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░░░█░ ║
|
||
║ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ║
|
||
╚═══════════════════════════════════════════════════════════════════════════════════════════════════╝
|
||
"""
|
||
return matrix_art
|
||
```
|
||
|
||
### 3. Content Flow Visualization
|
||
|
||
```python
|
||
def render_content_flow(self, flow_data: dict) -> str:
|
||
"""Визуализация потока контента в реальном времени"""
|
||
|
||
flow_art = f"""
|
||
┌─ CONTENT FLOW MONITOR ─────────────────────────────────────────────────────────────────────────────────┐
|
||
│ │
|
||
│ 📥 INCOMING 🔄 PROCESSING 📤 OUTGOING │
|
||
│ │
|
||
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
|
||
│ │ Node-A │════════════════▶│ THIS-NODE │════════════════▶│ Node-B │ │
|
||
│ │ {flow_data.get('incoming', {}).get('node_a', '0 KB/s'):>11} │ │ {flow_data.get('processing', '0 ops/s'):>11} │ │ {flow_data.get('outgoing', {}).get('node_b', '0 KB/s'):>11} │ │
|
||
│ └─────────────┘ └─────────────┘ └─────────────┘ │
|
||
│ ║ ║ ║ │
|
||
│ ▼ ▼ ▼ │
|
||
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
|
||
│ │ Node-C │════════════════▶│ QUEUE │════════════════▶│ Node-D │ │
|
||
│ │ {flow_data.get('incoming', {}).get('node_c', '0 KB/s'):>11} │ │ {flow_data.get('queue_size', '0 items'):>11} │ │ {flow_data.get('outgoing', {}).get('node_d', '0 KB/s'):>11} │ │
|
||
│ └─────────────┘ └─────────────┘ └─────────────┘ │
|
||
│ ║ ║ ║ │
|
||
│ ▼ ▼ ▼ │
|
||
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
|
||
│ │ Node-E │════════════════▶│ STORAGE │════════════════▶│ Node-F │ │
|
||
│ │ {flow_data.get('incoming', {}).get('node_e', '0 KB/s'):>11} │ │ {flow_data.get('storage_ops', '0 ops/s'):>11} │ │ {flow_data.get('outgoing', {}).get('node_f', '0 KB/s'):>11} │ │
|
||
│ └─────────────┘ └─────────────┘ └─────────────┘ │
|
||
│ │
|
||
│ Flow Statistics: │
|
||
│ • Total Throughput: {flow_data.get('total_throughput', '0 MB/s')} │
|
||
│ • Peak Bandwidth: {flow_data.get('peak_bandwidth', '0 MB/s')} │
|
||
│ • Average Latency: {flow_data.get('avg_latency', '0ms')} │
|
||
│ • Queue Backlog: {flow_data.get('queue_backlog', '0 items')} │
|
||
│ │
|
||
│ Legend: ════ High Volume │ ──── Normal │ ░░░░ Low Volume │ ╳╳╳╳ Error │
|
||
└────────────────────────────────────────────────────────────────────────────────────────────────────┘
|
||
"""
|
||
return flow_art
|
||
```
|
||
|
||
## API Endpoints для Мониторинга (/api/monitor/*)
|
||
|
||
### 1. Core Monitoring Endpoints
|
||
|
||
```python
|
||
from fastapi import APIRouter, HTTPException, BackgroundTasks
|
||
from fastapi.responses import StreamingResponse
|
||
import json
|
||
import asyncio
|
||
|
||
monitor_router = APIRouter(prefix="/api/monitor", tags=["monitoring"])
|
||
|
||
@monitor_router.get("/status")
|
||
async def get_node_status():
|
||
"""Получение статуса ноды"""
|
||
|
||
status = await NodeStatusCollector.get_current_status()
|
||
|
||
return {
|
||
"node_id": status["node_id"],
|
||
"uptime_seconds": status["uptime"],
|
||
"health_status": status["health"],
|
||
"peer_connections": status["peer_count"],
|
||
"content_stats": status["content_stats"],
|
||
"resource_usage": status["resource_usage"],
|
||
"network_metrics": status["network_metrics"],
|
||
"timestamp": status["timestamp"]
|
||
}
|
||
|
||
@monitor_router.get("/peers")
|
||
async def get_peer_status():
|
||
"""Статус всех подключенных пиров"""
|
||
|
||
peers = await PeerManager.get_all_peers_status()
|
||
|
||
return {
|
||
"total_peers": len(peers),
|
||
"active_peers": len([p for p in peers if p["status"] == "active"]),
|
||
"peers": [
|
||
{
|
||
"peer_id": peer["id"],
|
||
"address": peer["address"],
|
||
"status": peer["status"],
|
||
"latency_ms": peer["latency"],
|
||
"last_seen": peer["last_seen"],
|
||
"data_transferred": peer["data_transferred"],
|
||
"reputation_score": peer["reputation"]
|
||
}
|
||
for peer in peers
|
||
]
|
||
}
|
||
|
||
@monitor_router.get("/content")
|
||
async def get_content_metrics():
|
||
"""Метрики контента"""
|
||
|
||
metrics = await ContentMetricsCollector.get_metrics()
|
||
|
||
return {
|
||
"total_content_items": metrics["total_items"],
|
||
"content_by_type": metrics["by_type"],
|
||
"storage_usage": metrics["storage_usage"],
|
||
"replication_stats": metrics["replication"],
|
||
"sync_status": metrics["sync_status"],
|
||
"popular_content": metrics["popular_items"][:10]
|
||
}
|
||
|
||
@monitor_router.get("/network")
|
||
async def get_network_metrics():
|
||
"""Сетевые метрики"""
|
||
|
||
network_stats = await NetworkMetricsCollector.get_stats()
|
||
|
||
return {
|
||
"network_topology": network_stats["topology"],
|
||
"bandwidth_usage": network_stats["bandwidth"],
|
||
"message_stats": network_stats["messages"],
|
||
"consensus_metrics": network_stats["consensus"],
|
||
"error_rates": network_stats["errors"]
|
||
}
|
||
|
||
@monitor_router.get("/performance")
|
||
async def get_performance_metrics():
|
||
"""Метрики производительности"""
|
||
|
||
perf_data = await PerformanceCollector.get_metrics()
|
||
|
||
return {
|
||
"cpu_usage": perf_data["cpu"],
|
||
"memory_usage": perf_data["memory"],
|
||
"disk_io": perf_data["disk_io"],
|
||
"network_io": perf_data["network_io"],
|
||
"operation_latencies": perf_data["latencies"],
|
||
"throughput_stats": perf_data["throughput"]
|
||
}
|
||
```
|
||
|
||
### 2. Real-time Streaming Endpoints
|
||
|
||
```python
|
||
@monitor_router.get("/stream/status")
|
||
async def stream_node_status():
|
||
"""Потоковая передача статуса ноды"""
|
||
|
||
async def generate_status_stream():
|
||
while True:
|
||
try:
|
||
status = await NodeStatusCollector.get_current_status()
|
||
yield f"data: {json.dumps(status)}\n\n"
|
||
await asyncio.sleep(1)
|
||
except Exception as e:
|
||
yield f"data: {json.dumps({'error': str(e)})}\n\n"
|
||
break
|
||
|
||
return StreamingResponse(
|
||
generate_status_stream(),
|
||
media_type="text/plain",
|
||
headers={"Cache-Control": "no-cache"}
|
||
)
|
||
|
||
@monitor_router.get("/stream/content-flow")
|
||
async def stream_content_flow():
|
||
"""Потоковая передача данных о потоке контента"""
|
||
|
||
async def generate_flow_stream():
|
||
while True:
|
||
try:
|
||
flow_data = await ContentFlowMonitor.get_current_flow()
|
||
yield f"data: {json.dumps(flow_data)}\n\n"
|
||
await asyncio.sleep(0.5) # Высокая частота для real-time
|
||
except Exception as e:
|
||
yield f"data: {json.dumps({'error': str(e)})}\n\n"
|
||
break
|
||
|
||
return StreamingResponse(
|
||
generate_flow_stream(),
|
||
media_type="text/plain"
|
||
)
|
||
|
||
@monitor_router.post("/alerts/subscribe")
|
||
async def subscribe_to_alerts(subscription: AlertSubscription):
|
||
"""Подписка на алерты"""
|
||
|
||
subscription_id = await AlertManager.subscribe(subscription)
|
||
|
||
return {
|
||
"subscription_id": subscription_id,
|
||
"status": "subscribed",
|
||
"alert_types": subscription.alert_types
|
||
}
|
||
|
||
@monitor_router.get("/logs/tail")
|
||
async def tail_logs(lines: int = 100, level: str = "info"):
|
||
"""Получение последних логов"""
|
||
|
||
logs = await LogManager.get_recent_logs(lines, level)
|
||
|
||
return {
|
||
"logs": logs,
|
||
"total_lines": len(logs),
|
||
"level_filter": level
|
||
}
|
||
```
|
||
|
||
### 3. Advanced Analytics Endpoints
|
||
|
||
```python
|
||
@monitor_router.get("/analytics/performance")
|
||
async def get_performance_analytics(hours: int = 24):
|
||
"""Аналитика производительности за период"""
|
||
|
||
analytics = await PerformanceAnalyzer.analyze_period(hours)
|
||
|
||
return {
|
||
"period_hours": hours,
|
||
"summary": analytics["summary"],
|
||
"trends": analytics["trends"],
|
||
"bottlenecks": analytics["bottlenecks"],
|
||
"recommendations": analytics["recommendations"]
|
||
}
|
||
|
||
@monitor_router.get("/analytics/content-distribution")
|
||
async def get_content_distribution_analytics():
|
||
"""Аналитика распределения контента"""
|
||
|
||
distribution = await ContentAnalyzer.analyze_distribution()
|
||
|
||
return {
|
||
"replication_efficiency": distribution["efficiency"],
|
||
"load_balancing": distribution["balance"],
|
||
"hotspots": distribution["hotspots"],
|
||
"optimization_opportunities": distribution["optimizations"]
|
||
}
|
||
|
||
@monitor_router.get("/health-check")
|
||
async def comprehensive_health_check():
|
||
"""Комплексная проверка здоровья системы"""
|
||
|
||
health_status = await HealthChecker.perform_full_check()
|
||
|
||
return {
|
||
"overall_health": health_status["overall"],
|
||
"component_health": health_status["components"],
|
||
"critical_issues": health_status["critical"],
|
||
"warnings": health_status["warnings"],
|
||
"recommendations": health_status["recommendations"]
|
||
}
|
||
```
|
||
|
||
## Метрики Производительности и Нагрузки
|
||
|
||
### 1. Performance Metrics Collector
|
||
|
||
```python
|
||
class PerformanceMetricsCollector:
|
||
def __init__(self):
|
||
self.metrics_buffer = []
|
||
self.buffer_size = 1000
|
||
self.collection_interval = 5 # секунды
|
||
|
||
async def start_collection(self):
|
||
"""Запуск сбора метрик"""
|
||
asyncio.create_task(self.collect_system_metrics())
|
||
asyncio.create_task(self.collect_network_metrics())
|
||
asyncio.create_task(self.collect_application_metrics())
|
||
|
||
async def collect_system_metrics(self):
|
||
"""Сбор системных метрик"""
|
||
while True:
|
||
try:
|
||
metrics = {
|
||
"timestamp": datetime.utcnow().isoformat(),
|
||
"type": "system",
|
||
"cpu_percent": psutil.cpu_percent(interval=1),
|
||
"memory_percent": psutil.virtual_memory().percent,
|
||
"memory_available": psutil.virtual_memory().available,
|
||
"disk_usage": {
|
||
path: psutil.disk_usage(path).percent
|
||
for path in ["/", "/tmp", "/var/log"]
|
||
},
|
||
"disk_io": await self.get_disk_io_stats(),
|
||
"network_io": await self.get_network_io_stats(),
|
||
"load_average": os.getloadavg(),
|
||
"process_count": len(psutil.pids())
|
||
}
|
||
|
||
await self.store_metric(metrics)
|
||
await asyncio.sleep(self.collection_interval)
|
||
|
||
except Exception as e:
|
||
logger.error(f"Error collecting system metrics: {e}")
|
||
await asyncio.sleep(self.collection_interval)
|
||
|
||
async def collect_network_metrics(self):
|
||
"""Сбор сетевых метрик"""
|
||
while True:
|
||
try:
|
||
network_stats = await self.get_network_statistics()
|
||
|
||
metrics = {
|
||
"timestamp": datetime.utcnow().isoformat(),
|
||
"type": "network",
|
||
"active_connections": network_stats["connections"],
|
||
"bytes_sent": network_stats["bytes_sent"],
|
||
"bytes_received": network_stats["bytes_received"],
|
||
"packets_sent": network_stats["packets_sent"],
|
||
"packets_received": network_stats["packets_received"],
|
||
"errors": network_stats["errors"],
|
||
"drops": network_stats["drops"],
|
||
"peer_latencies": await self.measure_peer_latencies(),
|
||
"bandwidth_usage": await self.calculate_bandwidth_usage()
|
||
}
|
||
|
||
await self.store_metric(metrics)
|
||
await asyncio.sleep(self.collection_interval)
|
||
|
||
except Exception as e:
|
||
logger.error(f"Error collecting network metrics: {e}")
|
||
await asyncio.sleep(self.collection_interval)
|
||
|
||
async def collect_application_metrics(self):
|
||
"""Сбор метрик приложения"""
|
||
while True:
|
||
try:
|
||
app_stats = await self.get_application_statistics()
|
||
|
||
metrics = {
|
||
"timestamp": datetime.utcnow().isoformat(),
|
||
"type": "application",
|
||
"content_operations": app_stats["content_ops"],
|
||
"sync_operations": app_stats["sync_ops"],
|
||
"consensus_operations": app_stats["consensus_ops"],
|
||
"replication_operations": app_stats["replication_ops"],
|
||
"api_requests": app_stats["api_requests"],
|
||
"error_rates": app_stats["error_rates"],
|
||
"queue_sizes": app_stats["queue_sizes"],
|
||
"cache_hit_rates": app_stats["cache_stats"]
|
||
}
|
||
|
||
await self.store_metric(metrics)
|
||
await asyncio.sleep(self.collection_interval)
|
||
|
||
except Exception as e:
|
||
logger.error(f"Error collecting application metrics: {e}")
|
||
await asyncio.sleep(self.collection_interval)
|
||
```
|
||
|
||
### 2. Load Testing and Stress Monitoring
|
||
|
||
```python
|
||
class LoadMonitor:
|
||
def __init__(self):
|
||
self.load_thresholds = {
|
||
"cpu_critical": 90.0,
|
||
"cpu_warning": 70.0,
|
||
"memory_critical": 95.0,
|
||
"memory_warning": 80.0,
|
||
"disk_critical": 95.0,
|
||
"disk_warning": 85.0,
|
||
"network_critical": 90.0,
|
||
"network_warning": 70.0
|
||
}
|
||
|
||
async def monitor_load_continuously(self):
|
||
"""Непрерывный мониторинг нагрузки"""
|
||
while True:
|
||
try:
|
||
current_load = await self.assess_current_load()
|
||
|
||
# Проверка критических уровней
|
||
critical_alerts = await self.check_critical_levels(current_load)
|
||
if critical_alerts:
|
||
await self.handle_critical_alerts(critical_alerts)
|
||
|
||
# Проверка предупреждений
|
||
warning_alerts = await self.check_warning_levels(current_load)
|
||
if warning_alerts:
|
||
await self.handle_warning_alerts(warning_alerts)
|
||
|
||
# Адаптивное управление ресурсами
|
||
await self.adaptive_resource_management(current_load)
|
||
|
||
await asyncio.sleep(10) # Проверка каждые 10 секунд
|
||
|
||
except Exception as e:
|
||
logger.error(f"Error in load monitoring: {e}")
|
||
await asyncio.sleep(10)
|
||
|
||
async def assess_current_load(self) -> dict:
|
||
"""Оценка текущей нагрузки"""
|
||
return {
|
||
"cpu_load": psutil.cpu_percent(interval=1),
|
||
"memory_load": psutil.virtual_memory().percent,
|
||
"disk_load": max([
|
||
psutil.disk_usage(path).percent
|
||
for path in ["/", "/tmp", "/var/log"]
|
||
]),
|
||
"network_load": await self.calculate_network_load(),
|
||
"application_load": await self.calculate_application_load(),
|
||
"timestamp": datetime.utcnow()
|
||
}
|
||
|
||
async def adaptive_resource_management(self, current_load: dict):
|
||
"""Адаптивное управление ресурсами"""
|
||
|
||
# CPU нагрузка
|
||
if current_load["cpu_load"] > self.load_thresholds["cpu_warning"]:
|
||
await self.reduce_cpu_intensive_operations()
|
||
|
||
# Память
|
||
if current_load["memory_load"] > self.load_thresholds["memory_warning"]:
|
||
await self.optimize_memory_usage()
|
||
|
||
# Сеть
|
||
if current_load["network_load"] > self.load_thresholds["network_warning"]:
|
||
await self.throttle_network_operations()
|
||
|
||
# Приложение
|
||
if current_load["application_load"] > 80.0:
|
||
await self.scale_application_resources()
|
||
```
|
||
|
||
## Telegram Bot Команды для Управления
|
||
|
||
### 1. MY Network Telegram Bot
|
||
|
||
```python
|
||
from aiogram import Bot, Dispatcher, types
|
||
from aiogram.filters import Command
|
||
from aiogram.types import InlineKeyboardButton, InlineKeyboardMarkup
|
||
|
||
class MYNetworkTelegramBot:
|
||
def __init__(self, token: str, authorized_users: List[int]):
|
||
self.bot = Bot(token)
|
||
self.dp = Dispatcher()
|
||
self.authorized_users = set(authorized_users)
|
||
self.setup_handlers()
|
||
|
||
def setup_handlers(self):
|
||
"""Настройка обработчиков команд"""
|
||
|
||
@self.dp.message(Command("start"))
|
||
async def start_command(message: types.Message):
|
||
if message.from_user.id not in self.authorized_users:
|
||
await message.reply("❌ Access denied. Unauthorized user.")
|
||
return
|
||
|
||
keyboard = InlineKeyboardMarkup(inline_keyboard=[
|
||
[InlineKeyboardButton(text="📊 Node Status", callback_data="status")],
|
||
[InlineKeyboardButton(text="🌐 Network Info", callback_data="network")],
|
||
[InlineKeyboardButton(text="📁 Content Stats", callback_data="content")],
|
||
[InlineKeyboardButton(text="⚡ Performance", callback_data="performance")],
|
||
[InlineKeyboardButton(text="🔧 Controls", callback_data="controls")]
|
||
])
|
||
|
||
await message.reply(
|
||
"🤖 MY Network Control Bot\n\n"
|
||
"Welcome to the MY Network monitoring and control interface.\n"
|
||
"Select an option below:",
|
||
reply_markup=keyboard
|
||
)
|
||
|
||
@self.dp.message(Command("status"))
|
||
async def status_command(message: types.Message):
|
||
if message.from_user.id not in self.authorized_users:
|
||
return
|
||
|
||
try:
|
||
status = await NodeStatusCollector.get_current_status()
|
||
|
||
status_text = f"""
|
||
🖥 **MY Network Node Status**
|
||
|
||
🆔 Node ID: `{status['node_id'][:16]}...`
|
||
⏰ Uptime: {self.format_uptime(status['uptime'])}
|
||
🟢 Status: {status['health_status']}
|
||
👥 Peers: {status['peer_count']} connected
|
||
📁 Content: {status['content_count']} items
|
||
💾 Storage: {status['storage_usage']}
|
||
🔄 Sync: {status['sync_status']}
|
||
|
||
📊 **Resources:**
|
||
🖥 CPU: {status['cpu_usage']:.1f}%
|
||
💾 RAM: {status['memory_usage']:.1f}%
|
||
💿 Disk: {status['disk_usage']:.1f}%
|
||
🌐 Network: {status['network_io']}
|
||
"""
|
||
|
||
await message.reply(status_text, parse_mode="Markdown")
|
||
|
||
except Exception as e:
|
||
await message.reply(f"❌ Error getting status: {str(e)}")
|
||
|
||
@self.dp.message(Command("peers"))
|
||
async def peers_command(message: types.Message):
|
||
if message.from_user.id not in self.authorized_users:
|
||
return
|
||
|
||
try:
|
||
peers = await PeerManager.get_all_peers_status()
|
||
|
||
if not peers:
|
||
await message.reply("No peers connected.")
|
||
return
|
||
|
||
peers_text = "👥 **Connected Peers:**\n\n"
|
||
|
||
for peer in peers[:10]: # Показать первые 10
|
||
status_emoji = "🟢" if peer["status"] == "active" else "🔴"
|
||
peers_text += f"{status_emoji} `{peer['id'][:12]}...`\n"
|
||
peers_text += f" 📍 {peer['address']}\n"
|
||
peers_text += f" ⏱ {peer['latency']}ms\n"
|
||
peers_text += f" 📊 {peer['reputation']:.2f}/5.0\n\n"
|
||
|
||
if len(peers) > 10:
|
||
peers_text += f"... and {len(peers) - 10} more peers"
|
||
|
||
await message.reply(peers_text, parse_mode="Markdown")
|
||
|
||
except Exception as e:
|
||
await message.reply(f"❌ Error getting peers: {str(e)}")
|
||
|
||
@self.dp.message(Command("sync"))
|
||
async def sync_command(message: types.Message):
|
||
if message.from_user.id not in self.authorized_users:
|
||
return
|
||
|
||
try:
|
||
# Запуск принудительной синхронизации
|
||
sync_task = await ContentSyncManager.start_full_sync()
|
||
|
||
await message.reply(
|
||
f"🔄 Full synchronization started\n"
|
||
f"Task ID: `{sync_task.id}`\n"
|
||
f"Use /sync_status to check progress."
|
||
)
|
||
|
||
except Exception as e:
|
||
await message.reply(f"❌ Error starting sync: {str(e)}")
|
||
|
||
@self.dp.message(Command("alerts"))
|
||
async def alerts_command(message: types.Message):
|
||
if message.from_user.id not in self.authorized_users:
|
||
return
|
||
|
||
try:
|
||
recent_alerts = await AlertManager.get_recent_alerts(limit=10)
|
||
|
||
if not recent_alerts:
|
||
await message.reply("✅ No recent alerts.")
|
||
return
|
||
|
||
alerts_text = "🚨 **Recent Alerts:**\n\n"
|
||
|
||
for alert in recent_alerts:
|
||
severity_emoji = {
|
||
"critical": "🔴",
|
||
"warning": "🟡",
|
||
"info": "ℹ️"
|
||
}.get(alert["severity"], "ℹ️")
|
||
|
||
alerts_text += f"{severity_emoji} **{alert['title']}**\n"
|
||
alerts_text += f" {alert['message']}\n"
|
||
alerts_text += f" 📅 {alert['timestamp']}\n\n"
|
||
|
||
await message.reply(alerts_text, parse_mode="Markdown")
|
||
|
||
except Exception as e:
|
||
await message.reply(f"❌ Error getting alerts: {str(e)}")
|
||
```
|
||
|
||
### 2. Advanced Bot Commands
|
||
|
||
```python
|
||
@self.dp.message(Command("restart"))
|
||
async def restart_command(message: types.Message):
|
||
if message.from_user.id not in self.authorized_users:
|
||
return
|
||
|
||
# Подтверждение перезапуска
|
||
keyboard = InlineKeyboardMarkup(inline_keyboard=[
|
||
[InlineKeyboardButton(text="✅ Confirm Restart", callback_data="restart_confirm")],
|
||
[InlineKeyboardButton(text="❌ Cancel", callback_data="restart_cancel")]
|
||
])
|
||
|
||
await message.reply(
|
||
"⚠️ **Restart Confirmation**\n\n"
|
||
"This will restart the MY Network node.\n"
|
||
"All active connections will be lost.\n\n"
|
||
"Are you sure?",
|
||
reply_markup=keyboard,
|
||
parse_mode="Markdown"
|
||
)
|
||
|
||
@self.dp.message(Command("config"))
|
||
async def config_command(message: types.Message, args: str = None):
|
||
if message.from_user.id not in self.authorized_users:
|
||
return
|
||
|
||
if not args:
|
||
# Показать текущую конфигурацию
|
||
config = await ConfigManager.get_current_config()
|
||
|
||
config_text = f"""
|
||
⚙️ **Current Configuration:**
|
||
|
||
🔧 **Network Settings:**
|
||
• Max Peers: {config['max_peers']}
|
||
• Sync Interval: {config['sync_interval']}s
|
||
• Consensus Timeout: {config['consensus_timeout']}s
|
||
|
||
📊 **Resource Limits:**
|
||
• Max Storage: {config['max_storage']}
|
||
• Max Bandwidth: {config['max_bandwidth']}
|
||
• Max Memory: {config['max_memory']}
|
||
|
||
🔒 **Security:**
|
||
• Encryption: {config['encryption_enabled']}
|
||
• Auth Required: {config['auth_required']}
|
||
"""
|
||
|
||
await message.reply(config_text, parse_mode="Markdown")
|
||
else:
|
||
# Обновить конфигурацию
|
||
try:
|
||
key, value = args.split("=", 1)
|
||
await ConfigManager.update_config(key.strip(), value.strip())
|
||
await message.reply(f"✅ Configuration updated: {key} = {value}")
|
||
except ValueError:
|
||
await message.reply(
|
||
"❌ Invalid format. Use: /config key=value"
|
||
)
|
||
except Exception as e:
|
||
await message.reply(f"❌ Error updating config: {str(e)}")
|
||
|
||
@self.dp.message(Command("blacklist"))
|
||
async def blacklist_command(message: types.Message, args: str = None):
|
||
if message.from_user.id not in self.authorized_users:
|
||
return
|
||
|
||
if not args:
|
||
# Показать blacklist
|
||
blacklisted = await PeerManager.get_blacklisted_peers()
|
||
|
||
if not blacklisted:
|
||
await message.reply("📝 Blacklist is empty.")
|
||
return
|
||
|
||
blacklist_text = "🚫 **Blacklisted Peers:**\n\n"
|
||
for peer_id in blacklisted:
|
||
blacklist_text += f"• `{peer_id}`\n"
|
||
|
||
await message.reply(blacklist_text, parse_mode="Markdown")
|
||
else:
|
||
# Добавить в blacklist
|
||
try:
|
||
peer_id = args.strip()
|
||
await PeerManager.blacklist_peer(peer_id)
|
||
await message.reply(f"✅ Peer blacklisted: `{peer_id}`")
|
||
except Exception as e:
|
||
await message.reply(f"❌ Error blacklisting peer: {str(e)}")
|
||
```
|
||
|
||
## Web-интерфейс
|
||
|
||
### 1. Web Dashboard
|
||
|
||
```html
|
||
<!DOCTYPE html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>MY Network Monitoring Dashboard</title>
|
||
<style>
|
||
body {
|
||
background: #0d1117;
|
||
color: #c9d1d9;
|
||
font-family: 'Courier New', monospace;
|
||
margin: 0;
|
||
padding: 20px;
|
||
}
|
||
|
||
.dashboard {
|
||
max-width: 1600px;
|
||
margin: 0 auto;
|
||
}
|
||
|
||
.header {
|
||
text-align: center;
|
||
padding: 20px;
|
||
border: 2px solid #30363d;
|
||
margin-bottom: 20px;
|
||
background: linear-gradient(45deg, #0d1117, #161b22);
|
||
}
|
||
|
||
.status-grid {
|
||
display: grid;
|
||
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
|
||
gap: 20px;
|
||
margin-bottom: 30px;
|
||
}
|
||
|
||
.status-card {
|
||
background: #161b22;
|
||
border: 1px solid #30363d;
|
||
border-radius: 6px;
|
||
padding: 20px;
|
||
box-shadow: 0 0 10px rgba(0, 255, 0, 0.1);
|
||
}
|
||
|
||
.terminal {
|
||
background: #000;
|
||
border: 2px solid #00ff00;
|
||
border-radius: 4px;
|
||
padding: 15px;
|
||
font-family: 'Courier New', monospace;
|
||
font-size: 12px;
|
||
height: 400px;
|
||
overflow-y: auto;
|
||
white-space: pre-wrap;
|
||
}
|
||
|
||
.metric-bar {
|
||
background: #21262d;
|
||
height: 20px;
|
||
border-radius: 10px;
|
||
overflow: hidden;
|
||
margin: 5px 0;
|
||
}
|
||
|
||
.metric-fill {
|
||
height: 100%;
|
||
transition: width 0.3s ease;
|
||
}
|
||
|
||
.metric-fill.cpu { background: linear-gradient(90deg, #28a745, #ffc107, #dc3545); }
|
||
.metric-fill.memory { background: linear-gradient(90deg, #17a2b8, #6f42c1); }
|
||
.metric-fill.disk { background: linear-gradient(90deg, #fd7e14, #e83e8c); }
|
||
|
||
.blink {
|
||
animation: blink 1s infinite;
|
||
}
|
||
|
||
@keyframes blink {
|
||
0%, 50% { opacity: 1; }
|
||
51%, 100% { opacity: 0.3; }
|
||
}
|
||
|
||
.network-graph {
|
||
width: 100%;
|
||
height: 300px;
|
||
border: 1px solid #30363d;
|
||
background: #0d1117;
|
||
}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<div class="dashboard">
|
||
<div class="header">
|
||
<h1>🔹 MY NETWORK MONITORING DASHBOARD 🔹</h1>
|
||
<p>Real-time monitoring of distributed content network</p>
|
||
<div id="connection-status" class="blink">🟢 CONNECTED</div>
|
||
</div>
|
||
|
||
<div class="status-grid">
|
||
<div class="status-card">
|
||
<h3>📊 Node Status</h3>
|
||
<div id="node-status">
|
||
<p>Node ID: <span id="node-id">Loading...</span></p>
|
||
<p>Uptime: <span id="uptime">Loading...</span></p>
|
||
<p>Status: <span id="health-status">Loading...</span></p>
|
||
<p>Peers: <span id="peer-count">Loading...</span></p>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="status-card">
|
||
<h3>💾 Resources</h3>
|
||
<div>
|
||
<p>CPU Usage:</p>
|
||
<div class="metric-bar">
|
||
<div class="metric-fill cpu" id="cpu-bar" style="width: 0%"></div>
|
||
</div>
|
||
<p>Memory Usage:</p>
|
||
<div class="metric-bar">
|
||
<div class="metric-fill memory" id="memory-bar" style="width: 0%"></div>
|
||
</div>
|
||
<p>Disk Usage:</p>
|
||
<div class="metric-bar">
|
||
<div class="metric-fill disk" id="disk-bar" style="width: 0%"></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="status-card">
|
||
<h3>🌐 Network</h3>
|
||
<div id="network-stats">
|
||
<p>Bandwidth: <span id="bandwidth">Loading...</span></p>
|
||
<p>Latency: <span id="latency">Loading...</span></p>
|
||
<p>Messages/sec: <span id="message-rate">Loading...</span></p>
|
||
<p>Errors: <span id="error-count">Loading...</span></p>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="status-card">
|
||
<h3>📁 Content</h3>
|
||
<div id="content-stats">
|
||
<p>Total Items: <span id="content-count">Loading...</span></p>
|
||
<p>Sync Status: <span id="sync-status">Loading...</span></p>
|
||
<p>Replication Rate: <span id="replication-rate">Loading...</span></p>
|
||
<p>Storage Used: <span id="storage-used">Loading...</span></p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="status-grid">
|
||
<div class="status-card">
|
||
<h3>📡 Live Terminal</h3>
|
||
<div class="terminal" id="live-terminal">
|
||
Connecting to MY Network node...<br>
|
||
Establishing secure connection...<br>
|
||
<span class="blink">█</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="status-card">
|
||
<h3>🗺️ Network Topology</h3>
|
||
<canvas class="network-graph" id="network-graph"></canvas>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<script>
|
||
// WebSocket connection for real-time updates
|
||
const ws = new WebSocket('ws://localhost:8080/ws/monitor');
|
||
|
||
ws.onopen = function(event) {
|
||
document.getElementById('connection-status').textContent = '🟢 CONNECTED';
|
||
document.getElementById('connection-status').classList.remove('blink');
|
||
};
|
||
|
||
ws.onmessage = function(event) {
|
||
const data = JSON.parse(event.data);
|
||
updateDashboard(data);
|
||
};
|
||
|
||
ws.onclose = function(event) {
|
||
document.getElementById('connection-status').textContent = '🔴 DISCONNECTED';
|
||
document.getElementById('connection-status').classList.add('blink');
|
||
};
|
||
|
||
function updateDashboard(data) {
|
||
// Update node status
|
||
document.getElementById('node-id').textContent = data.node_id?.substring(0, 16) + '...';
|
||
document.getElementById('uptime').textContent = formatUptime(data.uptime);
|
||
document.getElementById('health-status').textContent = data.health_status;
|
||
document.getElementById('peer-count').textContent = data.peer_count;
|
||
|
||
// Update resource bars
|
||
document.getElementById('cpu-bar').style.width = data.cpu_usage + '%';
|
||
document.getElementById('memory-bar').style.width = data.memory_usage + '%';
|
||
document.getElementById('disk-bar').style.width = data.disk_usage + '%';
|
||
|
||
// Update network stats
|
||
document.getElementById('bandwidth').textContent = data.bandwidth;
|
||
document.getElementById('latency').textContent = data.latency + 'ms';
|
||
document.getElementById('message-rate').textContent = data.message_rate;
|
||
document.getElementById('error-count').textContent = data.error_count;
|
||
|
||
// Update content stats
|
||
document.getElementById('content-count').textContent = data.content_count;
|
||
document.getElementById('sync-status').textContent = data.sync_status;
|
||
document.getElementById('replication-rate').textContent = data.replication_rate;
|
||
document.getElementById('storage-used').textContent = data.storage_used;
|
||
|
||
// Update terminal
|
||
if (data.terminal_output) {
|
||
const terminal = document.getElementById('live-terminal');
|
||
terminal.innerHTML += data.terminal_output + '<br>';
|
||
terminal.scrollTop = terminal.scrollHeight;
|
||
}
|
||
}
|
||
|
||
function formatUptime(seconds) {
|
||
const days = Math.floor(seconds / 86400);
|
||
const hours = Math.floor((seconds % 86400) / 3600);
|
||
const minutes = Math.floor((seconds % 3600) / 60);
|
||
return `${days}d ${hours}h ${minutes}m`;
|
||
}
|
||
|
||
// Network topology visualization
|
||
function drawNetworkTopology() {
|
||
const canvas = document.getElementById('network-graph');
|
||
const ctx = canvas.getContext('2d');
|
||
|
||
// Simple network visualization
|
||
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||
ctx.strokeStyle = '#00ff00';
|
||
ctx.fillStyle = '#00ff00';
|
||
|
||
// Draw nodes and connections
|
||
// Implementation would show actual network topology
|
||
}
|
||
|
||
// Initialize
|
||
setInterval(drawNetworkTopology, 5000);
|
||
</script>
|
||
</body>
|
||
</html>
|
||
```
|
||
|
||
Данная система мониторинга обеспечивает полный контроль над MY Network с помощью различных интерфейсов - от хакерского ASCII-арт терминала до современного веб-интерфейса и Telegram бота для удаленного управления. |