Releases: jongpie/NebulaLogger
Track When An Admin Logs In As Another User
Core Unlocked Package Changes
Closed #396 by adding new fields & logic to determine if the current user (stored in Log__c.LoggedBy__c
) is being impersonated by another user
-
Added config & code to track impersonators using the Login As feature - this information is now tracked in the new field
LogEntryEvent__e.ImpersonatedById__c
andLog__c.ImpersonatedBy__c
-
Added new class
LoggerSObjectProxy
with inner classes that provide representations of problematic SObject TypesAuthSession
,LoginHistory
andNetwork
. This simplifies some of the downstream code, and makes things easier to test. -
Fixed an unreported
SObjectException
that would occur when logging a record ID for a template object, such asCaseComment
,CaseHistory
,AccountHistory
, etc., with the errorSystem.SObjectException: Cannot locate Apex Type for ID
Thanks to @surajp, @bussemac, @jkranz-rk, @jamessimone, and @nojanv for all of the help with this getting this new feature released!
v4.9.0 - Winter '23 Release
Managed Package Release
This release is for both the unlocked package (as always), as well as the managed package!
v4.8.0
of the managed package to provide configurable options to optimize Nebula Logger declaratively, and you may want to customize these new options to best suit your needs. Some of the new items includes:
https://github.com/jongpie/NebulaLogger/releases/tag/v4.8.4
- Optional usage of Platform Cache to provide org & session caching of data & metadata used by Nebula Logger. You may want to customize the cache partition size based on your org's available cache space (or disable this feature via a new
LoggerParameter__mdt
record, if you don't want Nebula Logger to use platform cache). - New
LoggerParameter__mdt
records to control Nebula Logger's querying of data it's recommended that _### you review the changes inv4.9.0
prior to upgrading in your org to ensure thatLoggerSettings__c
andLoggerParameter__mdt
records in yo**_**ur org, since some configuration options have changed. If you use the managed package & are upgrading, - New custom object
LoggerScenario__c
& expanded overall functionality of scenario-based logging via the methodsLogger.getScenario(String)
, Logger.setScenario(String)and
Logger.endScenario(String)`
You can see everything that's change between v4.8.0
and v4.9.0
by reviewing:
- The v4.9.0 milestone to see all of the issues & pull requests that are included in the this release.
- The diff between v4.8.0 and v4.9.0 to see all of the code & metadata changes that have been committed since the last managed package release.
Core Unlocked Package Changes
Metadata API Version
- Updated all metadata from API v55.0 (Summer '22 release) to v56.0 (Winter '23 release)
- Removed the now-deprecated picklist value "v55.0 - Summer '22 Release" in the field
Log__c.ApiVersion__c
Updated Visibility of Apex Methods
Updated the following methods from public
to global
so that they're now available in the managed package, using the Nebula
namespace - this should not have any direct impact on the unlocked package's functionality
-
Logger
class static methodsLogger.getVersionNumber()
Logger.endScenario(String scenario)
Logger.ignoreOrigin(System.Type apexType)
-
LogEntryEventBuilder
class instance methodsLogEntryEventBuilder.getLogEntryEvent()
- returns an instance ofLogEntryEvent__e
Metadata Cleanup
- Updated the descriptions in several custom metadata type objects and
LoggerParameter__mdt
records to provide more details & better reflect the current usage of each item
Bugfixes
- Fixed an
System.InvalidParameterValueException
that could occur inLogBatchPurgeScheduler
when thebatchSize
value wasnull
- now,LogBatchPurgeScheduler
checks fornull
values & uses a default value instead.- The default
batchSize
value has also been changed from200
to2000
. TheLogBatchPurger
job has always used200
as the default value because the original code (written years ago) wasn't scalable - it was rewritten to be much more scalable in v4.6.0 when the objectsLogEntryTag__c
andLoggerTag__c
were introduced, but the default batch size was never increased.
- The default
Better Handling of Apex Class Name Collisions
For orgs that use the unlocked package (core package), installation issues can occur if the org has a custom Apex class that matches the name of a standard Apex class, such as Limits
, Network
, Test
, Type
, etc. References throughout the codebase have been updated to include the System
namespace prefix to ensure that this type of metadata collision does not prevent installation of Nebula Logger.
Query Optimizations & More Configurable Controls
Core Package Changes
Synchronous Context Optimizations
Several enhancements have been made to reduce the overhead that Nebula Logger consumes when logging - these enhancements help with some platform limits, such as query limits, CPU time limits, etc. (closes #311 reported by @LawrenceLoz). Many thanks again to @LawrenceLoz for doing some stellar analysis on the codebase to identify some of these optimizations.
- Added new
LoggerParameter__mdt
recordEnableStackTraceParsing
to disable stack trace parsing org-wide. Although parsing stack traces can help provide contextual info for reporting, the code consumes CPU time in Apex - orgs can now choose if they want to disable this functionality to improve Nebula Logger's performance. - Added new
LoggerParameter__mdt
records to enable/disable ifLogEntryEventBuilder
queries run synchronously (default behavior). When these records are disabled (Value__c = 'false'
), the corresponding queries run asynchronously after platform events are published. This means that the corresponding fields aren't set onLogEntryEvent__e
, but are still populated onLog__c
andLogEntry__c
. Four (4) new custom metadata records are included:LoggerParameter.QueryAuthSessionDataSynchronously
LoggerParameter.QueryNetworkDataSynchronously
LoggerParameter.QueryOrganizationDataSynchronously
LoggerParameter.QueryUserDataSynchronously
- Updated
Logger
class to internally cached the value ofUserInfo.getSessionId()
. The original (erroneous) assumption was that the platform would handle caching this, but repeated calls to the method seem to consume additional CPU time - the value is now cached in a private constant.
Caching System Improvements
Platform Cache is now being leveraged to supplement the existing transaction caching (partially closes #311, and closes #389 reported by @rmccu)
- Added platform cache partion
LoggerCache
that comes with 3MB allocated, based on the 3MB that Salesforce provides for security-approved managed packages. Sadly, Nebula Logger has not yet gone through this process yet, but still seemed like a sensible default size to use.- 1MB allocated to the org partition
- 2MB allocated to the session partition
- Updated Apex class
LoggerCache
to now support 3 types of caching:LoggerCache.getTransactionCache()
. This is the existing caching system that's been used for a few releases. It caches values in a transaction using aprivate static final Map<String, Object>
constant. This is still used internally throughoutLoggerCache
to supplement some limitations with platform cache, such as not being able to cachenull
valuesLoggerCache.getOrganizationCache()
. This leverages the org partition of Platform CacheLoggerCache.getSessionCache()
. This leverages the session partition of Platform Cache
- Updated all existing caching in Nebula Logger to now leverages platform caching by default.
- Added a new
LoggerParameter__mdt
record 'UsePlatformCache' to control if Nebula Logger leverages platform cache. When 'UsePlatformCache' is disabled (Value__c = 'false'), Nebula Logger will only useLogger.getTransactionCache()
(which is existing behavior before platform cache was introduced).
Large Data Volume (LDV) Optimizations
I've included some query-related enhancements to address some of the performance problems that @rmccu brought up for orgs with large data volumes (2+ millions Log__c
records created daily)
- Added new
LoggerParameter__mdt
records to completely disable certain queries executed by Nebula Logger (closes #390 reported by @rmccu). Some of the queries used by Nebula Logger can perform poorly in orgs with large data volumes - the new records provide a way for orgs to completely disable certain queries, with the tradeoff that the corresponding fields will benull
. Seven (7) queries can now be fully disabled - there are still some other queries throughout Nebula Logger that don't have this option, but these should be the most critical queries.LoggerParameter.QueryApexClassData
- when disabled, theApexClass
object is not queried, and the relevant fields onLogEntry__c
are nullLoggerParameter.QueryAuthSessionData
- when disabled, theAuthSession
object is not queried, and the relevant fields onLogEntry__c
are nullLoggerParameter.QueryFlowDefinitionViewData
- when disabled, theFlowDefinitionView
object is not queried, and the relevant fields onLogEntry__c
are nullLoggerParameter.QueryNetworkData
- when disabled, theNetwork
object is not queried, and the relevant fields onLogEntry__c
are null. Note: this only applies to orgs that use an Experience Cloud site (stored in theNetwork
object)LoggerParameter.QueryOrganizationData
- when disabled, theOrganzation
object is not queried, and the relevant fields onLogEntry__c
are nullLoggerParameter.QueryRelatedRecordData
- when disabled, the dynamic queries used to query record names (based on the fieldLogEntry__c.RecordId__c
) are not executed, the fieldLogEntry__c.RecordName__c
is nullLoggerParameter.QueryUserData
- when disabled, theUser
object is not queried, and the relevant fields onLogEntry__c
are null
Bugfixes
- Fixed
LogEntry__c.Timestamp__c
being inaccurately set in some edge cases. This was an unreported bug found whereLogEntryEvent__e.TimestampString__c
could be out of sync withLogEntryEvent__e.Timestamp__c
, resulting in inaccurate data being stored inLogEntry__c.Timestamp__c
. The bug has been fixed & some additional tests have been added to ensure that this continues to behave as expected.
Data Model Changes
- Added new fields
LogEntryEvent__e.RequestId__c
andLog__c.RequestId__c
to store the value ofSystem.Request.getCurrent().getRequestId()
. In versions v3.1.0 through v4.7.2, this value was used forLog__c.TransactionId__c
, but reverted to using a more reliable customUUID
in v4.7.3 (the original solution). The newRequestId__c
fields provides a way to still report on this value, which can be helpful for tying Nebula Logger's data back to platform data & logs.
Test Improvements
- Fixed #393 (reported by @mykhaylo-partyka) by removing an unnecessary & problematic call to
List.sort()
on the expected query results - Added new
ApexTestSuite
LoggerExtraTests (only deployed to/used by the pipeline for integration tests) - Added more integrations tests, primarily for Experience Site (Community/Network/Portal/too-many-names-ahhh) testing around
Network
querying & setting of related fields - Make
LoggerEngineDataSelector
andLogManagementDataSelector
classes & methodsvirtual
& implemented test implementations in the respective test classesLoggerEngineDataSelector_Tests
andLogManagementDataSelector_Tests
to provide a cleaner way to test query executions within Nebula Logger's codebase. - The test implementations currently usedin test classes still execute all of the related queries, so the queries aren't returning mock values (when possible) just yet. This PR has most of the foundational changes need to support full mocking, but I'm planning to revisit some of the tests throughout the codebase in a future release to implement mock return values when possible. That will make it easier to test queried data in general, and should also give the tests classes another nice boost in test speed (in addition to some other substantial test speed improvements made in v4.7.1).
Experience Site Test Metadata Improvements
These changes only impact the pipeline to help validate logic related to orgs that use Nebula Logger for Experience Cloud sites (aka Community Cloud) - these changes don't have any direct functional changes to Nebula Logger
- Added high-volume traffic Community profile & related metadata changes for pipeline testing purposes
- Added more Apex tests for Experience Cloud scenarios in the
extra-tests
folder. These tests are only used in the pipeline - they are not included in the core package.
Async Failure Additions Plugin Package Changes
Created v1.0.2 of the Async Failure Additions plugin
- @jamessimone implemented an incredible, new feature for this plugin to automatically log Flow errors that occur in Screen Flows, using the platform event
FlowExecutionErrorEvent
(closes #372 - implemented in #392)
Slack Plugin Package Changes
Created v1.5.1 of the Slack plugin
- Updated the formatting of the field 'Last Log Entry Message' to handle line breaks
Many thanks to @jamessimone , @LawrenceLoz, @rmccu, and @mykhaylo-partyka for all of the help with this release!
Improved LogEntry__c Formula Fields for Limits
For each transaction limit returned in the Limits class, LogEntry__c
has 3 fields: "limit name" used, "limit name" max, and a "limit name" formula field that shows "Used / Max". This is helpful for quickly checking how much of each limit has been consumed. However, for some limits with a large max value (such as Heap Size), the formula field does not format the numbers (which is apparently quite difficult to do in a formula field), so you end up with values like "12425 / 6000000" which can sometimes be hard to read at glance, it makes it hard to tell what percentage of the limit has been consumed, as shown in this screenshot:
To help with this, 2 changes have been made to all of the limits formula fields on LogEntry__c
:
- Added a flag indicator based on the percent of the limit used, using somewhat arbitrary-but-sensible ranges:
- 90% or more of a limit consumed: a red flag is displayed
- 80-90% of a limit consumed: a yellow flag is displayed
- Less than 80%: a green flag is displayed
- Added percentage calculation based on the limit used: to make it easier at a glance to know how much of a limit has been consumed, each field now displays the percent used in parenthesis
With these changes in place, the limits are now much easier to understand at a glance - the colored flags help indicate if there are any limits to be worried about (red & yellow flags), and the percentage calculation tells you exactly how close you are to a particular limit:
More Controls for Scenario-Based Logging
- The field
LoggerSettings__c.DefaultLogScenario__c
has been renamed toLoggerSettings__c.DefaultScenario__c
, which is treated as a "new" field when upgrading. ExistingLoggerSettings__c
records in your org may need to be updated to move data inLoggerSettings__c.DefaultLogScenario__c
toLoggerSettings__c.DefaultScenario__c
. The original fieldLoggerSettings__c.DefaultScenario__c
is now deprecated & will no longer be used. - The object
LogScenarioRule__mdt
has been renamed toLoggerScenarioRule__mdt
, which is treated as a "new" object when upgrading. You will need to migrate any custom metadata records fromLogScenarioRule__mdt
to the new objectLoggerScenarioRule__mdt
. The original objectLogScenarioRule__mdt
is now deprecated & will no longer be used.
Core Package Changes
This release is complements some of the changes released in v4.8.1
, and closes #355 by further enhancing scenario-based logging
- Added new method
Logger.endScenario(String scenario)
suggested by @jamessimone. This provides a way for Apex developers to explicitly end a scenario, which then automatically rolls back to the previous scenario when applicable (and re-applies the previous scenario rule, if one exists) - Added new fields
LogEntryEvent__e.EntryScenario__c
andLogEntry__c.EntryScenario__c
(used in addition toLogEntryEvent__e.TransactionScenario__c
andLog__c.TransactionScenario__c
). If multiple scenarios are specified during a transaction, theEntryScenario__c
fields will indicate the specific scenario that was active when an entry was created. Another fantastic suggestion from @jamessimone - Deprecated
LogScenarioRule__mdt
object, replaced it with new objectLoggerScenarioRule__mdt
. This, combined withLogger.endScenario()
, closes #347 (reported by @mikesobczak)-
Using
LoggerScenarioRule__mdt
, some/all fields onLoggerSettings__c
can be optionally overridden, allowing more control for different modules/groupings of code with an org -
Using the optional
StartTime__c
andEndTime__c
datetime fields, you can control when aLoggerScenarioRule__mdt
should be used. This can be useful in situations where you need to temporarily override someLoggerSettings__c
for your scenario -
LogScenarioRule__mdt
Deprecated Object: -
LoggerScenarioRule__mdt
Revamped Object:
-
- Fixed #360 (reported by @NX-Mirco-Centrone) by changing
Logger.logDatabaseErrors()
overloads to always return a non-null instance ofLogEntryEventBuilder
- Updated backend code for LWC
relatedLogEntries
to remove a poorly-written & non-functioning Apex method that was trying determine the correct tab icon for theLogEntry__c
object. Hardcoding the icon name into the LWC is simpler, uses less resources, and actually functions 😅
Slack Plugin Package Changes
- Small cosmetic change in the messages posted to Slack - the fields
LogEntry__c.StackTrace__c
andLogEntry__c.ExceptionStackTrace__c
have been updated to be formatted as code blocks, instead of inline code snippets. This works better in Slack's UI when the fields contain line breaks. - Created new package version
v1.5.0
(making a somewhat arbitrary jump fromv0.10.0
, the old version numbers didn't align with the fact that the Slack plugin is production-ready)
Other Changes
- Fixed #363 (reported by @fehays) by correcting some references in the migration script
scripts/data/migrate-log-scenario-field-to-logger-scenario-object.apex
- Removed build numbers from all package versions listed in
sfdx-project.json
- the updated version numbers are now consistent with the version number tags published in GitHub
New LoggerScenario__c Custom Object
Log__c.Scenario__c
): you may need to update any customizations in your org, as this release deprecates the text field Log__c.Scenario__c
. If you have any customizations or plugins that leverage this field, you'll need to switch to using the new lookup field Log__c.TransactionScenario__c
.
Closed #349 by deprecating the field Log__c.Scenario__c
and replacing it with a new optional lookup Log__c.TransactionScenario__c
that leverages the new custom object LoggerScenario__c
. The LoggerScenario__c
object does not currently have any automation built-in - this PR is focused on just getting the object introduced, more features will be added later.
-
Added
LoggerScenario__c
object with a uniqued external ID fieldLoggerScenario__c .Unique__c
- this is set based on the valueLogEntryEvent__e.Scenario__c
(which can be set usingLogger.setScenario(String)
-
Added new "Logger Scenarios" tab to the Logger Console app, and rearranged the ordering of the included tabs
-
Added skeleton trigger handler class
LoggerScenarioHandler
- there's currently no object-specific logic implemented, but this provides an entry point for plugins. Additional logic will probably also be incorporated as part of #355 -
Added flexipage, page layout, compact layout, etc for the new object. I've arranged the UI to mimic the UI of the
Log__c
object's flexipage/layout -
Added an Apex script
./scripts/data/migrate-log-scenario-field-to-logger-scenario-object.apex
that migrates existing data from the text fieldLog__c.Scenario__c
to the new object & lookupLog__c.TransactionScenario__c
.- Existing orgs can run the script after upgrading to update existing records - but depending on how many
Log__c
records need to be updated, the script may need to be executed multiple times. It's not ideal, but this approach is easier that deploying a new, temporary batch job to do it in bulk.
- Existing orgs can run the script after upgrading to update existing records - but depending on how many
-
Updated
LoggerAdmin
, LoggerLogViewer, and
LoggerEndUserpermission sets to have access to the new
LoggerScenario__c` object -
Updated
LoggerEndUser
permission set to have read-only access to the tagging & scenario custom objects
v4.8.0 - Summer '22 Release
This (slightly late) release is for both the unlocked package (as always), as well as the managed package! If you use the managed package & are upgrading, you can review the v4.8.0 milestone to see all of the issues & pull requests that are included in the this release. LoggerSettings__c
and LoggerParameter__mdt
records in your org, since some configuration options have changed.
New Features
- Closed #335 by adding new method
Logger.ignoreOrigin(Type apexType)
- this allows plugins/external code to specify Apex classes to ignore when parsing each log entry's stack trace/origin (requested by @jamessimone for apex-rollup's nebula logger plugin and requested by @TKGC in #330) - Bumped all metadata to API v55.0 (Summer '22 release)
Bugfixes
- Fixed #331 (reported by @justin-lyon) by correcting some links in README for the docs site
- Fixed #339 (reported by @hernandezjesus) by cleaning up the Admin.profile that's currently included with the recipes metadata - the Admin.profile will eventually be replaced with a new permission set, but for now, this should make the metadata deployable
- Fixed #340 (reported by @EoghanMcMullen) by adding some extra checks for empty lists in
LogEntryEventBuilder
's methods stripInnaccessible() and getJson() - Fixed a null object exception that could occur in
LogMessage
when the message template is null (something I noticed when discussing #342) - Fixed #345 (reported by @eclarke12) by switching to using upserts (instead of inserts) for LogEntry__c and LogEntryTag__c records
- Fixed #346 (reported by @EllieAtWHL) by updating test stack traces for Aura & LWC to reflect the latest content + updating the logic used for parsing the component's stack trace
- Fixed #352 (reported by @adityavgpl) by updating a few failing tests to not run when the code is using a namespace prefix - due to platform limitations with stack traces, some of the tests simply will not work when running in the managed package
- Fixed an unreported issue where anonymous mode (controlled via
LoggerSettings__c.IsAnonymousModeEnabled__c
) would still assign the log to the logging user, resulting in theLog__c
not being fully anonymous. Now, if the logging user has anonymous enabled, then theLog__c
will be assigned to the user executing the classLogEntryEventHandler
- typically, this is the Automated Process users, but orgs have the ability to specify a different user
Thanks to everyone that helped with this release!
New "Log Batch Purge" tab
Enhancements
This release is a fantastic community contribution from @mar-ben - it provides the ability to view data metrics & execute the batch job LogBatchPurger
from the UI, which resolves #304 (implemented in #320).
-
New "Log Batch Purge" tab - available via the Logger Console app, the new tab displays the new LWC
logBatchPurge
.- This component displays the metrics for the number of records in
Log__c
,LogEntry__c
andLogEntryTag__c
, with filter options for "TODAY", "THIS WEEK" and "THIS MONTH" - The component also provides a button to run the
LogBatchPurger
- any user with view access to this tab, and either delete permissions onLog__c
or the custom permissionCanExecuteLogBatchPurger
can click the button to execute the batch job
- This component displays the metrics for the number of records in
Documentation
Finished implementing #292 by adding data classification metadata to all 560+ fields in the core package & plugin packages (implemented in #329), using the package Salesforce-Compliance-Metadata-Auditor by @Skullie1. All *.field-meta.xml
files now have these attributes populated:
businessStatus
- most fields have the valueActive
, and any deprecated fields have the valueDeprecateCandidate
complianceGroup
- Any field related to the logging user, the user's profile, session, or other user-specific/potentially identifying fields use the values
CCPA;GDPR;PII
- All other fields use the value
None
- originally I had left these null, but having a value (None
) explicitly populated seemed more clear from the perspectives of both documentation (for subscriber orgs) and maintenance (now, all fields should have some value set)
- Any field related to the logging user, the user's profile, session, or other user-specific/potentially identifying fields use the values
securityClassification
- all fields have the valueConfidential
. Based on the definition from this page, the valueConfidential
seemed like the most fitting option for logging data.
Bugfix for Logger.setScenario()
Added support for logging Apex errors in LWC/Aura
Resolved #299 (requested by @arbokrad) for LWC & Aura logging by updating the JavaScript function setError()
in logEntryBuilder.js
to support logging both JavaScript errors and Apex controller errors:
- Passing a JavaScript Error (existing functionality)
const logger = this.template.querySelector('c-logger'); const someError = new TypeError('oops'); console.log('the JavaScript error', error); const entry = logger.error(this.message).setError(someError).addTag('lwc logging demo'); console.log('entry==', JSON.parse(JSON.stringify(entry)));
- Passing an Apex error (new functionality)
const logger = this.template.querySelector('c-logger'); await callSomeApexMethod() .then(result => { console.log('the result from the Apex controller', JSON.parse(JSON.stringify(result))); }) .catch(error => { console.log('the Apex controller error', error); const entry = logger.error(this.message).setError(error); console.log('entry==', JSON.parse(JSON.stringify(entry))); });
This makes it easy for JS developers to pass either type of error, and Nebula Logger handles parsing the error data as needed. Below is a screenshot of the result of the new functionality of logging an Apex error - the green box shows that the LogEntry__c
originated from an LWC, but the red box shows that the error logged by the LWC was an Apex error