From 56ede0ea76107a47eb3080d66ccdb5e40f101955 Mon Sep 17 00:00:00 2001 From: JBg Date: Wed, 12 Mar 2025 08:28:34 +0100 Subject: [PATCH] Update Ping_Monitor.ps1 Added logging. --- Ping_Monitor.ps1 | 146 +++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 135 insertions(+), 11 deletions(-) diff --git a/Ping_Monitor.ps1 b/Ping_Monitor.ps1 index f00264a..3662d7f 100644 --- a/Ping_Monitor.ps1 +++ b/Ping_Monitor.ps1 @@ -7,6 +7,41 @@ $addressDefinitions = @( ) +# Set up logging configuration +$logFolder = ".\Logs" +$logFile = Join-Path $logFolder "network_monitor.log" +$statLogFile = Join-Path $logFolder "statistics.log" +$csvLogFile = Join-Path $logFolder "ping_data.csv" +$errorLogFile = Join-Path $logFolder "errors.log" + +# Create log directory if it doesn't exist +if (-not (Test-Path $logFolder)) { + New-Item -Path $logFolder -ItemType Directory | Out-Null +} + +# Initialize log files with headers +if (-not (Test-Path $csvLogFile)) { + "Timestamp,IPAddress,Status,ResponseTime,SuccessRate" | Out-File -FilePath $csvLogFile +} + +# Function to write to log file with timestamp +function Write-Log { + param( + [Parameter(Mandatory=$true)] + [string]$Message, + [string]$LogFile = $logFile, + [switch]$NoConsole + ) + $timestamp = Get-Date -Format 'yyyy-MM-dd HH:mm:ss' + "$timestamp - $Message" | Out-File -FilePath $LogFile -Append + if (-not $NoConsole) { + Write-Host "$timestamp - $Message" + } +} + +# Log script start +Write-Log "Network monitoring script started" + foreach ($addr in $addressDefinitions) { if ($addr -match "(\d+\.\d+\.\d+\.)(\d+)-(\d+)") { $prefix = $matches[1] @@ -20,6 +55,9 @@ foreach ($addr in $addressDefinitions) { } } +# Log monitored addresses +Write-Log "Monitoring IP addresses: $($addresses -join ', ')" + # Initialize hashtables to store statistics $stats = @{} foreach ($addr in $addresses) { @@ -32,6 +70,7 @@ foreach ($addr in $addresses) { Samples = [System.Collections.Queue]::new(60) # Fixed-size queue for better memory management LastStatus = $null StatusChanged = $false + LastLoggedStats = [DateTime]::MinValue } } @@ -68,13 +107,81 @@ function Write-StatusLog { [string]$OldStatus, [string]$NewStatus ) - $logMessage = "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss'): $Address status changed from $OldStatus to $NewStatus" - Add-Content -Path "network_monitor.log" -Value $logMessage + $statusText = if ($NewStatus -eq $true) { "UP" } else { "DOWN" } + $oldStatusText = if ($OldStatus -eq $true) { "UP" } else { "DOWN" } + $logMessage = "$Address status changed from $oldStatusText to $statusText" + + Write-Log $logMessage Write-Host "`n$logMessage" -ForegroundColor Yellow } +# Function to log statistics periodically +function Write-StatisticsLog { + param( + [string]$Address, + [hashtable]$Statistics, + [int]$IntervalMinutes = 15 + ) + + $now = Get-Date + if (($now - $Statistics.LastLoggedStats).TotalMinutes -ge $IntervalMinutes) { + $totalRequests = $Statistics.SuccessCount + $Statistics.FailCount + $successRate = if ($totalRequests -gt 0) { + [math]::Round(($Statistics.SuccessCount / $totalRequests) * 100, 1) + } else { 0 } + + $meanTime = if ($Statistics.Samples.Count -gt 0) { + [math]::Round((Get-Mean $Statistics.Samples), 1) + } else { 0 } + + $statsMessage = "$Address Stats - Min: $($Statistics.MinTime)ms, Max: $($Statistics.MaxTime)ms, " + + "Mean: ${meanTime}ms, Success Rate: ${successRate}%, " + + "Success Count: $($Statistics.SuccessCount), Fail Count: $($Statistics.FailCount)" + + Write-Log -Message $statsMessage -LogFile $statLogFile -NoConsole + $Statistics.LastLoggedStats = $now + } +} + +# Function to log ping data to CSV +function Write-PingDataLog { + param( + [string]$Address, + [bool]$Status, + [int]$ResponseTime, + [double]$SuccessRate + ) + + $statusText = if ($Status) { "UP" } else { "DOWN" } + $timestamp = Get-Date -Format 'yyyy-MM-dd HH:mm:ss' + "$timestamp,$Address,$statusText,$ResponseTime,$SuccessRate" | Out-File -FilePath $csvLogFile -Append +} + +# Function to handle errors +function Write-ErrorLog { + param( + [Parameter(Mandatory=$true)] + [System.Management.Automation.ErrorRecord]$ErrorRecord, + [string]$Context = "General" + ) + + $errorMessage = "[$Context] $($ErrorRecord.Exception.GetType().Name): $($ErrorRecord.Exception.Message)" + $errorDetails = $ErrorRecord | Format-List * -Force | Out-String + + Write-Log -Message $errorMessage -LogFile $errorLogFile -NoConsole + Write-Log -Message "Details: $errorDetails" -LogFile $errorLogFile -NoConsole + Write-Host "Error: $errorMessage" -ForegroundColor Red +} + # Main monitoring loop try { + $pingInterval = 1 # seconds between pings + $statsLogInterval = 15 # minutes between logging statistics + $csvLogFrequency = 5 # log every Nth ping to CSV to avoid huge files + $pingCounter = 0 + + Write-Log "Monitoring started with ping interval of ${pingInterval}s and stats logging every ${statsLogInterval} minutes" + while ($true) { Reset-Display $currentTime = Get-Date -Format "HH:mm:ss" @@ -85,17 +192,21 @@ try { Write-Host "IP Address Status Min Max Mean Success% Fails Trend" -ForegroundColor Yellow Write-Host "--------------- -------- ----- ----- ----- -------- ------ -------" -ForegroundColor Yellow + $pingCounter++ + foreach ($addr in $addresses) { $ping = New-Object System.Net.NetworkInformation.Ping try { $result = $ping.Send($addr, 1000) # 1 second timeout $status = $result.Status -eq 'Success' + $responseTime = if ($status) { $result.RoundtripTime } else { 0 } } catch { $status = $false + $responseTime = 0 + Write-ErrorLog -ErrorRecord $_ -Context "Ping to $addr" } if ($status) { - $responseTime = $result.RoundtripTime $stats[$addr].TotalTime += $responseTime $stats[$addr].SuccessCount++ @@ -117,12 +228,6 @@ try { $color = "Red" } - # Check for status changes and log them - if ($stats[$addr].LastStatus -ne $null -and $stats[$addr].LastStatus -ne $status) { - Write-StatusLog -Address $addr -OldStatus $stats[$addr].LastStatus -NewStatus $status - } - $stats[$addr].LastStatus = $status - # Calculate statistics $totalRequests = $stats[$addr].SuccessCount + $stats[$addr].FailCount $successRate = if ($totalRequests -gt 0) { @@ -132,6 +237,20 @@ try { [math]::Round((Get-Mean $stats[$addr].Samples), 1) } else { 0 } + # Check for status changes and log them + if ($null -ne $stats[$addr].LastStatus -and $stats[$addr].LastStatus -ne $status) { + Write-StatusLog -Address $addr -OldStatus $stats[$addr].LastStatus -NewStatus $status + } + $stats[$addr].LastStatus = $status + + # Log statistics periodically + Write-StatisticsLog -Address $addr -Statistics $stats[$addr] -IntervalMinutes $statsLogInterval + + # Log to CSV (but not every ping to avoid huge files) + if ($pingCounter % $csvLogFrequency -eq 0) { + Write-PingDataLog -Address $addr -Status $status -ResponseTime $responseTime -SuccessRate $successRate + } + # Calculate trend based on last 5 samples - suppress output $trend = if ($stats[$addr].Samples.Count -ge 5) { $recent = @([array]($stats[$addr].Samples)) @@ -159,9 +278,14 @@ try { Write-Host "$minField $maxField $meanField $successField $failsField $trend" } - Start-Sleep -Seconds 1 + Start-Sleep -Seconds $pingInterval } +} catch { + # Log any unhandled exceptions + Write-ErrorLog -ErrorRecord $_ -Context "Main monitoring loop" } finally { # Cleanup when script is interrupted - Write-Host "`nMonitoring stopped at $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')" -ForegroundColor Cyan + $endMessage = "Monitoring stopped at $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')" + Write-Log $endMessage + Write-Host "`n$endMessage" -ForegroundColor Cyan } \ No newline at end of file