Private/FreeLogClass.ps1

<#
.SYNOPSIS
A logging class that provides structured file-based logging with multiple severity levels.

.DESCRIPTION
The FreeLogClass implements a robust logging system that writes timestamped entries to a text file.
It automatically manages log file creation and maintains a validity state to ensure reliable logging operations.

Key features include:
- Automatic log file creation with initialization entry
- Multiple logging levels: LOG, WARN, ERROR, FAIL
- Consistent timestamp format (yyyy-MM-dd HH:mm:ss)
- Verbose output support for console feedback
- Built-in validation and error handling
- State tracking via IsValid property

.PARAMETER LogFilePath
The full file system path where log entries will be written. This parameter is required during
class instantiation and cannot be null or empty.

.PARAMETER IsValid
A boolean property that indicates whether the log file is currently accessible and writeable.
This is automatically managed by the class methods.

.INPUTS
None. This class does not accept pipeline input.

.OUTPUTS
None. All logging methods return [void] and the constructor does not return objects.

.EXAMPLE
$logger = [FreeLogClass]::new("C:\Logs\application.log")
$logger.Log("Application started successfully")
$logger.Warn("High memory usage detected")
$logger.Error("Failed to connect to database")

Creates a new log file (if it doesn't exist) and writes entries with timestamps.

.EXAMPLE
$VerbosePreference = 'Continue'
$logger = [FreeLogClass]::new("C:\Logs\app.log")
$logger.Log("Processing request #1234")

Logs to file and displays real-time verbose messages in the console.

.EXAMPLE
try {
    $logger = [FreeLogClass]::new("")
}
catch {
    Write-Error "Failed to initialize logger: $_"
}

Demonstrates proper error handling when invalid parameters are provided.

.EXAMPLE
$logger = [FreeLogClass]::new("C:\Windows\System32\logs\app.log")
try {
    $logger.Log("This might fail without admin rights")
}
catch {
    Write-Warning "Logging failed: $($logger.IsValid)" # IsValid will be $false
  }

.NOTES
File Name : FreeLogClass.ps1
Class Name : FreeLogClass
Author : Michael Free
Requires : PowerShell 5.0 or later (for classes)
Prerequisite : Write permissions to the target log directory

Log Format : [LEVEL] - [TIMESTAMP] - [MESSAGE]
Timestamp : yyyy-MM-dd HH:mm:ss (24-hour format)

Severity Levels (in order of increasing severity):
    LOG - Standard information messages
    WARN - Warning conditions that don't prevent operation
    ERROR - Error conditions that may affect functionality
    FAIL - Critical failures requiring immediate attention
    CREATED - Automatically generated when log file is created
#>

class FreeLogClass {
  [bool]$IsValid = $true
  [string]$LogFilePath

  FreeLogClass([string]$logFile) {
    $this.LogFilePath = $logFile
    $this.EnsureLogFileExists()
  }

  [bool]IsValidParam([string]$param) {
    return -not [string]::IsNullOrEmpty($param)
  }

  [void]EnsureLogFileExists() {
    if (-not $this.IsValidParam($this.LogFilePath)) {
      $this.IsValid = $false
      throw 'LogFilePath cannot be null or empty.'
    }
    if (-not (Test-Path -Path $this.LogFilePath)) {
      try {
        New-Item -Path $this.LogFilePath -ItemType File -Force
        $timestamp = (Get-Date).ToString('yyyy-MM-dd HH:mm:ss')
        $logEntry = "CREATED - $timestamp - Log File Created..."
        Add-Content -Path $this.LogFilePath -Value $logEntry
        Write-Verbose $logEntry
        $this.IsValid = $true
        $this.LogFilePath
      }
      catch {
        $this.IsValid = $false
        throw "Initialization failed: $_"
      }
    }
  }

  [void]Log([string]$message) {
    if (-not $this.IsValid) {
      throw 'Cannot execute LOG method because log file is not writeable.'
    }
    try {
      $timestamp = (Get-Date).ToString('yyyy-MM-dd HH:mm:ss')
      $logEntry = "LOG - $timestamp - $message"
      Add-Content -Path $this.LogFilePath -Value $logEntry
      Write-Verbose $logEntry
      $this.IsValid = $true
    }
    catch {
      $this.IsValid = $false
      throw "LOG method failure: $_"
    }
  }

  [void]Warn([string]$message) {
    if (-not $this.IsValid) {
      throw 'Cannot execute WARN method because log file is not writeable.'
    }
    try {
      $timestamp = (Get-Date).ToString('yyyy-MM-dd HH:mm:ss')
      $logEntry = "WARN - $timestamp - $message"
      Add-Content -Path $this.LogFilePath -Value $logEntry
      Write-Verbose $logEntry
      $this.IsValid = $true
    }
    catch {
      $this.IsValid = $false
      throw "WARN method failure: $_"
    }
  }

  [void]Error([string]$message) {
    if (-not $this.IsValid) {
      throw 'Cannot execute ERROR method because log file is not writeable.'
    }
    try {
      $timestamp = (Get-Date).ToString('yyyy-MM-dd HH:mm:ss')
      $logEntry = "ERROR - $timestamp - $message"
      Add-Content -Path $this.LogFilePath -Value $logEntry
      Write-Verbose $logEntry
      $this.IsValid = $true
    }
    catch {
      $this.IsValid = $false
      throw "ERROR method failure: $_"
    }
  }

  [void]Fail([string]$message) {
    if (-not $this.IsValid) {
      throw 'Cannot execute FAIL method because log file is not writeable.'
    }
    try {
      $timestamp = (Get-Date).ToString('yyyy-MM-dd HH:mm:ss')
      $logEntry = "FAIL - $timestamp - $message"
      Add-Content -Path $this.LogFilePath -Value $logEntry
      Write-Verbose $logEntry
      $this.IsValid = $true
    }
    catch {
      $this.IsValid = $false
      throw "FAIL method failure: $_"
    }
  }
}