- Updated all example commands to include -to MYORG parameter - Aligns with environment where no default org is configured - Ensures consistency between script examples and actual requirements
322 lines
8.2 KiB
PowerShell
322 lines
8.2 KiB
PowerShell
#!/usr/bin/env pwsh
|
|
|
|
<#
|
|
.SYNOPSIS
|
|
Debug logs tail wrapper for Salesforce CLI with real-time monitoring
|
|
|
|
.DESCRIPTION
|
|
A user-friendly wrapper around 'sf apex tail log' that provides real-time
|
|
debug log monitoring with filtering, formatting, and intelligent output colorization.
|
|
|
|
.PARAMETER to
|
|
Target org username or alias
|
|
|
|
.PARAMETER ui
|
|
Specific user ID to monitor (default: current user)
|
|
|
|
.PARAMETER lv
|
|
Log level: ERROR, WARN, INFO, DEBUG, FINE, FINER, FINEST
|
|
|
|
.PARAMETER dr
|
|
How long to tail logs in minutes (default: 30)
|
|
|
|
.PARAMETER ft
|
|
Filter log entries containing pattern
|
|
|
|
.PARAMETER ax
|
|
Show only Apex-related log entries
|
|
|
|
.PARAMETER nc
|
|
Disable colored output
|
|
|
|
.PARAMETER ve
|
|
Enable verbose output with timestamps
|
|
|
|
.PARAMETER hp
|
|
Show this help message
|
|
|
|
.EXAMPLE
|
|
.\sf-logs-tail.ps1 -to MYORG
|
|
.\sf-logs-tail.ps1 -to MYORG -lv DEBUG -dr 60
|
|
.\sf-logs-tail.ps1 -to MYORG -ft "MyClass" -ax
|
|
.\sf-logs-tail.ps1 -to sandbox -ui USER123
|
|
|
|
.NOTES
|
|
This script automatically checks for Salesforce CLI installation and runs
|
|
diagnostics if the CLI is not found.
|
|
|
|
Use Ctrl+C to stop tailing logs and exit.
|
|
#>
|
|
|
|
param(
|
|
[string]$to,
|
|
[string]$ui,
|
|
[ValidateSet("ERROR", "WARN", "INFO", "DEBUG", "FINE", "FINER", "FINEST")]
|
|
[string]$lv,
|
|
[int]$dr = 30,
|
|
[string]$ft,
|
|
[switch]$ax,
|
|
[switch]$nc,
|
|
[switch]$ve,
|
|
[switch]$hp
|
|
)
|
|
|
|
# Show help if no parameters provided
|
|
if (-not ($to -or $ui -or $lv -or $dr -ne 30 -or $ft -or $ax -or $nc -or $ve -or $hp)) {
|
|
Get-Help $MyInvocation.MyCommand.Path -Detailed
|
|
exit 0
|
|
}
|
|
|
|
# Show help if requested
|
|
if ($hp) {
|
|
Get-Help $MyInvocation.MyCommand.Path -Detailed
|
|
exit 0
|
|
}
|
|
|
|
# Function to check if Salesforce CLI is installed
|
|
function Test-SalesforceCLI {
|
|
try {
|
|
$null = Get-Command sf -ErrorAction Stop
|
|
return $true
|
|
} catch {
|
|
return $false
|
|
}
|
|
}
|
|
|
|
# Function to run sf-check diagnostics
|
|
function Invoke-SalesforceCheck {
|
|
$checkScript = if (Test-Path "sf-check.ps1") {
|
|
".\sf-check.ps1"
|
|
} elseif (Test-Path "sf-check.sh") {
|
|
"bash sf-check.sh"
|
|
} else {
|
|
$null
|
|
}
|
|
|
|
if ($checkScript) {
|
|
Write-Host "Running Salesforce CLI diagnostics..." -ForegroundColor Yellow
|
|
Invoke-Expression $checkScript
|
|
} else {
|
|
Write-Host "Salesforce CLI not found and no diagnostic script available." -ForegroundColor Red
|
|
Write-Host "Please install the Salesforce CLI: https://developer.salesforce.com/tools/salesforcecli" -ForegroundColor Red
|
|
}
|
|
}
|
|
|
|
# Function to colorize log level
|
|
function Write-ColorizedLogLevel {
|
|
param([string]$Level)
|
|
|
|
switch -Regex ($Level) {
|
|
"ERROR" { return Write-Host $Level -ForegroundColor Red -NoNewline; "" }
|
|
"WARN" { return Write-Host $Level -ForegroundColor Yellow -NoNewline; "" }
|
|
"INFO" { return Write-Host $Level -ForegroundColor Green -NoNewline; "" }
|
|
"DEBUG" { return Write-Host $Level -ForegroundColor Cyan -NoNewline; "" }
|
|
"FINE" { return Write-Host $Level -ForegroundColor Blue -NoNewline; "" }
|
|
"APEX" { return Write-Host $Level -ForegroundColor Magenta -NoNewline; "" }
|
|
default { return $Level }
|
|
}
|
|
}
|
|
|
|
# Function to format log entry
|
|
function Write-FormattedLogEntry {
|
|
param([string]$Line, [bool]$ShowColors, [bool]$ShowTimestamp)
|
|
|
|
if ($ShowColors) {
|
|
if ($ShowTimestamp) {
|
|
$timestamp = Get-Date -Format "HH:mm:ss"
|
|
Write-Host "[$timestamp] " -ForegroundColor Gray -NoNewline
|
|
}
|
|
|
|
# Colorize based on content
|
|
switch -Regex ($Line) {
|
|
"(ERROR|EXCEPTION|FATAL)" {
|
|
Write-Host $Line -ForegroundColor Red
|
|
}
|
|
"(WARN|WARNING)" {
|
|
Write-Host $Line -ForegroundColor Yellow
|
|
}
|
|
"(DEBUG|FINE)" {
|
|
Write-Host $Line -ForegroundColor Cyan
|
|
}
|
|
"(APEX|USER_DEBUG)" {
|
|
Write-Host $Line -ForegroundColor Magenta
|
|
}
|
|
default {
|
|
Write-Host $Line
|
|
}
|
|
}
|
|
} else {
|
|
Write-Host $Line
|
|
}
|
|
}
|
|
|
|
# Function to test if log entry should be shown
|
|
function Test-ShowLogEntry {
|
|
param([string]$Line, [string]$FilterPattern, [bool]$ApexOnlyMode)
|
|
|
|
# Apply apex-only filter
|
|
if ($ApexOnlyMode) {
|
|
if ($Line -notmatch "(APEX|USER_DEBUG|EXCEPTION|METHOD_|CONSTRUCTOR_|DML_|SOQL_|VALIDATION_|FLOW_)") {
|
|
return $false
|
|
}
|
|
}
|
|
|
|
# Apply custom filter
|
|
if ($FilterPattern) {
|
|
if ($Line -notmatch $FilterPattern) {
|
|
return $false
|
|
}
|
|
}
|
|
|
|
return $true
|
|
}
|
|
|
|
# Function to setup signal handlers
|
|
function Set-SignalHandlers {
|
|
# PowerShell equivalent of trap - handle Ctrl+C gracefully
|
|
$null = Register-EngineEvent PowerShell.Exiting -Action {
|
|
Write-Host ""
|
|
Write-Host "Stopping log tail..." -ForegroundColor Yellow
|
|
}
|
|
}
|
|
|
|
# Silently check for Salesforce CLI
|
|
if (-not (Test-SalesforceCLI)) {
|
|
Invoke-SalesforceCheck
|
|
exit 1
|
|
}
|
|
|
|
# Validate duration
|
|
if ($dr -lt 1) {
|
|
Write-Host "Error: Duration must be at least 1 minute" -ForegroundColor Red
|
|
exit 1
|
|
}
|
|
|
|
# Build the sf command
|
|
$sfArgs = @("apex", "tail", "log")
|
|
|
|
# Add optional parameters
|
|
if ($to) {
|
|
$sfArgs += "--target-org"
|
|
$sfArgs += $to
|
|
}
|
|
|
|
if ($ui) {
|
|
$sfArgs += "--user-id"
|
|
$sfArgs += $ui
|
|
}
|
|
|
|
if ($lv) {
|
|
$sfArgs += "--debug-level"
|
|
$sfArgs += $lv
|
|
}
|
|
|
|
# Set up signal handlers
|
|
Set-SignalHandlers
|
|
|
|
# Display log tail information
|
|
Write-Host "📡 Starting Debug Log Tail" -ForegroundColor Blue
|
|
Write-Host "===========================" -ForegroundColor Blue
|
|
|
|
if ($to) {
|
|
Write-Host "Target org: $to" -ForegroundColor Cyan
|
|
}
|
|
|
|
if ($ui) {
|
|
Write-Host "User ID: $ui" -ForegroundColor Cyan
|
|
} else {
|
|
Write-Host "User: Current user" -ForegroundColor Cyan
|
|
}
|
|
|
|
if ($lv) {
|
|
Write-Host "Log level: " -ForegroundColor Cyan -NoNewline
|
|
Write-ColorizedLogLevel $lv
|
|
Write-Host ""
|
|
}
|
|
|
|
Write-Host "Duration: $dr minutes" -ForegroundColor Cyan
|
|
|
|
if ($ft) {
|
|
Write-Host "Filter: $ft" -ForegroundColor Cyan
|
|
}
|
|
|
|
if ($ax) {
|
|
Write-Host "Mode: Apex-only logs" -ForegroundColor Yellow
|
|
}
|
|
|
|
if ($ve) {
|
|
Write-Host "Verbose: Enabled (with timestamps)" -ForegroundColor Yellow
|
|
}
|
|
|
|
# Color settings
|
|
$showColors = -not $nc
|
|
if ($nc) {
|
|
Write-Host "Colors: Disabled" -ForegroundColor Gray
|
|
}
|
|
|
|
Write-Host ""
|
|
Write-Host "Press Ctrl+C to stop tailing logs" -ForegroundColor Yellow
|
|
Write-Host ""
|
|
|
|
# Display the command being run
|
|
if ($ve) {
|
|
Write-Host "Executing: sf $($sfArgs -join ' ')" -ForegroundColor Gray
|
|
Write-Host ""
|
|
}
|
|
|
|
# Start the log tailing with timeout
|
|
try {
|
|
$job = Start-Job -ScriptBlock {
|
|
param($sfArgs)
|
|
& sf @sfArgs 2>$null
|
|
} -ArgumentList $sfArgs
|
|
|
|
$timeoutTime = (Get-Date).AddMinutes($dr)
|
|
|
|
while ((Get-Date) -lt $timeoutTime -and $job.State -eq "Running") {
|
|
$output = Receive-Job $job
|
|
|
|
foreach ($line in $output) {
|
|
if (Test-ShowLogEntry $line $ft $ax) {
|
|
Write-FormattedLogEntry $line $showColors $ve
|
|
}
|
|
}
|
|
|
|
Start-Sleep -Milliseconds 100
|
|
}
|
|
|
|
# Get any remaining output
|
|
$finalOutput = Receive-Job $job
|
|
foreach ($line in $finalOutput) {
|
|
if (Test-ShowLogEntry $line $ft $ax) {
|
|
Write-FormattedLogEntry $line $showColors $ve
|
|
}
|
|
}
|
|
|
|
$exitCode = 0
|
|
if ($job.State -eq "Running") {
|
|
Stop-Job $job
|
|
$exitCode = 124 # Timeout exit code
|
|
} elseif ($job.State -eq "Failed") {
|
|
$exitCode = 1
|
|
}
|
|
|
|
Remove-Job $job
|
|
|
|
Write-Host ""
|
|
if ($exitCode -eq 124) {
|
|
Write-Host "⏰ Log tail timed out after $dr minutes" -ForegroundColor Yellow
|
|
} elseif ($exitCode -eq 0) {
|
|
Write-Host "✅ Log tail completed successfully" -ForegroundColor Green
|
|
} else {
|
|
Write-Host "❌ Log tail failed with exit code: $exitCode" -ForegroundColor Red
|
|
Write-Host "💡 Check org connectivity and user permissions" -ForegroundColor Yellow
|
|
}
|
|
|
|
Write-Host "Tip: Use different filters to focus on specific log types" -ForegroundColor Gray
|
|
|
|
} catch {
|
|
Write-Host "Error during log tail execution: $($_.Exception.Message)" -ForegroundColor Red
|
|
exit 1
|
|
}
|