JotunMonitoring / PcMonitor / PcMonitor.py
PcMonitor.py
Raw
from prometheus_client import start_http_server, Gauge
import time
import ping3
from scapy.all import ARP, Ether, srp, IP, ICMP

pcs = [

    {"ip": "10.10.20.28", "pc":13, "location": "HUB1"},
    {"ip": "10.10.20.82", "pc":12, "location": "HUB1"},
    {"ip": "10.10.20.76", "pc":11, "location": "HUB1"},
    {"ip": "10.10.20.31", "pc":16, "location": "HUB1"},
    {"ip": "10.10.20.27", "pc":15, "location": "HUB1"},
    {"ip": "10.10.20.26", "pc":14, "location": "HUB1"},

    {"ip": "10.10.20.40", "pc":23, "location": "HUB2"},
    {"ip": "10.10.20.30", "pc":22, "location": "HUB2"},
    {"ip": "10.10.20.43", "pc":21, "location": "HUB2"},
    {"ip": "10.10.20.66", "pc":26, "location": "HUB2"},
    {"ip": "10.10.20.52", "pc":25, "location": "HUB2"},
    {"ip": "10.10.20.34", "pc":24, "location": "HUB2"},


    {"ip": "10.10.20.104", "pc":33, "location": "HUB3"},
    {"ip": "10.10.20.60", "pc":32, "location": "HUB3"},
    {"ip": "10.10.20.4", "pc":31, "location": "HUB3"},
    {"ip": "10.10.20.103", "pc":36, "location": "HUB3"},
    {"ip": "10.10.20.65", "pc":35, "location": "HUB3"},
    {"ip": "10.10.20.5", "pc":34, "location": "HUB3"},



    {"ip": "10.10.20.33", "pc":43, "location": "HUB4"},
    {"ip": "10.10.20.16", "pc":42, "location": "HUB4"},
    {"ip": "10.10.20.22", "pc":41, "location": "HUB4"},
    {"ip": "10.10.20.8", "pc":46, "location": "HUB4"},
    {"ip": "10.10.20.70", "pc":45, "location": "HUB4"},
    {"ip": "10.10.20.29", "pc":44, "location": "HUB4"},



    {"ip": "10.10.20.18", "pc":53, "location": "HUB5"},
    {"ip": "10.10.20.9", "pc":52, "location": "HUB5"},
    {"ip": "10.10.20.46", "pc":51, "location": "HUB5"},
    {"ip": "10.10.20.10", "pc":56, "location": "HUB5"},
    {"ip": "10.10.20.86", "pc":55, "location": "HUB5"},
    {"ip": "10.10.20.127", "pc":54, "location": "HUB5"},

    {"ip": "10.10.20.98", "pc":63, "location": "HUB6"},
    {"ip": "10.10.20.137", "pc":62, "location": "HUB6"},
    {"ip": "10.10.20.15", "pc":61, "location": "HUB6"},
    {"ip": "10.10.20.72", "pc":66, "location": "HUB6"},
    {"ip": "10.10.20.21", "pc":65, "location": "HUB6"},
    {"ip": "10.10.20.90", "pc":64, "location": "HUB6"},

    {"ip": "10.10.20.88", "pc":73, "location": "HUB7"},
    {"ip": "10.10.20.58", "pc":72, "location": "HUB7"},
    {"ip": "10.10.20.132", "pc":71, "location": "HUB7"},
    {"ip": "10.10.20.25", "pc":76, "location": "HUB7"},
    {"ip": "10.10.20.74", "pc":75, "location": "HUB7"},
    {"ip": "10.10.20.87", "pc":74, "location": "HUB7"},

]

pc_status = Gauge('pc_status', 'Status of PCs (1 = online, 0 = offline)', ['ip', 'location', 'pc'] )

def arp_scan(network):
    """
    Perform an ARP scan on the given network (e.g., '10.10.20.0/24').
    Returns a dictionary mapping IP addresses to MAC addresses.
    """
    # Create an ARP request packet for the network
    arp = ARP(pdst=network)
    # Create an Ethernet frame with a broadcast destination MAC
    ether = Ether(dst="ff:ff:ff:ff:ff:ff")
    packet = ether / arp

    # Send the packet and collect responses
    result = srp(packet, timeout=3, verbose=0)[0]

    devices = {}
    for sent, received in result:
        devices[received.psrc] = received.hwsrc
    return devices

def ping_pc(ip):
    """
    Ping a PC and return True if online, False if offline.
    """
    try:
        response = ping3.ping(ip, timeout=1)
        return response is not None
    except Exception:
        return False

def update_metrics():
    """
    Update Prometheus metrics with the status of each PC.
    """
    for pc in pcs:
        ip = pc["ip"]
        location = pc["location"]
        status = ping_pc(ip)
        pc_status.labels(ip=ip, location=location, pc=pc["ip"]).set(1 if status else 0)

def update_metrics_arp():
    """
    Update Prometheus metrics with the status of each PC using ARP scanning.
    Only works within your local subnet.
    """
    # Define your network range (adjust if necessary)
    network = "10.10.20.0/24"
    # Perform an ARP scan on the network
    devices = arp_scan(network)

    for pc in pcs:
        ip = pc["ip"]
        location = pc["location"]
        # Mark as online if the IP was found in the ARP scan
        status = 1 if ip in devices else 0
        pc_status.labels(ip=ip, location=location, pc=str(pc["pc"])).set(status)


if __name__ == '__main__':
    # Start the Prometheus HTTP server on port 8000
    start_http_server(8003)
    print("Prometheus metrics server started on port 8000")


    update_fn = update_metrics_arp
    # Continuously update metrics
    while True:
        update_fn()
        time.sleep(15)  # Update every 15 seconds