Skip to content

Releases: jongpie/NebulaLogger

Track When An Admin Logs In As Another User

22 Nov 19:30
81ce8b9
Compare
Choose a tag to compare

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 and Log__c.ImpersonatedBy__c

    image

  • Added new class LoggerSObjectProxy with inner classes that provide representations of problematic SObject Types AuthSession, LoginHistory and Network. 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 as CaseComment, CaseHistory, AccountHistory, etc., with the error System.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

21 Nov 19:41
a66edb4
Compare
Choose a tag to compare

Managed Package Release

This release is for both the unlocked package (as always), as well as the managed package!

⚠️ For orgs that are upgrading to this version of the managed package: there are several new features & feature flags that have been introduced since 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 in v4.9.0 prior to upgrading in your org to ensure that LoggerSettings__c and LoggerParameter__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 methods Logger.getScenario(String), Logger.setScenario(String)andLogger.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 methods

    • Logger.getVersionNumber()
    • Logger.endScenario(String scenario)
    • Logger.ignoreOrigin(System.Type apexType)
  • LogEntryEventBuilder class instance methods

    • LogEntryEventBuilder.getLogEntryEvent() - returns an instance of LogEntryEvent__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 in LogBatchPurgeScheduler when the batchSize value was null - now, LogBatchPurgeScheduler checks for null values & uses a default value instead.
    • The default batchSize value has also been changed from 200 to 2000. The LogBatchPurger job has always used 200 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 objects LogEntryTag__c and LoggerTag__c were introduced, but the default batch size was never increased.

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

30 Oct 19:23
977993e
Compare
Choose a tag to compare

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 record EnableStackTraceParsing 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 if LogEntryEventBuilder 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 on LogEntryEvent__e, but are still populated on Log__c and LogEntry__c. Four (4) new custom metadata records are included:
    1. LoggerParameter.QueryAuthSessionDataSynchronously
    2. LoggerParameter.QueryNetworkDataSynchronously
    3. LoggerParameter.QueryOrganizationDataSynchronously
    4. LoggerParameter.QueryUserDataSynchronously
  • Updated Logger class to internally cached the value of UserInfo.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:
    1. LoggerCache.getTransactionCache(). This is the existing caching system that's been used for a few releases. It caches values in a transaction using a private static final Map<String, Object> constant. This is still used internally throughout LoggerCache to supplement some limitations with platform cache, such as not being able to cache null values
    2. LoggerCache.getOrganizationCache(). This leverages the org partition of Platform Cache
    3. LoggerCache.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 use Logger.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 be null. 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.
    1. LoggerParameter.QueryApexClassData - when disabled, the ApexClass object is not queried, and the relevant fields on LogEntry__c are null
    2. LoggerParameter.QueryAuthSessionData - when disabled, the AuthSession object is not queried, and the relevant fields on LogEntry__c are null
    3. LoggerParameter.QueryFlowDefinitionViewData - when disabled, the FlowDefinitionView object is not queried, and the relevant fields on LogEntry__c are null
    4. LoggerParameter.QueryNetworkData - when disabled, the Network object is not queried, and the relevant fields on LogEntry__c are null. Note: this only applies to orgs that use an Experience Cloud site (stored in the Network object)
    5. LoggerParameter.QueryOrganizationData - when disabled, the Organzation object is not queried, and the relevant fields on LogEntry__c are null
    6. LoggerParameter.QueryRelatedRecordData - when disabled, the dynamic queries used to query record names (based on the field LogEntry__c.RecordId__c) are not executed, the field LogEntry__c.RecordName__c is null
    7. LoggerParameter.QueryUserData - when disabled, the User object is not queried, and the relevant fields on LogEntry__c are null

Bugfixes

  • Fixed LogEntry__c.Timestamp__c being inaccurately set in some edge cases. This was an unreported bug found where LogEntryEvent__e.TimestampString__c could be out of sync with LogEntryEvent__e.Timestamp__c, resulting in inaccurate data being stored in LogEntry__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 and Log__c.RequestId__c to store the value of System.Request.getCurrent().getRequestId(). In versions v3.1.0 through v4.7.2, this value was used for Log__c.TransactionId__c, but reverted to using a more reliable custom UUID in v4.7.3 (the original solution). The new RequestId__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 and LogManagementDataSelector classes & methods virtual & implemented test implementations in the respective test classes LoggerEngineDataSelector_Tests and LogManagementDataSelector_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

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

26 Sep 22:15
1a4b9b6
Compare
Choose a tag to compare

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:

