- Logger (
[Logger]): The main object you interact with. It holds configuration (likeMinLevel) and a list of appenders. Crucially, it should be disposed of when done ($logger.Dispose()). - Appenders (
[LogAppender]): Define where log messages go. This module includes:[ConsoleAppender]: Writes colored output to the PowerShell host.[FileAppender]: Writes formatted text to a specified file.[JsonAppender]: Writes JSON objects (one per line) to a specified file. You add instances of these to the logger's$logger._appenderslist.
- Severity Levels (
[LogLevel]): Define the importance of a message (Debug, Info, Warn, Error, Fatal). The logger'sMinLevelfilters messages below that level.
-
I. With Cmdletstry { $logger = [IO.Path]::Combine([IO.Path]::GetTempPath(), "MyAppLogs") | New-Logger $logger | Add-JsonAppender $logger | Write-LogEntry -level Info -Message "Added JSON appender. Logs now go to Console, `$env:TMP/MyAppLog/*{guid-filename}.log, and .json" $logger.LogInfoLine("This message goes to all appenders.") # Direct call } finally { $logger.ReadEntries(@{ type = "JSON" }) $logger.Dispose() }
-
II. With no cmdletsFor more control or when building your own modules/tools, you can use the classes directly.
# Import the module to make classes available Import-Module cliHelper.logger try { $Logdir = [IO.Path]::Combine([IO.Path]::GetTempPath(), "MyAppLogs") $logger = [Logger]::new($Logdir) $logger.MinLevel = [LogLevel]::Debug # Create and add appenders manually $logger.AddLogAppender([ConsoleAppender]@{}) $logger.AddLogAppender([FileAppender]"$Logdir/mytool.log") $logger.AddLogAppender([JsonAppender]"$Logdir/mytool_metrics.json") $logger.LogInfoLine("Object Logger Initialized. with $($logger.Session.LogAppenders.Count) appenders.") $logger.Debug("Detailed trace message.") # simulated failure: throw [System.IO.FileNotFoundException]::new("Required config file missing", "config.xml") } catch { $logger.LogFatalLine(("{0} :`n {1}" -f $_.FullyQualifiedErrorId, $_.ScriptStackTrace), $_.Exception) } finally { $logger.LogInfoLine("Check logs in $($logger.LogFiles)") $logger.Dispose() }
# .SYNPOSIS # A custom classes inheriting `LogEntry` # adds more structured data to logs. #.EXAMPLE # [CustomEntry]@{} class CustomEntry : LogEntry { [string]$CorrelationId # Custom field # Factory methods (required pattern) static [CustomEntry] Create([LogLevel]$severity, [string]$message) { return [CustomEntry]::Create($severity, $message, $null) } static [CustomEntry] Create([LogLevel]$severity, [string]$message, [Exception]$exception) { # Example: generate or retrieve CorrelationId $Id = (Get-Random -Maximum 10000).ToString("D5") return [CustomEntry]@{ Severity = $severity Message = $message Exception = $exception CorrelationId = $Id } } } # then: try { $logger = [Logger]::new() $logger.LogType = [CustomEntry] $logger.LogInfoLine("Logging event with custom entry type.") $logger.LogInfoLine("By default, If no LogAppender is added, Logs will only show in the console (like this).") } finally { $logger.Dispose() } $logger.LogInfoLine("Trying to log something else...") # this should throw an error: # OperationStopped: Cannot access a disposed object. # Object name: 'ConsoleAppender is already disposed'.
EOF