You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Django的网络设备实时监控:如何实现10秒自动更新状态

Great question! Let's break this down into manageable parts—you'll need a mix of Django backend logic to fetch device statuses, frontend JavaScript for auto-updates, and Mapbox for interactive map visualization. Here's a step-by-step implementation plan:

1. Backend Setup: Track Devices & Fetch Statuses

First, we'll build the foundation to manage your devices and retrieve their statuses via Ping or SNMP.

1.1 Define a Device Model

Create a Django model to store device details (so you don't hardcode them):

from django.db import models

class Device(models.Model):
    MONITOR_TYPES = (
        ('ping', 'Ping'),
        ('snmp', 'SNMP'),
    )
    name = models.CharField(max_length=50)  # e.g., PC1
    city = models.CharField(max_length=50)  # e.g., city1
    latitude = models.FloatField()  # For Mapbox mapping
    longitude = models.FloatField()
    monitor_type = models.CharField(max_length=10, choices=MONITOR_TYPES)
    target_ip = models.GenericIPAddressField()
    snmp_community = models.CharField(max_length=50, blank=True, null=True)  # Only for SNMP

    def __str__(self):
        return f"{self.name} ({self.city})"

1.2 Build Status-Checking Utilities

Write helper functions to ping devices or query SNMP:

# utils.py
import subprocess
from pysnmp.hlapi import *

def check_ping_status(ip):
    # Cross-platform ping (adjust args for Windows/Linux)
    ping_args = ['ping', '-c', '2', '-W', '1', ip] if os.name == 'posix' else ['ping', '-n', '2', '-w', '1000', ip]
    try:
        result = subprocess.run(
            ping_args,
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
            text=True
        )
        return result.returncode == 0  # 0 = success
    except Exception as e:
        print(f"Ping error for {ip}: {str(e)}")
        return False

def check_snmp_status(ip, community):
    try:
        # Query a basic SNMP OID (system description) to confirm reachability
        errorIndication, errorStatus, _, _ = next(
            getCmd(SnmpEngine(),
                   CommunityData(community),
                   UdpTransportTarget((ip, 161)),
                   ContextData(),
                   ObjectType(ObjectIdentity('1.3.6.1.2.1.1.1.0')))
        )
        return not (errorIndication or errorStatus)
    except Exception as e:
        print(f"SNMP error for {ip}: {str(e)}")
        return False

1.3 Create an API Endpoint for Status Data

Build a Django view that returns device statuses as JSON (for frontend consumption):

# views.py
from django.http import JsonResponse
from .models import Device
from .utils import check_ping_status, check_snmp_status

def device_status_api(request):
    devices = Device.objects.all()
    status_list = []
    
    for device in devices:
        is_online = False
        if device.monitor_type == 'ping':
            is_online = check_ping_status(device.target_ip)
        else:
            is_online = check_snmp_status(device.target_ip, device.snmp_community)
        
        status_list.append({
            'id': device.id,
            'name': device.name,
            'city': device.city,
            'lat': device.latitude,
            'lon': device.longitude,
            'is_online': is_online
        })
    
    return JsonResponse({'devices': status_list})

Don't forget to map this view in your urls.py:

path('api/device-status/', views.device_status_api, name='device-status-api')
2. Frontend: Auto-Update & Map Visualization

Now we'll build the webpage that pulls status data every 10 seconds and displays it on a Mapbox map.

2.1 Mapbox Integration & Auto-Update Logic

Add this to your Django template (replace YOUR_MAPBOX_TOKEN with your actual token from Mapbox):

<!-- map_template.html -->
<!DOCTYPE html>
<html>
<head>
    <title>Device Status Monitor</title>
    <script src='https://api.mapbox.com/mapbox-gl-js/v2.15.0/mapbox-gl.js'></script>
    <link href='https://api.mapbox.com/mapbox-gl-js/v2.15.0/mapbox-gl.css' rel='stylesheet' />
    <style>
        #map { width: 100%; height: 70vh; }
        .status-badge { padding: 8px; margin: 10px 0; border-radius: 4px; }
        .online { background-color: #d4edda; color: #155724; }
        .offline { background-color: #f8d7da; color: #721c24; }
    </style>
</head>
<body>
    <h1>Distributed Device Monitor</h1>
    <div id="status-summary" class="status-badge"></div>
    <div id="map"></div>

    <script>
        mapboxgl.accessToken = 'YOUR_MAPBOX_TOKEN';
        const map = new mapboxgl.Map({
            container: 'map',
            style: 'mapbox://styles/mapbox/streets-v12',
            center: [0, 0], // Adjust to your devices' average location
            zoom: 2
        });

        // Store markers to update them later (avoid re-creating every time)
        const deviceMarkers = {};

        // Fetch and update statuses
        function updateStatuses() {
            fetch('/api/device-status/')
                .then(res => res.json())
                .then(data => {
                    const summaryDiv = document.getElementById('status-summary');
                    const onlineCount = data.devices.filter(d => d.is_online).length;
                    summaryDiv.textContent = `Last updated: ${new Date().toLocaleString()} | ${onlineCount}/${data.devices.length} devices online`;
                    summaryDiv.className = `status-badge ${onlineCount === data.devices.length ? 'online' : 'offline'}`;

                    // Update map markers
                    data.devices.forEach(device => {
                        const markerColor = device.is_online ? '#2ecc71' : '#e74c3c';
                        
                        if (deviceMarkers[device.id]) {
                            // Update existing marker color
                            deviceMarkers[device.id].getElement().style.backgroundColor = markerColor;
                            deviceMarkers[device.id].getElement().title = `${device.name} (${device.city}): ${device.is_online ? 'Online' : 'Offline'}`;
                        } else {
                            // Create new marker
                            const markerEl = document.createElement('div');
                            markerEl.style.width = '22px';
                            markerEl.style.height = '22px';
                            markerEl.style.borderRadius = '50%';
                            markerEl.style.backgroundColor = markerColor;
                            markerEl.style.cursor = 'pointer';
                            markerEl.title = `${device.name} (${device.city}): ${device.is_online ? 'Online' : 'Offline'}`;

                            const marker = new mapboxgl.Marker(markerEl)
                                .setLngLat([device.lon, device.lat])
                                .addTo(map);
                            
                            deviceMarkers[device.id] = marker;
                        }
                    });
                })
                .catch(err => {
                    console.error('Failed to fetch status:', err);
                    document.getElementById('status-summary').textContent = 'Error updating status - retrying...';
                    document.getElementById('status-summary').className = 'status-badge offline';
                });
        }

        // Initial load + auto-update every 10 seconds
        window.onload = () => {
            updateStatuses();
            setInterval(updateStatuses, 10000);
        };
    </script>
</body>
</html>
3. Optimization & Best Practices
  • Performance: For large numbers of devices, use Celery + Redis to pre-fetch statuses asynchronously (e.g., every 5 seconds) and cache results. The API can then return cached data instead of running checks on every request.
  • Error Handling: Add retries for failed ping/SNMP checks, and handle cases where devices are unreachable (don't just return False—log the error for debugging).
  • Security: Never expose SNMP community strings in frontend code. All SNMP/Ping logic runs exclusively on the backend. Add Django authentication to the API endpoint if needed.
  • Cross-Platform Compatibility: The ping utility uses different arguments on Windows vs. Linux—we added a check for os.name to handle this, but test it in your environment.

内容的提问来源于stack exchange,提问作者shami shami

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 04:28:03