Lightweight Internet Uptime Monitor for Windows: Ping-Based Downtime Reporting Tool


8 views

Monitoring basic internet connectivity in small offices often gets overlooked until a chronic ISP issue emerges. Many existing solutions like PRTG or SolarWinds are overkill when you just need to:

  • Detect when the connection drops completely
  • Log outage duration
  • Generate ISP-compliant reports

For this Windows desktop scenario, we'll use Python because:

import subprocess
import datetime
import csv

def ping_host(host="8.8.8.8"):
    try:
        output = subprocess.check_output(
            ["ping", "-n", "1", "-w", "1000", host],
            stderr=subprocess.STDOUT,
            universal_newlines=True
        )
        return "Reply from" in output
    except:
        return False

The core monitoring logic requires these components:

class UptimeMonitor:
    def __init__(self):
        self.log_file = "uptime_log.csv"
        self._initialize_log()
        
    def _initialize_log(self):
        with open(self.log_file, 'a', newline='') as f:
            writer = csv.writer(f)
            writer.writerow(["Timestamp", "Status", "Duration"])
    
    def log_status(self, status, duration=None):
        timestamp = datetime.datetime.now().isoformat()
        with open(self.log_file, 'a', newline='') as f:
            writer = csv.writer(f)
            writer.writerow([timestamp, status, duration])

Here's the complete working script:

import time
import winsound

monitor = UptimeMonitor()
last_state = True
outage_start = None

while True:
    current_state = ping_host()
    
    if current_state != last_state:
        if not current_state:  # Downtime started
            outage_start = time.time()
            winsound.Beep(1000, 500)  # Audible alert
            monitor.log_status("DOWN")
        else:  # Recovery
            duration = round(time.time() - outage_start)
            monitor.log_status("UP", duration)
    
    last_state = current_state
    time.sleep(60)  # Check every minute

For creating ISP-friendly reports:

import pandas as pd

def generate_report():
    df = pd.read_csv("uptime_log.csv")
    outages = df[df['Status'] == 'UP'].copy()
    outages['Downtime (min)'] = outages['Duration'] / 60
    
    report = f"""
    Internet Outage Report
    ----------------------
    Total outages: {len(outages)}
    Longest outage: {outages['Downtime (min)'].max():.1f} minutes
    Total downtime: {outages['Downtime (min)'].sum():.1f} minutes
    """
    print(report)
  • Run as minimized window using pythonw.exe
  • Add to Windows startup folder
  • Set lower privilege requirements

When dealing with unreliable ISP connections at remote offices, you need concrete data to hold providers accountable. The requirements are specific:

  • Minimal resource usage on shared Windows workstations
  • No reliance on SNMP or specialized monitoring tools
  • Simple downtime duration recording (not full network metrics)
  • Report generation for ISP complaints

While tools like PRTG or Pingdom exist, they're overkill for this scenario. A Python script offers:

# Core advantages:
# - Zero installation (just Python interpreter)
# - Customizable logging thresholds
# - No background services
# - CSV output for Excel analysis

Here's a complete solution that logs to CSV every minute:

import os
import time
import csv
from datetime import datetime
from pythonping import ping

LOG_FILE = 'uptime_log.csv'
TARGET_IP = '8.8.8.8'
CHECK_INTERVAL = 60  # Seconds

def initialize_log():
    if not os.path.exists(LOG_FILE):
        with open(LOG_FILE, 'w', newline='') as f:
            writer = csv.writer(f)
            writer.writerow(['Timestamp', 'Status', 'Duration'])

def log_downtime(start_time, end_time):
    duration = round((end_time - start_time).total_seconds())
    with open(LOG_FILE, 'a', newline='') as f:
        writer = csv.writer(f)
        writer.writerow([
            start_time.strftime('%Y-%m-%d %H:%M:%S'),
            'DOWN',
            duration
        ])

def main():
    initialize_log()
    last_status = None
    outage_start = None
    
    while True:
        try:
            response = ping(TARGET_IP, count=1, timeout=2)
            current_status = 'UP' if response.success() else 'DOWN'
            
            if current_status != last_status:
                timestamp = datetime.now()
                if current_status == 'DOWN':
                    outage_start = timestamp
                elif outage_start:
                    log_downtime(outage_start, timestamp)
                    outage_start = None
                
                last_status = current_status
            
        except Exception as e:
            print(f"Error: {e}")
        
        time.sleep(CHECK_INTERVAL)

if __name__ == '__main__':
    main()

To make this persistent without a dedicated machine:

  1. Save as uptime_monitor.py
  2. Create a Windows Scheduled Task that runs at login
  3. Set action to: pythonw.exe uptime_monitor.py (hidden window)

The CSV output can be processed with this PowerShell snippet:

$data = Import-Csv .\uptime_log.csv | Where-Object { $_.Status -eq 'DOWN' -and $_.Duration -gt 5 }
$grouped = $data | Group-Object { [datetime]::Parse($_.Timestamp).ToString('yyyy-MM-dd') }

$report = foreach ($day in $grouped) {
    [PSCustomObject]@{
        Date = $day.Name
        Outages = $day.Count
        TotalMinutes = ($day.Group.Duration | Measure-Object -Sum).Sum / 60
        Longest = ($day.Group.Duration | Measure-Object -Max).Maximum
    }
}

$report | Export-Csv -Path "isp_report_$(Get-Date -Format yyyyMM).csv" -NoTypeInformation

For environments where Python isn't available:

$logFile = "C:\monitor\uptime.log"
$target = "8.8.8.8"

while ($true) {
    $status = if (Test-Connection $target -Count 1 -Quiet -ErrorAction SilentlyContinue) { "UP" } else { "DOWN" }
    $timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
    
    Add-Content -Path $logFile -Value "$timestamp,$status"
    
    Start-Sleep -Seconds 60
}