Debugging in Salesforce
Note — this blog is written for an audience who has basic knowledge about concepts referred in this blog such as Apex Classes, Triggers, Duplicate Rules, Validation Rules, etc. If you want to learn more about these concepts please go to Trailhead.
Also, the contents of this blog are written in order to give deep enough knowledge to readers so that they can use the referenced features efficiently. I will still insist to refer the links given in the “Additional Resources” section at the end of this blog for more in-depth information or not covered points.
Though we can not perform step-by-step debugging in Salesforce locally (possible remotely using Apex Interactive Debugging which is a paid service) unlike other platforms such as .NET or Node.js, however, we can generate Debug Logs which can be very helpful for both Salesforce App Builders and Developers as it can provide minute details of step-by-step execution of following Categories…
Apex Code
Any apex code statement which is executed as part of a transaction can be logged. E.g. Triggers, Visualforce Controllers-Actions-Getter and Setter Properties, DML-SOQL-SOSL statements, Web Service Callouts, Asynchronous Apex, system.debug() statements, etc.
System Validations
This includes validations which are done by system i.e. Matching and Duplicate Rules.
Custom Validations
This includes all the Validation Rules created by users.
Workflow
Though the term “Workflow” may look very specific, under this category comes Lightning Processes, Lightning Flows, Workflow Rules and their Actions.
Profiling
This provides information about the usage of resources from the defined Governor Limits associated to the above categories e.g. DML or SOQL statements and rows, number of Web Service Callouts, System Resources such as CPU Time and Heap Size, future or queueable jobs added, emails sent, etc.
How to generate Debug Logs?
Trace Flags
In order to generate debug logs for any of the above listed categories, we need to set trace flags. Trace Flags can be set for Apex Classes, Triggers and Users.
User Trace Flags
In the image — 1.0, the “User Trace Flags” section lists the active flags set for certain users.
Name column specifies the name of the user for whom the flag is set. Note that, this list does not display Apex Classes or Triggers for which Trace Flags are set. We need to check list of Apex Classes or Triggers to see the Flags status. Find the image below…
Refer image 1.0 and the section “User Trace Flags” in it for following…
Log Type specifies type of logs the flag will generate. Possible types are — USER_DEBUG, DEVELOPER_LOG, or CLASS_TRACING. However, in the “User Trace Flags” section, we can find only two types — USER_DEBUG and DEVELOPER_DEBUG.
USER_DEBUG type applies whenever, we manually set the Trace Flags for users by clicking on “New” button. While DEVELOPER_LOG type applies to Trace Flags which are automatically set by system i.e. whenever a user opens the Developer Console.
Value in Debug Level Name column is a reference to “Debug Level”. Debug Level is a setting that specifies to which Level a particular Category should be logged. See below image that shows list of Categories…
Possible values of “Levels” could be — None, Info, Error, Fine,Finer, Finest and Debug.
Debug Logs
This section (refer Image — 1.0) displays the logs generated for users for whom the Trace Flags are active. The active status of Trace Flags is determined by the “Start Date” and “Expiration Date” columns in the “User Trace Flags” section.
As specified above that the Trace Flags can be set for Apex Classes and Triggers, however, Debug Logs will be generated for them only when, a Trace Flag is set for a user and execution of flagged classes or triggers is triggered by that user. Note that, the Debug Levels set for Apex Classes and Triggers will be considered instead of that of Trace Flags set for that user while generating logs.
Also, it may happen that different Debug Levels are set for Apex Classes or Triggers which are calling each other. In this case as well, the Debug Levels set for each individual Apex Class or Trigger will be used to generate logs. Also, if the Trace Flags are not set for Apex Classes or Triggers, and a user is executing them, Debug Logs will be generated by considering Debug Levels set for the User Trace Flags.
System Logs vs Monitoring Logs
System logs are the logs which are generated by User Trace Flags with Log Type — DEVELOPER_LOG. That means, whenever a user executes apex code using “Execute Anonymous” or run test classes in Developer Console, debug logs are generated automatically. These logs will not be visible in “Debug Logs” section of the “Debug Logs” page (refer Image — 1.0). However, will be accessible in Developer Console.
Monitoring Logs on the other side are the logs that are generated whenever we set Trace Flags for users.
Limits
- A single Debug Log can be of a maximum size of 20 MB only. In case, if the execution of a transaction is generating logs more than 20 MB, the earlier lines of the logs will be removed and only latest lines will be retained.
- System Logs will be retained for a period of 1 day while Monitoring Logs will be retained for a period of 7 days.
- If the system generates Debug Logs weighing more than 1000 MB, system will not allow editing of existing or addition of new Trace Flags. Also, it will stop generating new logs. In this case, we will need to manually delete the logs to allow the system to generate new logs or wait for the auto-deletion period as specified above.
Reading and Understanding Debug Logs
Debug logs may generally overwhelm us with a lot of information that we may not be looking for. So, it is important for us to understand the format of Debug Logs so that we can quickly spot the only information we are looking for.
Header
Every Debug Log will have this section which will specify two types of information 1) API Version used to execute the transaction for which the log was generated and 2) Debug Levels for each Category which are logged. Note that each Category is separated by a semicolon (;) . Find image below for an example,
Execution Unit
These two lines delimits the execution of the transaction — EXECUTION_STARTED and EXECUTION_FINISHED. Note that these lines will come only once in a single Debug Log. Also, a single Debug Log is generated for a discrete single transaction.
Code Unit
These two lines delimits execution of a single category — CODE_UNIT_STARTED and CODE_UNIT_FINISHED. Note that Code Unit doesn’t mean Apex Code only. Code unit covers all the Categories listed above in this article. Refer Image — 1.2 for list of Categories.
We can use these lines to find how many categories are triggered by a transaction. This also helps us find our Category of interest e.g. a Trigger or a Validation Rule which is failing.
Log Lines
Each log line also follows a specific format. See below image…
Left side of the Timestamp is the date-time when the execution happened. Random number in the braces (xxxx) tells the time in nanoseconds that is elapsed since the execution of the transaction has started.
USER_DEBUG is the event type. Additional types could be, HEAP_ALLOCATE, VARIABLE_ASSIGNMENT, METHOD_ENTRY, CODE_UNIT_STARTED, EXECUTION_STARTED, etc.
[2] Is the line number in the Apex Class or Trigger. The line number may also point line number of code unit which is not accessible to us e.g. Managed Package code or system class code e.g. Database class.
“Hello World” — is the output or detail of the execution.
Additional Resources