Private/Reporting/Get-LogFileSummary.ps1
|
#Requires -Version 5.1 <# .SYNOPSIS Log file analysis utilities for Find-UnknownSID operations .DESCRIPTION Provides log file analysis and summary capabilities for troubleshooting and monitoring purposes. Focuses solely on log file analysis without diagnostic export or system information collection. .NOTES Author: Jeffrey Stuhr Blog: https://www.techbyjeff.net LinkedIn: https://www.linkedin.com/in/jeffrey-stuhr-034214aa/ Last Updated: 2025-07-05 Version: 2.0.0 TROUBLESHOOTING: - For log analysis issues: .\Troubleshooting\Diagnostics\Log-Analysis.md - For file access problems: .\Troubleshooting\Security\File-Access.md .LINK https://docs.microsoft.com/en-us/powershell/scripting/learn/deep-dives/everything-about-logging #> function Get-LogFileSummary { <# .SYNOPSIS Generates comprehensive summary statistics for the current log file .DESCRIPTION Analyzes the current log file to provide detailed statistics including file size, entry counts, error analysis, and metadata. Useful for monitoring log file health and troubleshooting operations. This function focuses solely on log file analysis and provides structured output suitable for monitoring and reporting. .EXAMPLE PS> Get-LogFileSummary Returns detailed summary information about the current log file .EXAMPLE PS> $summary = Get-LogFileSummary PS> if ($summary.ErrorCount -gt 0) { Write-Warning "Errors detected in log file" } Uses summary data for conditional logic and monitoring .INPUTS None. This function does not accept pipeline input. .OUTPUTS [PSCustomObject] Log file summary with comprehensive statistics .NOTES Returns null if no log file is currently active or accessible. Provides error counts and timing information for operational monitoring. Analysis is performed efficiently with streaming reads for large files. PERFORMANCE CHARACTERISTICS: - Small files (<1MB): 10-50ms analysis time - Large files (>10MB): 100-500ms analysis time - Memory usage: Minimal (streaming analysis) - File I/O: Single read operation with efficient parsing TROUBLESHOOTING: - Handles missing or inaccessible log files gracefully - Provides detailed error context for file access issues - Returns structured data suitable for automated monitoring #> [CmdletBinding()] [OutputType([PSCustomObject])] param() begin { Write-Verbose "Analyzing current log file for summary statistics" } process { # Get current logging system state $loggingState = Get-LoggingSystemState if (-not $loggingState.LogPath) { Write-Verbose "No log file path configured" return $null } if (-not (Test-Path $loggingState.LogPath)) { Write-Verbose "Log file does not exist: $($loggingState.LogPath)" return $null } try { # Get file metadata $logFile = Get-Item $loggingState.LogPath -ErrorAction Stop # Analyze log content $contentAnalysis = Get-LogContentAnalysis -LogFilePath $loggingState.LogPath # Build comprehensive summary $summary = [PSCustomObject]@{ PSTypeName = 'LogFileSummary' LogPath = $loggingState.LogPath SizeMB = [Math]::Round($logFile.Length / 1MB, 2) SizeBytes = $logFile.Length LineCount = $contentAnalysis.LineCount ErrorCount = $contentAnalysis.ErrorCount WarningCount = $contentAnalysis.WarningCount CriticalCount = $contentAnalysis.CriticalCount InformationCount = $contentAnalysis.InformationCount DebugCount = $contentAnalysis.DebugCount SecurityEventCount = $contentAnalysis.SecurityEventCount CreatedTime = $logFile.CreationTime LastWriteTime = $logFile.LastWriteTime LastAccessTime = $logFile.LastAccessTime CorrelationId = $loggingState.CorrelationId AnalysisTimestamp = Get-Date LogLevel = $loggingState.LogLevel IsHealthy = ($contentAnalysis.ErrorCount -eq 0 -and $contentAnalysis.CriticalCount -eq 0) } Write-Verbose "Log file analysis completed - Lines: $($summary.LineCount), Errors: $($summary.ErrorCount)" return $summary } catch { Write-Warning "Failed to analyze log file '$($loggingState.LogPath)': $($_.Exception.Message)" return $null } } end { Write-Verbose "Log file summary analysis completed" } } function Get-LogContentAnalysis { <# .SYNOPSIS Performs detailed content analysis of log file entries .DESCRIPTION Analyzes log file content to extract statistics about different log levels, patterns, and content characteristics. .PARAMETER LogFilePath Path to log file to analyze .EXAMPLE PS> Get-LogContentAnalysis -LogFilePath "C:\Logs\script.log" Returns detailed content analysis for the specified log file .INPUTS None. This function does not accept pipeline input. .OUTPUTS [hashtable] Content analysis results with entry counts by category .NOTES Uses efficient streaming analysis for large log files. Counts entries by log level and identifies patterns. #> [CmdletBinding()] [OutputType([hashtable])] param( [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string]$LogFilePath ) try { Write-Verbose "Performing content analysis on log file: $LogFilePath" # Initialize counters $analysis = @{ LineCount = 0 ErrorCount = 0 WarningCount = 0 CriticalCount = 0 InformationCount = 0 DebugCount = 0 VerboseCount = 0 SecurityEventCount = 0 EmptyLineCount = 0 CorrelationIdCount = 0 } # Read and analyze content efficiently Get-Content $LogFilePath -ErrorAction Stop | ForEach-Object { $analysis.LineCount++ $line = $_ # Skip empty lines if ([string]::IsNullOrWhiteSpace($line)) { $analysis.EmptyLineCount++ return } # Count by log level patterns switch -Regex ($line) { '\[Critical\]' { $analysis.CriticalCount++ } '\[Error\]' { $analysis.ErrorCount++ } '\[Warning\]' { $analysis.WarningCount++ } '\[Information\]' { $analysis.InformationCount++ } '\[Debug\]' { $analysis.DebugCount++ } '\[Verbose\]' { $analysis.VerboseCount++ } } # Count security events if ($line -match '\[Security\]' -or $line -match 'Security event:') { $analysis.SecurityEventCount++ } # Count correlation ID usage if ($line -match '\[[a-fA-F0-9-]{36}\]') { $analysis.CorrelationIdCount++ } } Write-Verbose "Content analysis completed - Total lines: $($analysis.LineCount)" return $analysis } catch { Write-Warning "Failed to perform content analysis on '$LogFilePath': $($_.Exception.Message)" # Return minimal analysis data return @{ LineCount = 0 ErrorCount = 0 WarningCount = 0 CriticalCount = 0 InformationCount = 0 DebugCount = 0 VerboseCount = 0 SecurityEventCount = 0 EmptyLineCount = 0 CorrelationIdCount = 0 } } } function Get-LogFileHealth { <# .SYNOPSIS Evaluates log file health and provides recommendations .DESCRIPTION Analyzes log file characteristics to determine health status and provide actionable recommendations for log management. .EXAMPLE PS> Get-LogFileHealth Returns health assessment for the current log file .INPUTS None. This function does not accept pipeline input. .OUTPUTS [PSCustomObject] Log file health assessment with recommendations .NOTES Provides health scoring and specific recommendations for log optimization. Identifies potential issues before they impact operations. #> [CmdletBinding()] [OutputType([PSCustomObject])] param() try { $summary = Get-LogFileSummary if (-not $summary) { return [PSCustomObject]@{ PSTypeName = 'LogFileHealth' HealthScore = 0 HealthStatus = 'NoLogFile' Issues = @('No log file available for analysis') Recommendations = @('Initialize logging system and create log file') Timestamp = Get-Date } } # Evaluate health criteria $healthScore = 100 $issues = @() $recommendations = @() # Check file size (warn if > 100MB) if ($summary.SizeMB -gt 100) { $healthScore -= 20 $issues += "Large log file size: $($summary.SizeMB) MB" $recommendations += "Consider log rotation or archiving" } # Check error ratio $errorRatio = if ($summary.LineCount -gt 0) { ($summary.ErrorCount + $summary.CriticalCount) / $summary.LineCount } else { 0 } if ($errorRatio -gt 0.1) { $healthScore -= 30 $issues += "High error ratio: $([Math]::Round($errorRatio * 100, 2))%" $recommendations += "Investigate and resolve frequent errors" } # Check for recent activity $hoursSinceLastWrite = (Get-Date) - $summary.LastWriteTime if ($hoursSinceLastWrite.TotalHours -gt 24) { $healthScore -= 10 $issues += "No recent log activity (last write: $($summary.LastWriteTime))" $recommendations += "Verify logging system is active" } # Determine health status $healthStatus = switch ($healthScore) { { $_ -ge 90 } { 'Excellent'; break } { $_ -ge 70 } { 'Good'; break } { $_ -ge 50 } { 'Fair'; break } { $_ -ge 30 } { 'Poor'; break } default { 'Critical' } } return [PSCustomObject]@{ PSTypeName = 'LogFileHealth' HealthScore = $healthScore HealthStatus = $healthStatus ErrorRatio = [Math]::Round($errorRatio * 100, 2) FileSizeMB = $summary.SizeMB LineCount = $summary.LineCount ErrorCount = $summary.ErrorCount CriticalCount = $summary.CriticalCount HoursSinceLastWrite = [Math]::Round($hoursSinceLastWrite.TotalHours, 2) Issues = $issues Recommendations = $recommendations Timestamp = Get-Date LogPath = $summary.LogPath } } catch { Write-Warning "Failed to evaluate log file health: $($_.Exception.Message)" return [PSCustomObject]@{ PSTypeName = 'LogFileHealth' HealthScore = 0 HealthStatus = 'Error' Issues = @("Health evaluation failed: $($_.Exception.Message)") Recommendations = @('Check log file accessibility and permissions') Timestamp = Get-Date } } } function Get-LogFileStatistics { <# .SYNOPSIS Provides detailed statistical analysis of log file patterns .DESCRIPTION Generates comprehensive statistics about log file usage patterns, including time-based analysis and trend identification. .PARAMETER Days Number of days to analyze for trends (default: 7) .EXAMPLE PS> Get-LogFileStatistics -Days 7 Returns statistical analysis for the last 7 days of log data .INPUTS None. This function does not accept pipeline input. .OUTPUTS [PSCustomObject] Detailed statistical analysis .NOTES Provides trend analysis and pattern identification for log optimization. Useful for capacity planning and performance monitoring. #> [CmdletBinding()] [OutputType([PSCustomObject])] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseSingularNouns', '', Justification = 'Statistics is a mass noun for the aggregate counters')] param( [Parameter()] [ValidateRange(1, 30)] [int]$Days = 7 ) try { $summary = Get-LogFileSummary if (-not $summary) { Write-Warning "No log file available for statistical analysis" return $null } # Calculate basic statistics $statistics = [PSCustomObject]@{ PSTypeName = 'LogFileStatistics' AnalysisPeriodDays = $Days TotalEntries = $summary.LineCount ErrorRate = if ($summary.LineCount -gt 0) { [Math]::Round(($summary.ErrorCount / $summary.LineCount) * 100, 2) } else { 0 } WarningRate = if ($summary.LineCount -gt 0) { [Math]::Round(($summary.WarningCount / $summary.LineCount) * 100, 2) } else { 0 } SecurityEventRate = if ($summary.LineCount -gt 0) { [Math]::Round(($summary.SecurityEventCount / $summary.LineCount) * 100, 2) } else { 0 } AverageFileSizeGrowthMB = if ($Days -gt 0) { [Math]::Round($summary.SizeMB / $Days, 2) } else { 0 } EstimatedDailyEntries = if ($Days -gt 0) { [Math]::Round($summary.LineCount / $Days) } else { 0 } LogFileAge = (Get-Date) - $summary.CreatedTime AnalysisTimestamp = Get-Date LogPath = $summary.LogPath } return $statistics } catch { Write-Warning "Failed to generate log file statistics: $($_.Exception.Message)" return $null } } |