Skip to content

Commit 5301439

Browse files
committed
Fix callstack source
1 parent 8345ca5 commit 5301439

File tree

5 files changed

+163
-17
lines changed

5 files changed

+163
-17
lines changed

README.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,29 @@ Get-Command -Module containers-toolkit
9797
Install-Containerd -Version "1.7.7" -InstallPath 'C:\Test\Path\Containerd'
9898
```
9999
100+
### Logging
101+
102+
The module uses a static logger designed for use across module files within the **Containers Toolkit**. It supports configurable log levels, console output, optional log file writing, and integration with the **Windows Event Log**.
103+
The logger supports the following log levels:
104+
105+
- `DEBUG`
106+
- `INFO`
107+
- `WARNING`
108+
- `ERROR`
109+
- `FATAL`
110+
111+
For more details on the logger, please refer to the [Logger documentation](./docs/LOGGER.md).
112+
113+
#### Logging Environment Variables
114+
115+
The logger uses the following environment variables to configure its behavior:
116+
117+
| Variable | Description |
118+
| ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
119+
| `$env:CTK_LOG_LEVEL` | Sets the minimum log level. Accepted values are: `DEBUG`, `INFO`, `WARNING`, `ERROR`, and `FATAL`. Defaults to `INFO` if not set. |
120+
| `$env:CTK_LOG_FILE` | Path to a file where logs should be written. If not set, logs will be written to the console and Windows Event Log (for applicable levels). **Note:** The logger does not handle log file rotation or cleanup—use external tooling for that. |
121+
| `$env:SKIP_CTK_LOGGING` | If set to `"true"`, suppresses console output for all log levels except `DEBUG` (when `$DebugPreference` is not `"SilentlyContinue"`). Logging to file (if set) and to the Windows Event Log (excluding `DEBUG`) still occurs. |
122+
100123
## Important Notes
101124
102125
1. Requires elevated PowerShell to run some commands.

containers-toolkit/Private/CommonToolUtilities.psm1

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -283,8 +283,7 @@ function Get-InstallationFile {
283283
Receive-File -Params $downloadParams
284284
}
285285
catch {
286-
[Logger]::Error("Failed to download $($downloadParams.Feature) release assets. $($_.Exception.Message)")
287-
Throw $_ # Re-throw the exception to halt execution if a download fails
286+
[Logger]::Fatal("Failed to download $($downloadParams.Feature) release assets. $($_.Exception.Message)")
288287
}
289288
}
290289

@@ -306,8 +305,7 @@ function Get-InstallationFile {
306305
}
307306
}
308307
catch {
309-
[Logger]::Error("Checksum verification process failed: $($_.Exception.Message)")
310-
Throw $_ # Re-throw the exception if checksum verification fails
308+
[Logger]::Fatal("Checksum verification process failed: $($_.Exception.Message)")
311309
}
312310

313311
# Remove the checksum file after verification

containers-toolkit/Private/logger.psm1

Lines changed: 45 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,8 @@ class Logger {
4545

4646
# Set quiet mode from environment variable: SKIP_CTK_LOGGING
4747
# User-defined environment variable to skip logging. Equivalent to --quiet.
48-
# If not set, all messages are logged to the terminal and to the event log.
4948
# If set, only DEBUG messages are logged to the terminal.
49+
# If not set, all messages are logged to the terminal and to the event log.
5050
static [bool] GetQuiet() {
5151
try {
5252
$quietValue = $env:SKIP_CTK_LOGGING
@@ -62,12 +62,42 @@ class Logger {
6262
return [Logger]::LogLevelRank[$Level.ToUpper()] -ge [Logger]::LogLevelRank[[Logger]::MinLevel]
6363
}
6464

65+
# Format the message for logging
66+
static [string] FormatMessage([object] $message) {
67+
if ($null -eq $message) {
68+
return "[null]"
69+
}
70+
71+
if ($message -is [string]) {
72+
return $message
73+
}
74+
75+
try {
76+
return $message | ConvertTo-Json -Depth 5 -Compress
77+
}
78+
catch {
79+
return $message.ToString()
80+
# $Message = $Message | Out-String
81+
}
82+
}
83+
84+
# Retrieve the function in the call stack that triggered the log
85+
static [pscustomobject] GetCallerFunction($CallStack) {
86+
$i = 3
87+
$CallerFunction = $CallStack[$i]
88+
89+
while ((-not $CallerFunction.Command) -and ($i -lt $CallStack.Count - 1)) {
90+
$i++
91+
$CallerFunction = $CallStack[$i]
92+
}
93+
94+
return $CallerFunction
95+
}
96+
6597
# Generate a parsed log message from the log level and message
6698
static [string] GetLogMessage([string] $Level, [string] $Message) {
6799
$CallStack = Get-PSCallStack
68-
69-
$CallStack | Tee-Object -FilePath "ctk.log" -Append | Out-Null
70-
$Caller = $CallStack | Where-Object { $_.Command } | Select-Object -Skip 2 -First 1
100+
$Caller = [Logger]::GetCallerFunction($CallStack)
71101

72102
$timestamp = (Get-Date).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ss.fffffffK")
73103
$cmd = $Caller.InvocationInfo.MyCommand
@@ -118,7 +148,7 @@ class Logger {
118148

119149
# Write log messages to the console and/or event log (or file)
120150
# This is the main logging function that handles all log levels
121-
static [void] Write([string] $Level, [string] $Message) {
151+
static [void] Write([string] $Level, [object] $Message) {
122152
# Set values
123153
[Logger]::MinLevel = [Logger]::GetMinLevel()
124154
[Logger]::LogFile = [Logger]::GetLogFile()
@@ -131,8 +161,11 @@ class Logger {
131161
return
132162
}
133163

164+
# Convert the message to a string
165+
$formatedMessage = [Logger]::FormatMessage($message)
166+
134167
# Generate the log message
135-
$parsedMessage = [Logger]::GetLogMessage($Level, $Message)
168+
$parsedMessage = [Logger]::GetLogMessage($Level, $formatedMessage)
136169

137170
# Default: Log to event log (non-DEBUG messages)
138171
if ($Level -ne "DEBUG") {
@@ -158,9 +191,10 @@ class Logger {
158191
}
159192
}
160193

161-
static [void] Fatal([string] $Message) { [Logger]::Write("FATAL", $Message) }
162-
static [void] Error([string] $Message) { [Logger]::Write("ERROR", $Message) }
163-
static [void] Warning([string] $Message) { [Logger]::Write("WARNING", $Message) }
164-
static [void] Info([string] $Message) { [Logger]::Write("INFO", $Message) }
165-
static [void] Debug([string] $Message) { [Logger]::Write("DEBUG", $Message) }
194+
static [void] Fatal([object] $Message) { [Logger]::Write("FATAL", $Message) }
195+
static [void] Error([object] $Message) { [Logger]::Write("ERROR", $Message) }
196+
static [void] Warning([object] $Message) { [Logger]::Write("WARNING", $Message) }
197+
static [void] Info([object] $Message) { [Logger]::Write("INFO", $Message) }
198+
static [void] Debug([object] $Message) { [Logger]::Write("DEBUG", $Message) }
199+
static [void] Log([string] $Level = "INFO", [string] $Message) { [Logger]::Write($Level, $Message) }
166200
}

containers-toolkit/Public/BuildkitTools.psm1

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -288,8 +288,7 @@ function Register-BuildkitdService {
288288
$command = "buildkitd.exe --register-service --debug --containerd-worker=true --service-name buildkitd"
289289
}
290290
else {
291-
[Logger]::Error("Failed to register buildkit service. Containerd conf file not found at $cniConfPath.`n`t1. Ensure that the required CNI plugins are installed or you can install them using 'Install-WinCNIPlugin'.`n`t2. Create the file to resolve this issue .`n`t3. Rerun this command 'Register-BuildkitdService'")
292-
Throw "Failed to register buildkit service. Containerd conf file not found at $cniConfPath."
291+
[Logger]::Fatal("Failed to register buildkit service. Containerd conf file not found at $cniConfPath.`n`t1. Ensure that the required CNI plugins are installed or you can install them using 'Install-WinCNIPlugin'.`n`t2. Create the file to resolve this issue .`n`t3. Rerun this command 'Register-BuildkitdService'")
293292
}
294293
}
295294

docs/LOGGER.md

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
# Containers Toolkit Logger
2+
3+
A static PowerShell logger designed for use across module files within the **Containers Toolkit**. It supports configurable log levels, console output, optional log file writing, and integration with the **Windows Event Log**.
4+
5+
## Key Features
6+
7+
- Supports multiple log levels: `DEBUG`, `INFO`, `WARNING`, `ERROR`, `FATAL`.
8+
- Logs messages to the **console**, **optional log file**, and the **Windows Event Log** (for applicable levels).
9+
- Minimum log level is determined dynamically from the `CTK_LOG_LEVEL` environment variable or PowerShell’s `$DebugPreference`.
10+
- Allows suppressing console output using the SKIP_CTK_LOGGING environment variable — similar to running in a quiet mode.
11+
12+
## Debug Logging Behavior
13+
14+
- `DEBUG` messages are only shown in the console if:
15+
16+
- `$DebugPreference` is not `"SilentlyContinue"`, **or**
17+
- the environment variable `CTK_LOG_LEVEL` is set to `"DEBUG"`.
18+
- `DEBUG` messages are **not** written to the Windows Event Log.
19+
20+
## Usage
21+
22+
To use the logger, you need to import the module (if it is not already imported).
23+
24+
```PowerShell
25+
using using module "..\Private\logger.psm1"
26+
```
27+
28+
## Log Levels
29+
30+
The logger supports the following log levels:
31+
32+
### Info level
33+
34+
```PowerShell
35+
[Logger]::Log("This is a test message") # Defaults to INFO level
36+
[Logger]::Log("This is a test message", "INFO")
37+
[Logger]::Info("This is a test message")
38+
39+
INFO: [2025-05-20T08:23:12Z] [Install-Nerdctl:42]: "This is a test message"
40+
```
41+
42+
### Debug level
43+
44+
To enable `DEBUG` level logging, set the environment variable `CTK_LOG_LEVEL` to `"DEBUG"` or ensure `$DebugPreference` is not set to `"SilentlyContinue"`.
45+
46+
```PowerShell
47+
[Logger]::Log("This is a test message", "DEBUG")
48+
[Logger]::Debug("This is a test message")
49+
50+
DEBUG: [2025-05-20T08:23:12Z] [Install-Nerdctl:42]: "This is a test message"
51+
```
52+
53+
### Warning level
54+
55+
```PowerShell
56+
[Logger]::Log("This is a test message", "WARNING")
57+
[Logger]::Warning("This is a test message")
58+
59+
WARNING: [2025-05-20T08:23:12Z] [Install-Nerdctl:42]: "This is a test message"
60+
```
61+
62+
### Error level
63+
64+
```PowerShell
65+
[Logger]::Log("This is a test message", "ERROR")
66+
[Logger]::Error("This is a test message")
67+
68+
ERROR: [2025-05-20T08:23:12Z] [Install-Nerdctl:42]: "This is a test message"
69+
```
70+
71+
### Fatal level
72+
73+
Throws a terminating error.
74+
75+
```PowerShell
76+
[Logger]::Log("This is a test message", "FATAL")
77+
[Logger]::Fatal("This is a test message")
78+
79+
80+
FATAL: [2025-05-20T08:23:12Z] [Install-Nerdctl:42]: "This is a test message"
81+
Exception: Uncaught Critical message
82+
```
83+
84+
## Environment Variables
85+
86+
The logger uses the following environment variables to configure its behavior:
87+
88+
| Variable | Description |
89+
| ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
90+
| `$env:CTK_LOG_LEVEL` | Sets the minimum log level. Accepted values are: `DEBUG`, `INFO`, `WARNING`, `ERROR`, and `FATAL`. Defaults to `INFO` if not set. |
91+
| `$env:CTK_LOG_FILE` | Path to a file where logs should be written. If not set, logs will be written to the console and Windows Event Log (for applicable levels). **Note:** The logger does not handle log file rotation or cleanup—use external tooling for that. |
92+
| `$env:SKIP_CTK_LOGGING` | If set to `"true"`, suppresses console output for all log levels except `DEBUG` (when `$DebugPreference` is not `"SilentlyContinue"`). Logging to file (if set) and to the Windows Event Log (excluding `DEBUG`) still occurs. |

0 commit comments

Comments
 (0)