Skip to content

Latest commit

 

History

History
240 lines (166 loc) · 7.22 KB

File metadata and controls

240 lines (166 loc) · 7.22 KB

PSLogging2

PowerShell Module Status Concurrency Automation

Quick StartLog StylesFunctionsConcurrencyDevelopment

Lightweight PowerShell logging for scripts, scheduled tasks, and automation jobs.

PSLogging2 provides file-based logging with simple writer functions, multiple log file layouts, optional timestamps, and SMTP delivery for completed logs. The module is designed for straightforward use in PowerShell 5.1 style environments while still being usable in newer shells.

Highlights

  • Three log file layouts: Simple, Standard, and Daily
  • Dedicated helpers for info, warning, and error messages
  • Optional timestamp placement controlled by -TimestampPosition <Front|Back|None>
  • Daily log reuse with automatic run separators
  • Atomic append logic for safer concurrent writes
  • Optional SMTP delivery with Send-Log

Repository Layout

PSLogging2/
|- Functions/     # Module functions
|- Docs/          # Review notes and planning docs
|- Tests/         # Validation and smoke-test scripts
|- PSLogging2.psm1
|- PSLogging2.psd1
`- README.md

Installation

Import from the repo

Import-Module .\PSLogging2.psm1 -Force

Install as a local module

Copy the PSLogging2 folder into one of your PowerShell module paths, then import it normally:

Import-Module PSLogging2

Quick Start

Import-Module .\PSLogging2.psm1 -Force

# Explicit LogContext pattern
$ctx = Start-Log -Style Simple -LogDir .\log -Title 'Inventory Script' -Version '1.0' -ToScreen -ReturnContext
Write-LogInfo -Message 'Starting run' -LogContext $ctx
Write-LogWarning -Message 'Using fallback configuration' -TimestampPosition Front -LogContext $ctx
Write-LogInfo -Message 'Completed step 1' -TimestampPosition Back -LogContext $ctx
Stop-Log -LogContext $ctx

Log Styles

Simple

Creates one log file per run.

Example output path:

log\2026-08-15_214530.log

Standard

Creates nested year and month folders, then writes a timestamped file for each run.

Example output path:

log\2026\2026-08\2026-08-15_214530.log

Use this when you want a clean archive layout for long-running or recurring automation.

Daily

Writes all runs for the same day into a shared daily log.

Example output path:

log\2026\2026-08\2026-08-15.log

When the file already exists, the module appends a run separator unless -DisableDailySeparator is used.

Common Examples

Standard logging

$ctx = Start-Log -Style Standard -LogDir .\log -Title 'Nightly Job' -Version '2.3' -ReturnContext
Write-LogInfo -Message 'Job started' -LogContext $ctx
Write-LogInfo -Message 'Import complete' -TimestampPosition Back -LogContext $ctx
Stop-Log -LogContext $ctx

Daily logging

$ctx = Start-Log -Style Daily -LogDir .\log -Title 'Daily Sync' -ReturnContext
Write-LogInfo -Message 'Sync started' -TimestampPosition Front -LogContext $ctx
Write-LogWarning -Message 'Remote system responded slowly' -LogContext $ctx
Stop-Log -LogContext $ctx

Error logging

$ctx = Start-Log -Style Simple -LogDir .\log -Title 'Deployment' -ReturnContext
Write-LogError -Message 'Deployment failed' -TimestampPosition Back -ToScreen -LogContext $ctx
Stop-Log -LogContext $ctx

Timestamp Behavior

Timestamps are optional and controlled by the -TimestampPosition parameter.

  • -TimestampPosition None (default): message is written as-is
  • -TimestampPosition Front: timestamp is prepended
  • -TimestampPosition Back: timestamp is appended

This behavior is covered by Pester tests for Write-LogInfo, Write-LogWarning, and Write-LogError, including invalid value rejection.

Example:

Write-LogInfo -Message 'Processing item' -TimestampPosition Front
Write-LogWarning -Message 'Retrying request' -TimestampPosition Back

Functions

Function Purpose
Start-Log Initializes the log path and writes the run header
Write-LogInfo Appends informational messages
Write-LogWarning Appends warning messages
Write-LogError Appends error messages and can optionally stop execution
Stop-Log Writes footer information and returns a status; use -Exit to terminate the caller
Send-Log Emails a completed log file through SMTP
New-LogContext Creates an explicit context when a log path already exists

Concurrency

PSLogging2 now uses atomic append logic for log writes.

  • Safer concurrent writes for Simple, Standard, and Daily
  • Daily mode can be shared across multiple runs without the earlier append race
  • Header and separator creation are also protected through the same log I/O helper approach

Concurrency test

The repo includes a basic concurrency test:

Set-Location .\Tests
.\Test-ConcurrentDaily.ps1 -Jobs 8 -LinesPerJob 250

Sending Logs By Email

Send-Log sends the full log body through .NET SmtpClient.

# Using explicit LogContext
$ctx = Start-Log -Style Standard -LogDir .\log -Title 'Nightly Job' -ReturnContext
Send-Log `
	-SMTPServer 'smtp.example.com' `
	-LogContext $ctx `
	-EmailFrom 'me@example.com' `
	-EmailTo 'team@example.com' `
	-EmailSubject 'Nightly Job Log'

Notes:

  • This currently uses legacy SmtpClient
  • The full log is read into memory before sending
  • Modern auth and large-log handling are future hardening items

Current Limitations

  • Writers and Send-Log require a single explicit LogContext returned by Start-Log -ReturnContext or created with New-LogContext, or an explicit -LogPath.

  • Send-Log is functional but not fully enterprise-hardened yet (modern auth, large-log handling)

  • Pipeline input is not supported for LogContext; pass a single context or path per command.

  • Stop-Log does not exit by default after writing the footer; pass -Exit to terminate the caller.

  • Write-LogError -ExitGracefully writes the footer and exits the calling process after a successful error entry.

  • Timestamp switches were replaced with -TimestampPosition, and writer functions validate Message input.

Development

Run the Pester suite

Import-Module .\PSLogging2.psm1 -Force
Invoke-Pester .\Tests\Pester

Run only the timestamp tests

Import-Module .\PSLogging2.psm1 -Force
Invoke-Pester .\Tests\Pester\Timestamp.Tests.ps1

Run the concurrency test

Set-Location .\Tests
.\Test-ConcurrentDaily.ps1

Review planned work

  • Implementation roadmap: Docs/plans.md
  • Review notes: Docs/Review.md

Contributing

Issues, fixes, and improvements are welcome. If you are planning a broader change, check Docs/plans.md first so the work lines up with the current roadmap.

License

This project is licensed under the terms in LICENSE.