When Salesforce is life!

Tag: Debug Log

[MadeInItaly] SFDX Lens, your italian Debug buddy

For the #MadeInItaly series where I want to showcase amazing artisanal Italian products from our incredible Italian Ohana, today’s guest post is delivered by Paolo Carrara, software developer, tech enthusiast, scrum master. After a Master’s degree in Software Engineering, he approached Salesforce ecosystem during his early career in a consulting firm and since then he’s been learning, coding, and thinking about new ways to improve his and his team’s work. A huge fan of the Agile movement and an active collaborator of the Italian agile community. You can visit his page (watch out for a hidden easter egg) here.


Many time things don’t go as we planned; we certainly don’t wish so but we must be prepared in such occasions, and when problems happen, there’s one just key factor: time.

That’s why I developed a tool that could help me get to the core problem quicker than whatever I was previously doing.

And that tool is SFDX Lens, a VS Code Extension available for free on the marketplace.

The typical scenario is this: you are happily developing the next new business logic in Salesforce when suddenly you get 3 different issues from 3 different users in your ticketing system, all marked with high priority. Ugh.
Now once you’ve read the ticket to understand what’s the problem you have to switch from your code to your QA environment, go to Setup > Debug Logs > New > compile all the required fields .. oh no! you have just created the 10th trace flag for the same user that was in debug last week.
Anyway, now you’re ready and can (if possible) replicate the issue, switch back to VS Code and inspect the log

And you have to do it 2 other times.

Or, you can leverage SFDX Lens’s Command SFDX Lens: Debug user from Org. With this command, the extension lets you pick just 3 options:

  1. An Org from the ones configured in your VS Code
  2. An active user to debug
  3. An amount of time from 15, 30 and 60 minutes

That’s it.

The extension will take care of setting a trace flag for that user with the maximum amount of precision allowed for the trace flag (which is more or less FINEST to everything), a process that usually take 1-2 seconds, and then you’re ready to replicate the issue and get the log in VS Code.

>Can you ask your user to replicate the issue himself?

Even better, “let me just activate the extension”, and 2 seconds after there you go, “go ahead”.

>Are you already connected to the QA environment?

Even better, you can skip point 1. With the command SFDX Lens: Debug user which creates a trace flag in the environment you’re connected to.

>Don’t want to search for the command in VSCode?

There’s a neat button for the command SFDX Lens: Debug user just in the activity bar below your code.

You don’t have to worry about trace flag pollution anymore, the extension ensures there will be just one trace flag per user (which is, the minimum required to set a trace flag)

Here’s a demo:

Right, now you have the log in VSCode and it’s a monolith of 7500 rows so.. what’s exactly happening here?

To address this question I often ask myself, I’ve developed a new command, right now in beta : SFDX Lens: Log Analysis (Beta) 

This command helps splitting the log into its components, each displayed visually and proportionally to its duration, so now you can focus on a single execution event at a time

This is particularly useful even for performance tuning, now you can see how many times a trigger fires per execution for example.

Here’s a demo:

Everything is made possible through the use of the @salesforce/core package available here: https://github.com/forcedotcom/sfdx-core

Now the circle is complete between getting the debug logs and analyzing them without leaving your IDE.

[Salesforce] The Sobject Crusade: ApexLog

Source: ApexLog

The ApexLog gives access to the Debug Log.

To enable log monitoring for a user, go to Setup > Logs > Debug Logs and click the New button to add an user.

These rows can be queried:

select id, StartTime, Application, DurationMilliseconds, Location, LogLength, LogUser.Name, Operation, Status from apexlog order by StartTime DESC

You can read all the infos regarding the given apex log, such as the User, kind of request, the size of the log, its status, but you cannot access the raw content: to get to the raw content you have to make a Tooling API request to the endpoint:

GET https://xxx.salesforce.com/services/data/v34.0/sobjects/ApexLog/[APEXLOG_ID]/Body/
 Headers:
  Authorization: Bearer [SESSION_TOKEN]

The session token could be grabbed with an anonymous Apex call to UserInfo.getSessionId() or using the OAuth Password flow described in the ActionLinkGroupTemplate object.

This is what you get:

