In this article we'll describe the process for logging in LWC in conjunction with Apex. We will examine how Pharos associates two different types of logs together under a single umbrella.
Logging across LWC and Apex can be very helpful in both troubleshooting and profiling. The most common scenario is to track your component's UI logs and link these together with Apex action calls on the back end. This approach will allow you to see all LWC and Apex logs under the same parent log.
We'll assume that the start of our user flow originates from a button click (an LWC action) and then continues on the back end in Apex. Our goal is to link together the two types of logs. Let's begin with the LWC side.
LWC Component
Let's place a button in our component that will start the main execution and logging from a click event.
Now, let's take a look at our LWC controller and create our first log.
logDemo.js
//this apex action will generate a transaction Id on the back end //that will be used across js and apeximport getTransactionId from'@salesforce/apex/LogDemoController.getTransactionId';//our apex action that will perform some loggingimport apexActionThatGeneratesDMLError from'@salesforce/apex/LogDemoController.apexActionThatGeneratesDMLError';//Triton logger componentimport Triton from'c/triton';//import Triton enums import { AREA, TYPE } from'c/triton';exportdefaultclassLogDemoextendsLightningElement { tritonLogger; @track transactionId;connectedCallback() {this.tritonLogger =newTriton(); }handleClick(event) {//note down some timing values for laterthis.startTime =performance.now();this.createdTimestamp =Date.now();//generate a transaction Id and start our UI executiongetTransactionId({ }).then((data) => {this.transactionId = data;this.executeScenario(); } }executeScenario() { this.tritonLogger.debug( TYPE.FRONTEND,/* type */ AREA.ACCOUNTS,/* functional area */'LWC action (from js) - DML Error',/* summary */'LWC action (from js) - DML Error - Execution Start',/* details */ this.transactionId,/* transaction Id generated earlier */ {name:'TritonDemo',function: 'executeScenario'},/* component info: name and function */performance.now() -this.startTime,/* duration of execution up to this point */this.createdTimestamp /* starting time of our execution */ );//invoke our Apex action passing in the transaction Id //for the apex controller to re-useapexActionThatGeneratesDMLError({ transactionId:this.transactionId }).then(() => { }).catch((error) => {//log this exceptionthis.tritonLogger.exception(error,null); }); }....}
The handleClick() method above will generate two LWC logs: one debug and one error log after the Apex action completes. Note that we are passing our generated transaction Id back to the Apex controller to use further during back-end logging.
Apex Controller
Next, let's look at our Apex controller. The action that we're calling from LWC is also doing some debug and error logging with the provided transaction Id.
LogDemoController.cls
public with sharing classLogDemoController {//this method will use our logger to create a new transaction Id@AuraEnabledpublicstaticStringgetTransactionId() {returnTriton.instance.startTransaction();}@AuraEnabledpublicstaticvoidapexActionThatGeneratesDMLError(String transactionId) {//letting our logger know to re-use an existing transaction IdLog.instance.resumeTransaction(transactionId);Log.instance.debug(TritonTypes.Type.Backend,/* type */TritonTypes.Area.Community,/* functional area */'LWC controller (apex) - DML Error',/* summary */'LWC controller (apex) - DML Error - Apex Execution Start'/* details */ );try {ContentVersion contentVersion =newContentVersion();contentVersion.ContentLocation='Apex Error';contentVersion.Title='Apex Error';contentVersion.PathOnClient='ApexError.pdf';//this insert statement will generate a DMLExceptioninsert contentVersion; } catch (Exception e) {//let's log this exceptionTriton.instance.error(TritonTypes.Area.Community, e); }}....}
Similar to our LWC controller, executing this action will result in a debug and an error log created.
The Result
Altogether, both LWC and Apex executions will generate the following log structure:
Parent LWC Debug Log from executeScenario(),line 34
Child Apex Debug Log from our apexActionThatGeneratesDMLError() action, line 13
Child Apex Error Log from our try/catch block inside the Apex action, line 38
The first log to get created within a sequence of logs using the same transaction Id automatically becomes the parent.