From bade2664ef467079fbc83bd3e8385429fad2b622 Mon Sep 17 00:00:00 2001 From: Jonathan Gillespie Date: Thu, 22 Sep 2022 16:31:26 -0400 Subject: [PATCH] More controls for scenario-based logging (#357) * Closed #347 & #356 by deprecating LogScenarioRule__mdt object & replacing it with a new object LoggerScenarioRule__mdt that provides optional overrides for all fields on LoggerSettings__c * Added new Apex class LogScenarioRule to manage accessing LoggerScenarioRule__mdt CMDT records * Incorporated the stellar idea from @jamessimone to tie LogEntry__c records to the new LoggerScenario__c object via a new lookup field LogEntry__c.EntryScenario__c * Added new method Logger.endScenario(String) so that Apex developers can explicitly end a scenario, which then automatically rolls back to the previous scenario (and re-applies the previous scenario rule, if one exists) - another fantastic suggestion from @jamessimone * Renamed LoggerSettings__c.DefaultLogScenario__c to LoggerSettings__c.DefaultScenario__c for consistency * Fixed #360 by changing Logger.logDatabaseErrors() overloads to always return a non-null instance of LogEntryEventBuilder * Updated some formatting in SlackLoggerPlugin to better format stack traces & create new plugin package version v1.5.0 * Fixed #363 by correcting some references in the migration script ./scripts/data/migrate-log-scenario-field-to-logger-scenario-object.apex * Added content in README that links to the wiki's architecture overview * Removed build numbers for package versions in sfdx-project.json, upgraded some packages in package.json to resolve some GitHub security alerts --- README.md | 17 +- docs/apex/Configuration/LoggerScenarioRule.md | 47 +++ .../RelatedLogEntriesController.md | 4 - docs/apex/Logger-Engine/Logger.md | 12 +- .../Test-Utilities/LoggerTestConfigurator.md | 10 +- docs/apex/index.md | 4 + .../classes/LoggerScenarioRule.cls | 71 ++++ .../classes/LoggerScenarioRule.cls-meta.xml | 5 + ...ogger Scenario Rule Layout.layout-meta.xml | 164 +++++++++ .../LoggerScenarioRule__mdt.object-meta.xml} | 4 +- .../fields/EndTime__c.field-meta.xml | 9 + .../IsAnonymousModeEnabled__c.field-meta.xml | 30 ++ ...ystemDebugLoggingEnabled__c.field-meta.xml | 30 ++ .../IsDataMaskingEnabled__c.field-meta.xml | 30 ++ .../fields/IsEnabled__c.field-meta.xml | 12 + ...iptConsoleLoggingEnabled__c.field-meta.xml | 30 ++ .../IsLogAssignmentEnabled__c.field-meta.xml | 30 ++ ...RetentionOverrideEnabled__c.field-meta.xml | 30 ++ .../fields/IsLoggerEnabled__c.field-meta.xml | 28 ++ ...ntStorageLocationEnabled__c.field-meta.xml | 28 ++ ...ordFieldStrippingEnabled__c.field-meta.xml | 30 ++ .../fields/IsSavingEnabled__c.field-meta.xml | 29 ++ ...NumberOfDaysToRetainLogs__c.field-meta.xml | 17 + ...formEventStorageLocation__c.field-meta.xml | 16 + .../fields/SaveMethod__c.field-meta.xml | 15 + .../fields/Scenario__c.field-meta.xml | 15 + .../fields/StartTime__c.field-meta.xml | 9 + .../fields/UserLoggingLevel__c.field-meta.xml | 55 +++ .../listViews/All.listView-meta.xml | 18 + .../fields/DefaultScenario__c.field-meta.xml | 16 + .../applications/LoggerConsole.app-meta.xml | 4 +- .../classes/LogBatchPurgeController_Tests.cls | 2 +- .../classes/LogEntryEventHandler.cls | 85 ++++- .../log-management/classes/LogHandler.cls | 45 +-- .../classes/RelatedLogEntriesController.cls | 37 -- .../LogEntryRecordPage.flexipage-meta.xml | 10 + ...oggerScenarioRecordPage.flexipage-meta.xml | 44 +++ ...gEntry__c-Log Entry Layout.layout-meta.xml | 4 +- .../layouts/Log__c-Log Layout.layout-meta.xml | 1 + ...__c-Logger Scenario Layout.layout-meta.xml | 16 +- .../logEntryEventStream.html | 4 +- .../logEntryEventStream.js | 2 +- .../__tests__/data/getSchemaForName.json | 6 +- .../loggerSettingsPageLayout.js | 2 +- .../__tests__/data/getQueryResult.json | 1 - .../relatedLogEntries/relatedLogEntries.html | 2 +- .../relatedLogEntries/relatedLogEntries.js | 1 - .../fields/EntryScenario__c.field-meta.xml | 14 + .../LoggerScenario__c.object-meta.xml | 2 +- ...narioCompactLayout.compactLayout-meta.xml} | 2 +- .../LoggerAdmin.permissionset-meta.xml | 5 + .../LoggerEndUser.permissionset-meta.xml | 5 + .../LoggerLogViewer.permissionset-meta.xml | 5 + .../main/logger-engine/classes/Logger.cls | 217 ++++++----- .../fields/EntryScenario__c.field-meta.xml | 16 + .../fields/Scenario__c.field-meta.xml | 4 +- .../TransactionScenario__c.field-meta.xml | 16 + .../core/tests/LoggerCore.testSuite-meta.xml | 1 + .../classes/LoggerScenarioRule_Tests.cls | 129 +++++++ .../LoggerScenarioRule_Tests.cls-meta.xml | 5 + .../classes/LogEntryEventHandler_Tests.cls | 194 +++++++++- .../classes/LogHandler_Tests.cls | 17 +- .../utilities/LoggerTestConfigurator.cls | 9 +- .../classes/ComponentLogger_Tests.cls | 3 +- .../classes/FlowCollectionLogEntry_Tests.cls | 3 +- .../classes/FlowLogEntry_Tests.cls | 3 +- .../classes/FlowRecordLogEntry_Tests.cls | 3 +- .../logger-engine/classes/Logger_Tests.cls | 336 +++++++++++++++--- .../DefaultLogScenario__c.field-meta.xml | 4 +- ...t-Log Scenario Rule Layout.layout-meta.xml | 0 .../LogScenarioRule__mdt.object-meta.xml | 6 + .../fields/IsEnabled__c.field-meta.xml | 0 ...NumberOfDaysToRetainLogs__c.field-meta.xml | 0 .../fields/Scenario__c.field-meta.xml | 0 .../fields/UserLoggingLevel__c.field-meta.xml | 0 .../listViews/All.listView-meta.xml | 0 .../managed-package/sfdx-project.json | 16 +- nebula-logger/plugins/slack/README.md | 4 +- .../slack/classes/SlackLoggerPlugin.cls | 4 +- .../recipes/profiles/Admin.profile-meta.xml | 11 +- package-lock.json | 65 +--- package.json | 4 +- ...nario-field-to-logger-scenario-object.apex | 6 +- sfdx-project.json | 106 +++--- .../Data_Classification.default.md-meta.xml | 2 +- 85 files changed, 1854 insertions(+), 444 deletions(-) create mode 100644 docs/apex/Configuration/LoggerScenarioRule.md create mode 100644 nebula-logger/core/main/configuration/classes/LoggerScenarioRule.cls create mode 100644 nebula-logger/core/main/configuration/classes/LoggerScenarioRule.cls-meta.xml create mode 100644 nebula-logger/core/main/configuration/layouts/LoggerScenarioRule__mdt-Logger Scenario Rule Layout.layout-meta.xml rename nebula-logger/core/main/configuration/objects/{LogScenarioRule__mdt/LogScenarioRule__mdt.object-meta.xml => LoggerScenarioRule__mdt/LoggerScenarioRule__mdt.object-meta.xml} (62%) create mode 100644 nebula-logger/core/main/configuration/objects/LoggerScenarioRule__mdt/fields/EndTime__c.field-meta.xml create mode 100644 nebula-logger/core/main/configuration/objects/LoggerScenarioRule__mdt/fields/IsAnonymousModeEnabled__c.field-meta.xml create mode 100644 nebula-logger/core/main/configuration/objects/LoggerScenarioRule__mdt/fields/IsApexSystemDebugLoggingEnabled__c.field-meta.xml create mode 100644 nebula-logger/core/main/configuration/objects/LoggerScenarioRule__mdt/fields/IsDataMaskingEnabled__c.field-meta.xml create mode 100644 nebula-logger/core/main/configuration/objects/LoggerScenarioRule__mdt/fields/IsEnabled__c.field-meta.xml create mode 100644 nebula-logger/core/main/configuration/objects/LoggerScenarioRule__mdt/fields/IsJavaScriptConsoleLoggingEnabled__c.field-meta.xml create mode 100644 nebula-logger/core/main/configuration/objects/LoggerScenarioRule__mdt/fields/IsLogAssignmentEnabled__c.field-meta.xml create mode 100644 nebula-logger/core/main/configuration/objects/LoggerScenarioRule__mdt/fields/IsLogRetentionOverrideEnabled__c.field-meta.xml create mode 100644 nebula-logger/core/main/configuration/objects/LoggerScenarioRule__mdt/fields/IsLoggerEnabled__c.field-meta.xml create mode 100644 nebula-logger/core/main/configuration/objects/LoggerScenarioRule__mdt/fields/IsPlatformEventStorageLocationEnabled__c.field-meta.xml create mode 100644 nebula-logger/core/main/configuration/objects/LoggerScenarioRule__mdt/fields/IsRecordFieldStrippingEnabled__c.field-meta.xml create mode 100644 nebula-logger/core/main/configuration/objects/LoggerScenarioRule__mdt/fields/IsSavingEnabled__c.field-meta.xml create mode 100644 nebula-logger/core/main/configuration/objects/LoggerScenarioRule__mdt/fields/NumberOfDaysToRetainLogs__c.field-meta.xml create mode 100644 nebula-logger/core/main/configuration/objects/LoggerScenarioRule__mdt/fields/PlatformEventStorageLocation__c.field-meta.xml create mode 100644 nebula-logger/core/main/configuration/objects/LoggerScenarioRule__mdt/fields/SaveMethod__c.field-meta.xml create mode 100644 nebula-logger/core/main/configuration/objects/LoggerScenarioRule__mdt/fields/Scenario__c.field-meta.xml create mode 100644 nebula-logger/core/main/configuration/objects/LoggerScenarioRule__mdt/fields/StartTime__c.field-meta.xml create mode 100644 nebula-logger/core/main/configuration/objects/LoggerScenarioRule__mdt/fields/UserLoggingLevel__c.field-meta.xml create mode 100644 nebula-logger/core/main/configuration/objects/LoggerScenarioRule__mdt/listViews/All.listView-meta.xml create mode 100644 nebula-logger/core/main/configuration/objects/LoggerSettings__c/fields/DefaultScenario__c.field-meta.xml create mode 100644 nebula-logger/core/main/log-management/objects/LogEntry__c/fields/EntryScenario__c.field-meta.xml rename nebula-logger/core/main/log-management/objects/LoggerScenario__c/compactLayouts/{LogScenarioCompactLayout.compactLayout-meta.xml => LoggerScenarioCompactLayout.compactLayout-meta.xml} (86%) create mode 100644 nebula-logger/core/main/logger-engine/objects/LogEntryEvent__e/fields/EntryScenario__c.field-meta.xml create mode 100644 nebula-logger/core/main/logger-engine/objects/LogEntryEvent__e/fields/TransactionScenario__c.field-meta.xml create mode 100644 nebula-logger/core/tests/configuration/classes/LoggerScenarioRule_Tests.cls create mode 100644 nebula-logger/core/tests/configuration/classes/LoggerScenarioRule_Tests.cls-meta.xml rename nebula-logger/{ => managed-package}/core/main/configuration/objects/LoggerSettings__c/fields/DefaultLogScenario__c.field-meta.xml (86%) rename nebula-logger/{core/main/configuration => managed-package/core/main/deprecated}/layouts/LogScenarioRule__mdt-Log Scenario Rule Layout.layout-meta.xml (100%) create mode 100644 nebula-logger/managed-package/core/main/deprecated/objects/LogScenarioRule__mdt/LogScenarioRule__mdt.object-meta.xml rename nebula-logger/{core/main/configuration => managed-package/core/main/deprecated}/objects/LogScenarioRule__mdt/fields/IsEnabled__c.field-meta.xml (100%) rename nebula-logger/{core/main/configuration => managed-package/core/main/deprecated}/objects/LogScenarioRule__mdt/fields/NumberOfDaysToRetainLogs__c.field-meta.xml (100%) rename nebula-logger/{core/main/configuration => managed-package/core/main/deprecated}/objects/LogScenarioRule__mdt/fields/Scenario__c.field-meta.xml (100%) rename nebula-logger/{core/main/configuration => managed-package/core/main/deprecated}/objects/LogScenarioRule__mdt/fields/UserLoggingLevel__c.field-meta.xml (100%) rename nebula-logger/{core/main/configuration => managed-package/core/main/deprecated}/objects/LogScenarioRule__mdt/listViews/All.listView-meta.xml (100%) diff --git a/README.md b/README.md index 0e1b4e047..619c9343e 100644 --- a/README.md +++ b/README.md @@ -3,12 +3,12 @@ [![Build](https://github.com/jongpie/NebulaLogger/actions/workflows/build.yml/badge.svg)](https://github.com/jongpie/NebulaLogger/actions/workflows/build.yml) [![codecov](https://codecov.io/gh/jongpie/NebulaLogger/branch/main/graph/badge.svg?token=1DJPDRM3N4)](https://codecov.io/gh/jongpie/NebulaLogger) -Designed for Salesforce admins, developers & architects. A robust logger for Apex, Lightning Components, Flow, Process Builder & Integrations. +The most robust logger for Salesforce. Works with Apex, Lightning Components, Flow, Process Builder & Integrations. Designed for Salesforce admins, developers & architects. -## Unlocked Package - v4.8.1 +## Unlocked Package - v4.8.2 -[![Install Unlocked Package in a Sandbox](./images/btn-install-unlocked-package-sandbox.png)](https://test.salesforce.com/packaging/installPackage.apexp?p0=04t5Y0000015luIQAQ) -[![Install Unlocked Package in Production](./images/btn-install-unlocked-package-production.png)](https://login.salesforce.com/packaging/installPackage.apexp?p0=04t5Y0000015luIQAQ) +[![Install Unlocked Package in a Sandbox](./images/btn-install-unlocked-package-sandbox.png)](https://test.salesforce.com/packaging/installPackage.apexp?p0=04t5Y0000015lvuQAA) +[![Install Unlocked Package in Production](./images/btn-install-unlocked-package-production.png)](https://login.salesforce.com/packaging/installPackage.apexp?p0=04t5Y0000015lvuQAA) [![View Documentation](./images/btn-view-documentation.png)](https://jongpie.github.io/NebulaLogger/) ## Managed Package - v4.8.0 @@ -34,7 +34,14 @@ Designed for Salesforce admins, developers & architects. A robust logger for Ape Learn more about the design and history of the project on [Joys Of Apex blog post](https://www.joysofapex.com/advanced-logging-using-nebula-logger/) ---- +## Architecture Overview + +Nebula Logger is built natively on Salesforce, using Apex, lightning components and various types of objects. There are no required external dependencies. To learn more about the architecture, check out the +[architecture overview in the wiki](https://raw.githubusercontent.com/wiki/jongpie/NebulaLogger/images/nebula-logger-architecture-overview.png). + + + + ## Installing diff --git a/docs/apex/Configuration/LoggerScenarioRule.md b/docs/apex/Configuration/LoggerScenarioRule.md new file mode 100644 index 000000000..5d7b84bdc --- /dev/null +++ b/docs/apex/Configuration/LoggerScenarioRule.md @@ -0,0 +1,47 @@ +--- +layout: default +--- + +## LoggerScenarioRule class + +Provides a centralized way to load scenario rules that override behavior within Nebula Logger + +--- + +### Methods + +#### `getAll()` → `Map` + +Returns a map containing any enabled `LoggerScenarioRule_t` records with valid `StartTime__c` and `EndTime__c` values (null is considered valid) + +##### Return + +**Type** + +Map<String, LoggerScenarioRule_t> + +**Description** + +The current transaction's cached `Map<String, LoggerScenarioRule_t>`, where the key + +#### `getInstance(String scenario)` → `LoggerScenarioRule_t` + +Returns the `LoggerScenarioRule_t` with the matching scenario, based on the field `LoggerScenarioRule_t.Scenario__c` + +##### Parameters + +| Param | Description | +| ---------- | ------------------------ | +| `scenario` | The name of the scenario | + +##### Return + +**Type** + +LoggerScenarioRule_t + +**Description** + +The matching `LoggerScenarioRule_t` if one is found, or `null` + +--- diff --git a/docs/apex/Log-Management/RelatedLogEntriesController.md b/docs/apex/Log-Management/RelatedLogEntriesController.md index bfc3e3565..11cebcc9c 100644 --- a/docs/apex/Log-Management/RelatedLogEntriesController.md +++ b/docs/apex/Log-Management/RelatedLogEntriesController.md @@ -128,10 +128,6 @@ Contains the plural label of the log entry sObject, fetched using a describe cal contains the log entry results from the query. -###### `tabIcon` → `String` - -contains the tab icon of the log entry, fetched using describe a call on the log entry sObject. - ###### `totalLogEntriesCount` → `Integer` Contains the number of records returned via the log entries query. diff --git a/docs/apex/Logger-Engine/Logger.md b/docs/apex/Logger-Engine/Logger.md index 1eda24588..5958a1be6 100644 --- a/docs/apex/Logger-Engine/Logger.md +++ b/docs/apex/Logger-Engine/Logger.md @@ -626,6 +626,16 @@ LogEntryEventBuilder The new entry's instance of `LogEntryEventBuilder`, useful for chaining methods +#### `endScenario(String scenario)` → `void` + +End the specified scenario, if it's the currently active scenario, and rolls back to the previous scenario (if a previous scenario was specified in the current transaction) + +##### Parameters + +| Param | Description | +| ---------- | ------------------------------- | +| `scenario` | The name of the scenario to end | + #### `error(LogMessage logMessage, Database.DeleteResult deleteResult)` → `LogEntryEventBuilder` Creates a new log entry with logging level == `LoggingLevel.ERROR` @@ -4470,7 +4480,7 @@ Sets the default save method used when calling saveLog() - any subsequent calls #### `setScenario(String scenario)` → `void` -Sets the scenario name for the current transaction - this is stored in `LogEntryEvent__e.Scenario__c` and `Log__c.Scenario__c`, and can be used to filter & group logs +Sets the current scenario, which can be used to identify modules or groupings of for the current transaction ##### Parameters diff --git a/docs/apex/Test-Utilities/LoggerTestConfigurator.md b/docs/apex/Test-Utilities/LoggerTestConfigurator.md index 022dc8d01..6c19b3b38 100644 --- a/docs/apex/Test-Utilities/LoggerTestConfigurator.md +++ b/docs/apex/Test-Utilities/LoggerTestConfigurator.md @@ -126,15 +126,15 @@ Loads the mock `LoggerSObjectHandler_t` during test execution | ------ | ----------------------------------------------------- | | `mock` | The mock instance of `LoggerSObjectHandler_t` to load | -#### `setMock(LogScenarioRule_t mock)` → `void` +#### `setMock(LoggerScenarioRule_t mock)` → `void` -Loads the mock `LogScenarioRule_t` during test execution +Loads the mock `LoggerScenarioRule_t` during test execution ##### Parameters -| Param | Description | -| ------ | ------------------------------------------------ | -| `mock` | The mock instance of `LogScenarioRule_t` to load | +| Param | Description | +| ------ | --------------------------------------------------- | +| `mock` | The mock instance of `LoggerScenarioRule_t` to load | #### `setMock(LogStatus_t mock)` → `void` diff --git a/docs/apex/index.md b/docs/apex/index.md index 8befad09d..23138145a 100644 --- a/docs/apex/index.md +++ b/docs/apex/index.md @@ -155,3 +155,7 @@ Provides a centralized way to load parameters for SObject handlers & plugins ### [LoggerPlugin](Configuration/LoggerPlugin) The core of the plugin framework, used to create custom Apex & Flow plugins for `LoggerSObjectHandler` and `LogBatchPurger` based on configurations stored in the custom metadata type `LoggerPlugin_t` + +### [LoggerScenarioRule](Configuration/LoggerScenarioRule) + +Provides a centralized way to load scenario rules that override behavior within Nebula Logger diff --git a/nebula-logger/core/main/configuration/classes/LoggerScenarioRule.cls b/nebula-logger/core/main/configuration/classes/LoggerScenarioRule.cls new file mode 100644 index 000000000..83abfb7dd --- /dev/null +++ b/nebula-logger/core/main/configuration/classes/LoggerScenarioRule.cls @@ -0,0 +1,71 @@ +//------------------------------------------------------------------------------------------------// +// This file is part of the Nebula Logger project, released under the MIT License. // +// See LICENSE file or go to https://github.com/jongpie/NebulaLogger for full license details. // +//------------------------------------------------------------------------------------------------// + +/** + * @group Configuration + * @description Provides a centralized way to load scenario rules that override behavior + * within Nebula Logger + */ +public without sharing class LoggerScenarioRule { + private static final Map SCENARIO_NAME_TO_SCENARIO_RULE = loadLogScenarioRules(); + + /** + * @description Returns a map containing any enabled `LoggerScenarioRule__mdt` records with + * valid `StartTime__c` and `EndTime__c` values (null is considered valid) + * @return The current transaction's cached `Map`, where the key + * is the log scenario (configured in `LoggerScenarioRule__mdt.Scenario__c`) + */ + public static Map getAll() { + return SCENARIO_NAME_TO_SCENARIO_RULE; + } + + /** + * @description Returns the `LoggerScenarioRule__mdt` with the matching scenario, + * based on the field `LoggerScenarioRule__mdt.Scenario__c` + * @param scenario The name of the scenario + * @return The matching `LoggerScenarioRule__mdt` if one is found, or `null` + */ + public static LoggerScenarioRule__mdt getInstance(String scenario) { + return SCENARIO_NAME_TO_SCENARIO_RULE.get(scenario); + } + + @TestVisible + private static void setMock(LoggerScenarioRule__mdt scenarioRule) { + if (String.isBlank(scenarioRule.Scenario__c) == true) { + throw new IllegalArgumentException('Scenario__c is required on `LoggerScenarioRule__mdt: \n' + JSON.serializePretty(scenarioRule)); + } + + if (isValid(scenarioRule) == true) { + SCENARIO_NAME_TO_SCENARIO_RULE.put(scenarioRule.Scenario__c, scenarioRule); + } + } + + private static Map loadLogScenarioRules() { + Map scenarioRules = new Map(); + for (LoggerScenarioRule__mdt scenarioRule : LoggerScenarioRule__mdt.getAll().values()) { + if (isValid(scenarioRule) == true) { + scenarioRules.put(scenarioRule.Scenario__c, scenarioRule); + } + } + + if (System.Test.isRunningTest() == true) { + scenarioRules.clear(); + } + + return scenarioRules; + } + + private static Boolean isValid(LoggerScenarioRule__mdt scenarioRule) { + Boolean isValid = false; + if (scenarioRule.IsEnabled__c == true) { + Datetime currentTime = System.now(); + Boolean startTimeIsValid = scenarioRule.StartTime__c == null || scenarioRule.StartTime__c <= currentTime; + Boolean endTimeIsValid = scenarioRule.EndTime__c == null || scenarioRule.EndTime__c >= currentTime; + + isValid = startTimeIsValid == true && endTimeIsValid == true; + } + return isValid; + } +} diff --git a/nebula-logger/core/main/configuration/classes/LoggerScenarioRule.cls-meta.xml b/nebula-logger/core/main/configuration/classes/LoggerScenarioRule.cls-meta.xml new file mode 100644 index 000000000..c47403d0b --- /dev/null +++ b/nebula-logger/core/main/configuration/classes/LoggerScenarioRule.cls-meta.xml @@ -0,0 +1,5 @@ + + + 55.0 + Active + diff --git a/nebula-logger/core/main/configuration/layouts/LoggerScenarioRule__mdt-Logger Scenario Rule Layout.layout-meta.xml b/nebula-logger/core/main/configuration/layouts/LoggerScenarioRule__mdt-Logger Scenario Rule Layout.layout-meta.xml new file mode 100644 index 000000000..ac3f1a26f --- /dev/null +++ b/nebula-logger/core/main/configuration/layouts/LoggerScenarioRule__mdt-Logger Scenario Rule Layout.layout-meta.xml @@ -0,0 +1,164 @@ + + + + false + true + true + + + + Required + MasterLabel + + + Required + DeveloperName + + + Required + Scenario__c + + + + + Edit + IsEnabled__c + + + Edit + StartTime__c + + + Edit + EndTime__c + + + + + + true + true + true + + + + Edit + IsLoggerEnabled__c + + + Edit + UserLoggingLevel__c + + + Edit + IsSavingEnabled__c + + + Edit + SaveMethod__c + + + + + Edit + IsAnonymousModeEnabled__c + + + Edit + IsApexSystemDebugLoggingEnabled__c + + + Edit + IsJavaScriptConsoleLoggingEnabled__c + + + Edit + IsDataMaskingEnabled__c + + + Edit + IsRecordFieldStrippingEnabled__c + + + + + + true + true + true + + + + Edit + IsPlatformEventStorageLocationEnabled__c + + + Edit + PlatformEventStorageLocation__c + + + Edit + IsLogAssignmentEnabled__c + + + + + Edit + IsLogRetentionOverrideEnabled__c + + + Edit + NumberOfDaysToRetainLogs__c + + + + + + false + true + true + + + + Required + NamespacePrefix + + + Readonly + CreatedById + + + + + Edit + IsProtected + + + Readonly + LastModifiedById + + + + + + true + true + false + + + + + + + false + false + false + false + false + + 00h63000007CAvC + 4 + 0 + Default + + diff --git a/nebula-logger/core/main/configuration/objects/LogScenarioRule__mdt/LogScenarioRule__mdt.object-meta.xml b/nebula-logger/core/main/configuration/objects/LoggerScenarioRule__mdt/LoggerScenarioRule__mdt.object-meta.xml similarity index 62% rename from nebula-logger/core/main/configuration/objects/LogScenarioRule__mdt/LogScenarioRule__mdt.object-meta.xml rename to nebula-logger/core/main/configuration/objects/LoggerScenarioRule__mdt/LoggerScenarioRule__mdt.object-meta.xml index 3c9a934f5..beddfb99b 100644 --- a/nebula-logger/core/main/configuration/objects/LogScenarioRule__mdt/LogScenarioRule__mdt.object-meta.xml +++ b/nebula-logger/core/main/configuration/objects/LoggerScenarioRule__mdt/LoggerScenarioRule__mdt.object-meta.xml @@ -1,6 +1,6 @@ - - Log Scenario Rules + + Logger Scenario Rules Public diff --git a/nebula-logger/core/main/configuration/objects/LoggerScenarioRule__mdt/fields/EndTime__c.field-meta.xml b/nebula-logger/core/main/configuration/objects/LoggerScenarioRule__mdt/fields/EndTime__c.field-meta.xml new file mode 100644 index 000000000..627e50bbe --- /dev/null +++ b/nebula-logger/core/main/configuration/objects/LoggerScenarioRule__mdt/fields/EndTime__c.field-meta.xml @@ -0,0 +1,9 @@ + + + EndTime__c + false + DeveloperControlled + + false + DateTime + diff --git a/nebula-logger/core/main/configuration/objects/LoggerScenarioRule__mdt/fields/IsAnonymousModeEnabled__c.field-meta.xml b/nebula-logger/core/main/configuration/objects/LoggerScenarioRule__mdt/fields/IsAnonymousModeEnabled__c.field-meta.xml new file mode 100644 index 000000000..1a25b9cbb --- /dev/null +++ b/nebula-logger/core/main/configuration/objects/LoggerScenarioRule__mdt/fields/IsAnonymousModeEnabled__c.field-meta.xml @@ -0,0 +1,30 @@ + + + IsAnonymousModeEnabled__c + Active + PII;GDPR;CCPA + false + DeveloperControlled + When enabled, any logs generated will not have any user-specific details set - any fields related to the User, Profile, etc. will be null. Note: this feature only works properly when using the save method EVENT_BUS. + + false + Confidential + Picklist + + true + + false + + true + false + + + + false + false + + + + + diff --git a/nebula-logger/core/main/configuration/objects/LoggerScenarioRule__mdt/fields/IsApexSystemDebugLoggingEnabled__c.field-meta.xml b/nebula-logger/core/main/configuration/objects/LoggerScenarioRule__mdt/fields/IsApexSystemDebugLoggingEnabled__c.field-meta.xml new file mode 100644 index 000000000..fe1a7bf59 --- /dev/null +++ b/nebula-logger/core/main/configuration/objects/LoggerScenarioRule__mdt/fields/IsApexSystemDebugLoggingEnabled__c.field-meta.xml @@ -0,0 +1,30 @@ + + + IsApexSystemDebugLoggingEnabled__c + Active + PII;GDPR;CCPA + false + DeveloperControlled + When enabled, Logger will automatically call Apex's System.debug(). To help with performance, this option should be disabled in production unless you are actively troubleshooting an issue. + + false + Confidential + Picklist + + true + + false + + true + false + + + + false + false + + + + + diff --git a/nebula-logger/core/main/configuration/objects/LoggerScenarioRule__mdt/fields/IsDataMaskingEnabled__c.field-meta.xml b/nebula-logger/core/main/configuration/objects/LoggerScenarioRule__mdt/fields/IsDataMaskingEnabled__c.field-meta.xml new file mode 100644 index 000000000..d1df79402 --- /dev/null +++ b/nebula-logger/core/main/configuration/objects/LoggerScenarioRule__mdt/fields/IsDataMaskingEnabled__c.field-meta.xml @@ -0,0 +1,30 @@ + + + IsDataMaskingEnabled__c + Active + PII;GDPR;CCPA + false + DeveloperControlled + When enabled, any data-mask rules (configured in LogEntryDataMaskRule__mdt) will be automatically applied to log entry messages. + + false + Confidential + Picklist + + true + + false + + true + false + + + + false + false + + + + + diff --git a/nebula-logger/core/main/configuration/objects/LoggerScenarioRule__mdt/fields/IsEnabled__c.field-meta.xml b/nebula-logger/core/main/configuration/objects/LoggerScenarioRule__mdt/fields/IsEnabled__c.field-meta.xml new file mode 100644 index 000000000..54f633604 --- /dev/null +++ b/nebula-logger/core/main/configuration/objects/LoggerScenarioRule__mdt/fields/IsEnabled__c.field-meta.xml @@ -0,0 +1,12 @@ + + + IsEnabled__c + Active + None + true + false + DeveloperControlled + + Confidential + Checkbox + diff --git a/nebula-logger/core/main/configuration/objects/LoggerScenarioRule__mdt/fields/IsJavaScriptConsoleLoggingEnabled__c.field-meta.xml b/nebula-logger/core/main/configuration/objects/LoggerScenarioRule__mdt/fields/IsJavaScriptConsoleLoggingEnabled__c.field-meta.xml new file mode 100644 index 000000000..4257b4829 --- /dev/null +++ b/nebula-logger/core/main/configuration/objects/LoggerScenarioRule__mdt/fields/IsJavaScriptConsoleLoggingEnabled__c.field-meta.xml @@ -0,0 +1,30 @@ + + + IsJavaScriptConsoleLoggingEnabled__c + Active + PII;GDPR;CCPA + false + DeveloperControlled + When enabled, Logger will automatically call the browser's console.log() function when logging via lightning components. To help with performance, this option should be disabled in production unless you are actively troubleshooting an issue. + + false + Confidential + Picklist + + true + + false + + true + false + + + + false + false + + + + + diff --git a/nebula-logger/core/main/configuration/objects/LoggerScenarioRule__mdt/fields/IsLogAssignmentEnabled__c.field-meta.xml b/nebula-logger/core/main/configuration/objects/LoggerScenarioRule__mdt/fields/IsLogAssignmentEnabled__c.field-meta.xml new file mode 100644 index 000000000..b792f6364 --- /dev/null +++ b/nebula-logger/core/main/configuration/objects/LoggerScenarioRule__mdt/fields/IsLogAssignmentEnabled__c.field-meta.xml @@ -0,0 +1,30 @@ + + + IsLogAssignmentEnabled__c + Active + PII;GDPR;CCPA + false + DeveloperControlleda + Controls if new Log__c records associated with the scenario (based on Log__c.TransactionScenario__c) are automatically assigned to the owner of the LoggerScenario__c record. + + false + Confidential + Picklist + + true + + false + + true + false + + + + false + false + + + + + diff --git a/nebula-logger/core/main/configuration/objects/LoggerScenarioRule__mdt/fields/IsLogRetentionOverrideEnabled__c.field-meta.xml b/nebula-logger/core/main/configuration/objects/LoggerScenarioRule__mdt/fields/IsLogRetentionOverrideEnabled__c.field-meta.xml new file mode 100644 index 000000000..9990dd15b --- /dev/null +++ b/nebula-logger/core/main/configuration/objects/LoggerScenarioRule__mdt/fields/IsLogRetentionOverrideEnabled__c.field-meta.xml @@ -0,0 +1,30 @@ + + + IsLogRetentionOverrideEnabled__c + Active + PII;GDPR;CCPA + false + DeveloperControlled + When enabled, the value specified in NumberOfDaysToRetainLogs__c (including null) will override the value specified in LoggerSettings__c. + + false + Confidential + Picklist + + true + + false + + true + false + + + + false + false + + + + + diff --git a/nebula-logger/core/main/configuration/objects/LoggerScenarioRule__mdt/fields/IsLoggerEnabled__c.field-meta.xml b/nebula-logger/core/main/configuration/objects/LoggerScenarioRule__mdt/fields/IsLoggerEnabled__c.field-meta.xml new file mode 100644 index 000000000..138579117 --- /dev/null +++ b/nebula-logger/core/main/configuration/objects/LoggerScenarioRule__mdt/fields/IsLoggerEnabled__c.field-meta.xml @@ -0,0 +1,28 @@ + + + IsLoggerEnabled__c + Active + PII;GDPR;CCPA + false + DeveloperControlled + + false + Confidential + Picklist + + true + + false + + true + false + + + + false + false + + + + + diff --git a/nebula-logger/core/main/configuration/objects/LoggerScenarioRule__mdt/fields/IsPlatformEventStorageLocationEnabled__c.field-meta.xml b/nebula-logger/core/main/configuration/objects/LoggerScenarioRule__mdt/fields/IsPlatformEventStorageLocationEnabled__c.field-meta.xml new file mode 100644 index 000000000..00df067b3 --- /dev/null +++ b/nebula-logger/core/main/configuration/objects/LoggerScenarioRule__mdt/fields/IsPlatformEventStorageLocationEnabled__c.field-meta.xml @@ -0,0 +1,28 @@ + + + IsPlatformEventStorageLocationEnabled__c + Active + PII;GDPR;CCPA + false + DeveloperControlled + + false + Confidential + Picklist + + true + + false + + true + false + + + + false + false + + + + + diff --git a/nebula-logger/core/main/configuration/objects/LoggerScenarioRule__mdt/fields/IsRecordFieldStrippingEnabled__c.field-meta.xml b/nebula-logger/core/main/configuration/objects/LoggerScenarioRule__mdt/fields/IsRecordFieldStrippingEnabled__c.field-meta.xml new file mode 100644 index 000000000..fc16f4794 --- /dev/null +++ b/nebula-logger/core/main/configuration/objects/LoggerScenarioRule__mdt/fields/IsRecordFieldStrippingEnabled__c.field-meta.xml @@ -0,0 +1,30 @@ + + + IsRecordFieldStrippingEnabled__c + Active + PII;GDPR;CCPA + false + DeveloperControlled + When enabled, any time an SObject record is logged, only fields that the current user can access will be included in the record's JSON. + + false + Confidential + Picklist + + true + + false + + true + false + + + + false + false + + + + + diff --git a/nebula-logger/core/main/configuration/objects/LoggerScenarioRule__mdt/fields/IsSavingEnabled__c.field-meta.xml b/nebula-logger/core/main/configuration/objects/LoggerScenarioRule__mdt/fields/IsSavingEnabled__c.field-meta.xml new file mode 100644 index 000000000..9cb5a6e38 --- /dev/null +++ b/nebula-logger/core/main/configuration/objects/LoggerScenarioRule__mdt/fields/IsSavingEnabled__c.field-meta.xml @@ -0,0 +1,29 @@ + + + IsSavingEnabled__c + Active + PII;GDPR;CCPA + false + DeveloperControlled + Controls if saving is enabled - when disabled, any calls to saveLog() are ignored. + + false + Confidential + Picklist + + true + + false + + true + false + + + + false + false + + + + + diff --git a/nebula-logger/core/main/configuration/objects/LoggerScenarioRule__mdt/fields/NumberOfDaysToRetainLogs__c.field-meta.xml b/nebula-logger/core/main/configuration/objects/LoggerScenarioRule__mdt/fields/NumberOfDaysToRetainLogs__c.field-meta.xml new file mode 100644 index 000000000..63ac8a31e --- /dev/null +++ b/nebula-logger/core/main/configuration/objects/LoggerScenarioRule__mdt/fields/NumberOfDaysToRetainLogs__c.field-meta.xml @@ -0,0 +1,17 @@ + + + NumberOfDaysToRetainLogs__c + Active + None + false + DeveloperControlled + This value is used to set the field Log__c.LogRetentionDate__c, which is then used by LogBatchPurger to delete old logs. To keep logs indefinitely, set this field to a blank value (null). + + 4 + false + 0 + Confidential + Number + false + diff --git a/nebula-logger/core/main/configuration/objects/LoggerScenarioRule__mdt/fields/PlatformEventStorageLocation__c.field-meta.xml b/nebula-logger/core/main/configuration/objects/LoggerScenarioRule__mdt/fields/PlatformEventStorageLocation__c.field-meta.xml new file mode 100644 index 000000000..4ada74179 --- /dev/null +++ b/nebula-logger/core/main/configuration/objects/LoggerScenarioRule__mdt/fields/PlatformEventStorageLocation__c.field-meta.xml @@ -0,0 +1,16 @@ + + + PlatformEventStorageLocation__c + Active + PII;GDPR;CCPA + false + DeveloperControlled + This controls the default location where LogEntryEvent__e records are stored - when null, LogEntryEvent__e records will not be stored. + + 255 + false + Confidential + Text + false + diff --git a/nebula-logger/core/main/configuration/objects/LoggerScenarioRule__mdt/fields/SaveMethod__c.field-meta.xml b/nebula-logger/core/main/configuration/objects/LoggerScenarioRule__mdt/fields/SaveMethod__c.field-meta.xml new file mode 100644 index 000000000..187aca46f --- /dev/null +++ b/nebula-logger/core/main/configuration/objects/LoggerScenarioRule__mdt/fields/SaveMethod__c.field-meta.xml @@ -0,0 +1,15 @@ + + + SaveMethod__c + Active + PII;GDPR;CCPA + false + DeveloperControlled + This controls the default save method used by Logger when calling saveLog(). In most situations, EVENT_BUS should be used. + + 255 + false + Confidential + Text + false + diff --git a/nebula-logger/core/main/configuration/objects/LoggerScenarioRule__mdt/fields/Scenario__c.field-meta.xml b/nebula-logger/core/main/configuration/objects/LoggerScenarioRule__mdt/fields/Scenario__c.field-meta.xml new file mode 100644 index 000000000..bc224c4b0 --- /dev/null +++ b/nebula-logger/core/main/configuration/objects/LoggerScenarioRule__mdt/fields/Scenario__c.field-meta.xml @@ -0,0 +1,15 @@ + + + Scenario__c + Active + false + PII;GDPR;CCPA + false + DeveloperControlled + + 255 + true + Confidential + Text + true + diff --git a/nebula-logger/core/main/configuration/objects/LoggerScenarioRule__mdt/fields/StartTime__c.field-meta.xml b/nebula-logger/core/main/configuration/objects/LoggerScenarioRule__mdt/fields/StartTime__c.field-meta.xml new file mode 100644 index 000000000..5b8931a62 --- /dev/null +++ b/nebula-logger/core/main/configuration/objects/LoggerScenarioRule__mdt/fields/StartTime__c.field-meta.xml @@ -0,0 +1,9 @@ + + + StartTime__c + false + DeveloperControlled + + false + DateTime + diff --git a/nebula-logger/core/main/configuration/objects/LoggerScenarioRule__mdt/fields/UserLoggingLevel__c.field-meta.xml b/nebula-logger/core/main/configuration/objects/LoggerScenarioRule__mdt/fields/UserLoggingLevel__c.field-meta.xml new file mode 100644 index 000000000..9fae8b25c --- /dev/null +++ b/nebula-logger/core/main/configuration/objects/LoggerScenarioRule__mdt/fields/UserLoggingLevel__c.field-meta.xml @@ -0,0 +1,55 @@ + + + UserLoggingLevel__c + Active + PII;GDPR;CCPA + false + DeveloperControlled + Overrides the user's logging level (normally controlled via LoggerSettings__c.LoggingLevel__c) for any transactions with the specified Scenario + + false + Confidential + Picklist + + true + + false + + ERROR + false + + + + WARN + false + + + + INFO + false + + + + DEBUG + false + + + + FINE + false + + + + FINER + false + + + + FINEST + false + + + + + diff --git a/nebula-logger/core/main/configuration/objects/LoggerScenarioRule__mdt/listViews/All.listView-meta.xml b/nebula-logger/core/main/configuration/objects/LoggerScenarioRule__mdt/listViews/All.listView-meta.xml new file mode 100644 index 000000000..f8290bbd7 --- /dev/null +++ b/nebula-logger/core/main/configuration/objects/LoggerScenarioRule__mdt/listViews/All.listView-meta.xml @@ -0,0 +1,18 @@ + + + All + MasterLabel + DeveloperName + Scenario__c + IsEnabled__c + StartTime__c + EndTime__c + IsLoggerEnabled__c + UserLoggingLevel__c + NumberOfDaysToRetainLogs__c + IsSavingEnabled__c + SaveMethod__c + IsLogAssignmentEnabled__c + Everything + + diff --git a/nebula-logger/core/main/configuration/objects/LoggerSettings__c/fields/DefaultScenario__c.field-meta.xml b/nebula-logger/core/main/configuration/objects/LoggerSettings__c/fields/DefaultScenario__c.field-meta.xml new file mode 100644 index 000000000..dcaa84bfc --- /dev/null +++ b/nebula-logger/core/main/configuration/objects/LoggerSettings__c/fields/DefaultScenario__c.field-meta.xml @@ -0,0 +1,16 @@ + + + DefaultScenario__c + Active + CCPA;GDPR;PII + Sets a default scenario for the transaction + false + Sets a default scenario for the transaction + + 255 + false + Confidential + false + Text + false + diff --git a/nebula-logger/core/main/log-management/applications/LoggerConsole.app-meta.xml b/nebula-logger/core/main/log-management/applications/LoggerConsole.app-meta.xml index 3b97e506c..596ab0f70 100644 --- a/nebula-logger/core/main/log-management/applications/LoggerConsole.app-meta.xml +++ b/nebula-logger/core/main/log-management/applications/LoggerConsole.app-meta.xml @@ -40,10 +40,10 @@ LogEntry__c - LoggerScenario__c + Log__c - Log__c + LoggerScenario__c LoggerSettings diff --git a/nebula-logger/core/main/log-management/classes/LogBatchPurgeController_Tests.cls b/nebula-logger/core/main/log-management/classes/LogBatchPurgeController_Tests.cls index 603421630..f1fc6b011 100644 --- a/nebula-logger/core/main/log-management/classes/LogBatchPurgeController_Tests.cls +++ b/nebula-logger/core/main/log-management/classes/LogBatchPurgeController_Tests.cls @@ -3,7 +3,7 @@ // See LICENSE file or go to https://github.com/jongpie/NebulaLogger for full license details. // //------------------------------------------------------------------------------------------------// @SuppressWarnings('PMD.ApexDoc, PMD.CyclomaticComplexity, PMD.ExcessiveParameterList, PMD.MethodNamingConventions,PMD.CognitiveComplexity') -@IsTest +@IsTest(IsParallel=false) private class LogBatchPurgeController_Tests { static final String CUSTOM_PURGE_ACTION = 'Custom'; static final String DEFAULT_PURGE_ACTION = 'Delete'; diff --git a/nebula-logger/core/main/log-management/classes/LogEntryEventHandler.cls b/nebula-logger/core/main/log-management/classes/LogEntryEventHandler.cls index 036266e7d..2f14b36e4 100644 --- a/nebula-logger/core/main/log-management/classes/LogEntryEventHandler.cls +++ b/nebula-logger/core/main/log-management/classes/LogEntryEventHandler.cls @@ -63,11 +63,18 @@ public without sharing class LogEntryEventHandler extends LoggerSObjectHandler { } private List filterLogEntryEventsToSave(List newLogEntryEvents) { + final String trueString = String.valueOf(true); List logEntryEventsToSave = new List(); for (LogEntryEvent__e logEntryEvent : newLogEntryEvents) { User loggingUser = new User(Id = logEntryEvent.LoggedById__c, ProfileId = logEntryEvent.ProfileId__c); - LoggerSettings__c loggingUserSettings = Logger.getUserSettings(loggingUser); - if (loggingUserSettings.DefaultPlatformEventStorageLocation__c == DEFAULT_STORAGE_LOCATION_NAME) { + String platformEventStorageLocation = Logger.getUserSettings(loggingUser).DefaultPlatformEventStorageLocation__c; + if (logEntryEvent.TransactionScenario__c != null && LoggerScenarioRule.getAll().containsKey(logEntryEvent.TransactionScenario__c) == true) { + LoggerScenarioRule__mdt scenarioRule = LoggerScenarioRule.getInstance(logEntryEvent.TransactionScenario__c); + if (scenarioRule.IsPlatformEventStorageLocationEnabled__c == trueString) { + platformEventStorageLocation = scenarioRule.PlatformEventStorageLocation__c; + } + } + if (platformEventStorageLocation == DEFAULT_STORAGE_LOCATION_NAME) { logEntryEventsToSave.add(logEntryEvent); } } @@ -75,19 +82,36 @@ public without sharing class LogEntryEventHandler extends LoggerSObjectHandler { } private void upsertLoggerScenarios() { + List scenarioFields = new List{ + Schema.LogEntryEvent__e.EntryScenario__c, + Schema.LogEntryEvent__e.TransactionScenario__c + }; for (LogEntryEvent__e logEntryEvent : this.logEntryEvents) { - if (String.isBlank(logEntryEvent.Scenario__c) == true || SCENARIO_UNIQUE_ID_TO_SCENARIO.containsKey(logEntryEvent.Scenario__c)) { - continue; - } + for (Schema.SObjectField scenarioField : scenarioFields) { + String scenario = (String) logEntryEvent.get(scenarioField); - LoggerScenario__c loggerScenario = new LoggerScenario__c(Name = logEntryEvent.Scenario__c, UniqueId__c = logEntryEvent.Scenario__c); - loggerScenario.setOptions(DML_OPTIONS); - SCENARIO_UNIQUE_ID_TO_SCENARIO.put(loggerScenario.UniqueId__c, loggerScenario); + if (String.isBlank(scenario) == true || SCENARIO_UNIQUE_ID_TO_SCENARIO.containsKey(scenario)) { + continue; + } + + LoggerScenario__c loggerScenario = new LoggerScenario__c(Name = scenario, UniqueId__c = scenario); + loggerScenario.setOptions(DML_OPTIONS); + SCENARIO_UNIQUE_ID_TO_SCENARIO.put(loggerScenario.UniqueId__c, loggerScenario); + } } List upsertResults = LoggerDataStore.getDatabase() .upsertRecords(SCENARIO_UNIQUE_ID_TO_SCENARIO.values(), Schema.LoggerScenario__c.UniqueId__c, System.Test.isRunningTest()); LoggerEmailSender.sendErrorEmail(Schema.LoggerScenario__c.SObjectType, upsertResults); + + // Requery to get the OwnerId field as well + for (LoggerScenario__c loggerScenario : [ + SELECT Id, Name, OwnerId, UniqueId__c + FROM LoggerScenario__c + WHERE Id IN :SCENARIO_UNIQUE_ID_TO_SCENARIO.values() + ]) { + SCENARIO_UNIQUE_ID_TO_SCENARIO.put(loggerScenario.UniqueId__c, loggerScenario); + } } private void upsertLogs() { @@ -102,12 +126,7 @@ public without sharing class LogEntryEventHandler extends LoggerSObjectHandler { continue; } - User loggingUser = new User(Id = logEntryEvent.LoggedById__c, ProfileId = logEntryEvent.ProfileId__c); - LoggerSettings__c loggingUserSettings = Logger.getUserSettings(loggingUser); - Id logOwnerId = loggingUser.Id; - if (logEntryEvent.UserType__c == GUEST_USER_TYPE || String.isBlank(logOwnerId) == true || loggingUserSettings.IsAnonymousModeEnabled__c == true) { - logOwnerId = UserInfo.getUserId(); - } + Id logOwnerId = this.determineLogOwnerId(logEntryEvent); Log__c log = new Log__c( ApiReleaseNumber__c = recentLogWithApiReleaseDetails?.ApiReleaseNumber__c, @@ -141,7 +160,7 @@ public without sharing class LogEntryEventHandler extends LoggerSObjectHandler { ParentLogTransactionId__c = logEntryEvent.ParentLogTransactionId__c, ProfileId__c = logEntryEvent.ProfileId__c, ProfileName__c = logEntryEvent.ProfileName__c, - Scenario__c = logEntryEvent.Scenario__c, + Scenario__c = logEntryEvent.TransactionScenario__c, SessionId__c = logEntryEvent.SessionId__c, SessionSecurityLevel__c = logEntryEvent.SessionSecurityLevel__c, SessionType__c = logEntryEvent.SessionType__c, @@ -161,8 +180,11 @@ public without sharing class LogEntryEventHandler extends LoggerSObjectHandler { UserType__c = logEntryEvent.UserType__c ); - if (String.isNotBlank(logEntryEvent.Scenario__c) == true && SCENARIO_UNIQUE_ID_TO_SCENARIO.containsKey(logEntryEvent.Scenario__c) == true) { - log.TransactionScenario__c = SCENARIO_UNIQUE_ID_TO_SCENARIO.get(logEntryEvent.Scenario__c).Id; + if ( + String.isNotBlank(logEntryEvent.TransactionScenario__c) == true && + SCENARIO_UNIQUE_ID_TO_SCENARIO.containsKey(logEntryEvent.TransactionScenario__c) == true + ) { + log.TransactionScenario__c = SCENARIO_UNIQUE_ID_TO_SCENARIO.get(logEntryEvent.TransactionScenario__c).Id; } TRANSACTION_ID_TO_LOG.put(log.TransactionId__c, log); @@ -274,6 +296,14 @@ public without sharing class LogEntryEventHandler extends LoggerSObjectHandler { TriggerOperationType__c = logEntryEvent.TriggerOperationType__c, TriggerSObjectType__c = logEntryEvent.TriggerSObjectType__c ); + + if ( + String.isNotBlank(logEntryEvent.EntryScenario__c) == true && + SCENARIO_UNIQUE_ID_TO_SCENARIO.containsKey(logEntryEvent.EntryScenario__c) == true + ) { + logEntry.EntryScenario__c = SCENARIO_UNIQUE_ID_TO_SCENARIO.get(logEntryEvent.EntryScenario__c).Id; + } + logEntry.setOptions(DML_OPTIONS); this.logEntries.add(logEntry); @@ -376,6 +406,27 @@ public without sharing class LogEntryEventHandler extends LoggerSObjectHandler { } } + private Id determineLogOwnerId(LogEntryEvent__e logEntryEvent) { + Id logOwnerId = logEntryEvent.LoggedById__c; + + LoggerSettings__c loggingUserSettings = Logger.getUserSettings(new User(Id = logEntryEvent.LoggedById__c, ProfileId = logEntryEvent.ProfileId__c)); + if (logEntryEvent.UserType__c == GUEST_USER_TYPE || String.isBlank(logOwnerId) == true || loggingUserSettings.IsAnonymousModeEnabled__c == true) { + logOwnerId = UserInfo.getUserId(); + } + + if (logEntryEvent.TransactionScenario__c != null && LoggerScenarioRule.getAll().containsKey(logEntryEvent.TransactionScenario__c) == true) { + LoggerScenarioRule__mdt scenarioRule = LoggerScenarioRule.getInstance(logEntryEvent.TransactionScenario__c); + if ( + scenarioRule.IsLogAssignmentEnabled__c == String.valueOf(true) && + SCENARIO_UNIQUE_ID_TO_SCENARIO.containsKey(logEntryEvent.TransactionScenario__c) == true + ) { + logOwnerId = SCENARIO_UNIQUE_ID_TO_SCENARIO.get(logEntryEvent.TransactionScenario__c).OwnerId; + } + } + + return logOwnerId; + } + private Map getTagNameToId(Schema.SObjectType tagSObjectType) { Map tagNameToId = new Map(); diff --git a/nebula-logger/core/main/log-management/classes/LogHandler.cls b/nebula-logger/core/main/log-management/classes/LogHandler.cls index 670875665..8b0ef31e6 100644 --- a/nebula-logger/core/main/log-management/classes/LogHandler.cls +++ b/nebula-logger/core/main/log-management/classes/LogHandler.cls @@ -10,7 +10,6 @@ @SuppressWarnings('PMD.CognitiveComplexity, PMD.CyclomaticComplexity') public without sharing class LogHandler extends LoggerSObjectHandler { private static final Map MOCK_LOG_STATUS_TO_STATUS = new Map(); - private static final Map MOCK_SCENARIO_TO_SCENARIO_RULE = new Map(); @TestVisible private List logs; @@ -91,7 +90,7 @@ public without sharing class LogHandler extends LoggerSObjectHandler { } } - if (logsToUpdate.isEmpty()) { + if (logsToUpdate.isEmpty() == true) { return; } @@ -133,7 +132,6 @@ public without sharing class LogHandler extends LoggerSObjectHandler { } private void setLogRetentionDetails() { - Map scenarioToScenarioRule = queryLogScenarioRules(this.logs, this.loggerScenariosById); for (Log__c log : this.logs) { // If the retention date has already been populated, leave it as-is if (log.LogRetentionDate__c != null) { @@ -144,16 +142,23 @@ public without sharing class LogHandler extends LoggerSObjectHandler { LoggerSettings__c loggingUserSettings = getLoggingUserSettings(log); // Load the configured scenario rule (if one exists) - LogScenarioRule__mdt matchingScenarioRule; + LoggerScenarioRule__mdt matchingScenarioRule; if (log.TransactionScenario__c != null) { LoggerScenario__c loggerScenario = this.loggerScenariosById.get(log.TransactionScenario__c); - matchingScenarioRule = scenarioToScenarioRule.get(loggerScenario.UniqueId__c); + matchingScenarioRule = LoggerScenarioRule.getInstance(loggerScenario.UniqueId__c); + if ( + matchingScenarioRule != null && + (matchingScenarioRule.IsLogRetentionOverrideEnabled__c == null || + Boolean.valueOf(matchingScenarioRule.IsLogRetentionOverrideEnabled__c) != true) + ) { + matchingScenarioRule = null; + } } Integer daysToRetainLog = Integer.valueOf( matchingScenarioRule != null ? matchingScenarioRule.NumberOfDaysToRetainLogs__c : loggingUserSettings.DefaultNumberOfDaysToRetainLogs__c ); - // TODO Add new field to LogScenarioRule__mdt for setting the default log purge action (same concept as matchingScenarioRule.NumberOfDaysToRetainLogs__c above) + // TODO Add new field to LoggerScenarioRule__mdt for setting the default log purge action (same concept as matchingScenarioRule.NumberOfDaysToRetainLogs__c above) // When daysToRetainLog is null, assume that the log should be kept forever, // and set the retention date to null so that LogBatchPurger filters out/ignores the record @@ -269,36 +274,8 @@ public without sharing class LogHandler extends LoggerSObjectHandler { return usersByUsername; } - private static Map queryLogScenarioRules(List logs, Map loggerScenariosById) { - Set scenarios = new Set(); - for (Log__c log : logs) { - if (log.TransactionScenario__c != null && loggerScenariosById.containsKey(log.TransactionScenario__c) == true) { - scenarios.add(loggerScenariosById.get(log.TransactionScenario__c).UniqueId__c); - } - } - - Map scenarioToScenarioRule = new Map(); - for (LogScenarioRule__mdt scenarioRule : LogScenarioRule__mdt.getAll().values()) { - if (scenarioRule.IsEnabled__c == true && scenarios.contains(scenarioRule.Scenario__c) == true) { - scenarioToScenarioRule.put(scenarioRule.Scenario__c, scenarioRule); - } - } - - if (System.Test.isRunningTest() == true) { - scenarioToScenarioRule.clear(); - scenarioToScenarioRule.putAll(MOCK_SCENARIO_TO_SCENARIO_RULE); - } - - return scenarioToScenarioRule; - } - @TestVisible private static void setMockLogStatus(LogStatus__mdt logStatus) { MOCK_LOG_STATUS_TO_STATUS.put(logStatus.MasterLabel, logStatus); } - - @TestVisible - private static void setMockScenarioRule(LogScenarioRule__mdt scenarioRule) { - MOCK_SCENARIO_TO_SCENARIO_RULE.put(scenarioRule.Scenario__c, scenarioRule); - } } diff --git a/nebula-logger/core/main/log-management/classes/RelatedLogEntriesController.cls b/nebula-logger/core/main/log-management/classes/RelatedLogEntriesController.cls index 1bf162c7f..dc5d67e00 100644 --- a/nebula-logger/core/main/log-management/classes/RelatedLogEntriesController.cls +++ b/nebula-logger/core/main/log-management/classes/RelatedLogEntriesController.cls @@ -152,36 +152,6 @@ public with sharing class RelatedLogEntriesController { return relationshipName + '.' + displayFieldApiName; } - @SuppressWarnings('PMD.CognitiveComplexity') - private static String getTabIcon(Schema.SObjectType sobjectType) { - String sobjectName = sobjectType.getDescribe().getName(); - - String tabIcon; - for (Schema.DescribeTabSetResult tabSetResult : Schema.describeTabs()) { - for (Schema.DescribeTabResult tabResult : tabSetResult.getTabs()) { - if (tabResult.getSObjectName() != sobjectName) { - continue; - } - - String iconType = tabResult.isCustom() ? 'custom' : 'standard'; - String svgIconName; - for (Schema.DescribeIconResult icon : tabResult.getIcons()) { - if (icon.getContentType() != 'image/svg+xml') { - continue; - } - - svgIconName = icon.getUrl().substringAfterLast('/').replace('.svg', ''); - tabIcon = iconType + ':' + svgIconName; - break; - } - } - } - - return tabIcon; - } - - // Inner classes - /** * @description Inner, wrapper class that contains query result information after querying related log entries. */ @@ -216,12 +186,6 @@ public with sharing class RelatedLogEntriesController { @AuraEnabled public List records { get; set; } - /** - * @description contains the tab icon of the log entry, fetched using describe a call on the log entry sObject. - */ - @AuraEnabled - public String tabIcon { get; set; } - /** * @description Contains the number of records returned via the log entries query. */ @@ -234,7 +198,6 @@ public with sharing class RelatedLogEntriesController { this.label = LOG_ENTRY_SOBJECT_TYPE.getDescribe().getLabel(); this.labelPlural = LOG_ENTRY_SOBJECT_TYPE.getDescribe().getLabelPlural(); this.records = records; - this.tabIcon = getTabIcon(LOG_SOBJECT_TYPE); this.totalLogEntriesCount = totalLogEntriesCount; } } diff --git a/nebula-logger/core/main/log-management/flexipages/LogEntryRecordPage.flexipage-meta.xml b/nebula-logger/core/main/log-management/flexipages/LogEntryRecordPage.flexipage-meta.xml index fec8cef86..d4f2f92db 100644 --- a/nebula-logger/core/main/log-management/flexipages/LogEntryRecordPage.flexipage-meta.xml +++ b/nebula-logger/core/main/log-management/flexipages/LogEntryRecordPage.flexipage-meta.xml @@ -74,6 +74,16 @@ RecordTimestamp__cField + + + + uiBehavior + readonly + + Record.EntryScenario__c + RecordEntryScenario__cField + + Facet-cb40f95d-9915-4ba5-815c-f3e53bcc4001 Facet diff --git a/nebula-logger/core/main/log-management/flexipages/LoggerScenarioRecordPage.flexipage-meta.xml b/nebula-logger/core/main/log-management/flexipages/LoggerScenarioRecordPage.flexipage-meta.xml index 6d62b2c12..52511ad56 100644 --- a/nebula-logger/core/main/log-management/flexipages/LoggerScenarioRecordPage.flexipage-meta.xml +++ b/nebula-logger/core/main/log-management/flexipages/LoggerScenarioRecordPage.flexipage-meta.xml @@ -60,6 +60,36 @@ relatedTabContent Facet + + + + + parentFieldApiName + LoggerScenario__c.Id + + + relatedListApiName + LogEntries__r + + + relatedListComponentOverride + ADVGRID + + + rowsToDisplay + 30 + + + showActionBar + true + + force:relatedListSingleContainer + force_relatedListSingleContainer3 + + + Facet-bf77ace2-6cee-4ca4-88b4-990633a74278 + Facet + @@ -123,6 +153,20 @@ relatedListsTab + + + + body + Facet-bf77ace2-6cee-4ca4-88b4-990633a74278 + + + title + Log Entries + + flexipage:tab + flexipage_tab3 + + diff --git a/nebula-logger/core/main/log-management/layouts/LogEntry__c-Log Entry Layout.layout-meta.xml b/nebula-logger/core/main/log-management/layouts/LogEntry__c-Log Entry Layout.layout-meta.xml index af7eae2f0..7184402f5 100644 --- a/nebula-logger/core/main/log-management/layouts/LogEntry__c-Log Entry Layout.layout-meta.xml +++ b/nebula-logger/core/main/log-management/layouts/LogEntry__c-Log Entry Layout.layout-meta.xml @@ -31,7 +31,7 @@ Readonly - EpochTimestamp__c + EntryScenario__c @@ -455,7 +455,7 @@ false false - 00h1k000003yap8 + 00h63000007CAv9 4 0 Default diff --git a/nebula-logger/core/main/log-management/layouts/Log__c-Log Layout.layout-meta.xml b/nebula-logger/core/main/log-management/layouts/Log__c-Log Layout.layout-meta.xml index c3c3dda3e..ee61a07f3 100644 --- a/nebula-logger/core/main/log-management/layouts/Log__c-Log Layout.layout-meta.xml +++ b/nebula-logger/core/main/log-management/layouts/Log__c-Log Layout.layout-meta.xml @@ -365,6 +365,7 @@ Origin__c Message__c RecordDetailedLink__c + EntryScenario__c LoggingLevelWithImage__c TransactionEntryNumber__c LogEntry__c.Log__c diff --git a/nebula-logger/core/main/log-management/layouts/LoggerScenario__c-Logger Scenario Layout.layout-meta.xml b/nebula-logger/core/main/log-management/layouts/LoggerScenario__c-Logger Scenario Layout.layout-meta.xml index 3ecec04c0..2a123fa3f 100644 --- a/nebula-logger/core/main/log-management/layouts/LoggerScenario__c-Logger Scenario Layout.layout-meta.xml +++ b/nebula-logger/core/main/log-management/layouts/LoggerScenario__c-Logger Scenario Layout.layout-meta.xml @@ -103,13 +103,27 @@ StartTime__c Desc + + New + NAME + LoggedByUsernameLink__c + LoggingLevelWithImage__c + Log__c + LogTransactionId__c + OriginType__c + OriginLocation__c + Timestamp__c + LogEntry__c.EntryScenario__c + Timestamp__c + Desc + false false false false false - 00h63000007c9rO + 00h63000007ebDj 4 0 Default diff --git a/nebula-logger/core/main/log-management/lwc/logEntryEventStream/logEntryEventStream.html b/nebula-logger/core/main/log-management/lwc/logEntryEventStream/logEntryEventStream.html index 68228387c..c1500d0e5 100644 --- a/nebula-logger/core/main/log-management/lwc/logEntryEventStream/logEntryEventStream.html +++ b/nebula-logger/core/main/log-management/lwc/logEntryEventStream/logEntryEventStream.html @@ -40,9 +40,9 @@ >