diff --git a/README.md b/README.md index c32d75e07..95febe2da 100644 --- a/README.md +++ b/README.md @@ -5,13 +5,13 @@ The most robust observability solution for Salesforce experts. Built 100% natively on the platform, and designed to work seamlessly with Apex, Lightning Components, Flow, OmniStudio, and integrations. -## Unlocked Package - v4.15.0 +## Unlocked Package - v4.15.1 -[![Install Unlocked Package in a Sandbox](./images/btn-install-unlocked-package-sandbox.png)](https://test.salesforce.com/packaging/installPackage.apexp?p0=04t5Y0000015odKQAQ) -[![Install Unlocked Package in Production](./images/btn-install-unlocked-package-production.png)](https://login.salesforce.com/packaging/installPackage.apexp?p0=04t5Y0000015odKQAQ) +[![Install Unlocked Package in a Sandbox](./images/btn-install-unlocked-package-sandbox.png)](https://test.salesforce.com/packaging/installPackage.apexp?p0=04t5Y0000015ohhQAA) +[![Install Unlocked Package in Production](./images/btn-install-unlocked-package-production.png)](https://login.salesforce.com/packaging/installPackage.apexp?p0=04t5Y0000015ohhQAA) [![View Documentation](./images/btn-view-documentation.png)](https://github.com/jongpie/NebulaLogger/wiki) -`sf package install --wait 20 --security-type AdminsOnly --package 04t5Y0000015odKQAQ` +`sf package install --wait 20 --security-type AdminsOnly --package 04t5Y0000015ohhQAA` --- diff --git a/nebula-logger/core/main/log-management/classes/LogHandler.cls b/nebula-logger/core/main/log-management/classes/LogHandler.cls index a16e8f199..742996c14 100644 --- a/nebula-logger/core/main/log-management/classes/LogHandler.cls +++ b/nebula-logger/core/main/log-management/classes/LogHandler.cls @@ -11,7 +11,7 @@ public without sharing class LogHandler extends LoggerSObjectHandler { private static final Map MOCK_LOG_STATUS_TO_STATUS = new Map(); - private static final List ORGANIZATION_LIMITS { + private static final List ORGANIZATION_LIMITS { get { if (ORGANIZATION_LIMITS == null) { ORGANIZATION_LIMITS = loadOrganizationLimits(); @@ -40,7 +40,7 @@ public without sharing class LogHandler extends LoggerSObjectHandler { this.loggerScenariosById = queryLoggerScenarios(this.logs); this.setClosedStatusFields(); - this.setOrganizationLimits(); + this.setSerializableOrganizationLimits(); // The log OwnerId field should support being manually changed, so only auto-set it on insert this.setOwnerId(); this.setParentLog(); @@ -87,7 +87,7 @@ public without sharing class LogHandler extends LoggerSObjectHandler { } } - private void setOrganizationLimits() { + private void setSerializableOrganizationLimits() { if (LoggerParameter.STORE_ORGANIZATION_LIMITS == false) { return; } @@ -285,21 +285,22 @@ public without sharing class LogHandler extends LoggerSObjectHandler { return logStatusNameToStatus; } - private static List loadOrganizationLimits() { - List organizationLimits = new List(); + private static List loadOrganizationLimits() { + List serializableOrganizationLimits = new List(); + Map systemOrgLimits = System.OrgLimits.getMap(); - List systemOrgLimitNames = new List(System.OrgLimits.getMap().keySet()); + List systemOrgLimitNames = new List(systemOrgLimits.keySet()); systemOrgLimitNames.sort(); for (String systemOrgLimitName : systemOrgLimitNames) { - System.OrgLimit systemOrgLimit = System.OrgLimits.getMap().get(systemOrgLimitName); - OrganizationLimit organizationLimit = new OrganizationLimit(); - organizationLimit.Name = systemOrgLimit.getName(); - organizationLimit.Used = systemOrgLimit.getValue(); - organizationLimit.Max = systemOrgLimit.getLimit(); - organizationLimits.add(organizationLimit); + System.OrgLimit systemOrgLimit = systemOrgLimits.get(systemOrgLimitName); + SerializableOrganizationLimit serializableOrganizationLimit = new SerializableOrganizationLimit(); + serializableOrganizationLimit.Name = systemOrgLimit.getName(); + serializableOrganizationLimit.Used = systemOrgLimit.getValue(); + serializableOrganizationLimit.Max = systemOrgLimit.getLimit(); + serializableOrganizationLimits.add(serializableOrganizationLimit); } - return organizationLimits; + return serializableOrganizationLimits; } private static Map queryLoggerScenarios(List logs) { @@ -344,9 +345,12 @@ public without sharing class LogHandler extends LoggerSObjectHandler { MOCK_LOG_STATUS_TO_STATUS.put(logStatus.MasterLabel, logStatus); } + // The class System.OrgLimit isn't serializable, so this DTO is used instead + // so that the serialized string can be stored in Log__c.OrganizationLimits__c. + // The JSON data is then displayed on the Log__c page using a custom LWC. @SuppressWarnings('PMD.ApexDoc') @TestVisible - private class OrganizationLimit { + private class SerializableOrganizationLimit { public String Name { get; set; } public Integer Used { get; set; } public Integer Max { get; set; } diff --git a/nebula-logger/core/main/logger-engine/classes/Logger.cls b/nebula-logger/core/main/logger-engine/classes/Logger.cls index 9765df3eb..ece863848 100644 --- a/nebula-logger/core/main/logger-engine/classes/Logger.cls +++ b/nebula-logger/core/main/logger-engine/classes/Logger.cls @@ -15,7 +15,7 @@ global with sharing class Logger { // There's no reliable way to get the version number dynamically in Apex @TestVisible - private static final String CURRENT_VERSION_NUMBER = 'v4.15.0'; + private static final String CURRENT_VERSION_NUMBER = 'v4.15.1'; private static final System.LoggingLevel FALLBACK_LOGGING_LEVEL = System.LoggingLevel.DEBUG; private static final List LOG_ENTRIES_BUFFER = new List(); private static final String MISSING_SCENARIO_ERROR_MESSAGE = 'No logger scenario specified. A scenario is required for logging in this org.'; diff --git a/nebula-logger/core/main/logger-engine/lwc/logger/loggerService.js b/nebula-logger/core/main/logger-engine/lwc/logger/loggerService.js index 10222f37b..6818ef0db 100644 --- a/nebula-logger/core/main/logger-engine/lwc/logger/loggerService.js +++ b/nebula-logger/core/main/logger-engine/lwc/logger/loggerService.js @@ -10,7 +10,7 @@ import LoggerServiceTaskQueue from './loggerServiceTaskQueue'; import getSettings from '@salesforce/apex/ComponentLogger.getSettings'; import saveComponentLogEntries from '@salesforce/apex/ComponentLogger.saveComponentLogEntries'; -const CURRENT_VERSION_NUMBER = 'v4.15.0'; +const CURRENT_VERSION_NUMBER = 'v4.15.1'; const CONSOLE_OUTPUT_CONFIG = { messagePrefix: `%c Nebula Logger ${CURRENT_VERSION_NUMBER} `, diff --git a/nebula-logger/core/tests/log-management/classes/LogHandler_Tests.cls b/nebula-logger/core/tests/log-management/classes/LogHandler_Tests.cls index b69566f72..ac1cd0699 100644 --- a/nebula-logger/core/tests/log-management/classes/LogHandler_Tests.cls +++ b/nebula-logger/core/tests/log-management/classes/LogHandler_Tests.cls @@ -183,24 +183,24 @@ private class LogHandler_Tests { ); log = [SELECT Id, HasOrganizationLimits__c, OrganizationLimits__c FROM Log__c WHERE Id = :log.Id]; System.Assert.isTrue(log.HasOrganizationLimits__c); - Map limitNameToExpectedOrganizationLimits = new Map(); + Map limitNameToExpectedOrganizationLimits = new Map(); List sortedSystemOrgLimitNames = new List(System.OrgLimits.getMap().keySet()); sortedSystemOrgLimitNames.sort(); for (String systemOrgLimitName : sortedSystemOrgLimitNames) { System.OrgLimit systemOrgLimit = System.OrgLimits.getMap().get(systemOrgLimitName); - LogHandler.OrganizationLimit organizationLimit = new LogHandler.OrganizationLimit(); + LogHandler.SerializableOrganizationLimit organizationLimit = new LogHandler.SerializableOrganizationLimit(); organizationLimit.Name = systemOrgLimit.getName(); organizationLimit.Used = systemOrgLimit.getValue(); organizationLimit.Max = systemOrgLimit.getLimit(); limitNameToExpectedOrganizationLimits.put(organizationLimit.Name, organizationLimit); } - List returnedOrganizationLimits = (List) System.JSON.deserialize( + List returnedOrganizationLimits = (List) System.JSON.deserialize( log.OrganizationLimits__c, - List.class + List.class ); System.Assert.areEqual(limitNameToExpectedOrganizationLimits.size(), returnedOrganizationLimits.size()); - for (LogHandler.OrganizationLimit returnedOrganizationLimit : returnedOrganizationLimits) { - LogHandler.OrganizationLimit expectedOrganizationLimit = limitNameToExpectedOrganizationLimits.get(returnedOrganizationLimit.Name); + for (LogHandler.SerializableOrganizationLimit returnedOrganizationLimit : returnedOrganizationLimits) { + LogHandler.SerializableOrganizationLimit expectedOrganizationLimit = limitNameToExpectedOrganizationLimits.get(returnedOrganizationLimit.Name); // Some limits are recalculated, even during a single transaction, // so ensure that the expected limit's Used value is at least higher than the returned limit's Used value System.Assert.isTrue(expectedOrganizationLimit.Used >= returnedOrganizationLimit.Used); diff --git a/nebula-logger/managed-package/sfdx-project.json b/nebula-logger/managed-package/sfdx-project.json index 32b87b8cf..1da1b4d9b 100644 --- a/nebula-logger/managed-package/sfdx-project.json +++ b/nebula-logger/managed-package/sfdx-project.json @@ -11,10 +11,10 @@ "postInstallScript": "LoggerInstallHandler", "scopeProfiles": true, "ancestorVersion": "HIGHEST", - "versionNumber": "4.15.0.NEXT", - "versionName": "Winter '25 Release", - "versionDescription": "View the v4.15.0 milestone in GitHub for the list of changes - https://github.com/jongpie/NebulaLogger/milestone/15?closed=1", - "releaseNotesUrl": "https://github.com/jongpie/NebulaLogger/releases/tag/v4.15.0" + "versionNumber": "4.16.0.NEXT", + "versionName": "Spring '25 Release", + "versionDescription": "View the v4.16.0 milestone in GitHub for the list of changes - https://github.com/jongpie/NebulaLogger/milestone/16?closed=1", + "releaseNotesUrl": "https://github.com/jongpie/NebulaLogger/releases/tag/v4.16.0" } ], "packageAliases": { diff --git a/package.json b/package.json index d628ea557..05a4aaf55 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "nebula-logger", - "version": "4.15.0", + "version": "4.15.1", "description": "The most robust logger for Salesforce. Works with Apex, Lightning Components, Flow, Process Builder & Integrations. Designed for Salesforce admins, developers & architects.", "author": "Jonathan Gillespie", "license": "MIT", diff --git a/sfdx-project.json b/sfdx-project.json index abc5755fc..97dbbffcd 100644 --- a/sfdx-project.json +++ b/sfdx-project.json @@ -9,9 +9,9 @@ "path": "./nebula-logger/core", "definitionFile": "./config/scratch-orgs/base-scratch-def.json", "scopeProfiles": true, - "versionNumber": "4.15.0.NEXT", - "versionName": "Winter '25 Release", - "versionDescription": "Updated all metadata to API v62.0, replaced compact layouts with new dynamic highlights components in all flexipages", + "versionNumber": "4.15.1.NEXT", + "versionName": "System.OrgLimits Optimisations", + "versionDescription": "Updated LogHandler class to cache the Apex call to System.OrgLimits.getMap() to reduce CPU usage", "releaseNotesUrl": "https://github.com/jongpie/NebulaLogger/releases", "unpackagedMetadata": { "path": "./nebula-logger/extra-tests" @@ -204,6 +204,7 @@ "Nebula Logger - Core@4.14.17-improved-javascript-console-output": "04t5Y0000015ocRQAQ", "Nebula Logger - Core@4.14.18-added-setrecord()-overload-for-list-and-set-parameters": "04t5Y0000015ocbQAA", "Nebula Logger - Core@4.15.0-winter-'25-release": "04t5Y0000015odKQAQ", + "Nebula Logger - Core@4.15.1-system.orglimits-optimisations": "04t5Y0000015ohhQAA", "Nebula Logger - Core Plugin - Async Failure Additions": "0Ho5Y000000blO4SAI", "Nebula Logger - Core Plugin - Async Failure Additions@1.0.0": "04t5Y0000015lhiQAA", "Nebula Logger - Core Plugin - Async Failure Additions@1.0.1": "04t5Y0000015lhsQAA",