Update Ping_Monitor.ps1
Added logging.
This commit is contained in:
146
Ping_Monitor.ps1
146
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) {
|
foreach ($addr in $addressDefinitions) {
|
||||||
if ($addr -match "(\d+\.\d+\.\d+\.)(\d+)-(\d+)") {
|
if ($addr -match "(\d+\.\d+\.\d+\.)(\d+)-(\d+)") {
|
||||||
$prefix = $matches[1]
|
$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
|
# Initialize hashtables to store statistics
|
||||||
$stats = @{}
|
$stats = @{}
|
||||||
foreach ($addr in $addresses) {
|
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
|
Samples = [System.Collections.Queue]::new(60) # Fixed-size queue for better memory management
|
||||||
LastStatus = $null
|
LastStatus = $null
|
||||||
StatusChanged = $false
|
StatusChanged = $false
|
||||||
|
LastLoggedStats = [DateTime]::MinValue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,13 +107,81 @@ function Write-StatusLog {
|
|||||||
[string]$OldStatus,
|
[string]$OldStatus,
|
||||||
[string]$NewStatus
|
[string]$NewStatus
|
||||||
)
|
)
|
||||||
$logMessage = "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss'): $Address status changed from $OldStatus to $NewStatus"
|
$statusText = if ($NewStatus -eq $true) { "UP" } else { "DOWN" }
|
||||||
Add-Content -Path "network_monitor.log" -Value $logMessage
|
$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
|
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
|
# Main monitoring loop
|
||||||
try {
|
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) {
|
while ($true) {
|
||||||
Reset-Display
|
Reset-Display
|
||||||
$currentTime = Get-Date -Format "HH:mm:ss"
|
$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 "IP Address Status Min Max Mean Success% Fails Trend" -ForegroundColor Yellow
|
||||||
Write-Host "--------------- -------- ----- ----- ----- -------- ------ -------" -ForegroundColor Yellow
|
Write-Host "--------------- -------- ----- ----- ----- -------- ------ -------" -ForegroundColor Yellow
|
||||||
|
|
||||||
|
$pingCounter++
|
||||||
|
|
||||||
foreach ($addr in $addresses) {
|
foreach ($addr in $addresses) {
|
||||||
$ping = New-Object System.Net.NetworkInformation.Ping
|
$ping = New-Object System.Net.NetworkInformation.Ping
|
||||||
try {
|
try {
|
||||||
$result = $ping.Send($addr, 1000) # 1 second timeout
|
$result = $ping.Send($addr, 1000) # 1 second timeout
|
||||||
$status = $result.Status -eq 'Success'
|
$status = $result.Status -eq 'Success'
|
||||||
|
$responseTime = if ($status) { $result.RoundtripTime } else { 0 }
|
||||||
} catch {
|
} catch {
|
||||||
$status = $false
|
$status = $false
|
||||||
|
$responseTime = 0
|
||||||
|
Write-ErrorLog -ErrorRecord $_ -Context "Ping to $addr"
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($status) {
|
if ($status) {
|
||||||
$responseTime = $result.RoundtripTime
|
|
||||||
$stats[$addr].TotalTime += $responseTime
|
$stats[$addr].TotalTime += $responseTime
|
||||||
$stats[$addr].SuccessCount++
|
$stats[$addr].SuccessCount++
|
||||||
|
|
||||||
@@ -117,12 +228,6 @@ try {
|
|||||||
$color = "Red"
|
$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
|
# Calculate statistics
|
||||||
$totalRequests = $stats[$addr].SuccessCount + $stats[$addr].FailCount
|
$totalRequests = $stats[$addr].SuccessCount + $stats[$addr].FailCount
|
||||||
$successRate = if ($totalRequests -gt 0) {
|
$successRate = if ($totalRequests -gt 0) {
|
||||||
@@ -132,6 +237,20 @@ try {
|
|||||||
[math]::Round((Get-Mean $stats[$addr].Samples), 1)
|
[math]::Round((Get-Mean $stats[$addr].Samples), 1)
|
||||||
} else { 0 }
|
} 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
|
# Calculate trend based on last 5 samples - suppress output
|
||||||
$trend = if ($stats[$addr].Samples.Count -ge 5) {
|
$trend = if ($stats[$addr].Samples.Count -ge 5) {
|
||||||
$recent = @([array]($stats[$addr].Samples))
|
$recent = @([array]($stats[$addr].Samples))
|
||||||
@@ -159,9 +278,14 @@ try {
|
|||||||
Write-Host "$minField $maxField $meanField $successField $failsField $trend"
|
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 {
|
} finally {
|
||||||
# Cleanup when script is interrupted
|
# 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
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user