Closed jongpie closed 3 months ago
Thanks @jamessimone for reviewing! I'm going to merge this ASAP, then try to finally merge PR #700 this week 🥳
Awesome! Nice work
Attention: Patch coverage is 97.50000%
with 1 line
in your changes missing coverage. Please review.
Project coverage is 95.39%. Comparing base (
91f2eb2
) to head (aca9a06
).
Files | Patch % | Lines |
---|---|---|
...ore/main/logger-engine/classes/ComponentLogger.cls | 97.43% | 1 Missing :warning: |
:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Have feedback on the report? Share it here.
This is a big PR, so here's a lot of context to explain the issues at hand & what's changing.
Context: The current JavaScript stack trace parsing logic is veeeeery broken
Using the
c/logger
LWC (orNebula/logger
in the managed package), JavaScript developers can adding logging to their own Aura components & LWCs. And much like logging in Apex, when logging in JavaScript, Nebula Logger (tries to) use stack trace parsing to automatically track details about your components, such as the name & function in your component that added a log entry. These details are then stored in fields likeLogEntry__c.OriginLocation__c
,LogEntry__c.OriginSourceApiName__c
,LogEntry__c.OriginSourceActionName__c
, etc.Thanks to some great feedback & contributions from @ZackFra and others, it turns out that there are some big problems with the current approach. This PR fixes several issues related to JavaScript stack trace parsing, including:
logger
in markup (instead of using theimport
approach in JS).This PR will be used in place of PR #692 - after some extensive testing of the current release and changes in #692, I found that there some other related parsing issues with the current release's overall approach, and resolving everything while using the same overall approach/architecture would be fairly challenging. But credit & many thanks to @ZackFra for identifying the critical problems in the current code & how to resolve them. This PR leverages several of the same approaches @ZackFra used in #692.
One outstanding issue not addressed by this PR:
async
functions (example below) have some details missing from their stack traces. This is in part due tocreateLogger()
being anasync
functionOld Approach: JS Stack Trace Parsing Occurred in Apex
Previously, JavaScript stack traces were parsed by the Apex classes
ComponentLogger
andLoggerStackTrace
. One thought behind using this approach was doing it in JavaScript would require the user's browser to do more work, so offloading the parsing to Apex (instead of JS) would help minimize any performance impact of using thelogger
LWC.But, building the parsing in Apex has the downside of making Nebula Logger the only project in the Salesforce ecosystem (that I'm aware of) that's trying to parse JavaScript stack traces using Apex. I have not been able to find any available projects/libraries/classes to provide this - so it has to be built, and maintained, just for Nebula Logger.
Before realizing the number of variations possible in JS stack traces, using Apex still seemed reasonable. But based on some of the info found by @ZackFra in issue #691 and PR #692, I did some extensive testing (some of which is detailed in this comment), using a combination of:
c/logger
createLogger()
in another LWC's.js
file<c-logger>
in another LWC's.html
file<c:logger>
in an Aura component's.cmp
filelightning__AppPage
lightning__FlowScreen
lightning__HomePage
lightning__RecordAction
lightning__RecordPage
lightning__Tab
lightning__UtilityBar
lightningCommunity__Page
Improved Recipes Metadata: Testing These Issues Was Too Difficult
It took a lot of effort to even be able to test these scenarios/permutations, as Nebula Logger's repo didn't have sample metadata setup for most of these scenarios.
Previously, I was really only testing the recipes demo components via custom tabs / the target
lightning__Tab
. And when testing that target, in Firefox (my preferred browser), the stack trace parsing (built in Apex) worked. But in several other contexts, and in almost every other browser, the stack trace parsing logic resulted in inaccurate or missing data.This led to me spending some time focusing on just making it easy for me to be able test logging in different targets, using multiple browsers. This includes:
recipes
metadata so that the 3 demo components (listed below) can now be easily tested in multiple contexts, using theLogger Recipes
app<c:loggerAuraEmbedDemo>
Aura component<c-loggerLWCEmbedDemo>
LWC<c-loggerLWCImportDemo>
LWCconfig
(used by the pipeline & during development)Now, the recipes app is setup to quickly test the 3 demo components in multiple
targets
New Approach: JS Stack Trace Parsing Now Occurs in JS
Once I was able to test JS logging in multiple targets & browsers, I was able to see some huge/critical differences in the stack traces generated in several scenarios. This led to 2 decisions:
The complexity of trying to fix the Apex approach quickly grew: @ZackFra introduced in PR #692 some changes that improved the Apex code that parses JS stack traces (and fixed the parsing in several situations). But for some situations/browsers still did not work correctly, so I spent some trying extend the logic to cover more scenarios. The complexity of this quickly escalated.
When parsing the JS stack trace in Apex, there wasn't a great way to show any of the parsed stack trace's data in JS. Ideally, I want JS logging to be able to show some useful summary in
console.log()
statements (when enabled) to help developers better debug their components. But to do this, the frontend would need to have the parsed stack trace data. This has always been an issue with using Apex to (async) parse the JS stack tracesAs a result, I looked into options for parsing stack traces directly in JavaScript, with 2 hopes/goals in mind:
console.log()
statements to provide Salesforce developers with more context.Eventually, I came across the open source library JavaScript library
stacktrace.js
. It provides cross-browser stack trace parsing, directly in JavaScript. After prototyping this out for several days, it seems to provide (with a few tweaks) accurate stack trace parsing for all of the permutations of browsers + Salesforce targets + methods of calling thelogger
LWC.This PR incorporates a modified version of its stack trace parsing code - all of the Apex code that previously handled JS stack traces has now be removed (with a few lingering items that are deprecated & will be removed in a future release).
Improved the Output of
console.log()
StatementsLastly, since JS stack trace parsing now happens directly in JS, this makes it easier to provide some helpful context to the
console.log()
statements that Nebula Logger automatically executes.Old Approach
In previous versions, Nebula Logger would automatically include the JS object representation of a component log entry every time it auto-calls a
console
log function. This is/was done to try to make it easy for JavaScript developers to see some logging context directly in their browser when debugging.But due to how locker service/locker web security (LWC) work, the object was always shown as a
Proxy
objectTo then actually see the object's data, JS developers would have to store the
Proxy
as a variable in their browser's dev console, and then runJSON.parse(JSON.stringify(theProxyObject))
. So although the data was available in the browser, it was very tedious to actually leverage the data.I also tried printing the
Proxy
object, usingJSON.stringify(theProxyObject)
- but because it contained the original, unparsed stack trace (and not a parsed version of it), the printed string was huuuuuge, and it was still very difficult to quickly see the relevant lines from the stack trace.New Approach
With JS stack trace parsing now happening in the browser, each JS logging statement now includes a pretty-printed JSON string that includes the most relevant info about the log entry's origin:
AuraDefinitionBundle
orLightningComponentBundle
)Now developers can see at a glance the relevant info about their component that logged something.
Console output in Chrome:
Console output in Firefox:
Console output in Microsoft Edge: