- Replace single-character options with memorable two-character alternatives - Based on syllable mapping: -to (target-org), -qy (query), -fm (format), etc. - Updated all bash and PowerShell scripts with consistent options - Added comprehensive documentation and examples to README.md - Maintains backward compatibility with long options - More intuitive and self-documenting than traditional CLI options
316 lines
8.2 KiB
PowerShell
316 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 o
|
|
Target org username or alias
|
|
|
|
.PARAMETER UserId
|
|
Specific user ID to monitor (default: current user)
|
|
|
|
.PARAMETER Level
|
|
Log level: ERROR, WARN, INFO, DEBUG, FINE, FINER, FINEST
|
|
|
|
.PARAMETER Duration
|
|
How long to tail logs in minutes (default: 30)
|
|
|
|
.PARAMETER Filter
|
|
Filter log entries containing pattern
|
|
|
|
.PARAMETER ApexOnly
|
|
Show only Apex-related log entries
|
|
|
|
.PARAMETER NoColors
|
|
Disable colored output
|
|
|
|
.PARAMETER Verbose
|
|
Enable verbose output with timestamps
|
|
|
|
.PARAMETER Help
|
|
Show this help message
|
|
|
|
.EXAMPLE
|
|
.\sf-logs-tail.ps1
|
|
.\sf-logs-tail.ps1 -Level DEBUG -Duration 60
|
|
.\sf-logs-tail.ps1 -Filter "MyClass" -ApexOnly
|
|
.\sf-logs-tail.ps1 -o sandbox -UserId 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]$o,
|
|
[string]$UserId,
|
|
[ValidateSet("ERROR", "WARN", "INFO", "DEBUG", "FINE", "FINER", "FINEST")]
|
|
[string]$Level,
|
|
[int]$Duration = 30,
|
|
[string]$Filter,
|
|
[switch]$ApexOnly,
|
|
[switch]$NoColors,
|
|
[switch]$Verbose,
|
|
[switch]$Help
|
|
)
|
|
|
|
# Show help if requested
|
|
if ($Help) {
|
|
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 ($Duration -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 ($o) {
|
|
$sfArgs += "--target-org"
|
|
$sfArgs += $o
|
|
}
|
|
|
|
if ($UserId) {
|
|
$sfArgs += "--user-id"
|
|
$sfArgs += $UserId
|
|
}
|
|
|
|
if ($Level) {
|
|
$sfArgs += "--debug-level"
|
|
$sfArgs += $Level
|
|
}
|
|
|
|
# Set up signal handlers
|
|
Set-SignalHandlers
|
|
|
|
# Display log tail information
|
|
Write-Host "📡 Starting Debug Log Tail" -ForegroundColor Blue
|
|
Write-Host "===========================" -ForegroundColor Blue
|
|
|
|
if ($o) {
|
|
Write-Host "Target org: $o" -ForegroundColor Cyan
|
|
}
|
|
|
|
if ($UserId) {
|
|
Write-Host "User ID: $UserId" -ForegroundColor Cyan
|
|
} else {
|
|
Write-Host "User: Current user" -ForegroundColor Cyan
|
|
}
|
|
|
|
if ($Level) {
|
|
Write-Host "Log level: " -ForegroundColor Cyan -NoNewline
|
|
Write-ColorizedLogLevel $Level
|
|
Write-Host ""
|
|
}
|
|
|
|
Write-Host "Duration: $Duration minutes" -ForegroundColor Cyan
|
|
|
|
if ($Filter) {
|
|
Write-Host "Filter: $Filter" -ForegroundColor Cyan
|
|
}
|
|
|
|
if ($ApexOnly) {
|
|
Write-Host "Mode: Apex-only logs" -ForegroundColor Yellow
|
|
}
|
|
|
|
if ($Verbose) {
|
|
Write-Host "Verbose: Enabled (with timestamps)" -ForegroundColor Yellow
|
|
}
|
|
|
|
# Color settings
|
|
$showColors = -not $NoColors
|
|
if ($NoColors) {
|
|
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 ($Verbose) {
|
|
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($Duration)
|
|
|
|
while ((Get-Date) -lt $timeoutTime -and $job.State -eq "Running") {
|
|
$output = Receive-Job $job
|
|
|
|
foreach ($line in $output) {
|
|
if (Test-ShowLogEntry $line $Filter $ApexOnly) {
|
|
Write-FormattedLogEntry $line $showColors $Verbose
|
|
}
|
|
}
|
|
|
|
Start-Sleep -Milliseconds 100
|
|
}
|
|
|
|
# Get any remaining output
|
|
$finalOutput = Receive-Job $job
|
|
foreach ($line in $finalOutput) {
|
|
if (Test-ShowLogEntry $line $Filter $ApexOnly) {
|
|
Write-FormattedLogEntry $line $showColors $Verbose
|
|
}
|
|
}
|
|
|
|
$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 $Duration 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
|
|
}
|