Add docs/logging.fallback.md
This commit is contained in:
137
docs/logging.fallback.md
Normal file
137
docs/logging.fallback.md
Normal file
@@ -0,0 +1,137 @@
|
||||
# logging.fallback.ps1
|
||||
|
||||
This file implements SAMY’s fallback logging functions used across the project.
|
||||
|
||||
It supports:
|
||||
- Console logging (color-coded)
|
||||
- In-memory log caching (for UI/diagnostics)
|
||||
- Optional file logging (UTF-8 **without BOM**)
|
||||
- Optional Windows Event Log logging, including:
|
||||
- first-run creation of the log/source (when elevated)
|
||||
- resolving “source bound to the wrong log” problems
|
||||
|
||||
---
|
||||
|
||||
## Regions overview
|
||||
|
||||
### Globals
|
||||
**What it does**
|
||||
- Initializes shared global state used by logging:
|
||||
- `LogCache`: an `ArrayList` of log entries created during execution.
|
||||
- `EventSinkCache`: a `Hashtable` caching resolved Event Log sinks so we do not repeatedly initialize/bind.
|
||||
|
||||
**Why it exists**
|
||||
- Makes log output available to UI or post-run summaries.
|
||||
- Prevents repeated Event Log setup attempts and repeated warnings.
|
||||
|
||||
---
|
||||
|
||||
### Helpers: Formatting + File
|
||||
**What it does**
|
||||
- `Get-LogColor(Level)`: maps `Info/Warning/Error/Success/General` to console colors.
|
||||
- `Get-EventIdForLevel(Level, CustomEventID)`: returns default Event IDs by level unless overridden.
|
||||
- `Get-EventEntryTypeForLevel(Level)`: maps levels to Event Log entry types.
|
||||
- `Append-Utf8NoBomLine(Path, Line)`: appends a line to a file using UTF-8 **without BOM**.
|
||||
|
||||
**Why it exists**
|
||||
- Keeps the main logging functions readable.
|
||||
- Ensures runtime log files comply with the repository encoding rule (UTF-8 no BOM).
|
||||
|
||||
---
|
||||
|
||||
### Helpers: Event Log Binding
|
||||
**Background**
|
||||
Windows Event Log has a key constraint:
|
||||
|
||||
A **Source** can only be registered to **one** Log at a time.
|
||||
|
||||
Example:
|
||||
- If source `SVMSP_Module` is registered to `Application`,
|
||||
you cannot write with:
|
||||
`Write-EventLog -LogName "SVSMSP Events" -Source "SVMSP_Module"`
|
||||
until that binding is repaired or avoided.
|
||||
|
||||
**What it does**
|
||||
- `Test-IsAdmin()`: checks if the current PowerShell session is elevated.
|
||||
- `Initialize-EventLogBinding(DesiredLog, DesiredSource, ConflictPolicy)`:
|
||||
returns an effective `{ LogName, Source, IsAdmin }` that is safe to use for `Write-EventLog`.
|
||||
|
||||
**ConflictPolicy**
|
||||
If `DesiredSource` exists but is bound to a different log, one of these policies applies:
|
||||
|
||||
- `Repair` (default)
|
||||
- Removes the existing source registration from its current log
|
||||
- Recreates it under `DesiredLog`
|
||||
- Requires elevation
|
||||
- Best when you want **all SAMY logs in one custom log**
|
||||
|
||||
- `Unique`
|
||||
- Creates a new SAMY-specific source under `DesiredLog`
|
||||
(e.g., `SVMSP_Module.SAMY`, `SVMSP_Module.SAMY2`, etc.)
|
||||
- Does not delete anything
|
||||
- Requires elevation to create the new source
|
||||
- Best when you want **no deletion / no rebinding risk**
|
||||
|
||||
- `Follow`
|
||||
- Uses whichever log the source is already bound to
|
||||
- Never deletes anything
|
||||
- May log to `Application` if that’s where the source already exists
|
||||
- Best when you want **maximum safety and minimum changes**
|
||||
|
||||
**Non-admin behavior**
|
||||
If not elevated and the desired source does not exist, the code falls back to:
|
||||
- `LogName = Application`
|
||||
- `Source = Windows PowerShell`
|
||||
|
||||
This avoids trying to create custom Event Log sources without admin rights.
|
||||
|
||||
---
|
||||
|
||||
### Public: Write-LogHelper
|
||||
**What it does**
|
||||
This is the core fallback logger.
|
||||
|
||||
Always does:
|
||||
- Writes a formatted message to console (with color)
|
||||
- Adds an entry to `Global:LogCache`
|
||||
|
||||
Optionally does:
|
||||
- File logging (when `-LogFile` is provided)
|
||||
- Event Log logging (when `-LogToEvent` is set)
|
||||
|
||||
**Event Log caching**
|
||||
To avoid repeating setup work, the function caches the resolved Event Log sink:
|
||||
- Key format: `"$EventLog|$EventSource|$EventLogConflictPolicy"`
|
||||
- Cached value includes:
|
||||
- `Ready` (boolean)
|
||||
- `LogName` (effective log to write to)
|
||||
- `Source` (effective source to write with)
|
||||
|
||||
**Parameters that matter most**
|
||||
- `-Message`: text to log
|
||||
- `-Level`: affects console color, EventId, EntryType
|
||||
- `-TaskCategory`: included in formatted message and event message
|
||||
- `-LogToEvent`: enable/disable Event Log writes
|
||||
- `-EventLog`, `-EventSource`: desired Event Log sink
|
||||
- `-EventLogConflictPolicy`: `Repair`, `Unique`, or `Follow`
|
||||
|
||||
---
|
||||
|
||||
### Public: Write-LogHybrid
|
||||
**What it does**
|
||||
A wrapper for compatibility.
|
||||
|
||||
Behavior:
|
||||
- If a preferred logger function `Write-Log` exists, it calls that.
|
||||
- Otherwise it calls `Write-LogHelper`.
|
||||
|
||||
**Why it exists**
|
||||
- Lets SAMY swap logging implementations without changing all call sites.
|
||||
|
||||
---
|
||||
|
||||
## Typical usage examples
|
||||
|
||||
### Console only
|
||||
```powershell
|
||||
Write-LogHybrid -Message "Starting SAMY" -Level Info -TaskCategory "Startup"
|
||||
Reference in New Issue
Block a user