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