Private/Logging/Write-OnypheLog.ps1
|
Function Write-OnypheLog { <# .SYNOPSIS write a log entry to the configured logging destination (file or Windows Event Log) .DESCRIPTION Central logging entry point, intended to be called by public cmdlets. Reads and normalizes the Logging section of the configuration, filters by MinimumLevel, and dispatches to Write-OnypheFileLogEntry or Write-OnypheEventLogEntry depending on Mode. Every entry is stamped with the identity of the user running the command ([System.Environment]::UserName - used instead of WindowsIdentity so this keeps working on the PowerShell Core/Linux/macOS hosts this module also targets). When -BoundParameters is supplied, its keys/values are appended to the message with Credential/Password/Secret/Token/APIKey-named parameters redacted, so secrets - notably the -APIKey parameter used throughout this module - never reach a log file or the Windows Event Log. Callers typically pass this only on the Debug-level entry-point log for each cmdlet invocation. No-ops silently when logging is disabled (Logging.Enabled = $false, the default for configs that predate this feature) or when Level is below the configured MinimumLevel. Never throws - a logging failure must never break the cmdlet's actual Onyphe API work. .PARAMETER Config the parsed configuration object returned by Read-OnypheConfigFile .PARAMETER Level severity of this entry: Debug, Information, Warning, or Error .PARAMETER Message the log message .PARAMETER CmdletName name of the calling cmdlet, e.g. $MyInvocation.MyCommand.Name .PARAMETER BoundParameters optional. $PSBoundParameters of the calling cmdlet; appended to the message with sensitive values redacted .OUTPUTS none .EXAMPLE Write-OnypheLog -Config $Config -Level Debug -CmdletName $MyInvocation.MyCommand.Name -Message 'Cmdlet invoked' -BoundParameters $PSBoundParameters .EXAMPLE Write-OnypheLog -Config $Config -Level Information -CmdletName 'Get-OnypheInfo' -Message 'Retrieved results for category geoloc' #> [cmdletbinding()] Param ( [parameter(Mandatory=$true)] [PSCustomObject]$Config, [parameter(Mandatory=$true)] [ValidateSet('Debug','Information','Warning','Error')] [string]$Level, [parameter(Mandatory=$true)] [string]$Message, [parameter(Mandatory=$true)] [string]$CmdletName, [parameter(Mandatory=$false)] [hashtable]$BoundParameters ) try { $LoggingConfig = Get-OnypheLoggingConfig -Config $Config if (!$LoggingConfig.Enabled) { return } $MinimumSeverity = $script:LogLevelSeverity[$LoggingConfig.MinimumLevel] $EntrySeverity = $script:LogLevelSeverity[$Level] if ($EntrySeverity -lt $MinimumSeverity) { return } $FullMessage = $Message if ($BoundParameters) { $Redacted = foreach ($key in ($BoundParameters.Keys | Sort-Object)) { if ($key -match 'Credential|Password|Secret|Token|APIKey') { "$key=<redacted>" } else { "$key=$($BoundParameters[$key])" } } $FullMessage = "$Message ($($Redacted -join '; '))" } $Entry = [PSCustomObject]@{ Timestamp = Get-Date Level = $Level UserName = [System.Environment]::UserName CmdletName = $CmdletName Message = $FullMessage } if ($LoggingConfig.Mode -eq 'EventLog') { Write-OnypheEventLogEntry -EventLog $LoggingConfig.EventLog -Entry $Entry } else { Write-OnypheFileLogEntry -File $LoggingConfig.File -Entry $Entry } } catch { if (!$script:LoggingSinkFailed) { $script:LoggingSinkFailed = $true Write-Warning "Use-Onyphe logging failed and will be skipped for the rest of this session: $_" } } } |