34.0 APEX_CODE,FINEST;APEX_PROFILING,INFO;CALLOUT,INFO;DB,INFO;SYSTEM,DEBUG;VALIDATION,INFO;VISUALFORCE,INFO;WORKFLOW,INFO
17:13:22.020 (20181893)|EXECUTION_STARTED
17:13:22.020 (20210501)|CODE_UNIT_STARTED|[EXTERNAL]|06624000003BOE1|VF: /apex/ConfirmationTokenRequired
17:35:30.036 (36842637)|CODE_UNIT_FINISHED|execute_anonymous_apex
17:35:30.038 (38198449)|EXECUTION_FINISHED
17:13:22.040 (40498571)|CODE_UNIT_STARTED|[EXTERNAL]|ApexDataSource:MongoDBDataSrouceProvider
17:13:22.040 (40523619)|CODE_UNIT_STARTED|[EXTERNAL]|ApexDataSource:MongoDBDataSrouceProvider
17:13:22.043 (43448400)|HEAP_ALLOCATE|[71]|Bytes:3
17:13:22.043 (43497592)|HEAP_ALLOCATE|[76]|Bytes:152
17:13:22.043 (43514859)|HEAP_ALLOCATE|[272]|Bytes:408
17:13:22.043 (43534730)|HEAP_ALLOCATE|[285]|Bytes:408
17:13:22.043 (43553779)|HEAP_ALLOCATE|[379]|Bytes:48
17:13:22.043 (43582592)|HEAP_ALLOCATE|[131]|Bytes:6
17:13:22.043 (43605101)|HEAP_ALLOCATE|[EXTERNAL]|Bytes:6
17:13:22.043 (43624664)|METHOD_ENTRY|[1]|01p2400000AgxCj|MongoDBDataSrouceProvider.MongoDBDataSrouceProvider()
17:13:22.043 (43630791)|STATEMENT_EXECUTE|[1]
17:13:22.043 (43636403)|STATEMENT_EXECUTE|[1]
17:13:22.043 (43641248)|METHOD_EXIT|[1]|MongoDBDataSrouceProvider
17:13:22.043 (43660705)|HEAP_ALLOCATE|[EXTERNAL]|Bytes:4
17:13:22.043 (43671735)|VARIABLE_SCOPE_BEGIN|[1]|this|MongoDBDataSrouceProvider|true|false
17:13:22.043 (43713117)|VARIABLE_ASSIGNMENT|[1]|this|{}|0x74896a31
17:13:22.043 (43758665)|SYSTEM_CONSTRUCTOR_ENTRY|[EXTERNAL]|()
17:13:22.043 (43866237)|SYSTEM_CONSTRUCTOR_EXIT|[EXTERNAL]|()
17:13:22.043 (43880333)|STATEMENT_EXECUTE|[1]
17:13:22.043 (43892018)|CODE_UNIT_FINISHED|ApexDataSource:MongoDBDataSrouceProvider
17:13:22.044 (44048812)|HEAP_ALLOCATE|[EXTERNAL]|Bytes:4
17:13:22.044 (44059804)|SYSTEM_MODE_ENTER|false
17:13:22.044 (44067540)|VARIABLE_SCOPE_BEGIN|[7]|this|MongoDBDataSrouceProvider|true|false
17:13:22.044 (44087738)|VARIABLE_ASSIGNMENT|[7]|this|{}|0x74896a31
17:13:22.044 (44101508)|STATEMENT_EXECUTE|[7]
17:13:22.044 (44104497)|STATEMENT_EXECUTE|[8]
17:13:22.044 (44112485)|HEAP_ALLOCATE|[8]|Bytes:4
17:13:22.044 (44182135)|SYSTEM_CONSTRUCTOR_ENTRY|[8]|()
17:13:22.044 (44204845)|SYSTEM_CONSTRUCTOR_EXIT|[8]|()
17:13:22.044 (44210268)|VARIABLE_SCOPE_BEGIN|[8]|capabilities|List|true|false
17:13:22.044 (44237205)|HEAP_ALLOCATE|[EXTERNAL]|Bytes:4
17:13:22.044 (44259684)|VARIABLE_ASSIGNMENT|[8]|capabilities|{"s":1,"v":[]}|0x3ce93902
17:13:22.044 (44264466)|STATEMENT_EXECUTE|[9]
17:13:22.044 (44381336)|SYSTEM_METHOD_ENTRY|[9]|List.add(Object)
17:13:22.044 (44408889)|HEAP_ALLOCATE|[EXTERNAL]|Bytes:4
17:13:22.044 (44420907)|SYSTEM_METHOD_EXIT|[9]|List.add(Object)
17:13:22.044 (44426463)|STATEMENT_EXECUTE|[10]
17:13:22.044 (44439376)|SYSTEM_METHOD_ENTRY|[10]|List.add(Object)
17:13:22.044 (44453626)|HEAP_ALLOCATE|[EXTERNAL]|Bytes:4
17:13:22.044 (44462615)|SYSTEM_METHOD_EXIT|[10]|List.add(Object)
17:13:22.044 (44466873)|STATEMENT_EXECUTE|[11]
17:13:22.044 (44476051)|SYSTEM_MODE_EXIT|false
17:13:22.044 (44490717)|CODE_UNIT_FINISHED|ApexDataSource:MongoDBDataSrouceProvider
17:13:22.061 (61085594)|CUMULATIVE_LIMIT_USAGE
17:13:22.061 (61085594)|LIMIT_USAGE_FOR_NS|(default)|

Powered by WordPress & Theme by Anders Norén