debug-log-analyzer icon indicating copy to clipboard operation
debug-log-analyzer copied to clipboard

feat: show sobject type for dml when type is SObject

Open lcottercertinia opened this issue 1 year ago • 2 comments

Is your feature request related to a problem?

The first think I usually look for (when checking DML) is the object type and it often just says SObject (from the list type). We very rarely use mixed DML.

Describe the solution you'd like

Wow about parsing it from the trigger type if present?

0:00:00:000 CODE_UNIT_STARTED [EXTERNAL]|<anId>|ns.MyObjectTrigger on MyObject trigger event BeforeInsert|__sfdc_trigger/ns/MyObjectTrigger

Instead of showing DML Op:Insert Type:SObject we can parse from the CODE_UNIT_STARTED and show DML Op:Insert Type:MyObject

Sometimes we lack some SObject type info 1 issue is that we are not provided with either the namespace or whether the SObject is a standard or custom object. e.g MyObject could be MyObject or MyObject__c or ns__MyObject__c we have no way of knowing.

mixed dml If we have multiple CODE_UNIT_STARTED and therefore multiple SObject types for a single DML it would break the grouping. We should intead keep the dml being grouped on op and type:SObject and add additional context to show how many object types were included in the dml

Edit not currently deliverable we need SF changes to log output, see this comment

lcottercertinia avatar May 09 '24 16:05 lcottercertinia

Determining the SObject type from triggers is unreliable since you only get CODE_UNIT log lines if there is a trigger present on the object, meaning if we were inserting a List<SObject> that had both Accounts and Opportunities, but we only had a trigger on Account, it would look like the List<SObject> only contained Accounts.

jcoultercertinia avatar Sep 04 '25 14:09 jcoultercertinia

Here is a log example showing the above case outline by @jcoultercertinia Since we only have a trigger for Account we would incorrectly assign Account as the Type. In this case leaving SObject is actually clearer since it gives a clue there are multiple types. We could say 1 or more but that is fairly implicit when type is SObject.

What we need is more information from Salesforce in the logs, here is an SF idea to get that added Ideally we would get 1 of 2 outputs or similar information.

  1. 03:34:54.1 (2386017)|DML_BEGIN|[6]|Op:Insert|Type:SObject|Rows:1, 1| Account, Opportunity
  2. 03:34:54.1 (2386017)|DML_BEGIN|[6]|Op:Insert|Type:Account, Opportunity|Rows:1, 1
64.0 APEX_CODE,INFO;APEX_PROFILING,NONE;CALLOUT,NONE;DATA_ACCESS,INFO;DB,FINEST;NBA,INFO;SYSTEM,DEBUG;VALIDATION,NONE;VISUALFORCE,NONE;WAVE,INFO;WORKFLOW,NONE
Execute Anonymous: Account a1 = new Account(name='a1');
Execute Anonymous: Account a2 = new Account(name='a2');
Execute Anonymous: Opportunity o1 = new Opportunity(name='o1', stageName ='Prospecting', closeDate= system.today()+1);
Execute Anonymous: Opportunity o2 = new Opportunity(name='o2', stageName ='Prospecting', closeDate= system.today()+1);
Execute Anonymous:
Execute Anonymous: insert a1;
Execute Anonymous: insert new list<Sobject>{a2, o1};
Execute Anonymous: insert o2;
02:43:29.6 (6439116)|USER_INFO|[EXTERNAL]|<userId>|<username>|(GMT-07:00) Pacific Daylight Time (America/Los_Angeles)|GMT-07:00
02:43:29.6 (6476007)|EXECUTION_STARTED
02:43:29.6 (6494190)|CODE_UNIT_STARTED|[EXTERNAL]|execute_anonymous_apex
02:43:29.6 (7331393)|DML_BEGIN|[6]|Op:Insert|Type:Account|Rows:1
02:43:29.6 (63520881)|CODE_UNIT_STARTED|[EXTERNAL]|<Id>|pse.AccountTrigger on Account trigger event BeforeInsert|__sfdc_trigger/pse/AccountTrigger
02:43:29.6 (67475121)|SOQL_EXECUTE_BEGIN|[29]|Aggregations:1|SELECT Name, Id, appirio_core__group_key__c, (SELECT appirio_core__Value__c FROM appirio_core__Values__r ORDER BY appirio_core__Sort__c ASC NULLS FIRST) FROM appirio_core__Config_Option__c
02:43:29.6 (137278841)|SOQL_EXECUTE_EXPLAIN|[29]|TableScan on appirio_core__Config_Option__c : [], cardinality: 582, sobjectCardinality: 582, relativeCost 2.841
02:43:29.6 (137300814)|SOQL_EXECUTE_END|[29]|Rows:582
02:43:29.6 (169198830)|SYSTEM_MODE_ENTER|false
02:43:29.6 (180510329)|SYSTEM_MODE_EXIT|false
02:43:29.6 (180530623)|SYSTEM_MODE_ENTER|false
02:43:29.6 (191040707)|SYSTEM_MODE_EXIT|false
02:43:29.6 (191230175)|CODE_UNIT_FINISHED|pse.AccountTrigger on Account trigger event BeforeInsert|__sfdc_trigger/pse/AccountTrigger
02:43:29.6 (240186429)|CODE_UNIT_STARTED|[EXTERNAL]|<Id>|pse.AccountTrigger on Account trigger event AfterInsert|__sfdc_trigger/pse/AccountTrigger
02:43:29.6 (240467847)|SYSTEM_MODE_ENTER|false
02:43:29.6 (240485848)|SYSTEM_MODE_EXIT|false
02:43:29.6 (240616345)|CODE_UNIT_FINISHED|pse.AccountTrigger on Account trigger event AfterInsert|__sfdc_trigger/pse/AccountTrigger
02:43:29.6 (250739145)|DML_END|[6]
02:43:29.6 (251969856)|DML_BEGIN|[7]|Op:Insert|Type:SObject|Rows:2
02:43:29.6 (264499494)|CODE_UNIT_STARTED|[EXTERNAL]|<Id>|pse.AccountTrigger on Account trigger event BeforeInsert|__sfdc_trigger/pse/AccountTrigger
02:43:29.6 (264913065)|SYSTEM_MODE_ENTER|false
02:43:29.6 (264937230)|SYSTEM_MODE_EXIT|false
02:43:29.6 (265085067)|CODE_UNIT_FINISHED|pse.AccountTrigger on Account trigger event BeforeInsert|__sfdc_trigger/pse/AccountTrigger
02:43:29.6 (292896199)|CODE_UNIT_STARTED|[EXTERNAL]|<Id>|pse.AccountTrigger on Account trigger event AfterInsert|__sfdc_trigger/pse/AccountTrigger
02:43:29.6 (293145878)|SYSTEM_MODE_ENTER|false
02:43:29.6 (293164589)|SYSTEM_MODE_EXIT|false
02:43:29.6 (293287373)|CODE_UNIT_FINISHED|pse.AccountTrigger on Account trigger event AfterInsert|__sfdc_trigger/pse/AccountTrigger
02:43:29.6 (383510011)|DML_END|[7]
02:43:29.6 (384652982)|DML_BEGIN|[8]|Op:Insert|Type:Opportunity|Rows:1
02:43:29.6 (414422727)|DML_END|[8]
02:43:29.6 (464220500)|CODE_UNIT_FINISHED|execute_anonymous_apex
02:43:29.6 (464240062)|EXECUTION_FINISHED

lcottercertinia avatar Sep 05 '25 11:09 lcottercertinia