image

To help with this, 2 changes have been made to all of the limits formula fields on LogEntry__c:

  1. 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
  2. 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:

image

More Controls for Scenario-Based Logging

22 Sep 20:57
bade266
Compare
Choose a tag to compare

⚠️ For orgs that are upgrading to this version & that use scenario-based logging functionality: This release deprecates/renames 1 object & 1 field,so you may need to update some configurations in your org to use the new metadata:

  • The field LoggerSettings__c.DefaultLogScenario__c has been renamed to LoggerSettings__c.DefaultScenario__c, which is treated as a "new" field when upgrading. Existing LoggerSettings__c records in your org may need to be updated to move data in LoggerSettings__c.DefaultLogScenario__c to LoggerSettings__c.DefaultScenario__c. The original field LoggerSettings__c.DefaultScenario__c is now deprecated & will no longer be used.
  • The object LogScenarioRule__mdt has been renamed to LoggerScenarioRule__mdt, which is treated as a "new" object when upgrading. You will need to migrate any custom metadata records from LogScenarioRule__mdt to the new object LoggerScenarioRule__mdt. The original object LogScenarioRule__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 and LogEntry__c.EntryScenario__c (used in addition to LogEntryEvent__e.TransactionScenario__c and Log__c.TransactionScenario__c). If multiple scenarios are specified during a transaction, the EntryScenario__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 object LoggerScenarioRule__mdt. This, combined with Logger.endScenario(), closes #347 (reported by @mikesobczak)
    • Using LoggerScenarioRule__mdt, some/all fields on LoggerSettings__c can be optionally overridden, allowing more control for different modules/groupings of code with an org

    • Using the optional StartTime__c and EndTime__c datetime fields, you can control when a LoggerScenarioRule__mdt should be used. This can be useful in situations where you need to temporarily override some LoggerSettings__c for your scenario

    • LogScenarioRule__mdt Deprecated Object:

      image

    • LoggerScenarioRule__mdt Revamped Object:

      image

  • Fixed #360 (reported by @NX-Mirco-Centrone) by changing Logger.logDatabaseErrors() overloads to always return a non-null instance of LogEntryEventBuilder
  • Updated backend code for LWC relatedLogEntries to remove a poorly-written & non-functioning Apex method that was trying determine the correct tab icon for the LogEntry__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 and LogEntry__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 from v0.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

08 Sep 02:44
5f59b7a
Compare
Choose a tag to compare

⚠️ For orgs that are upgrading to this version & use scenario-based logging functionality (stored in 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 field LoggerScenario__c .Unique__c - this is set based on the value LogEntryEvent__e.Scenario__c (which can be set using Logger.setScenario(String)

  • Added new "Logger Scenarios" tab to the Logger Console app, and rearranged the ordering of the included tabs

    image

  • 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

    image

  • Added an Apex script ./scripts/data/migrate-log-scenario-field-to-logger-scenario-object.apex that migrates existing data from the text field Log__c.Scenario__c to the new object & lookup Log__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.
  • Updated LoggerAdmin, LoggerLogViewer, and LoggerEndUserpermission sets to have access to the newLoggerScenario__c` object

  • Updated LoggerEndUser permission set to have read-only access to the tagging & scenario custom objects

v4.8.0 - Summer '22 Release

24 Aug 14:58
3f20f6f
Compare
Choose a tag to compare

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. ⚠️ For orgs that are upgrading to this version of the managed package: it's recommended that you review 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 the Log__c not being fully anonymous. Now, if the logging user has anonymous enabled, then the Log__c will be assigned to the user executing the class LogEntryEventHandler - 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

14 Jun 14:17
dbbe32c
Compare
Choose a tag to compare

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 and LogEntryTag__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 on Log__c or the custom permission CanExecuteLogBatchPurger can click the button to execute the batch job

    image

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 value Active, and any deprecated fields have the value DeprecateCandidate
  • 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)
  • securityClassification - all fields have the value Confidential. Based on the definition from this page, the value Confidential seemed like the most fitting option for logging data.

Bugfix for Logger.setScenario()

08 Jun 20:04
8d00cf5
Compare
Choose a tag to compare
  • Fixed #326 by correcting a typo in a comparison operator in Logger.setScenario() - it was using = instead of ==. Thanks to @feisley for reporting this!
  • Made a few small optimizations to Logger_Tests so it can run tests in parallel

Added support for logging Apex errors in LWC/Aura

03 Jun 02:31
e120ff1
Compare
Choose a tag to compare

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

image