Finding and fixing bugs in Salesforce requires a structured diagnostic approach. Because Apex runs in a multi-tenant cloud environment with strict governor limits, developers cannot simply pause production transactions at will. Mastering platform debugging tools—including Trace Flags, granular logging levels, Anonymous Apex, and interactive replay tools—dramatically reduces troubleshooting time.
1. Configuring Targeted Debug Logs & Trace Flags
Debug logs track database operations, governor limit allocations, workflow rules, and custom Apex execution. Rather than capturing everything and hitting file size caps, configure targeted Trace Flags to collect only what you need.
- Navigate to Setup > Debug Logs in Salesforce.
- Click New under the Traced Entity Type section.
- Select User (or Automated Process / Apex Class) and select your target user.
- Create or select a Debug Level (e.g., set
Apex CodetoFINEST,DatabasetoINFO, andSystemtoDEBUG). - Set an expiration window and click Save.
- Max Log Size: Individual logs are capped at 20 MB. Logs exceeding this size are truncated.
- Storage Retention: Salesforce retains up to 1,000 MB of logs for up to 24 hours before automatic purge.
- Log Levels: Ordered from least to most verbose:
NONE<ERROR<WARN<INFO<DEBUG<FINE<FINER<FINEST.
2. Writing Smart, Structured System.debug Statements
Unstructured debug strings clutter your logs and make searching difficult. Always use explicit LoggingLevel enums and format statements so they can be isolated using log filters.
Differentiating between routine execution tracking, payload inspection, and caught exceptions:
public with sharing class PaymentProcessingService {
public static void executePayment(Id accountId, Decimal amount) {
// High-level operational checkpoint
System.debug(LoggingLevel.INFO, 'Starting payment processing for Account: ' + accountId);
try {
if (amount <= 0) {
System.debug(LoggingLevel.WARN, 'Invalid amount provided: ' + amount);
throw new IllegalArgumentException('Payment amount must be greater than zero.');
}
// Verbose payload debugging for deep troubleshooting
System.debug(LoggingLevel.FINEST, String.format('Payload check: AccountId={0}, Amount={1}', new Object[]{ accountId, amount }));
// Payment logic execution...
} catch (Exception ex) {
// Critical error logging with full stack trace
System.debug(LoggingLevel.ERROR, 'Payment Failure: ' + ex.getMessage() + ' | Stack: ' + ex.getStackTraceString());
throw new AuraHandledException('Payment could not be processed.');
}
}
}
3. Rapid Prototyping with Anonymous Apex
The Execute Anonymous window in Developer Console or VS Code allows you to run isolated code blocks on the fly without deploying permanent classes. It is ideal for validating SOQL query syntax, verifying service methods, or inspecting integration payloads.
- User Context: Anonymous Apex executes with the permissions of the current running user, respecting sharing rules and Object/Field-Level Security.
- Ephemeral State: Changes persist to the database unless wrapped in a test rollback pattern (
Database.rollback()). - Open Log Checkbox: Checking Open Log immediately displays the resulting execution tree and debug outputs upon completion.
4. Advanced Debugging: Replay Debugger & Logging Frameworks
Modern enterprise Salesforce development has evolved beyond manual text-log scanning:
- Apex Replay Debugger (VS Code): Download execution logs directly into VS Code to set breakpoints, inspect variables, and step forward and backward through the code execution timeline locally.
- Developer Console Checkpoints: Set up to 5 checkpoints to capture in-memory heap dumps and SOQL query statistics at exact execution lines.
- Open-Source Logging Frameworks (e.g., Nebula Logger): Enterprise orgs deploy persistent logging frameworks that capture exceptions, user transactions, and metadata changes asynchronously into custom objects and platform events.
5. Common Traps & Debugging Best Practices
Setting debug log filters to
FINEST across loops in high-volume triggers causes immediate Log Truncation (hitting the 20 MB cap) and consumes valuable CPU time. Never leave verbose trace flags enabled for long periods in active sandboxes or production.
LoggingLevel enums in code, filter logs in Developer Console by checking "Debug Only", and use the Apex Replay Debugger in VS Code for zero-cost interactive stepping.
- Filter by "Debug Only": In Developer Console, check the Debug Only box at the bottom of the log viewer to filter out system noise and view only your explicit
System.debug()statements. - Clean Up Active Trace Flags: Regularly delete expired or unused trace flags to keep org log generation lean.
- Always Capture the Stack Trace: When catching exceptions, always log
ex.getStackTraceString()alongsideex.getMessage()to locate the exact class and line number of the failure.
Summary
Mastering Apex debugging is about combining real-time log analysis with structured code inspection. By configuring targeted trace flags, writing leveled System.debug statements, leveraging the Apex Replay Debugger in VS Code, and adopting robust logging frameworks, you can troubleshoot complex issues quickly and maintain resilient Salesforce applications.