diff --git a/.gitignore b/.gitignore index 0328057e8..635620af6 100644 --- a/.gitignore +++ b/.gitignore @@ -9,12 +9,6 @@ test-coverage/ temp/ -# Additional folders that are temporarily copied when creating a version of the managed package -nebula-logger/managed-package/core/main/configuration/ -nebula-logger/managed-package/core/main/log-management/ -nebula-logger/managed-package/core/main/logger-engine/ -nebula-logger/managed-package/core/tests/ - # NPM node_modules/ yarn.lock diff --git a/README.md b/README.md index ce4f0b5c5..79920c913 100644 --- a/README.md +++ b/README.md @@ -5,13 +5,13 @@ The most robust logger for Salesforce. Works with Apex, Lightning Components, Flow, Process Builder & Integrations. Designed for Salesforce admins, developers & architects. -## Unlocked Package - v4.10.5 +## Unlocked Package - v4.10.6 -[![Install Unlocked Package in a Sandbox](./images/btn-install-unlocked-package-sandbox.png)](https://test.salesforce.com/packaging/installPackage.apexp?p0=04t5Y0000023SCHQA2) -[![Install Unlocked Package in Production](./images/btn-install-unlocked-package-production.png)](https://login.salesforce.com/packaging/installPackage.apexp?p0=04t5Y0000023SCHQA2) +[![Install Unlocked Package in a Sandbox](./images/btn-install-unlocked-package-sandbox.png)](https://test.salesforce.com/packaging/installPackage.apexp?p0=04t5Y0000023SCqQAM) +[![Install Unlocked Package in Production](./images/btn-install-unlocked-package-production.png)](https://login.salesforce.com/packaging/installPackage.apexp?p0=04t5Y0000023SCqQAM) [![View Documentation](./images/btn-view-documentation.png)](https://jongpie.github.io/NebulaLogger/) -`sfdx package install --wait 20 --security-type AdminsOnly --package 04t5Y0000023SCHQA2` +`sfdx package install --wait 20 --security-type AdminsOnly --package 04t5Y0000023SCqQAM` ## Managed Package - v4.10.0 diff --git a/config/linters/.eslintrc.json b/config/linters/.eslintrc.json index 6676eb429..5a7867158 100644 --- a/config/linters/.eslintrc.json +++ b/config/linters/.eslintrc.json @@ -18,7 +18,7 @@ "@lwc/lwc/no-attributes-during-construction": "error", "@lwc/lwc/no-deprecated": "error", "@lwc/lwc/no-document-query": "error", - "@lwc/lwc/no-dupe-class-members": "error", + "@lwc/lwc/no-dupe-class-members": "warn", "@lwc/lwc/no-inner-html": "error", "@lwc/lwc/no-leading-uppercase-api-name": "error", "@lwc/lwc/prefer-custom-event": "error", diff --git a/config/linters/lint-staged.config.js b/config/linters/lint-staged.config.js index 33f406577..8d1693a3a 100644 --- a/config/linters/lint-staged.config.js +++ b/config/linters/lint-staged.config.js @@ -5,9 +5,10 @@ module.exports = { '*.{cls,cmp,component,css,html,js,json,md,page,trigger,yaml,yml}': filenames => filenames.map(filename => `prettier --write '${filename}'`), '**/lwc/**': filenames => { return [`eslint --config ./config/linters/.eslintrc.json ${filenames.join(' ')} --fix`, `npm run test:lwc`]; - }, - '*.{cls,trigger}': () => { - return [`npm run scan:apex`]; - // return [`npm run scan:apex`, `npm run docs:fix && git add ./docs/ && git commit --amend --no-edit`]; } + // FIXME this command should only scan the changed Apex files (instead of scanning all Apex files) + // '*.{cls,trigger}': () => { + // return [`npm run scan:apex`]; + // // return [`npm run scan:apex`, `npm run docs:fix && git add ./docs/ && git commit --amend --no-edit`]; + // } }; diff --git a/docs/apex/Log-Management/LogBatchPurgeController.md b/docs/apex/Log-Management/LogBatchPurgeController.md index b26b43434..025c72178 100644 --- a/docs/apex/Log-Management/LogBatchPurgeController.md +++ b/docs/apex/Log-Management/LogBatchPurgeController.md @@ -24,6 +24,20 @@ Boolean true if the current user has delete permission on the Log\_\_c object. +#### `getBatchPurgeJobRecords()` → `List` + +Returns `List<AsyncApexJob>` to display logBatchPurger jobs details in a Datatable. + +##### Return + +**Type** + +List<AsyncApexJob> + +**Description** + +The instance of `List<AsyncApexJob>`, containing list of logBatchPurge jobs. + #### `getMetrics(String dateFilterOption)` → `Map` return a `Map<String,Object>` contains metrics for number of `Log__c`, `LogEntry__c`, `LogEntryTag__c` records to purge, for the given timeframe TODAY/ THIS_WEEK/ THIS_MONTH. The metrics is grouped by `Log__c.LogPurgeAction__c`. @@ -58,20 +72,6 @@ List<PicklistOption> The instance of `List<PicklistOption>`, containing all picklist options for purge Action. -#### `getBatchPurgeJobRecords()` → `List` - -Returns `List<AsyncApexJob>` to display logBatchPurger jobs details in a Datatable. - -##### Return - -**Type** - -List<AsyncApexJob> - -**Description** - -The instance of `List<AsyncApexJob>`, containing list of logBatchPurge jobs. - #### `runBatchPurge()` → `String` execute the logBatchPurger batch with batch size 2000 diff --git a/docs/apex/Logger-Engine/ComponentLogger.md b/docs/apex/Logger-Engine/ComponentLogger.md index 89a2542e2..715d9b757 100644 --- a/docs/apex/Logger-Engine/ComponentLogger.md +++ b/docs/apex/Logger-Engine/ComponentLogger.md @@ -85,6 +85,30 @@ A DTO object used to create log entries for lightning components ##### Properties +###### `browserFormFactor` → `String` + +The form factor of the user's browser + +###### `browserLanguage` → `String` + +The language set in the user's browser + +###### `browserScreenResolution` → `String` + +The resolution of the user's device + +###### `browserUrl` → `String` + +The URL displayed in the user's browser + +###### `browserUserAgent` → `String` + +The user agent of the user's browser + +###### `browserWindowResolution` → `String` + +The resolution of the user's browser window + ###### `error` → `ComponentError` (Optional) A JavaScript Error to log diff --git a/docs/apex/Logger-Engine/Logger.md b/docs/apex/Logger-Engine/Logger.md index 7b0b171ba..c347ce12a 100644 --- a/docs/apex/Logger-Engine/Logger.md +++ b/docs/apex/Logger-Engine/Logger.md @@ -5628,8 +5628,6 @@ Asynchronoulsy publishes the list of `LogEntryEvent__e` records Boolean used when saving records. If true, all records must save correctly or an exception is thrown. If false, partial processing is enabled, and if an indidividual record fails, successful records are still saved without exception. -###### `environment` → `String` - ###### `location` → `String` ###### `maintenanceWindow` → `String` @@ -5642,8 +5640,6 @@ List of records to save. ###### `releaseVersion` → `String` -###### `status` → `String` - --- ##### Methods diff --git a/docs/lightning-components/LogEntryBuilder.md b/docs/lightning-components/LogEntryBuilder.md index 39be58ffd..ce66c3108 100644 --- a/docs/lightning-components/LogEntryBuilder.md +++ b/docs/lightning-components/LogEntryBuilder.md @@ -12,6 +12,7 @@ - [.setError(error)](#LogEntryBuilder+setError) [LogEntryBuilder](#LogEntryBuilder) - [.addTag(tag)](#LogEntryBuilder+addTag) [LogEntryBuilder](#LogEntryBuilder) - [.addTags(tags)](#LogEntryBuilder+addTags) [LogEntryBuilder](#LogEntryBuilder) + - [.getComponentLogEntry()](#LogEntryBuilder+getComponentLogEntry) ComponentLogEntry @@ -102,3 +103,12 @@ Appends the tag to the existing list of tags | Param | Type | Description | | ----- | --------------------------------- | -------------------------------------------------------- | | tags | Array.<String> | The list of strings to add as tags for the current entry | + + + +### logEntryBuilder.getComponentLogEntry() ComponentLogEntry + +Returns the object used to save log entry data + +**Kind**: instance method of [LogEntryBuilder](#LogEntryBuilder) +**Returns**: ComponentLogEntry - An instance of `ComponentLogEntry` that matches the Apex class `ComponentLogger.ComponentLogEntry` diff --git a/nebula-logger/core/main/log-management/classes/LogEntryEventHandler.cls b/nebula-logger/core/main/log-management/classes/LogEntryEventHandler.cls index 8643e5492..ccc4bb3f7 100644 --- a/nebula-logger/core/main/log-management/classes/LogEntryEventHandler.cls +++ b/nebula-logger/core/main/log-management/classes/LogEntryEventHandler.cls @@ -141,8 +141,12 @@ public without sharing class LogEntryEventHandler extends LoggerSObjectHandler { } Log__c log = new Log__c( + // TODO Log__c.ApiReleaseNumber__c and Log__c.ApiReleaseVersion__c are both deprecated, + // in a future release, remove these reference (and delete the fields) ApiReleaseNumber__c = recentLogWithApiReleaseDetails?.ApiReleaseNumber__c, ApiReleaseVersion__c = recentLogWithApiReleaseDetails?.ApiReleaseVersion__c, + // TODO Log__c.ApiVersion__c and LogEntryEvent__e.ApiVersion__c are both deprecated, + // in a future release, remove this reference (and delete the fields) ApiVersion__c = logEntryEvent.ApiVersion__c, ImpersonatedBy__c = logEntryEvent.ImpersonatedById__c, Locale__c = logEntryEvent.Locale__c, @@ -162,12 +166,15 @@ public without sharing class LogEntryEventHandler extends LoggerSObjectHandler { NetworkName__c = logEntryEvent.NetworkName__c, NetworkSelfRegistrationUrl__c = logEntryEvent.NetworkSelfRegistrationUrl__c, NetworkUrlPathPrefix__c = logEntryEvent.NetworkUrlPathPrefix__c, + OrganizationApiVersion__c = logEntryEvent.OrganizationApiVersion__c, OrganizationDomainUrl__c = logEntryEvent.OrganizationDomainUrl__c, OrganizationEnvironmentType__c = logEntryEvent.OrganizationEnvironmentType__c, OrganizationId__c = logEntryEvent.OrganizationId__c, OrganizationInstanceName__c = logEntryEvent.OrganizationInstanceName__c, OrganizationName__c = logEntryEvent.OrganizationName__c, OrganizationNamespacePrefix__c = logEntryEvent.OrganizationNamespacePrefix__c, + OrganizationReleaseNumber__c = recentLogWithApiReleaseDetails?.OrganizationReleaseNumber__c, + OrganizationReleaseVersion__c = recentLogWithApiReleaseDetails?.OrganizationReleaseVersion__c, OrganizationType__c = logEntryEvent.OrganizationType__c, OwnerId = this.determineLogOwnerId(logEntryEvent), ParentLogTransactionId__c = logEntryEvent.ParentLogTransactionId__c, @@ -244,6 +251,12 @@ public without sharing class LogEntryEventHandler extends LoggerSObjectHandler { } LogEntry__c logEntry = new LogEntry__c( + BrowserFormFactor__c = logEntryEvent.BrowserFormFactor__c, + BrowserLanguage__c = logEntryEvent.BrowserLanguage__c, + BrowserScreenResolution__c = logEntryEvent.BrowserScreenResolution__c, + BrowserUrl__c = logEntryEvent.BrowserUrl__c, + BrowserUserAgent__c = logEntryEvent.BrowserUserAgent__c, + BrowserWindowResolution__c = logEntryEvent.BrowserWindowResolution__c, ComponentType__c = logEntryEvent.ComponentType__c, DatabaseResultCollectionSize__c = logEntryEvent.DatabaseResultCollectionSize__c, DatabaseResultCollectionType__c = logEntryEvent.DatabaseResultCollectionType__c, @@ -692,14 +705,14 @@ public without sharing class LogEntryEventHandler extends LoggerSObjectHandler { WHERE Id IN :this.logIds AND ApiReleaseNumber__c = NULL LIMIT :System.Limits.getLimitDmlRows() ]) { - // TODO Logger.ApiResponse has new properties that aren't currently being captured here, - // so in a future release, add new custom fields to capture more (all?) properties - // - environment - // - location - // - maintenanceWindow - // ✔ releaseNumber - // ✔ releaseVersion - // - status + log.OrganizationLocation__c = statusApiResponse.location; + log.OrganizationReleaseNumber__c = statusApiResponse.releaseNumber; + log.OrganizationReleaseVersion__c = statusApiResponse.releaseVersion; + + // TODO ApiReleaseNumber__c and ApiReleaseVersion__c are deprecated as of v4.10.6 + // For now, they're still set so orgs have time to migrate to the new fields, but in + // a future release, ApiReleaseNumber__c and ApiReleaseVersion__c should be completely + // remove from the codebase log.ApiReleaseNumber__c = statusApiResponse.releaseNumber; log.ApiReleaseVersion__c = statusApiResponse.releaseVersion; diff --git a/nebula-logger/core/main/log-management/classes/LogEntryHandler.cls b/nebula-logger/core/main/log-management/classes/LogEntryHandler.cls index a376d93ab..bb44739e2 100644 --- a/nebula-logger/core/main/log-management/classes/LogEntryHandler.cls +++ b/nebula-logger/core/main/log-management/classes/LogEntryHandler.cls @@ -140,6 +140,10 @@ public without sharing class LogEntryHandler extends LoggerSObjectHandler { for (LogEntry__c logEntry : flowLogEntries) { FlowDefinitionView flowDefinition = flowApiNameToDefinition.get(logEntry.OriginLocation__c); + if (flowDefinition == null) { + continue; + } + logEntry.FlowActiveVersionId__c = flowDefinition.ActiveVersionId; logEntry.FlowDescription__c = flowDefinition.Description; logEntry.FlowDurableId__c = flowDefinition.DurableId; @@ -147,6 +151,9 @@ public without sharing class LogEntryHandler extends LoggerSObjectHandler { logEntry.FlowLastModifiedByName__c = flowDefinition.LastModifiedBy; logEntry.FlowLastModifiedDate__c = flowDefinition.LastModifiedDate; logEntry.FlowProcessType__c = flowDefinition.ProcessType; + logEntry.FlowRecordTriggerType__c = flowDefinition.RecordTriggerType; + logEntry.FlowTriggerOrder__c = flowDefinition.TriggerOrder; + logEntry.FlowTriggerSObjectType__c = flowDefinition.TriggerObjectOrEvent?.QualifiedApiName; logEntry.FlowTriggerType__c = flowDefinition.TriggerType; } } diff --git a/nebula-logger/core/main/log-management/classes/LogManagementDataSelector.cls b/nebula-logger/core/main/log-management/classes/LogManagementDataSelector.cls index 0fe46412e..a308fb26e 100644 --- a/nebula-logger/core/main/log-management/classes/LogManagementDataSelector.cls +++ b/nebula-logger/core/main/log-management/classes/LogManagementDataSelector.cls @@ -101,7 +101,7 @@ public without sharing virtual class LogManagementDataSelector { Datetime fourHoursAgo = System.now().addMinutes(-4 * 60); List logs = [ - SELECT Id, ApiReleaseNumber__c, ApiReleaseVersion__c + SELECT Id, ApiReleaseNumber__c, ApiReleaseVersion__c, OrganizationReleaseNumber__c, OrganizationReleaseVersion__c FROM Log__c WHERE CreatedDate >= :fourHoursAgo AND CreatedDate = TODAY AND ApiReleaseNumber__c != NULL ORDER BY CreatedDate DESC @@ -162,7 +162,11 @@ public without sharing virtual class LogManagementDataSelector { LastModifiedDate, ManageableState, ProcessType, - TriggerType + RecordTriggerType, + TriggerObjectOrEvent.QualifiedApiName, + TriggerOrder, + TriggerType, + VersionNumber FROM FlowDefinitionView WHERE ApiName IN :flowApiNames AND IsActive = TRUE ]; diff --git a/nebula-logger/core/main/log-management/classes/LoggerHomeHeaderController.cls b/nebula-logger/core/main/log-management/classes/LoggerHomeHeaderController.cls index c91f2bd80..11174b441 100644 --- a/nebula-logger/core/main/log-management/classes/LoggerHomeHeaderController.cls +++ b/nebula-logger/core/main/log-management/classes/LoggerHomeHeaderController.cls @@ -30,12 +30,10 @@ public without sharing class LoggerHomeHeaderController { Logger.StatusApiResponse statusApiResponse = Logger.callStatusApi(); if (statusApiResponse != null) { - environment.organizationEnvironment = statusApiResponse.environment; environment.organizationInstanceLocation = statusApiResponse.location; environment.organizationMaintenanceWindow = statusApiResponse.maintenanceWindow; environment.organizationReleaseNumber = statusApiResponse.releaseNumber; environment.organizationReleaseVersion = statusApiResponse.releaseVersion; - environment.organizationStatus = statusApiResponse.status; if (statusApiResponse.Products != null && statusApiResponse.Products.isEmpty() == false) { environment.organizationInstanceProducts = getInstanceProductNames(statusApiResponse); @@ -66,8 +64,6 @@ public without sharing class LoggerHomeHeaderController { @AuraEnabled public String organizationDomainUrl = 'Unknown'; @AuraEnabled - public String organizationEnvironment = 'Unknown'; - @AuraEnabled public String organizationFormattedCreatedDate = 'Unknown'; @AuraEnabled public String organizationId = 'Unknown'; @@ -86,8 +82,6 @@ public without sharing class LoggerHomeHeaderController { @AuraEnabled public String organizationReleaseVersion = 'Unknown'; @AuraEnabled - public String organizationStatus = 'Unknown'; - @AuraEnabled public String organizationType = 'Unknown'; } } 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 2891c8e28..5f150e264 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 @@ -1153,6 +1153,36 @@ RecordFlowTriggerType__cField + + + + uiBehavior + none + + Record.FlowTriggerSObjectType__c + RecordFlowTriggerSObjectType_cField + + + + + + uiBehavior + none + + Record.FlowTriggerOrder__c + RecordFlowTriggerOrder_cField + + + + + + uiBehavior + none + + Record.FlowRecordTriggerType__c + RecordFlowRecordTriggerType_cField + + Facet-17586de5-b418-46c3-8e43-07f6a5e7321a Facet @@ -1276,6 +1306,98 @@ Facet-6b39517d-52f9-42f2-bf33-d392592baaa4 Facet + + + + + uiBehavior + none + + Record.BrowserUserAgent__c + RecordBrowserUserAgent_cField + + + + + + uiBehavior + none + + Record.BrowserUrl__c + RecordBrowserUrl_cField + + + + + + uiBehavior + none + + Record.BrowserLanguage__c + RecordBrowserLanguage_cField + + + Facet-2dc994c6-5590-48da-8d0a-5f81b3755c5d + Facet + + + + + + uiBehavior + none + + Record.BrowserFormFactor__c + RecordBrowserFormFactor_cField + + + + + + uiBehavior + none + + Record.BrowserWindowResolution__c + RecordBrowserWindowResolution_cField + + + + + + uiBehavior + none + + Record.BrowserScreenResolution__c + RecordBrowserScreenResolution_cField + + + Facet-a07ca2be-bb73-4048-9b60-7392cf56866a + Facet + + + + + + body + Facet-2dc994c6-5590-48da-8d0a-5f81b3755c5d + + flexipage:column + flexipage_column17 + + + + + + body + Facet-a07ca2be-bb73-4048-9b60-7392cf56866a + + flexipage:column + flexipage_column18 + + + Facet-81767854-f045-476a-a24f-aa790ad2f249 + Facet + @@ -1402,6 +1524,26 @@ + + + + columns + Facet-81767854-f045-476a-a24f-aa790ad2f249 + + + label + Browser Information + + flexipage:fieldSection + flexipage_fieldSection12 + + + {!Record.BrowserUserAgent__c} + NE + + + + sidebar Region diff --git a/nebula-logger/core/main/log-management/flexipages/LogRecordPage.flexipage-meta.xml b/nebula-logger/core/main/log-management/flexipages/LogRecordPage.flexipage-meta.xml index 6c2ff17a3..b28aecf22 100644 --- a/nebula-logger/core/main/log-management/flexipages/LogRecordPage.flexipage-meta.xml +++ b/nebula-logger/core/main/log-management/flexipages/LogRecordPage.flexipage-meta.xml @@ -854,30 +854,40 @@ uiBehavior - readonly + none - Record.ApiVersion__c - RecordApiVersion__cField + Record.OrganizationLocation__c + RecordOrganizationLocation_cField uiBehavior - readonly + none - Record.ApiReleaseVersion__c - RecordApiReleaseVersion__cField + Record.OrganizationApiVersion__c + RecordOrganizationApiVersion_cField uiBehavior - readonly + none + + Record.OrganizationReleaseNumber__c + RecordOrganizationReleaseNumber_cField + + + + + + uiBehavior + none - Record.ApiReleaseNumber__c - RecordApiReleaseNumber__cField + Record.OrganizationReleaseVersion__c + RecordOrganizationReleaseVersion_cField Facet-7a49dd50-62e1-43c4-a95b-81a04f2e4a8e 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 8d2c24d72..ba1d2a141 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 @@ -122,6 +122,41 @@ + + true + true + true + + + + Edit + BrowserUserAgent__c + + + Edit + BrowserUrl__c + + + Edit + BrowserLanguage__c + + + + + Edit + BrowserFormFactor__c + + + Edit + BrowserScreenResolution__c + + + Edit + BrowserWindowResolution__c + + + + true true @@ -163,6 +198,18 @@ Readonly FlowTriggerType__c + + Readonly + FlowTriggerSObjectType__c + + + Readonly + FlowTriggerOrder__c + + + Readonly + FlowRecordTriggerType__c + Readonly FlowVersionRunInMode__c @@ -455,7 +502,7 @@ false false - 00h63000007CAv9 + 00hDE00000AG9kW 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 228676262..b7e5afbcf 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 @@ -294,15 +294,19 @@ Readonly - ApiVersion__c + OrganizationLocation__c Readonly - ApiReleaseVersion__c + OrganizationApiVersion__c Readonly - ApiReleaseNumber__c + OrganizationReleaseVersion__c + + + Readonly + OrganizationReleaseNumber__c diff --git a/nebula-logger/core/main/log-management/lwc/loggerHomeHeader/__tests__/loggerHomeHeader.test.js b/nebula-logger/core/main/log-management/lwc/loggerHomeHeader/__tests__/loggerHomeHeader.test.js index e06316c04..99144ad11 100644 --- a/nebula-logger/core/main/log-management/lwc/loggerHomeHeader/__tests__/loggerHomeHeader.test.js +++ b/nebula-logger/core/main/log-management/lwc/loggerHomeHeader/__tests__/loggerHomeHeader.test.js @@ -7,7 +7,6 @@ const MOCK_ENVIRONMENT_DETAILS = { loggerVersionNumber: 'v4.10.4', organizationApiVersion: 'v57.0', organizationCreatedByUsername: 'some.username@test.com', - organizationEnvironment: 'sandbox', organizationFormattedCreatedDate: '5/22/2023, 2:09 PM', organizationId: '00D8G000000E1S9UAK', organizationInstanceLocation: 'NA', @@ -77,7 +76,6 @@ describe('c-logger-home-header', () => { 'environment-organizationId': MOCK_ENVIRONMENT_DETAILS.organizationId, 'environment-organizationName': MOCK_ENVIRONMENT_DETAILS.organizationName, 'environment-organizationType': MOCK_ENVIRONMENT_DETAILS.organizationType, - 'environment-organizationEnvironment': MOCK_ENVIRONMENT_DETAILS.organizationEnvironment, 'environment-organizationInstanceName': MOCK_ENVIRONMENT_DETAILS.organizationInstanceName, 'environment-organizationInstanceLocation': MOCK_ENVIRONMENT_DETAILS.organizationInstanceLocation, 'environment-organizationInstanceProducts': MOCK_ENVIRONMENT_DETAILS.organizationInstanceProducts, diff --git a/nebula-logger/core/main/log-management/lwc/loggerHomeHeader/loggerHomeHeader.html b/nebula-logger/core/main/log-management/lwc/loggerHomeHeader/loggerHomeHeader.html index 55e708298..78f7cf346 100644 --- a/nebula-logger/core/main/log-management/lwc/loggerHomeHeader/loggerHomeHeader.html +++ b/nebula-logger/core/main/log-management/lwc/loggerHomeHeader/loggerHomeHeader.html @@ -116,14 +116,6 @@

value={environment.organizationType} variant="label-inline" > - + + BrowserFormFactor__c + Active + None + false + + false + Confidential + true + false + Picklist + + + false + + Large + false + + + + Medium + false + + + + Small + false + + + + + diff --git a/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/BrowserLanguage__c.field-meta.xml b/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/BrowserLanguage__c.field-meta.xml new file mode 100644 index 000000000..14e4f669f --- /dev/null +++ b/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/BrowserLanguage__c.field-meta.xml @@ -0,0 +1,12 @@ + + + BrowserLanguage__c + false + + 255 + false + false + false + Text + false + diff --git a/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/BrowserScreenResolution__c.field-meta.xml b/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/BrowserScreenResolution__c.field-meta.xml new file mode 100644 index 000000000..782101af3 --- /dev/null +++ b/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/BrowserScreenResolution__c.field-meta.xml @@ -0,0 +1,12 @@ + + + BrowserScreenResolution__c + false + + 255 + false + false + false + Text + false + diff --git a/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/BrowserUrl__c.field-meta.xml b/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/BrowserUrl__c.field-meta.xml new file mode 100644 index 000000000..f504dd1fe --- /dev/null +++ b/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/BrowserUrl__c.field-meta.xml @@ -0,0 +1,10 @@ + + + BrowserUrl__c + false + + false + false + false + Url + diff --git a/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/BrowserUserAgent__c.field-meta.xml b/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/BrowserUserAgent__c.field-meta.xml new file mode 100644 index 000000000..55388c7ab --- /dev/null +++ b/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/BrowserUserAgent__c.field-meta.xml @@ -0,0 +1,15 @@ + + + BrowserUserAgent__c + Active + None + false + + 255 + false + Confidential + false + false + Text + false + diff --git a/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/BrowserWindowResolution__c.field-meta.xml b/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/BrowserWindowResolution__c.field-meta.xml new file mode 100644 index 000000000..cfa057f7f --- /dev/null +++ b/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/BrowserWindowResolution__c.field-meta.xml @@ -0,0 +1,12 @@ + + + BrowserWindowResolution__c + false + + 255 + false + false + false + Text + false + diff --git a/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/FlowLastModifiedByName__c.field-meta.xml b/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/FlowLastModifiedByName__c.field-meta.xml index c6965d8c6..1026c9d64 100644 --- a/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/FlowLastModifiedByName__c.field-meta.xml +++ b/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/FlowLastModifiedByName__c.field-meta.xml @@ -2,7 +2,7 @@ FlowLastModifiedByName__c Active - CCPA;GDPR;PII + PII;GDPR;CCPA For more details, refer to https://developer.salesforce.com/docs/atlas.en-us.object_reference.meta/object_reference/sforce_api_objects_flowdefinitionview.htm false diff --git a/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/FlowLastModifiedDate__c.field-meta.xml b/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/FlowLastModifiedDate__c.field-meta.xml index 43f7ac934..5269b9add 100644 --- a/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/FlowLastModifiedDate__c.field-meta.xml +++ b/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/FlowLastModifiedDate__c.field-meta.xml @@ -2,7 +2,7 @@ FlowLastModifiedDate__c Active - CCPA;GDPR;PII + PII;GDPR;CCPA For more details, refer to https://developer.salesforce.com/docs/atlas.en-us.object_reference.meta/object_reference/sforce_api_objects_flowdefinitionview.htm false diff --git a/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/FlowRecordTriggerType__c.field-meta.xml b/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/FlowRecordTriggerType__c.field-meta.xml new file mode 100644 index 000000000..62753407c --- /dev/null +++ b/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/FlowRecordTriggerType__c.field-meta.xml @@ -0,0 +1,66 @@ + + + FlowRecordTriggerType__c + Active + None + For more details, refer to https://developer.salesforce.com/docs/atlas.en-us.object_reference.meta/object_reference/sforce_api_objects_flowdefinitionview.htm + false + Specifies what causes the flow to run. + + false + Confidential + false + false + Picklist + + + false + + Create + false + + + + CreateAndUpdate + false + + + + Delete + false + + + + None + false + + + + Update + false + + + + PlatformEvent + false + + + + RecordAfterSave + false + + + + RecordBeforeSave + false + + + + Scheduled + false + + + + + diff --git a/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/FlowTriggerOrder__c.field-meta.xml b/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/FlowTriggerOrder__c.field-meta.xml new file mode 100644 index 000000000..e1386cb63 --- /dev/null +++ b/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/FlowTriggerOrder__c.field-meta.xml @@ -0,0 +1,19 @@ + + + FlowTriggerOrder__c + Active + None + For more details, refer to https://developer.salesforce.com/docs/atlas.en-us.object_reference.meta/object_reference/sforce_api_objects_flowdefinitionview.htm + false + The run order of a record-triggered flow, from 1 to 2,000. + + 10 + false + 0 + Confidential + false + false + Number + false + diff --git a/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/FlowTriggerSObjectType__c.field-meta.xml b/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/FlowTriggerSObjectType__c.field-meta.xml new file mode 100644 index 000000000..83c438c55 --- /dev/null +++ b/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/FlowTriggerSObjectType__c.field-meta.xml @@ -0,0 +1,43 @@ + + + FlowTriggerSObjectType__c + Active + None + false + + false + Confidential + true + false + Picklist + + + false + + Account + false + + + + Case + false + + + + Lead + false + + + + Unknown + false + + + + User + false + + + + + diff --git a/nebula-logger/core/main/log-management/objects/Log__c/fields/ApiReleaseNumber__c.field-meta.xml b/nebula-logger/core/main/log-management/objects/Log__c/fields/ApiReleaseNumber__c.field-meta.xml index 0d4a20e76..57141a679 100644 --- a/nebula-logger/core/main/log-management/objects/Log__c/fields/ApiReleaseNumber__c.field-meta.xml +++ b/nebula-logger/core/main/log-management/objects/Log__c/fields/ApiReleaseNumber__c.field-meta.xml @@ -1,12 +1,12 @@ ApiReleaseNumber__c - Active + DeprecateCandidate None The release number for the org's instance - determined by making a callout to status.salesforce.com false The release number for the org's instance - determined by making a callout to status.salesforce.com - + 255 false Confidential diff --git a/nebula-logger/core/main/log-management/objects/Log__c/fields/ApiReleaseVersion__c.field-meta.xml b/nebula-logger/core/main/log-management/objects/Log__c/fields/ApiReleaseVersion__c.field-meta.xml index 46087ac45..20cbc5628 100644 --- a/nebula-logger/core/main/log-management/objects/Log__c/fields/ApiReleaseVersion__c.field-meta.xml +++ b/nebula-logger/core/main/log-management/objects/Log__c/fields/ApiReleaseVersion__c.field-meta.xml @@ -1,12 +1,12 @@ ApiReleaseVersion__c - Active + DeprecateCandidate None The release version for the org's instance - determined by making a callout to status.salesforce.com false The release version for the org's instance - determined by making a callout to status.salesforce.com - + 255 false Confidential diff --git a/nebula-logger/core/main/log-management/objects/Log__c/fields/ApiVersion__c.field-meta.xml b/nebula-logger/core/main/log-management/objects/Log__c/fields/ApiVersion__c.field-meta.xml index 51b4f2bd0..8a0476fce 100644 --- a/nebula-logger/core/main/log-management/objects/Log__c/fields/ApiVersion__c.field-meta.xml +++ b/nebula-logger/core/main/log-management/objects/Log__c/fields/ApiVersion__c.field-meta.xml @@ -1,12 +1,12 @@ ApiVersion__c - Active + DeprecateCandidate None The Salesforce release (API version) of the environment false The Salesforce release (API version) of the environment - + false Confidential false diff --git a/nebula-logger/core/main/log-management/objects/Log__c/fields/OrganizationApiVersion__c.field-meta.xml b/nebula-logger/core/main/log-management/objects/Log__c/fields/OrganizationApiVersion__c.field-meta.xml new file mode 100644 index 000000000..0f53b238a --- /dev/null +++ b/nebula-logger/core/main/log-management/objects/Log__c/fields/OrganizationApiVersion__c.field-meta.xml @@ -0,0 +1,31 @@ + + + OrganizationApiVersion__c + Active + None + The Salesforce release (API version) of the environment + false + The Salesforce release (API version) of the environment + + false + Confidential + false + false + false + Picklist + + + false + + v58.0 + false + + + + v57.0 + false + + + + + diff --git a/nebula-logger/core/main/log-management/objects/Log__c/fields/OrganizationLocation__c.field-meta.xml b/nebula-logger/core/main/log-management/objects/Log__c/fields/OrganizationLocation__c.field-meta.xml new file mode 100644 index 000000000..a20cd56eb --- /dev/null +++ b/nebula-logger/core/main/log-management/objects/Log__c/fields/OrganizationLocation__c.field-meta.xml @@ -0,0 +1,35 @@ + + + OrganizationLocation__c + Active + None + false + + false + Confidential + true + true + false + Picklist + + true + + false + + APAC + false + + + + EMEA + false + + + + NA + false + + + + + diff --git a/nebula-logger/core/main/log-management/objects/Log__c/fields/OrganizationReleaseNumber__c.field-meta.xml b/nebula-logger/core/main/log-management/objects/Log__c/fields/OrganizationReleaseNumber__c.field-meta.xml new file mode 100644 index 000000000..7c550fcad --- /dev/null +++ b/nebula-logger/core/main/log-management/objects/Log__c/fields/OrganizationReleaseNumber__c.field-meta.xml @@ -0,0 +1,18 @@ + + + OrganizationReleaseNumber__c + Active + None + The release number for the org's instance - determined by making a callout to status.salesforce.com + false + The release number for the org's instance - determined by making a callout to status.salesforce.com + + 255 + false + Confidential + false + false + false + Text + false + diff --git a/nebula-logger/core/main/log-management/objects/Log__c/fields/OrganizationReleaseVersion__c.field-meta.xml b/nebula-logger/core/main/log-management/objects/Log__c/fields/OrganizationReleaseVersion__c.field-meta.xml new file mode 100644 index 000000000..1d34c27f3 --- /dev/null +++ b/nebula-logger/core/main/log-management/objects/Log__c/fields/OrganizationReleaseVersion__c.field-meta.xml @@ -0,0 +1,18 @@ + + + OrganizationReleaseVersion__c + Active + None + The release version for the org's instance - determined by making a callout to status.salesforce.com + false + The release version for the org's instance - determined by making a callout to status.salesforce.com + + 255 + false + Confidential + false + false + false + Text + false + diff --git a/nebula-logger/core/main/log-management/permissionsets/LoggerAdmin.permissionset-meta.xml b/nebula-logger/core/main/log-management/permissionsets/LoggerAdmin.permissionset-meta.xml index 134c2c1ca..0c1fea59c 100644 --- a/nebula-logger/core/main/log-management/permissionsets/LoggerAdmin.permissionset-meta.xml +++ b/nebula-logger/core/main/log-management/permissionsets/LoggerAdmin.permissionset-meta.xml @@ -169,6 +169,36 @@ LogEntry__c.ApexMethodName__c true + + false + LogEntry__c.BrowserFormFactor__c + true + + + false + LogEntry__c.BrowserLanguage__c + true + + + false + LogEntry__c.BrowserScreenResolution__c + true + + + false + LogEntry__c.BrowserUrl__c + true + + + false + LogEntry__c.BrowserUserAgent__c + true + + + false + LogEntry__c.BrowserWindowResolution__c + true + false LogEntry__c.ComponentApiName__c @@ -279,6 +309,21 @@ LogEntry__c.FlowProcessType__c true + + false + LogEntry__c.FlowRecordTriggerType__c + true + + + false + LogEntry__c.FlowTriggerOrder__c + true + + + false + LogEntry__c.FlowTriggerSObjectType__c + true + false LogEntry__c.FlowTriggerType__c @@ -944,6 +989,11 @@ Log__c.NetworkUrlPathPrefix__c true + + false + Log__c.OrganizationApiVersion__c + true + false Log__c.OrganizationDomainUrl__c @@ -969,6 +1019,11 @@ Log__c.OrganizationInstanceReleaseCycle__c true + + false + Log__c.OrganizationLocation__c + true + false Log__c.OrganizationName__c @@ -979,6 +1034,16 @@ Log__c.OrganizationNamespacePrefix__c true + + false + Log__c.OrganizationReleaseNumber__c + true + + + false + Log__c.OrganizationReleaseVersion__c + true + false Log__c.OrganizationType__c diff --git a/nebula-logger/core/main/log-management/permissionsets/LoggerLogViewer.permissionset-meta.xml b/nebula-logger/core/main/log-management/permissionsets/LoggerLogViewer.permissionset-meta.xml index b36be70e7..69ced886a 100644 --- a/nebula-logger/core/main/log-management/permissionsets/LoggerLogViewer.permissionset-meta.xml +++ b/nebula-logger/core/main/log-management/permissionsets/LoggerLogViewer.permissionset-meta.xml @@ -93,6 +93,36 @@ LogEntry__c.ApexMethodName__c true + + false + LogEntry__c.BrowserFormFactor__c + true + + + false + LogEntry__c.BrowserLanguage__c + true + + + false + LogEntry__c.BrowserScreenResolution__c + true + + + false + LogEntry__c.BrowserUrl__c + true + + + false + LogEntry__c.BrowserUserAgent__c + true + + + false + LogEntry__c.BrowserWindowResolution__c + true + false LogEntry__c.ComponentApiName__c @@ -203,6 +233,21 @@ LogEntry__c.FlowProcessType__c true + + false + LogEntry__c.FlowRecordTriggerType__c + true + + + false + LogEntry__c.FlowTriggerOrder__c + true + + + false + LogEntry__c.FlowTriggerSObjectType__c + true + false LogEntry__c.FlowTriggerType__c @@ -868,6 +913,11 @@ Log__c.NetworkUrlPathPrefix__c true + + false + Log__c.OrganizationApiVersion__c + true + false Log__c.OrganizationDomainUrl__c @@ -893,6 +943,11 @@ Log__c.OrganizationInstanceReleaseCycle__c true + + false + Log__c.OrganizationLocation__c + true + false Log__c.OrganizationName__c @@ -903,6 +958,16 @@ Log__c.OrganizationNamespacePrefix__c true + + false + Log__c.OrganizationReleaseNumber__c + true + + + false + Log__c.OrganizationReleaseVersion__c + true + false Log__c.OrganizationType__c diff --git a/nebula-logger/core/main/logger-engine/classes/ComponentLogger.cls b/nebula-logger/core/main/logger-engine/classes/ComponentLogger.cls index 7716dbf17..bcf28d4c5 100644 --- a/nebula-logger/core/main/logger-engine/classes/ComponentLogger.cls +++ b/nebula-logger/core/main/logger-engine/classes/ComponentLogger.cls @@ -48,6 +48,7 @@ public inherited sharing class ComponentLogger { } logEntryEventBuilder.getLogEntryEvent().Timestamp__c = componentLogEntry.timestamp; + setBrowserDetails(logEntryEventBuilder, componentLogEntry); setComponentErrorDetails(logEntryEventBuilder, componentLogEntry.error); setStackTraceDetails(logEntryEventBuilder, componentLogEntry.stack); } @@ -64,6 +65,15 @@ public inherited sharing class ComponentLogger { } } + private static void setBrowserDetails(LogEntryEventBuilder logEntryEventBuilder, ComponentLogEntry componentLogEntry) { + logEntryEventBuilder.getLogEntryEvent().BrowserFormFactor__c = componentLogEntry.browserFormFactor; + logEntryEventBuilder.getLogEntryEvent().BrowserLanguage__c = componentLogEntry.browserLanguage; + logEntryEventBuilder.getLogEntryEvent().BrowserScreenResolution__c = componentLogEntry.browserScreenResolution; + logEntryEventBuilder.getLogEntryEvent().BrowserUrl__c = componentLogEntry.browserUrl; + logEntryEventBuilder.getLogEntryEvent().BrowserUserAgent__c = componentLogEntry.browserUserAgent; + logEntryEventBuilder.getLogEntryEvent().BrowserWindowResolution__c = componentLogEntry.browserWindowResolution; + } + private static void setComponentErrorDetails(LogEntryEventBuilder logEntryEventBuilder, ComponentError componentError) { if (componentError == null) { return; @@ -221,6 +231,42 @@ public inherited sharing class ComponentLogger { * @description A DTO object used to create log entries for lightning components */ public class ComponentLogEntry { + /** + * @description The form factor of the user's browser + */ + @AuraEnabled + public String browserFormFactor { get; set; } + + /** + * @description The language set in the user's browser + */ + @AuraEnabled + public String browserLanguage { get; set; } + + /** + * @description The resolution of the user's device + */ + @AuraEnabled + public String browserScreenResolution { get; set; } + + /** + * @description The URL displayed in the user's browser + */ + @AuraEnabled + public String browserUrl { get; set; } + + /** + * @description The user agent of the user's browser + */ + @AuraEnabled + public String browserUserAgent { get; set; } + + /** + * @description The resolution of the user's browser window + */ + @AuraEnabled + public String browserWindowResolution { get; set; } + /** * @description The name of the `LoggingLevel` enum value */ diff --git a/nebula-logger/core/main/logger-engine/classes/Logger.cls b/nebula-logger/core/main/logger-engine/classes/Logger.cls index 132b5c60b..1a6255540 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.10.5'; + private static final String CURRENT_VERSION_NUMBER = 'v4.10.6'; private static final System.LoggingLevel FALLBACK_LOGGING_LEVEL = System.LoggingLevel.DEBUG; private static final Set IGNORED_APEX_CLASSES = initializeIgnoredApexClasses(); private static final List LOG_ENTRIES_BUFFER = new List(); @@ -3195,6 +3195,7 @@ global with sharing class Logger { logEntryEvent.ApiVersion__c = getOrganizationApiVersion(); logEntryEvent.EntryScenario__c = currentEntryScenario; logEntryEvent.LoggerVersionNumber__c = CURRENT_VERSION_NUMBER; + logEntryEvent.OrganizationApiVersion__c = getOrganizationApiVersion(); logEntryEvent.OrganizationDomainUrl__c = ORGANIZATION_DOMAIN_URL; logEntryEvent.RequestId__c = REQUEST_ID; logEntryEvent.SystemMode__c = getCurrentQuiddity()?.name(); @@ -3316,12 +3317,10 @@ global with sharing class Logger { // Inner class used for deserializing data from the status API @SuppressWarnings('PMD.ApexDoc, PMD.VariableNamingConventions') public class StatusApiResponse { - public String environment { get; set; } public String location { get; set; } public String maintenanceWindow { get; set; } public String releaseNumber { get; set; } public String releaseVersion { get; set; } - public String status { get; set; } public List Products { get; set; } } diff --git a/nebula-logger/core/main/logger-engine/lwc/logger/__tests__/logger.test.js b/nebula-logger/core/main/logger-engine/lwc/logger/__tests__/logger.test.js index 14949ab82..f417074d6 100644 --- a/nebula-logger/core/main/logger-engine/lwc/logger/__tests__/logger.test.js +++ b/nebula-logger/core/main/logger-engine/lwc/logger/__tests__/logger.test.js @@ -1,4 +1,5 @@ import { createElement } from 'lwc'; +import FORM_FACTOR from '@salesforce/client/formFactor'; // Recommended approach import { createLogger } from 'c/logger'; // Legacy approach @@ -44,13 +45,13 @@ describe('logger lwc import tests', () => { await logger.getUserSettings(); const scenario = 'some scenario'; const message = 'some message'; - const firstLogEntry = await logger.finest(message); + const firstLogEntry = logger.finest(message).getComponentLogEntry(); await flushPromises(); - expect(firstLogEntry.scenario).toBeUndefined(); + expect(firstLogEntry.scenario).toBeNull(); expect(logger.getBufferSize()).toEqual(1); - const secondLogEntry = logger.info(message); + const secondLogEntry = logger.info(message).getComponentLogEntry(); await flushPromises(); - expect(secondLogEntry.scenario).toBeUndefined(); + expect(secondLogEntry.scenario).toBeNull(); expect(logger.getBufferSize()).toEqual(2); await logger.setScenario(scenario); @@ -64,7 +65,7 @@ describe('logger lwc import tests', () => { getSettings.mockResolvedValue({ ...MOCK_GET_SETTINGS }); const message = 'component log entry with loggingLevel ERROR'; - const logEntry = logger.error(message); + const logEntry = logger.error(message).getComponentLogEntry(); await flushPromises(); expect(logger.getBufferSize()).toEqual(1); @@ -77,7 +78,7 @@ describe('logger lwc import tests', () => { getSettings.mockResolvedValue({ ...MOCK_GET_SETTINGS }); const message = 'component log entry with loggingLevel WARN'; - const logEntry = logger.warn(message); + const logEntry = logger.warn(message).getComponentLogEntry(); await flushPromises(); expect(logger.getBufferSize()).toEqual(1); @@ -90,7 +91,7 @@ describe('logger lwc import tests', () => { getSettings.mockResolvedValue({ ...MOCK_GET_SETTINGS }); const message = 'component log entry with loggingLevel INFO'; - const logEntry = logger.info(message); + const logEntry = logger.info(message).getComponentLogEntry(); await flushPromises(); expect(logger.getBufferSize()).toEqual(1); @@ -103,7 +104,7 @@ describe('logger lwc import tests', () => { getSettings.mockResolvedValue({ ...MOCK_GET_SETTINGS }); const message = 'component log entry with loggingLevel DEBUG'; - const logEntry = logger.debug(message); + const logEntry = logger.debug(message).getComponentLogEntry(); await flushPromises(); expect(logger.getBufferSize()).toEqual(1); @@ -116,7 +117,7 @@ describe('logger lwc import tests', () => { getSettings.mockResolvedValue({ ...MOCK_GET_SETTINGS }); const message = 'component log entry with loggingLevel FINE'; - const logEntry = logger.fine(message); + const logEntry = logger.fine(message).getComponentLogEntry(); await flushPromises(); expect(logger.getBufferSize()).toEqual(1); @@ -129,7 +130,7 @@ describe('logger lwc import tests', () => { getSettings.mockResolvedValue({ ...MOCK_GET_SETTINGS }); const message = 'component log entry with loggingLevel FINER'; - const logEntry = logger.finer(message); + const logEntry = logger.finer(message).getComponentLogEntry(); await flushPromises(); expect(logger.getBufferSize()).toEqual(1); @@ -142,7 +143,7 @@ describe('logger lwc import tests', () => { getSettings.mockResolvedValue({ ...MOCK_GET_SETTINGS }); const message = 'component log entry with loggingLevel FINEST'; - const logEntry = logger.finest(message); + const logEntry = logger.finest(message).getComponentLogEntry(); await flushPromises(); expect(logger.getBufferSize()).toEqual(1); @@ -154,11 +155,12 @@ describe('logger lwc import tests', () => { const logger = createLogger(); getSettings.mockResolvedValue({ ...MOCK_GET_SETTINGS }); await logger.getUserSettings(); - const logEntry = logger.info('example log entry'); + const logEntryBuilder = logger.info('example log entry'); + const logEntry = logEntryBuilder.getComponentLogEntry(); expect(logEntry.recordId).toBeFalsy(); const mockUserId = '0052F000008yLcEQAU'; - logEntry.setRecordId(mockUserId); + logEntryBuilder.setRecordId(mockUserId); expect(logEntry.recordId).toEqual(mockUserId); }); @@ -167,11 +169,12 @@ describe('logger lwc import tests', () => { const logger = createLogger(); getSettings.mockResolvedValue({ ...MOCK_GET_SETTINGS }); await logger.getUserSettings(); - const logEntry = logger.info('example log entry'); + const logEntryBuilder = logger.info('example log entry'); + const logEntry = logEntryBuilder.getComponentLogEntry(); expect(logEntry.record).toBeFalsy(); const mockUserRecord = { Id: '0052F000008yLcEQAU', FirstName: 'Jonathan', LastName: 'Gillespie' }; - logEntry.setRecord(mockUserRecord); + logEntryBuilder.setRecord(mockUserRecord); expect(logEntry.record).toEqual(mockUserRecord); }); @@ -180,14 +183,15 @@ describe('logger lwc import tests', () => { const logger = createLogger(); getSettings.mockResolvedValue({ ...MOCK_GET_SETTINGS }); await logger.getUserSettings(); - const logEntry = logger.info('example log entry'); + const logEntryBuilder = logger.info('example log entry'); + const logEntry = logEntryBuilder.getComponentLogEntry(); expect(logEntry.error).toBeFalsy(); const error = new TypeError('oops'); expect(error).toBeTruthy(); expect(error.message).toBeTruthy(); expect(error.stack).toBeTruthy(); - logEntry.setError(error); + logEntryBuilder.setError(error); expect(logEntry.error.message).toEqual(error.message); expect(logEntry.error.stack).toEqual(error.stack); @@ -197,7 +201,8 @@ describe('logger lwc import tests', () => { it('sets Apex error details when using recommended import approach', async () => { const logger = createLogger(); getSettings.mockResolvedValue({ ...MOCK_GET_SETTINGS }); - const logEntry = logger.info('example log entry'); + const logEntryBuilder = logger.info('example log entry'); + const logEntry = logEntryBuilder.getComponentLogEntry(); expect(logEntry.error).toBeFalsy(); const error = { body: { @@ -211,7 +216,7 @@ describe('logger lwc import tests', () => { expect(error.body.message).toBeTruthy(); expect(error.body.stackTrace).toBeTruthy(); - logEntry.setError(error); + logEntryBuilder.setError(error); expect(logEntry.error.message).toEqual(error.body.message); expect(logEntry.error.stack).toEqual(error.body.stackTrace); @@ -221,11 +226,12 @@ describe('logger lwc import tests', () => { it('adds tags when using recommended import approach', async () => { const logger = createLogger(); getSettings.mockResolvedValue({ ...MOCK_GET_SETTINGS }); - const logEntry = logger.info('example log entry'); + const logEntryBuilder = logger.info('example log entry'); + const logEntry = logEntryBuilder.getComponentLogEntry(); expect(logEntry.recordId).toBeFalsy(); const mockTags = ['first tag', 'second tag', 'third tag']; - logEntry.addTags(mockTags); + logEntryBuilder.addTags(mockTags); expect(logEntry.tags.length).toEqual(mockTags.length); }); @@ -233,14 +239,15 @@ describe('logger lwc import tests', () => { it('deduplicates tags when using recommended import approach', async () => { const logger = createLogger(); getSettings.mockResolvedValue({ ...MOCK_GET_SETTINGS }); - const logEntry = logger.info('example log entry'); + const logEntryBuilder = logger.info('example log entry'); + const logEntry = logEntryBuilder.getComponentLogEntry(); expect(logEntry.recordId).toBeFalsy(); const mockTags = ['duplicate tag', 'duplicate tag']; expect(mockTags.length).toEqual(2); expect(new Set(mockTags).size).toEqual(1); for (let i = 0; i < mockTags.length; i++) { - logEntry.addTag(mockTags[i]); + logEntryBuilder.addTag(mockTags[i]); } expect(logEntry.tags.length).toEqual(1); @@ -260,7 +267,8 @@ describe('logger lwc import tests', () => { .setRecord({ Id: 'some_record_Id' }) .setError(error) .addTag('a tag') - .addTags(['a second tag', 'a third tag']); + .addTags(['a second tag', 'a third tag']) + .getComponentLogEntry(); await flushPromises(); expect(logger.getBufferSize()).toEqual(0); @@ -289,7 +297,8 @@ describe('logger lwc import tests', () => { .setRecord({ Id: 'some_record_Id' }) .setError(error) .addTag('a tag') - .addTags(['a second tag', 'a third tag']); + .addTags(['a second tag', 'a third tag']) + .getComponentLogEntry(); await flushPromises(); expect(logger.getBufferSize()).toEqual(0); @@ -318,7 +327,8 @@ describe('logger lwc import tests', () => { .setRecord({ Id: 'some_record_Id' }) .setError(error) .addTag('a tag') - .addTags(['a second tag', 'a third tag']); + .addTags(['a second tag', 'a third tag']) + .getComponentLogEntry(); await flushPromises(); expect(logger.getBufferSize()).toEqual(0); @@ -347,7 +357,8 @@ describe('logger lwc import tests', () => { .setRecord({ Id: 'some_record_Id' }) .setError(error) .addTag('a tag') - .addTags(['a second tag', 'a third tag']); + .addTags(['a second tag', 'a third tag']) + .getComponentLogEntry(); await flushPromises(); expect(logger.getBufferSize()).toEqual(0); @@ -376,7 +387,8 @@ describe('logger lwc import tests', () => { .setRecord({ Id: 'some_record_Id' }) .setError(error) .addTag('a tag') - .addTags(['a second tag', 'a third tag']); + .addTags(['a second tag', 'a third tag']) + .getComponentLogEntry(); await flushPromises(); expect(logger.getBufferSize()).toEqual(0); @@ -405,7 +417,8 @@ describe('logger lwc import tests', () => { .setRecord({ Id: 'some_record_Id' }) .setError(error) .addTag('a tag') - .addTags(['a second tag', 'a third tag']); + .addTags(['a second tag', 'a third tag']) + .getComponentLogEntry(); await flushPromises(); expect(logger.getBufferSize()).toEqual(0); @@ -434,7 +447,8 @@ describe('logger lwc import tests', () => { .setRecord({ Id: 'some_record_Id' }) .setError(error) .addTag('a tag') - .addTags(['a second tag', 'a third tag']); + .addTags(['a second tag', 'a third tag']) + .getComponentLogEntry(); await flushPromises(); expect(logger.getBufferSize()).toEqual(0); @@ -507,14 +521,14 @@ describe('logger lwc legacy markup tests', () => { document.body.appendChild(logger); getSettings.mockResolvedValue({ ...MOCK_GET_SETTINGS }); const message = 'some message'; - const firstLogEntry = await logger.finest(message); - expect(firstLogEntry.scenario).toBeUndefined(); + const firstLogEntry = await logger.finest(message).getComponentLogEntry(); + expect(firstLogEntry.scenario).toBeNull(); expect(logger.getBufferSize()).toEqual(1); - const secondLogEntry = await logger.info(message); - expect(secondLogEntry.scenario).toBeUndefined(); + const secondLogEntry = await logger.info(message).getComponentLogEntry(); + expect(secondLogEntry.scenario).toBeNull(); expect(logger.getBufferSize()).toEqual(2); - const scenario = 'some scenario'; + const scenario = 'another scenario'; logger.setScenario(scenario); expect(firstLogEntry.scenario).toEqual(scenario); @@ -527,7 +541,7 @@ describe('logger lwc legacy markup tests', () => { getSettings.mockResolvedValue({ ...MOCK_GET_SETTINGS }); const message = 'component log entry with loggingLevel ERROR'; - const logEntry = await logger.error(message); + const logEntry = await logger.error(message).getComponentLogEntry(); expect(logger.getBufferSize()).toEqual(1); expect(logEntry.loggingLevel).toEqual('ERROR'); @@ -539,7 +553,7 @@ describe('logger lwc legacy markup tests', () => { getSettings.mockResolvedValue({ ...MOCK_GET_SETTINGS }); const message = 'component log entry with loggingLevel WARN'; - const logEntry = await logger.warn(message); + const logEntry = await logger.warn(message).getComponentLogEntry(); expect(logger.getBufferSize()).toEqual(1); expect(logEntry.loggingLevel).toEqual('WARN'); @@ -552,7 +566,7 @@ describe('logger lwc legacy markup tests', () => { getSettings.mockResolvedValue({ ...MOCK_GET_SETTINGS }); const message = 'component log entry with loggingLevel INFO'; - const logEntry = await logger.info(message); + const logEntry = await logger.info(message).getComponentLogEntry(); expect(logger.getBufferSize()).toEqual(1); expect(logEntry.loggingLevel).toEqual('INFO'); @@ -565,7 +579,7 @@ describe('logger lwc legacy markup tests', () => { getSettings.mockResolvedValue({ ...MOCK_GET_SETTINGS }); const message = 'component log entry with loggingLevel DEBUG'; - const logEntry = await logger.debug(message); + const logEntry = await logger.debug(message).getComponentLogEntry(); expect(logger.getBufferSize()).toEqual(1); expect(logEntry.loggingLevel).toEqual('DEBUG'); @@ -578,7 +592,7 @@ describe('logger lwc legacy markup tests', () => { getSettings.mockResolvedValue({ ...MOCK_GET_SETTINGS }); const message = 'component log entry with loggingLevel FINE'; - const logEntry = await logger.fine(message); + const logEntry = await logger.fine(message).getComponentLogEntry(); expect(logger.getBufferSize()).toEqual(1); expect(logEntry.loggingLevel).toEqual('FINE'); @@ -591,7 +605,7 @@ describe('logger lwc legacy markup tests', () => { getSettings.mockResolvedValue({ ...MOCK_GET_SETTINGS }); const message = 'component log entry with loggingLevel FINER'; - const logEntry = await logger.finer(message); + const logEntry = await logger.finer(message).getComponentLogEntry(); expect(logger.getBufferSize()).toEqual(1); expect(logEntry.loggingLevel).toEqual('FINER'); @@ -604,7 +618,7 @@ describe('logger lwc legacy markup tests', () => { getSettings.mockResolvedValue({ ...MOCK_GET_SETTINGS }); const message = 'component log entry with loggingLevel FINEST'; - const logEntry = await logger.finest(message); + const logEntry = await logger.finest(message).getComponentLogEntry(); expect(logger.getBufferSize()).toEqual(1); expect(logEntry.loggingLevel).toEqual('FINEST'); @@ -615,11 +629,12 @@ describe('logger lwc legacy markup tests', () => { const logger = createElement('c-logger', { is: Logger }); document.body.appendChild(logger); getSettings.mockResolvedValue({ ...MOCK_GET_SETTINGS }); - const logEntry = await logger.info('example log entry'); + const logEntryBuilder = await logger.info('example log entry'); + const logEntry = logEntryBuilder.getComponentLogEntry(); expect(logEntry.recordId).toBeFalsy(); const mockUserId = '0052F000008yLcEQAU'; - logEntry.setRecordId(mockUserId); + logEntryBuilder.setRecordId(mockUserId); expect(logEntry.recordId).toEqual(mockUserId); }); @@ -628,11 +643,12 @@ describe('logger lwc legacy markup tests', () => { const logger = createElement('c-logger', { is: Logger }); document.body.appendChild(logger); getSettings.mockResolvedValue({ ...MOCK_GET_SETTINGS }); - const logEntry = await logger.info('example log entry'); + const logEntryBuilder = await logger.info('example log entry'); + const logEntry = logEntryBuilder.getComponentLogEntry(); expect(logEntry.record).toBeFalsy(); const mockUserRecord = { Id: '0052F000008yLcEQAU', FirstName: 'Jonathan', LastName: 'Gillespie' }; - logEntry.setRecord(mockUserRecord); + logEntryBuilder.setRecord(mockUserRecord); expect(logEntry.record).toEqual(mockUserRecord); }); @@ -641,14 +657,15 @@ describe('logger lwc legacy markup tests', () => { const logger = createElement('c-logger', { is: Logger }); document.body.appendChild(logger); getSettings.mockResolvedValue({ ...MOCK_GET_SETTINGS }); - const logEntry = await logger.info('example log entry'); + const logEntryBuilder = await logger.info('example log entry'); + const logEntry = logEntryBuilder.getComponentLogEntry(); expect(logEntry.error).toBeFalsy(); const error = new TypeError('oops'); expect(error).toBeTruthy(); expect(error.message).toBeTruthy(); expect(error.stack).toBeTruthy(); - logEntry.setError(error); + logEntryBuilder.setError(error); expect(logEntry.error.message).toEqual(error.message); expect(logEntry.error.stack).toEqual(error.stack); @@ -659,7 +676,8 @@ describe('logger lwc legacy markup tests', () => { const logger = createElement('c-logger', { is: Logger }); document.body.appendChild(logger); getSettings.mockResolvedValue({ ...MOCK_GET_SETTINGS }); - const logEntry = await logger.info('example log entry'); + const logEntryBuilder = logger.info('example log entry'); + const logEntry = logEntryBuilder.getComponentLogEntry(); expect(logEntry.error).toBeFalsy(); const error = { body: { @@ -673,7 +691,7 @@ describe('logger lwc legacy markup tests', () => { expect(error.body.message).toBeTruthy(); expect(error.body.stackTrace).toBeTruthy(); - logEntry.setError(error); + logEntryBuilder.setError(error); expect(logEntry.error.message).toEqual(error.body.message); expect(logEntry.error.stack).toEqual(error.body.stackTrace); @@ -684,11 +702,12 @@ describe('logger lwc legacy markup tests', () => { const logger = createElement('c-logger', { is: Logger }); document.body.appendChild(logger); getSettings.mockResolvedValue({ ...MOCK_GET_SETTINGS }); - const logEntry = await logger.info('example log entry'); + const logEntryBuilder = logger.info('example log entry'); + const logEntry = logEntryBuilder.getComponentLogEntry(); expect(logEntry.recordId).toBeFalsy(); const mockTags = ['first tag', 'second tag', 'third tag']; - logEntry.addTags(mockTags); + logEntryBuilder.addTags(mockTags); expect(logEntry.tags.length).toEqual(mockTags.length); }); @@ -697,14 +716,15 @@ describe('logger lwc legacy markup tests', () => { const logger = createElement('c-logger', { is: Logger }); document.body.appendChild(logger); getSettings.mockResolvedValue({ ...MOCK_GET_SETTINGS }); - const logEntry = await logger.info('example log entry'); + const logEntryBuilder = logger.info('example log entry'); + const logEntry = logEntryBuilder.getComponentLogEntry(); expect(logEntry.recordId).toBeFalsy(); const mockTags = ['duplicate tag', 'duplicate tag']; expect(mockTags.length).toEqual(2); expect(new Set(mockTags).size).toEqual(1); for (let i = 0; i < mockTags.length; i++) { - logEntry.addTag(mockTags[i]); + logEntryBuilder.addTag(mockTags[i]); } expect(logEntry.tags.length).toEqual(1); @@ -725,7 +745,8 @@ describe('logger lwc legacy markup tests', () => { .setRecord({ Id: 'some_record_Id' }) .setError(error) .addTag('a tag') - .addTags(['a second tag', 'a third tag']); + .addTags(['a second tag', 'a third tag']) + .getComponentLogEntry(); expect(logger.getBufferSize()).toEqual(0); expect(logEntry.loggingLevel).toEqual('ERROR'); @@ -754,7 +775,8 @@ describe('logger lwc legacy markup tests', () => { .setRecord({ Id: 'some_record_Id' }) .setError(error) .addTag('a tag') - .addTags(['a second tag', 'a third tag']); + .addTags(['a second tag', 'a third tag']) + .getComponentLogEntry(); expect(logger.getBufferSize()).toEqual(0); expect(logEntry.loggingLevel).toEqual('WARN'); @@ -783,7 +805,8 @@ describe('logger lwc legacy markup tests', () => { .setRecord({ Id: 'some_record_Id' }) .setError(error) .addTag('a tag') - .addTags(['a second tag', 'a third tag']); + .addTags(['a second tag', 'a third tag']) + .getComponentLogEntry(); expect(logger.getBufferSize()).toEqual(0); expect(logEntry.loggingLevel).toEqual('INFO'); @@ -812,7 +835,8 @@ describe('logger lwc legacy markup tests', () => { .setRecord({ Id: 'some_record_Id' }) .setError(error) .addTag('a tag') - .addTags(['a second tag', 'a third tag']); + .addTags(['a second tag', 'a third tag']) + .getComponentLogEntry(); expect(logger.getBufferSize()).toEqual(0); expect(logEntry.loggingLevel).toEqual('DEBUG'); @@ -841,7 +865,8 @@ describe('logger lwc legacy markup tests', () => { .setRecord({ Id: 'some_record_Id' }) .setError(error) .addTag('a tag') - .addTags(['a second tag', 'a third tag']); + .addTags(['a second tag', 'a third tag']) + .getComponentLogEntry(); expect(logger.getBufferSize()).toEqual(0); expect(logEntry.loggingLevel).toEqual('FINE'); @@ -870,9 +895,16 @@ describe('logger lwc legacy markup tests', () => { .setRecord({ Id: 'some_record_Id' }) .setError(error) .addTag('a tag') - .addTags(['a second tag', 'a third tag']); + .addTags(['a second tag', 'a third tag']) + .getComponentLogEntry(); expect(logger.getBufferSize()).toEqual(0); + expect(logEntry.browserFormFactor).toEqual(FORM_FACTOR); + expect(logEntry.browserLanguage).toEqual(window.navigator.language); + expect(logEntry.browserScreenResolution).toEqual(window.screen.availWidth + ' x ' + window.screen.availHeight); + expect(logEntry.browserUrl).toEqual(window.location.href); + expect(logEntry.browserUserAgent).toEqual(window.navigator.userAgent); + expect(logEntry.browserWindowResolution).toEqual(window.innerWidth + ' x ' + window.innerHeight); expect(logEntry.loggingLevel).toEqual('FINER'); expect(logEntry.recordId).toEqual('some_record_Id'); expect(logEntry.record).toEqual({ Id: 'some_record_Id' }); @@ -899,7 +931,8 @@ describe('logger lwc legacy markup tests', () => { .setRecord({ Id: 'some_record_Id' }) .setError(error) .addTag('a tag') - .addTags(['a second tag', 'a third tag']); + .addTags(['a second tag', 'a third tag']) + .getComponentLogEntry(); await flushPromises(); expect(logger.getBufferSize()).toEqual(0); diff --git a/nebula-logger/core/main/logger-engine/lwc/logger/logEntryBuilder.js b/nebula-logger/core/main/logger-engine/lwc/logger/logEntryBuilder.js index 7469aa345..e5774b03c 100644 --- a/nebula-logger/core/main/logger-engine/lwc/logger/logEntryBuilder.js +++ b/nebula-logger/core/main/logger-engine/lwc/logger/logEntryBuilder.js @@ -2,8 +2,33 @@ // 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. // //------------------------------------------------------------------------------------------------// +import FORM_FACTOR from '@salesforce/client/formFactor'; + +// JavaScript equivalent to the Apex class ComponentLogger.ComponentLogEntry +const ComponentLogEntry = class { + browserFormFactor = null; + browserLanguage = null; + browserScreenResolution = null; + browserUrl = null; + browserUserAgent = null; + browserWindowResolution = null; + error = null; + loggingLevel = null; + message = null; + record = null; + recordId = null; + scenario = null; + stack = new Error().stack; + tags = []; + timestamp = new Date().toISOString(); + + constructor(loggingLevel) { + this.loggingLevel = loggingLevel; + } +}; const LogEntryBuilder = class { + #componentLogEntry; #settingsPromise; /** @@ -13,11 +38,10 @@ const LogEntryBuilder = class { * @param {Boolean} isConsoleLoggingEnabled Determines if `console.log()` methods are execute */ constructor(loggingLevel, settingsPromise) { + this.#componentLogEntry = new ComponentLogEntry(loggingLevel); this.#settingsPromise = settingsPromise; - this.loggingLevel = loggingLevel; - this.stack = new Error().stack; - this.timestamp = new Date().toISOString(); - this.tags = []; + + this._setBrowserDetails(); } /** @@ -26,7 +50,7 @@ const LogEntryBuilder = class { * @return {LogEntryBuilder} The same instance of `LogEntryBuilder`, useful for chaining methods */ setMessage(message) { - this.message = message; + this.#componentLogEntry.message = message; this._logToConsole(); return this; } @@ -37,7 +61,7 @@ const LogEntryBuilder = class { * @return {LogEntryBuilder} The same instance of `LogEntryBuilder`, useful for chaining methods */ setRecordId(recordId) { - this.recordId = recordId; + this.#componentLogEntry.recordId = recordId; return this; } @@ -47,7 +71,7 @@ const LogEntryBuilder = class { * @return {LogEntryBuilder} The same instance of `LogEntryBuilder`, useful for chaining methods */ setRecord(record) { - this.record = record; + this.#componentLogEntry.record = record; return this; } @@ -57,15 +81,15 @@ const LogEntryBuilder = class { * @return {LogEntryBuilder} The same instance of `LogEntryBuilder`, useful for chaining methods */ setError(error) { - this.error = {}; + this.#componentLogEntry.error = {}; if (error.body) { - this.error.message = error.body.message; - this.error.stack = error.body.stackTrace; - this.error.type = error.body.exceptionType; + this.#componentLogEntry.error.message = error.body.message; + this.#componentLogEntry.error.stack = error.body.stackTrace; + this.#componentLogEntry.error.type = error.body.exceptionType; } else { - this.error.message = error.message; - this.error.stack = error.stack; - this.error.type = 'JavaScript.' + error.name; + this.#componentLogEntry.error.message = error.message; + this.#componentLogEntry.error.stack = error.stack; + this.#componentLogEntry.error.type = 'JavaScript.' + error.name; } return this; } @@ -76,9 +100,9 @@ const LogEntryBuilder = class { * @return {LogEntryBuilder} The same instance of `LogEntryBuilder`, useful for chaining methods */ addTag(tag) { - this.tags.push(tag); + this.#componentLogEntry.tags.push(tag); // Deduplicate the list of tags - this.tags = Array.from(new Set(this.tags)); + this.#componentLogEntry.tags = Array.from(new Set(this.#componentLogEntry.tags)); return this; } @@ -94,6 +118,23 @@ const LogEntryBuilder = class { return this; } + /** + * @description Returns the object used to save log entry data + * @return {ComponentLogEntry} An instance of `ComponentLogEntry` that matches the Apex class `ComponentLogger.ComponentLogEntry` + */ + getComponentLogEntry() { + return this.#componentLogEntry; + } + + _setBrowserDetails() { + this.#componentLogEntry.browserFormFactor = FORM_FACTOR; + this.#componentLogEntry.browserLanguage = window.navigator.language; + this.#componentLogEntry.browserScreenResolution = window.screen.availWidth + ' x ' + window.screen.availHeight; + this.#componentLogEntry.browserUrl = window.location.href; + this.#componentLogEntry.browserUserAgent = window.navigator.userAgent; + this.#componentLogEntry.browserWindowResolution = window.innerWidth + ' x ' + window.innerHeight; + } + /* eslint-disable no-console */ _logToConsole() { this.#settingsPromise().then(setting => { @@ -121,12 +162,12 @@ const LogEntryBuilder = class { break; } - consoleLoggingFunction(consoleMessagePrefix, consoleFormatting, this.message); - console.groupCollapsed(consoleMessagePrefix, consoleFormatting, 'Details for: ' + this.message); + consoleLoggingFunction(consoleMessagePrefix, consoleFormatting, this.#componentLogEntry.message); + console.groupCollapsed(consoleMessagePrefix, consoleFormatting, 'Details for: ' + this.#componentLogEntry.message); // The use of JSON.parse(JSON.stringify()) is intended to help ensure that the output is readable, // including handling proxy objects. If any cyclic objects are used, this approach could fail consoleLoggingFunction(JSON.parse(JSON.stringify(this))); - console.trace(); + // console.trace(); console.groupEnd(); }); } diff --git a/nebula-logger/core/main/logger-engine/lwc/logger/logger.js b/nebula-logger/core/main/logger-engine/lwc/logger/logger.js index 60409048e..d80c81f91 100644 --- a/nebula-logger/core/main/logger-engine/lwc/logger/logger.js +++ b/nebula-logger/core/main/logger-engine/lwc/logger/logger.js @@ -6,7 +6,7 @@ import { LightningElement, api } from 'lwc'; import { createLoggerService } from './loggerService'; -const CURRENT_VERSION_NUMBER = 'v4.10.5'; +const CURRENT_VERSION_NUMBER = 'v4.10.6'; export default class Logger extends LightningElement { #loggerService = createLoggerService(); 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 dcc1da628..63004d0da 100644 --- a/nebula-logger/core/main/logger-engine/lwc/logger/loggerService.js +++ b/nebula-logger/core/main/logger-engine/lwc/logger/loggerService.js @@ -190,7 +190,7 @@ const LoggerService = class { } const loggingPromise = this._loadSettingsFromServer().then(() => { if (this._meetsUserLoggingLevel(loggingLevel) === true) { - this.#componentLogEntries.push(logEntryBuilder); + this.#componentLogEntries.push(logEntryBuilder.getComponentLogEntry()); } }); this.#loggingPromises.push(loggingPromise); diff --git a/nebula-logger/core/main/logger-engine/objects/LogEntryEvent__e/fields/ApiVersion__c.field-meta.xml b/nebula-logger/core/main/logger-engine/objects/LogEntryEvent__e/fields/ApiVersion__c.field-meta.xml index 760fac3ea..9c2195719 100644 --- a/nebula-logger/core/main/logger-engine/objects/LogEntryEvent__e/fields/ApiVersion__c.field-meta.xml +++ b/nebula-logger/core/main/logger-engine/objects/LogEntryEvent__e/fields/ApiVersion__c.field-meta.xml @@ -1,13 +1,13 @@ ApiVersion__c - Active + DeprecateCandidate None false false false false - + 5 false Confidential diff --git a/nebula-logger/core/main/logger-engine/objects/LogEntryEvent__e/fields/BrowserFormFactor__c.field-meta.xml b/nebula-logger/core/main/logger-engine/objects/LogEntryEvent__e/fields/BrowserFormFactor__c.field-meta.xml new file mode 100644 index 000000000..77e548969 --- /dev/null +++ b/nebula-logger/core/main/logger-engine/objects/LogEntryEvent__e/fields/BrowserFormFactor__c.field-meta.xml @@ -0,0 +1,13 @@ + + + BrowserFormFactor__c + false + false + false + false + + 255 + false + Text + false + diff --git a/nebula-logger/core/main/logger-engine/objects/LogEntryEvent__e/fields/BrowserLanguage__c.field-meta.xml b/nebula-logger/core/main/logger-engine/objects/LogEntryEvent__e/fields/BrowserLanguage__c.field-meta.xml new file mode 100644 index 000000000..d9c020507 --- /dev/null +++ b/nebula-logger/core/main/logger-engine/objects/LogEntryEvent__e/fields/BrowserLanguage__c.field-meta.xml @@ -0,0 +1,13 @@ + + + BrowserLanguage__c + false + false + false + false + + 255 + false + Text + false + diff --git a/nebula-logger/core/main/logger-engine/objects/LogEntryEvent__e/fields/BrowserScreenResolution__c.field-meta.xml b/nebula-logger/core/main/logger-engine/objects/LogEntryEvent__e/fields/BrowserScreenResolution__c.field-meta.xml new file mode 100644 index 000000000..cddf48194 --- /dev/null +++ b/nebula-logger/core/main/logger-engine/objects/LogEntryEvent__e/fields/BrowserScreenResolution__c.field-meta.xml @@ -0,0 +1,13 @@ + + + BrowserScreenResolution__c + false + false + false + false + + 255 + false + Text + false + diff --git a/nebula-logger/core/main/logger-engine/objects/LogEntryEvent__e/fields/BrowserUrl__c.field-meta.xml b/nebula-logger/core/main/logger-engine/objects/LogEntryEvent__e/fields/BrowserUrl__c.field-meta.xml new file mode 100644 index 000000000..cca354013 --- /dev/null +++ b/nebula-logger/core/main/logger-engine/objects/LogEntryEvent__e/fields/BrowserUrl__c.field-meta.xml @@ -0,0 +1,13 @@ + + + BrowserUrl__c + false + false + false + false + + 255 + false + Text + false + diff --git a/nebula-logger/core/main/logger-engine/objects/LogEntryEvent__e/fields/BrowserUserAgent__c.field-meta.xml b/nebula-logger/core/main/logger-engine/objects/LogEntryEvent__e/fields/BrowserUserAgent__c.field-meta.xml new file mode 100644 index 000000000..6a764729c --- /dev/null +++ b/nebula-logger/core/main/logger-engine/objects/LogEntryEvent__e/fields/BrowserUserAgent__c.field-meta.xml @@ -0,0 +1,16 @@ + + + BrowserUserAgent__c + Active + None + false + false + false + false + + 255 + false + Confidential + Text + false + diff --git a/nebula-logger/core/main/logger-engine/objects/LogEntryEvent__e/fields/BrowserWindowResolution__c.field-meta.xml b/nebula-logger/core/main/logger-engine/objects/LogEntryEvent__e/fields/BrowserWindowResolution__c.field-meta.xml new file mode 100644 index 000000000..f95ba5071 --- /dev/null +++ b/nebula-logger/core/main/logger-engine/objects/LogEntryEvent__e/fields/BrowserWindowResolution__c.field-meta.xml @@ -0,0 +1,13 @@ + + + BrowserWindowResolution__c + false + false + false + false + + 255 + false + Text + false + diff --git a/nebula-logger/core/main/logger-engine/objects/LogEntryEvent__e/fields/OrganizationApiVersion__c.field-meta.xml b/nebula-logger/core/main/logger-engine/objects/LogEntryEvent__e/fields/OrganizationApiVersion__c.field-meta.xml new file mode 100644 index 000000000..ec565cbe6 --- /dev/null +++ b/nebula-logger/core/main/logger-engine/objects/LogEntryEvent__e/fields/OrganizationApiVersion__c.field-meta.xml @@ -0,0 +1,16 @@ + + + OrganizationApiVersion__c + Active + None + false + false + false + false + + 5 + false + Confidential + Text + false + diff --git a/nebula-logger/core/tests/log-management/classes/LogEntryEventHandler_Tests.cls b/nebula-logger/core/tests/log-management/classes/LogEntryEventHandler_Tests.cls index 6b6e5e1dd..dfd93c788 100644 --- a/nebula-logger/core/tests/log-management/classes/LogEntryEventHandler_Tests.cls +++ b/nebula-logger/core/tests/log-management/classes/LogEntryEventHandler_Tests.cls @@ -6,9 +6,6 @@ @SuppressWarnings('PMD.ApexDoc, PMD.CyclomaticComplexity, PMD.ExcessiveParameterList, PMD.MethodNamingConventions, PMD.NcssMethodCount, PMD.NcssTypeCount') @IsTest(IsParallel=false) private class LogEntryEventHandler_Tests { - private static final String MOCK_RELEASE_NUMBER = '230.12.2'; - private static final String MOCK_RELEASE_VERSION = 'Spring \'21 Patch 12.2'; - @IsTest static void it_should_return_the_logEntryEvent_sobjectType() { System.Assert.areEqual(Schema.LogEntryEvent__e.SObjectType, new LogEntryEventHandler().getSObjectType()); @@ -998,9 +995,10 @@ private class LogEntryEventHandler_Tests { LoggerTestConfigurator.setupMockSObjectHandlerConfigurations(); LoggerTestConfigurator.getSObjectHandlerConfiguration(Schema.Log__c.SObjectType).IsEnabled__c = false; LoggerTestConfigurator.getSObjectHandlerConfiguration(Schema.LogEntry__c.SObjectType).IsEnabled__c = false; + Logger.StatusApiResponse mockApiResponse = createStatusApiResponse(); System.Test.setMock( System.HttpCalloutMock.class, - LoggerMockDataCreator.createHttpCallout().setStatusCode(200).setResponseBody(createStatusApiResponseJson()) + LoggerMockDataCreator.createHttpCallout().setStatusCode(200).setResponseBody(System.JSON.serialize(mockApiResponse)) ); LoggerParameter__mdt mockCallStatusApiParameter = new LoggerParameter__mdt(DeveloperName = 'CallStatusApi', Value__c = 'true'); LoggerTestConfigurator.setMock(mockCallStatusApiParameter); @@ -1023,8 +1021,12 @@ private class LogEntryEventHandler_Tests { Log__c log = getLog(); System.Assert.areEqual(1, log.LogEntries__r.size()); LogEntry__c logEntry = log.LogEntries__r.get(0); - System.Assert.areEqual(MOCK_RELEASE_NUMBER, log.ApiReleaseNumber__c); - System.Assert.areEqual(MOCK_RELEASE_VERSION, log.ApiReleaseVersion__c); + System.Assert.areEqual(mockApiResponse.location, log.OrganizationLocation__c); + System.Assert.areEqual(mockApiResponse.releaseNumber, log.OrganizationReleaseNumber__c); + System.Assert.areEqual(mockApiResponse.releaseVersion, log.OrganizationReleaseVersion__c); + // Legacy fields + System.Assert.areEqual(log.OrganizationReleaseNumber__c, log.ApiReleaseNumber__c); + System.Assert.areEqual(log.OrganizationReleaseVersion__c, log.ApiReleaseVersion__c); validateLogFields(logEntryEvent, log); validateLogEntryFields(logEntryEvent, logEntry); } @@ -1035,7 +1037,13 @@ private class LogEntryEventHandler_Tests { LoggerTestConfigurator.setupMockSObjectHandlerConfigurations(); LoggerTestConfigurator.getSObjectHandlerConfiguration(Schema.Log__c.SObjectType).IsEnabled__c = false; LoggerTestConfigurator.getSObjectHandlerConfiguration(Schema.LogEntry__c.SObjectType).IsEnabled__c = false; - Log__c recentLog = new Log__c(ApiReleaseNumber__c = 'QWERTY', ApiReleaseVersion__c = 'ASDF', TransactionId__c = 'ABC-XYZ'); + Log__c recentLog = new Log__c( + ApiReleaseNumber__c = 'QWERTY', + ApiReleaseVersion__c = 'ASDF', + OrganizationReleaseNumber__c = 'POIUY', + OrganizationReleaseVersion__c = 'LKJH', + TransactionId__c = 'ABC-XYZ' + ); insert recentLog; insert new LogEntry__c(Log__c = recentLog.Id, Timestamp__c = System.now().addHours(-1)); LoggerParameter__mdt mockCallStatusApiParameter = new LoggerParameter__mdt(DeveloperName = 'CallStatusApi', Value__c = 'true'); @@ -1062,6 +1070,8 @@ private class LogEntryEventHandler_Tests { LogEntry__c logEntry = log.LogEntries__r.get(0); System.Assert.areEqual(recentLog.ApiReleaseNumber__c, log.ApiReleaseNumber__c); System.Assert.areEqual(recentLog.ApiReleaseVersion__c, log.ApiReleaseVersion__c); + System.Assert.areEqual(recentLog.OrganizationReleaseNumber__c, log.OrganizationReleaseNumber__c); + System.Assert.areEqual(recentLog.OrganizationReleaseVersion__c, log.OrganizationReleaseVersion__c); validateLogFields(logEntryEvent, log); validateLogEntryFields(logEntryEvent, logEntry); } @@ -1072,9 +1082,10 @@ private class LogEntryEventHandler_Tests { LoggerTestConfigurator.setupMockSObjectHandlerConfigurations(); LoggerTestConfigurator.getSObjectHandlerConfiguration(Schema.Log__c.SObjectType).IsEnabled__c = false; LoggerTestConfigurator.getSObjectHandlerConfiguration(Schema.LogEntry__c.SObjectType).IsEnabled__c = false; + Logger.StatusApiResponse mockApiResponse = createStatusApiResponse(); System.Test.setMock( System.HttpCalloutMock.class, - LoggerMockDataCreator.createHttpCallout().setStatusCode(400).setResponseBody(createStatusApiResponseJson()) + LoggerMockDataCreator.createHttpCallout().setStatusCode(200).setResponseBody(System.JSON.serialize(mockApiResponse)) ); LoggerParameter__mdt mockCallStatusApiParameter = new LoggerParameter__mdt(DeveloperName = 'CallStatusApi', Value__c = 'false'); LoggerTestConfigurator.setMock(mockCallStatusApiParameter); @@ -1100,6 +1111,8 @@ private class LogEntryEventHandler_Tests { System.Assert.areEqual(logEntryEvent.TransactionId__c, log.TransactionId__c); System.Assert.isNull(log.ApiReleaseNumber__c); System.Assert.isNull(log.ApiReleaseVersion__c); + System.Assert.isNull(log.OrganizationReleaseNumber__c); + System.Assert.isNull(log.OrganizationReleaseVersion__c); validateLogFields(logEntryEvent, log); validateLogEntryFields(logEntryEvent, logEntry); } @@ -1110,9 +1123,10 @@ private class LogEntryEventHandler_Tests { LoggerTestConfigurator.setupMockSObjectHandlerConfigurations(); LoggerTestConfigurator.getSObjectHandlerConfiguration(Schema.Log__c.SObjectType).IsEnabled__c = false; LoggerTestConfigurator.getSObjectHandlerConfiguration(Schema.LogEntry__c.SObjectType).IsEnabled__c = false; + Logger.StatusApiResponse mockApiResponse = createStatusApiResponse(); System.Test.setMock( System.HttpCalloutMock.class, - LoggerMockDataCreator.createHttpCallout().setStatusCode(400).setResponseBody(createStatusApiResponseJson()) + LoggerMockDataCreator.createHttpCallout().setStatusCode(400).setResponseBody(System.JSON.serialize(mockApiResponse)) ); LoggerParameter__mdt mockCallStatusApiParameter = new LoggerParameter__mdt(DeveloperName = 'CallStatusApi', Value__c = 'true'); LoggerTestConfigurator.setMock(mockCallStatusApiParameter); @@ -1176,11 +1190,12 @@ private class LogEntryEventHandler_Tests { return logEntryEvent; } - private static String createStatusApiResponseJson() { - Logger.StatusApiResponse apiResponse = new Logger.StatusApiResponse(); - apiResponse.releaseNumber = MOCK_RELEASE_NUMBER; - apiResponse.releaseVersion = MOCK_RELEASE_VERSION; - return JSON.serialize(apiResponse); + private static Logger.StatusApiResponse createStatusApiResponse() { + Logger.StatusApiResponse mockApiResponse = new Logger.StatusApiResponse(); + mockApiResponse.location = 'NA'; + mockApiResponse.releaseNumber = '242.19.17'; + mockApiResponse.releaseVersion = 'Spring \'23 Patch 19.17'; + return mockApiResponse; } private static Log__c getLog() { @@ -1202,12 +1217,16 @@ private class LogEntryEventHandler_Tests { LoginType__c, LogoutUrl__c, NetworkId__c, + OrganizationApiVersion__c, OrganizationDomainUrl__c, OrganizationEnvironmentType__c, OrganizationId__c, OrganizationInstanceName__c, + OrganizationLocation__c, OrganizationName__c, OrganizationNamespacePrefix__c, + OrganizationReleaseNumber__c, + OrganizationReleaseVersion__c, OrganizationType__c, OwnerId, ParentLogTransactionId__c, @@ -1239,6 +1258,12 @@ private class LogEntryEventHandler_Tests { UserType__c, ( SELECT + BrowserFormFactor__c, + BrowserLanguage__c, + BrowserScreenResolution__c, + BrowserUrl__c, + BrowserUserAgent__c, + BrowserWindowResolution__c, ComponentType__c, DatabaseResultCollectionSize__c, DatabaseResultCollectionType__c, @@ -1349,6 +1374,7 @@ private class LogEntryEventHandler_Tests { System.Assert.areEqual(logEntryEvent.LogoutUrl__c, log.LogoutUrl__c, 'log.LogoutUrl__c was not properly set'); System.Assert.areEqual(logEntryEvent.NetworkId__c, log.NetworkId__c, 'log.NetworkId__c was not properly set'); System.Assert.areEqual(logOwnerId, log.OwnerId, 'log.OwnerId was not properly set'); + System.Assert.areEqual(logEntryEvent.OrganizationApiVersion__c, log.OrganizationApiVersion__c, 'log.OrganizationApiVersion__c was not properly set'); System.Assert.areEqual(logEntryEvent.ParentLogTransactionId__c, log.ParentLogTransactionId__c, 'log.ParentLogTransactionId__c was not properly set'); System.Assert.areEqual(logEntryEvent.ProfileId__c, log.ProfileId__c, 'log.ProfileId__c was not properly set'); System.Assert.areEqual(logEntryEvent.ProfileName__c, log.ProfileName__c, 'log.ProfileName__c was not properly set'); @@ -1411,6 +1437,20 @@ private class LogEntryEventHandler_Tests { } private static void validateLogEntryFields(LogEntryEvent__e logEntryEvent, LogEntry__c logEntry) { + System.Assert.areEqual(logEntryEvent.BrowserFormFactor__c, logEntry.BrowserFormFactor__c, 'logEntry.BrowserFormFactor__c was not properly set'); + System.Assert.areEqual(logEntryEvent.BrowserLanguage__c, logEntry.BrowserLanguage__c, 'logEntry.BrowserLanguage__c was not properly set'); + System.Assert.areEqual( + logEntryEvent.BrowserScreenResolution__c, + logEntry.BrowserScreenResolution__c, + 'logEntry.BrowserScreenResolution__c was not properly set' + ); + System.Assert.areEqual(logEntryEvent.BrowserUrl__c, logEntry.BrowserUrl__c, 'logEntry.BrowserUrl__c was not properly set'); + System.Assert.areEqual(logEntryEvent.BrowserUserAgent__c, logEntry.BrowserUserAgent__c, 'logEntry.BrowserUserAgent__c was not properly set'); + System.Assert.areEqual( + logEntryEvent.BrowserWindowResolution__c, + logEntry.BrowserWindowResolution__c, + 'logEntry.BrowserWindowResolution__c was not properly set' + ); System.Assert.areEqual(logEntryEvent.ComponentType__c, logEntry.ComponentType__c, 'logEntry.ComponentType__c was not properly set'); System.Assert.areEqual( logEntryEvent.DatabaseResultCollectionSize__c, diff --git a/nebula-logger/core/tests/log-management/classes/LogEntryHandler_Tests.cls b/nebula-logger/core/tests/log-management/classes/LogEntryHandler_Tests.cls index cf44f70b8..f38037b33 100644 --- a/nebula-logger/core/tests/log-management/classes/LogEntryHandler_Tests.cls +++ b/nebula-logger/core/tests/log-management/classes/LogEntryHandler_Tests.cls @@ -557,6 +557,56 @@ private class LogEntryHandler_Tests { System.Assert.areEqual(methodName, logEntry.ApexMethodName__c); } + @IsTest + static void it_should_set_gracefully_skip_setting_flow_details_when_origin_location_is_not_valid_flow_api_name() { + Log__c log = new Log__c(TransactionId__c = '1234'); + insert log; + LoggerTestConfigurator.setupMockSObjectHandlerConfigurations(); + String invalidOriginLocation = 'A_Very_Fake_Flow_API_Name'; + LogEntry__c logEntry = new LogEntry__c(Log__c = log.Id, OriginLocation__c = invalidOriginLocation, OriginType__c = 'Flow'); + + insert logEntry; + + logEntry = [ + SELECT + FlowActiveVersionId__c, + FlowDescription__c, + FlowDurableId__c, + FlowLabel__c, + FlowLastModifiedByName__c, + FlowLastModifiedDate__c, + FlowProcessType__c, + FlowRecordTriggerType__c, + FlowTriggerSObjectType__c, + FlowTriggerOrder__c, + FlowTriggerType__c, + FlowVersionApiVersionRuntime__c, + FlowVersionNumber__c, + FlowVersionRunInMode__c, + Id, + OriginLocation__c, + OriginType__c + FROM LogEntry__c + WHERE Id = :logEntry.Id + ]; + System.Assert.areEqual(invalidOriginLocation, logEntry.OriginLocation__c); + System.Assert.areEqual('Flow', logEntry.OriginType__c); + System.Assert.isNull(logEntry.FlowActiveVersionId__c); + System.Assert.isNull(logEntry.FlowDescription__c); + System.Assert.isNull(logEntry.FlowDurableId__c); + System.Assert.isNull(logEntry.FlowLabel__c); + System.Assert.isNull(logEntry.FlowLastModifiedByName__c); + System.Assert.isNull(logEntry.FlowLastModifiedDate__c); + System.Assert.isNull(logEntry.FlowProcessType__c); + System.Assert.isNull(logEntry.FlowRecordTriggerType__c); + System.Assert.isNull(logEntry.FlowTriggerSObjectType__c); + System.Assert.isNull(logEntry.FlowTriggerOrder__c); + System.Assert.isNull(logEntry.FlowTriggerType__c); + System.Assert.isNull(logEntry.FlowVersionApiVersionRuntime__c); + System.Assert.isNull(logEntry.FlowVersionNumber__c); + System.Assert.isNull(logEntry.FlowVersionRunInMode__c); + } + private static String getNamespacePrefix() { String className = LogEntryHandler_Tests.class.getName(); String namespacePrefix = className.contains('.') ? className.substringBefore('.') : ''; diff --git a/nebula-logger/core/tests/log-management/classes/LogManagementDataSelector_Tests.cls b/nebula-logger/core/tests/log-management/classes/LogManagementDataSelector_Tests.cls index 20604a4cc..618b5cee8 100644 --- a/nebula-logger/core/tests/log-management/classes/LogManagementDataSelector_Tests.cls +++ b/nebula-logger/core/tests/log-management/classes/LogManagementDataSelector_Tests.cls @@ -96,16 +96,29 @@ private class LogManagementDataSelector_Tests { static void it_returns_cached_recent_log_with_api_release_details() { LoggerTestConfigurator.setupMockSObjectHandlerConfigurations(); LoggerTestConfigurator.getSObjectHandlerConfiguration(Schema.Log__c.SObjectType).IsEnabled__c = false; - Log__c olderLog = new Log__c(ApiReleaseNumber__c = 'QWERTY', ApiReleaseVersion__c = 'ASDF', TransactionId__c = 'ABC'); - Log__c expectedLog = new Log__c(ApiReleaseNumber__c = 'QWERTY', ApiReleaseVersion__c = 'ASDF', TransactionId__c = 'XYZ'); + Log__c olderLog = new Log__c( + ApiReleaseNumber__c = 'olderLog.ApiReleaseNumber__c', + ApiReleaseVersion__c = 'olderLog.ApiReleaseVersion__c', + OrganizationReleaseNumber__c = 'olderLog.OrganizationReleaseNumber__c', + OrganizationReleaseVersion__c = 'olderLog.OrganizationReleaseVersion__c', + TransactionId__c = 'olderLog.TransactionId__c' + ); + Log__c expectedLog = new Log__c( + ApiReleaseNumber__c = 'expectedLog.ApiReleaseNumber__c', + ApiReleaseVersion__c = 'expectedLog.ApiReleaseVersion__c', + OrganizationReleaseNumber__c = 'expectedLog.OrganizationReleaseNumber__c', + OrganizationReleaseVersion__c = 'expectedLog.OrganizationReleaseVersion__c', + TransactionId__c = 'expectedLog.TransactionId__c' + ); insert new List{ olderLog, expectedLog }; System.Test.setCreatedDate(olderLog.Id, System.now().addMinutes(-5)); System.Assert.areEqual(1, System.Limits.getQueries()); - for (Integer i = 0; i < 5; i++) { + for (Integer i = 0; i < 3; i++) { Log__c returnedLog = LogManagementDataSelector.getInstance().getCachedRecentLogWithApiReleaseDetails(); System.Assert.areEqual(expectedLog.Id, returnedLog.Id); + System.Assert.areEqual(JSON.serialize(expectedLog), JSON.serialize(expectedLog)); } System.Assert.areEqual(2, System.Limits.getQueries()); diff --git a/nebula-logger/core/tests/log-management/classes/LoggerHomeHeaderController_Tests.cls b/nebula-logger/core/tests/log-management/classes/LoggerHomeHeaderController_Tests.cls index d209a4d71..97ef6385a 100644 --- a/nebula-logger/core/tests/log-management/classes/LoggerHomeHeaderController_Tests.cls +++ b/nebula-logger/core/tests/log-management/classes/LoggerHomeHeaderController_Tests.cls @@ -31,7 +31,6 @@ private class LoggerHomeHeaderController_Tests { System.Assert.areEqual(Logger.getOrganizationApiVersion(), returnedEnvironment.organizationApiVersion); System.Assert.areEqual(organization.CreatedBy.Username, returnedEnvironment.organizationCreatedByUsername); System.Assert.areEqual(System.URL.getOrgDomainUrl()?.toExternalForm(), returnedEnvironment.organizationDomainUrl); - System.Assert.areEqual(mockApiResponse.environment, returnedEnvironment.organizationEnvironment); System.Assert.areEqual(organization.CreatedDate.format(), returnedEnvironment.organizationFormattedCreatedDate); System.Assert.areEqual(System.UserInfo.getOrganizationId(), returnedEnvironment.organizationId); System.Assert.areEqual(mockApiResponse.location, returnedEnvironment.organizationInstanceLocation); @@ -41,7 +40,6 @@ private class LoggerHomeHeaderController_Tests { System.Assert.areEqual(System.UserInfo.getOrganizationName(), returnedEnvironment.organizationName); System.Assert.areEqual(mockApiResponse.releaseNumber, returnedEnvironment.organizationReleaseNumber); System.Assert.areEqual(mockApiResponse.releaseVersion, returnedEnvironment.organizationReleaseVersion); - System.Assert.areEqual(mockApiResponse.status, returnedEnvironment.organizationStatus); System.Assert.areEqual(organization.OrganizationType, returnedEnvironment.organizationType); } @@ -66,7 +64,6 @@ private class LoggerHomeHeaderController_Tests { System.Assert.areEqual(Logger.getOrganizationApiVersion(), returnedEnvironment.organizationApiVersion); System.Assert.areEqual(organization.CreatedBy.Username, returnedEnvironment.organizationCreatedByUsername); System.Assert.areEqual(System.URL.getOrgDomainUrl()?.toExternalForm(), returnedEnvironment.organizationDomainUrl); - System.Assert.areEqual(mockApiResponse.environment, returnedEnvironment.organizationEnvironment); System.Assert.areEqual(organization.CreatedDate.format(), returnedEnvironment.organizationFormattedCreatedDate); System.Assert.areEqual(System.UserInfo.getOrganizationId(), returnedEnvironment.organizationId); System.Assert.areEqual(mockApiResponse.location, returnedEnvironment.organizationInstanceLocation); @@ -76,7 +73,6 @@ private class LoggerHomeHeaderController_Tests { System.Assert.areEqual(System.UserInfo.getOrganizationName(), returnedEnvironment.organizationName); System.Assert.areEqual(mockApiResponse.releaseNumber, returnedEnvironment.organizationReleaseNumber); System.Assert.areEqual(mockApiResponse.releaseVersion, returnedEnvironment.organizationReleaseVersion); - System.Assert.areEqual(mockApiResponse.status, returnedEnvironment.organizationStatus); System.Assert.areEqual(organization.OrganizationType, returnedEnvironment.organizationType); } @@ -95,7 +91,6 @@ private class LoggerHomeHeaderController_Tests { System.Assert.areEqual(Logger.getOrganizationApiVersion(), returnedEnvironment.organizationApiVersion); System.Assert.areEqual(organization.CreatedBy.Username, returnedEnvironment.organizationCreatedByUsername); System.Assert.areEqual(System.URL.getOrgDomainUrl()?.toExternalForm(), returnedEnvironment.organizationDomainUrl); - System.Assert.areEqual('Unknown', returnedEnvironment.organizationEnvironment); System.Assert.areEqual(organization.CreatedDate.format(), returnedEnvironment.organizationFormattedCreatedDate); System.Assert.areEqual(System.UserInfo.getOrganizationId(), returnedEnvironment.organizationId); System.Assert.areEqual('Unknown', returnedEnvironment.organizationInstanceLocation); @@ -105,18 +100,15 @@ private class LoggerHomeHeaderController_Tests { System.Assert.areEqual(System.UserInfo.getOrganizationName(), returnedEnvironment.organizationName); System.Assert.areEqual('Unknown', returnedEnvironment.organizationReleaseNumber); System.Assert.areEqual('Unknown', returnedEnvironment.organizationReleaseVersion); - System.Assert.areEqual('Unknown', returnedEnvironment.organizationStatus); System.Assert.areEqual(organization.OrganizationType, returnedEnvironment.organizationType); } private static Logger.StatusApiResponse createMockStatusApiResponse() { Logger.StatusApiResponse mockApiResponse = new Logger.StatusApiResponse(); - mockApiResponse.environment = 'sandbox'; mockApiResponse.location = 'NA'; mockApiResponse.maintenanceWindow = 'Saturdays 07:00 PM - 11:00 PM PST'; mockApiResponse.releaseNumber = '242.19.17'; mockApiResponse.releaseVersion = 'Spring \'23 Patch 19.17'; - mockApiResponse.status = 'OK'; return mockApiResponse; } } diff --git a/nebula-logger/core/tests/logger-engine/classes/ComponentLogger_Tests.cls b/nebula-logger/core/tests/logger-engine/classes/ComponentLogger_Tests.cls index f3e5eb4b2..37c2bf12e 100644 --- a/nebula-logger/core/tests/logger-engine/classes/ComponentLogger_Tests.cls +++ b/nebula-logger/core/tests/logger-engine/classes/ComponentLogger_Tests.cls @@ -49,14 +49,7 @@ private class ComponentLogger_Tests { @IsTest static void it_should_save_component_log_entry() { LoggerDataStore.setMock(LoggerMockDataStore.getEventBus()); - User currentUser = new User(FirstName = System.UserInfo.getFirstName(), Id = System.UserInfo.getUserId(), ProfileId = System.UserInfo.getProfileId()); - ComponentLogger.ComponentLogEntry componentLogEntry = new ComponentLogger.ComponentLogEntry(); - componentLogEntry.loggingLevel = System.LoggingLevel.INFO.name(); - componentLogEntry.message = 'hello, world'; - componentLogEntry.recordId = currentUser.Id; - componentLogEntry.record = currentUser; - componentLogEntry.timestamp = System.now().addDays(-1 / 24); - componentLogEntry.tags = new List{ 'some tag', 'one more tag' }; + ComponentLogger.ComponentLogEntry componentLogEntry = createMockComponentLogEntry(); System.Assert.areEqual(0, Logger.saveLogCallCount); System.Assert.areEqual(0, LoggerMockDataStore.getEventBus().getPublishCallCount()); System.Assert.areEqual(0, LoggerMockDataStore.getEventBus().getPublishedPlatformEvents().size()); @@ -68,10 +61,16 @@ private class ComponentLogger_Tests { System.Assert.areEqual(1, LoggerMockDataStore.getEventBus().getPublishedPlatformEvents().size()); LogEntryEvent__e publishedLogEntryEvent = (LogEntryEvent__e) LoggerMockDataStore.getEventBus().getPublishedPlatformEvents().get(0); System.Assert.areEqual('Component', publishedLogEntryEvent.OriginType__c); + System.Assert.areEqual(componentLogEntry.browserFormFactor, publishedLogEntryEvent.BrowserFormFactor__c); + System.Assert.areEqual(componentLogEntry.browserLanguage, publishedLogEntryEvent.BrowserLanguage__c); + System.Assert.areEqual(componentLogEntry.browserScreenResolution, publishedLogEntryEvent.BrowserScreenResolution__c); + System.Assert.areEqual(componentLogEntry.browserUrl, publishedLogEntryEvent.BrowserUrl__c); + System.Assert.areEqual(componentLogEntry.browserUserAgent, publishedLogEntryEvent.BrowserUserAgent__c); + System.Assert.areEqual(componentLogEntry.browserWindowResolution, publishedLogEntryEvent.BrowserWindowResolution__c); System.Assert.areEqual(componentLogEntry.loggingLevel, publishedLogEntryEvent.LoggingLevel__c); System.Assert.areEqual(componentLogEntry.message, publishedLogEntryEvent.Message__c); System.Assert.areEqual(componentLogEntry.recordId, publishedLogEntryEvent.RecordId__c); - System.Assert.areEqual(JSON.serializePretty(currentUser), publishedLogEntryEvent.RecordJson__c); + System.Assert.areEqual(JSON.serializePretty(componentLogEntry.record), publishedLogEntryEvent.RecordJson__c); System.Assert.areEqual(Schema.SObjectType.User.getName(), publishedLogEntryEvent.RecordSObjectType__c); System.Assert.areEqual(componentLogEntry.timestamp, publishedLogEntryEvent.Timestamp__c); } @@ -80,15 +79,8 @@ private class ComponentLogger_Tests { static void it_should_save_component_log_entry_with_queueable_job() { LoggerDataStore.setMock(LoggerMockDataStore.getEventBus()); LoggerDataStore.setMock(LoggerMockDataStore.getJobQueue()); - User currentUser = new User(FirstName = System.UserInfo.getFirstName(), Id = System.UserInfo.getUserId(), ProfileId = System.UserInfo.getProfileId()); System.Assert.areEqual(0, System.Limits.getQueueableJobs(), 'Test should start with 0 queueable jobs used'); - ComponentLogger.ComponentLogEntry componentLogEntry = new ComponentLogger.ComponentLogEntry(); - componentLogEntry.loggingLevel = System.LoggingLevel.INFO.name(); - componentLogEntry.message = 'hello, world'; - componentLogEntry.recordId = currentUser.Id; - componentLogEntry.record = currentUser; - componentLogEntry.timestamp = System.now().addDays(-1 / 24); - componentLogEntry.tags = new List{ 'some tag', 'one more tag' }; + ComponentLogger.ComponentLogEntry componentLogEntry = createMockComponentLogEntry(); System.Test.startTest(); System.Assert.areEqual(0, Logger.saveLogCallCount); System.Assert.areEqual(0, LoggerMockDataStore.getEventBus().getPublishCallCount()); @@ -106,10 +98,16 @@ private class ComponentLogger_Tests { System.Assert.areEqual(1, LoggerMockDataStore.getEventBus().getPublishedPlatformEvents().size()); LogEntryEvent__e publishedLogEntryEvent = (LogEntryEvent__e) LoggerMockDataStore.getEventBus().getPublishedPlatformEvents().get(0); System.Assert.areEqual('Component', publishedLogEntryEvent.OriginType__c); + System.Assert.areEqual(componentLogEntry.browserFormFactor, publishedLogEntryEvent.BrowserFormFactor__c); + System.Assert.areEqual(componentLogEntry.browserLanguage, publishedLogEntryEvent.BrowserLanguage__c); + System.Assert.areEqual(componentLogEntry.browserScreenResolution, publishedLogEntryEvent.BrowserScreenResolution__c); + System.Assert.areEqual(componentLogEntry.browserUrl, publishedLogEntryEvent.BrowserUrl__c); + System.Assert.areEqual(componentLogEntry.browserUserAgent, publishedLogEntryEvent.BrowserUserAgent__c); + System.Assert.areEqual(componentLogEntry.browserWindowResolution, publishedLogEntryEvent.BrowserWindowResolution__c); System.Assert.areEqual(componentLogEntry.loggingLevel, publishedLogEntryEvent.LoggingLevel__c); System.Assert.areEqual(componentLogEntry.message, publishedLogEntryEvent.Message__c); System.Assert.areEqual(componentLogEntry.recordId, publishedLogEntryEvent.RecordId__c); - System.Assert.areEqual(JSON.serializePretty(currentUser), publishedLogEntryEvent.RecordJson__c); + System.Assert.areEqual(JSON.serializePretty(componentLogEntry.record), publishedLogEntryEvent.RecordJson__c); System.Assert.areEqual(Schema.SObjectType.User.getName(), publishedLogEntryEvent.RecordSObjectType__c); System.Assert.areEqual(componentLogEntry.timestamp, publishedLogEntryEvent.Timestamp__c); } @@ -117,19 +115,12 @@ private class ComponentLogger_Tests { @IsTest static void it_should_save_component_log_entry_with_javascript_error() { LoggerDataStore.setMock(LoggerMockDataStore.getEventBus()); - User currentUser = new User(FirstName = System.UserInfo.getFirstName(), Id = System.UserInfo.getUserId(), ProfileId = System.UserInfo.getProfileId()); ComponentLogger.ComponentError mockComponentError = new ComponentLogger.ComponentError(); mockComponentError.message = 'some JavaScript error message'; mockComponentError.stack = 'some \nstack \ntrace \nstring'; mockComponentError.type = 'JavaScript.ReferenceError'; - ComponentLogger.ComponentLogEntry componentLogEntry = new ComponentLogger.ComponentLogEntry(); + ComponentLogger.ComponentLogEntry componentLogEntry = createMockComponentLogEntry(); componentLogEntry.error = mockComponentError; - componentLogEntry.loggingLevel = System.LoggingLevel.INFO.name(); - componentLogEntry.message = 'hello, world'; - componentLogEntry.recordId = currentUser.Id; - componentLogEntry.record = currentUser; - componentLogEntry.timestamp = System.now().addDays(-1 / 24); - componentLogEntry.tags = new List{ 'some tag', 'one more tag' }; System.Assert.areEqual(0, Logger.saveLogCallCount); System.Assert.areEqual(0, LoggerMockDataStore.getEventBus().getPublishCallCount()); System.Assert.areEqual(0, LoggerMockDataStore.getEventBus().getPublishedPlatformEvents().size()); @@ -141,6 +132,12 @@ private class ComponentLogger_Tests { System.Assert.areEqual(1, LoggerMockDataStore.getEventBus().getPublishedPlatformEvents().size()); LogEntryEvent__e publishedLogEntryEvent = (LogEntryEvent__e) LoggerMockDataStore.getEventBus().getPublishedPlatformEvents().get(0); System.Assert.areEqual('Component', publishedLogEntryEvent.OriginType__c); + System.Assert.areEqual(componentLogEntry.browserFormFactor, publishedLogEntryEvent.BrowserFormFactor__c); + System.Assert.areEqual(componentLogEntry.browserLanguage, publishedLogEntryEvent.BrowserLanguage__c); + System.Assert.areEqual(componentLogEntry.browserScreenResolution, publishedLogEntryEvent.BrowserScreenResolution__c); + System.Assert.areEqual(componentLogEntry.browserUrl, publishedLogEntryEvent.BrowserUrl__c); + System.Assert.areEqual(componentLogEntry.browserUserAgent, publishedLogEntryEvent.BrowserUserAgent__c); + System.Assert.areEqual(componentLogEntry.browserWindowResolution, publishedLogEntryEvent.BrowserWindowResolution__c); System.Assert.areEqual(componentLogEntry.loggingLevel, publishedLogEntryEvent.LoggingLevel__c); System.Assert.areEqual(componentLogEntry.message, publishedLogEntryEvent.Message__c); System.Assert.areEqual(componentLogEntry.timestamp, publishedLogEntryEvent.Timestamp__c); @@ -152,7 +149,6 @@ private class ComponentLogger_Tests { @IsTest static void it_should_save_component_log_entry_with_apex_controller_error() { LoggerDataStore.setMock(LoggerMockDataStore.getEventBus()); - User currentUser = new User(FirstName = System.UserInfo.getFirstName(), Id = System.UserInfo.getUserId(), ProfileId = System.UserInfo.getProfileId()); System.Exception mockApexException = new System.DmlException( 'It is with much sadness that I must inform you that this DML statement was most unsuccessful' ); @@ -160,14 +156,8 @@ private class ComponentLogger_Tests { mockComponentError.message = mockApexException.getMessage(); mockComponentError.stack = mockApexException.getStackTraceString(); mockComponentError.type = mockApexException.getTypeName(); - ComponentLogger.ComponentLogEntry componentLogEntry = new ComponentLogger.ComponentLogEntry(); + ComponentLogger.ComponentLogEntry componentLogEntry = createMockComponentLogEntry(); componentLogEntry.error = mockComponentError; - componentLogEntry.loggingLevel = System.LoggingLevel.INFO.name(); - componentLogEntry.message = 'hello, world'; - componentLogEntry.recordId = currentUser.Id; - componentLogEntry.record = currentUser; - componentLogEntry.timestamp = System.now().addDays(-1 / 24); - componentLogEntry.tags = new List{ 'some tag', 'one more tag' }; System.Assert.areEqual(0, Logger.saveLogCallCount); System.Assert.areEqual(0, LoggerMockDataStore.getEventBus().getPublishCallCount()); System.Assert.areEqual(0, LoggerMockDataStore.getEventBus().getPublishedPlatformEvents().size()); @@ -179,6 +169,12 @@ private class ComponentLogger_Tests { System.Assert.areEqual(1, LoggerMockDataStore.getEventBus().getPublishedPlatformEvents().size()); LogEntryEvent__e publishedLogEntryEvent = (LogEntryEvent__e) LoggerMockDataStore.getEventBus().getPublishedPlatformEvents().get(0); System.Assert.areEqual('Component', publishedLogEntryEvent.OriginType__c); + System.Assert.areEqual(componentLogEntry.browserFormFactor, publishedLogEntryEvent.BrowserFormFactor__c); + System.Assert.areEqual(componentLogEntry.browserLanguage, publishedLogEntryEvent.BrowserLanguage__c); + System.Assert.areEqual(componentLogEntry.browserScreenResolution, publishedLogEntryEvent.BrowserScreenResolution__c); + System.Assert.areEqual(componentLogEntry.browserUrl, publishedLogEntryEvent.BrowserUrl__c); + System.Assert.areEqual(componentLogEntry.browserUserAgent, publishedLogEntryEvent.BrowserUserAgent__c); + System.Assert.areEqual(componentLogEntry.browserWindowResolution, publishedLogEntryEvent.BrowserWindowResolution__c); System.Assert.areEqual(componentLogEntry.loggingLevel, publishedLogEntryEvent.LoggingLevel__c); System.Assert.areEqual(componentLogEntry.message, publishedLogEntryEvent.Message__c); System.Assert.areEqual(componentLogEntry.timestamp, publishedLogEntryEvent.Timestamp__c); @@ -191,11 +187,8 @@ private class ComponentLogger_Tests { static void it_should_set_logger_scenario() { LoggerDataStore.setMock(LoggerMockDataStore.getEventBus()); Logger.getUserSettings().LoggingLevel__c = System.LoggingLevel.FINEST.name(); - ComponentLogger.ComponentLogEntry componentLogEntry = new ComponentLogger.ComponentLogEntry(); - componentLogEntry.loggingLevel = System.LoggingLevel.INFO.name(); - componentLogEntry.message = 'hello, world'; + ComponentLogger.ComponentLogEntry componentLogEntry = createMockComponentLogEntry(); componentLogEntry.scenario = 'Some scenario'; - componentLogEntry.timestamp = System.now(); System.Assert.areEqual(0, Logger.saveLogCallCount); System.Assert.areEqual(0, LoggerMockDataStore.getEventBus().getPublishCallCount()); System.Assert.areEqual(0, LoggerMockDataStore.getEventBus().getPublishedPlatformEvents().size()); @@ -217,11 +210,8 @@ private class ComponentLogger_Tests { String expectedComponentType = 'Aura'; String expectedComponentApiName = 'c/loggerAuraDemo'; String expectedComponentFunctionName = 'saveLogAuraExample'; - ComponentLogger.ComponentLogEntry componentLogEntry = new ComponentLogger.ComponentLogEntry(); - componentLogEntry.loggingLevel = System.LoggingLevel.INFO.name(); - componentLogEntry.message = 'hello, world'; + ComponentLogger.ComponentLogEntry componentLogEntry = createMockComponentLogEntry(); componentLogEntry.stack = getMockAuraComponentStackTrace(); - componentLogEntry.timestamp = System.now().addDays(-1 / 24); System.Assert.areEqual(0, Logger.saveLogCallCount); System.Assert.areEqual(0, LoggerMockDataStore.getEventBus().getPublishCallCount()); System.Assert.areEqual(0, LoggerMockDataStore.getEventBus().getPublishedPlatformEvents().size()); @@ -233,6 +223,12 @@ private class ComponentLogger_Tests { System.Assert.areEqual(1, LoggerMockDataStore.getEventBus().getPublishedPlatformEvents().size()); LogEntryEvent__e publishedLogEntryEvent = (LogEntryEvent__e) LoggerMockDataStore.getEventBus().getPublishedPlatformEvents().get(0); System.Assert.areEqual('Component', publishedLogEntryEvent.OriginType__c); + System.Assert.areEqual(componentLogEntry.browserFormFactor, publishedLogEntryEvent.BrowserFormFactor__c); + System.Assert.areEqual(componentLogEntry.browserLanguage, publishedLogEntryEvent.BrowserLanguage__c); + System.Assert.areEqual(componentLogEntry.browserScreenResolution, publishedLogEntryEvent.BrowserScreenResolution__c); + System.Assert.areEqual(componentLogEntry.browserUrl, publishedLogEntryEvent.BrowserUrl__c); + System.Assert.areEqual(componentLogEntry.browserUserAgent, publishedLogEntryEvent.BrowserUserAgent__c); + System.Assert.areEqual(componentLogEntry.browserWindowResolution, publishedLogEntryEvent.BrowserWindowResolution__c); System.Assert.areEqual(componentLogEntry.loggingLevel, publishedLogEntryEvent.LoggingLevel__c); System.Assert.areEqual(componentLogEntry.message, publishedLogEntryEvent.Message__c); System.Assert.areEqual('Component', publishedLogEntryEvent.OriginType__c); @@ -250,11 +246,8 @@ private class ComponentLogger_Tests { String expectedComponentType = 'LWC'; String expectedComponentApiName = 'c/loggerLWCDemo'; String expectedComponentFunctionName = 'saveLogWebExample'; - ComponentLogger.ComponentLogEntry componentLogEntry = new ComponentLogger.ComponentLogEntry(); - componentLogEntry.loggingLevel = System.LoggingLevel.INFO.name(); - componentLogEntry.message = 'hello, world'; + ComponentLogger.ComponentLogEntry componentLogEntry = createMockComponentLogEntry(); componentLogEntry.stack = getMockWebComponentStackTrace(); - componentLogEntry.timestamp = System.now().addDays(-1 / 24); System.Assert.areEqual(0, Logger.saveLogCallCount); System.Assert.areEqual(0, LoggerMockDataStore.getEventBus().getPublishCallCount()); System.Assert.areEqual(0, LoggerMockDataStore.getEventBus().getPublishedPlatformEvents().size()); @@ -266,6 +259,12 @@ private class ComponentLogger_Tests { System.Assert.areEqual(1, LoggerMockDataStore.getEventBus().getPublishedPlatformEvents().size()); LogEntryEvent__e publishedLogEntryEvent = (LogEntryEvent__e) LoggerMockDataStore.getEventBus().getPublishedPlatformEvents().get(0); System.Assert.areEqual('Component', publishedLogEntryEvent.OriginType__c); + System.Assert.areEqual(componentLogEntry.browserFormFactor, publishedLogEntryEvent.BrowserFormFactor__c); + System.Assert.areEqual(componentLogEntry.browserLanguage, publishedLogEntryEvent.BrowserLanguage__c); + System.Assert.areEqual(componentLogEntry.browserScreenResolution, publishedLogEntryEvent.BrowserScreenResolution__c); + System.Assert.areEqual(componentLogEntry.browserUrl, publishedLogEntryEvent.BrowserUrl__c); + System.Assert.areEqual(componentLogEntry.browserUserAgent, publishedLogEntryEvent.BrowserUserAgent__c); + System.Assert.areEqual(componentLogEntry.browserWindowResolution, publishedLogEntryEvent.BrowserWindowResolution__c); System.Assert.areEqual(componentLogEntry.loggingLevel, publishedLogEntryEvent.LoggingLevel__c); System.Assert.areEqual(componentLogEntry.message, publishedLogEntryEvent.Message__c); System.Assert.areEqual('Component', publishedLogEntryEvent.OriginType__c); @@ -277,6 +276,24 @@ private class ComponentLogger_Tests { System.Assert.areEqual(componentLogEntry.timestamp, publishedLogEntryEvent.Timestamp__c); } + private static ComponentLogger.ComponentLogEntry createMockComponentLogEntry() { + User currentUser = new User(FirstName = System.UserInfo.getFirstName(), Id = System.UserInfo.getUserId(), ProfileId = System.UserInfo.getProfileId()); + ComponentLogger.ComponentLogEntry componentLogEntry = new ComponentLogger.ComponentLogEntry(); + componentLogEntry.browserFormFactor = 'Large'; + componentLogEntry.browserLanguage = 'en-US'; + componentLogEntry.browserScreenResolution = '1536 x 824'; + componentLogEntry.browserUrl = 'https://flow-ruby-5228.scratch.lightning.force.com/lightning/n/Logger_lwc_demo?c__asdfsdf=asdf'; + componentLogEntry.browserUserAgent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/113.0'; + componentLogEntry.browserWindowResolution = '1536 x 474'; + componentLogEntry.loggingLevel = System.LoggingLevel.INFO.name(); + componentLogEntry.message = 'hello, world'; + componentLogEntry.recordId = currentUser.Id; + componentLogEntry.record = currentUser; + componentLogEntry.timestamp = System.now().addDays(-1 / 24); + componentLogEntry.tags = new List{ 'some tag', 'one more tag' }; + return componentLogEntry; + } + private static String getMockAuraComponentStackTrace() { // This is a copy of an actual stack trace generated from c/loggerAuraDemo return 'LogEntryBuilder@https://flow-ability-5496.lightning.force.com/lightning/n/modules/c/logger.js:28:24' + diff --git a/nebula-logger/core/tests/logger-engine/classes/Logger_Tests.cls b/nebula-logger/core/tests/logger-engine/classes/Logger_Tests.cls index b78f8061e..ff766dd03 100644 --- a/nebula-logger/core/tests/logger-engine/classes/Logger_Tests.cls +++ b/nebula-logger/core/tests/logger-engine/classes/Logger_Tests.cls @@ -291,12 +291,13 @@ private class Logger_Tests { @IsTest static void it_should_set_transaction_details() { - for (Integer i = 0; i < 10; i++) { - LogEntryEventBuilder builder = Logger.info('my log entry'); + for (Integer i = 0; i < 3; i++) { + LogEntryEventBuilder builder = Logger.info('my log entry for index ' + i); System.Assert.isNotNull(builder.getLogEntryEvent().LoggerVersionNumber__c); - System.Assert.areEqual(Logger.CURRENT_VERSION_NUMBER, builder.getLogEntryEvent().LoggerVersionNumber__c); + System.Assert.areEqual(Logger.getVersionNumber(), builder.getLogEntryEvent().LoggerVersionNumber__c); System.Assert.areEqual(Logger.getScenario(), builder.getLogEntryEvent().EntryScenario__c); + System.Assert.areEqual(Logger.getOrganizationApiVersion(), builder.getLogEntryEvent().OrganizationApiVersion__c); System.Assert.areEqual(System.URL.getOrgDomainUrl()?.toExternalForm(), builder.getLogEntryEvent().OrganizationDomainUrl__c); System.Assert.areEqual(Logger.getParentLogTransactionId(), builder.getLogEntryEvent().ParentLogTransactionId__c); System.Assert.areEqual(System.Request.getCurrent().getRequestId(), builder.getLogEntryEvent().RequestId__c); @@ -7607,12 +7608,10 @@ private class Logger_Tests { LoggerParameter.setMock(new LoggerParameter__mdt(DeveloperName = 'CallStatusApi', Value__c = System.JSON.serialize(true))); System.Assert.isTrue(LoggerParameter.CALL_STATUS_API); Logger.StatusApiResponse mockApiResponse = new Logger.StatusApiResponse(); - mockApiResponse.environment = 'sandbox'; mockApiResponse.location = 'NA'; mockApiResponse.maintenanceWindow = 'Saturdays 07:00 PM - 11:00 PM PST'; mockApiResponse.releaseNumber = '242.19.17'; mockApiResponse.releaseVersion = 'Spring \'23 Patch 19.17'; - mockApiResponse.status = 'OK'; System.Test.setMock( System.HttpCalloutMock.class, LoggerMockDataCreator.createHttpCallout().setStatusCode(200).setResponseBody(JSON.serialize(mockApiResponse)) diff --git a/nebula-logger/extra-tests/tests/LogEntryHandler_Tests_Flow.cls b/nebula-logger/extra-tests/tests/LogEntryHandler_Tests_Flow.cls index 79d60f1b5..69bfcdabe 100644 --- a/nebula-logger/extra-tests/tests/LogEntryHandler_Tests_Flow.cls +++ b/nebula-logger/extra-tests/tests/LogEntryHandler_Tests_Flow.cls @@ -18,19 +18,22 @@ private class LogEntryHandler_Tests_Flow { insert logEntry; logEntry = getLogEntry(); - System.Assert.isNull(logEntry.OriginLocation__c, 'Origin Location was not null.'); - System.Assert.areEqual('Flow', logEntry.OriginType__c, 'Origin Type was not equal to Flow.'); - System.Assert.isNull(logEntry.FlowActiveVersionId__c, 'FlowActiveVersionId was not null.'); - System.Assert.isNull(logEntry.FlowDescription__c, 'Flow Description was not null.'); - System.Assert.isNull(logEntry.FlowDurableId__c, 'FlowDurableId was not null.'); - System.Assert.isNull(logEntry.FlowLabel__c, 'Flow Label was not null.'); - System.Assert.isNull(logEntry.FlowLastModifiedByName__c, 'FlowLastModifiedByName was not null.'); - System.Assert.isNull(logEntry.FlowLastModifiedDate__c, 'FlowLastModifiedDate was not null.'); - System.Assert.isNull(logEntry.FlowProcessType__c, 'FlowProcessType was not null.'); - System.Assert.isNull(logEntry.FlowTriggerType__c, 'FlowTriggerType was not null.'); - System.Assert.isNull(logEntry.FlowVersionApiVersionRuntime__c, 'FlowVersionApiVersionRuntime was not null.'); - System.Assert.isNull(logEntry.FlowVersionNumber__c, 'FlowVersionNumber was not null.'); - System.Assert.isNull(logEntry.FlowVersionRunInMode__c, 'FlowVersionRunInMode was not null.'); + System.Assert.isNull(logEntry.OriginLocation__c); + System.Assert.areEqual('Flow', logEntry.OriginType__c); + System.Assert.isNull(logEntry.FlowActiveVersionId__c); + System.Assert.isNull(logEntry.FlowDescription__c); + System.Assert.isNull(logEntry.FlowDurableId__c); + System.Assert.isNull(logEntry.FlowLabel__c); + System.Assert.isNull(logEntry.FlowLastModifiedByName__c); + System.Assert.isNull(logEntry.FlowLastModifiedDate__c); + System.Assert.isNull(logEntry.FlowProcessType__c); + System.Assert.isNull(logEntry.FlowRecordTriggerType__c); + System.Assert.isNull(logEntry.FlowTriggerSObjectType__c); + System.Assert.isNull(logEntry.FlowTriggerOrder__c); + System.Assert.isNull(logEntry.FlowTriggerType__c); + System.Assert.isNull(logEntry.FlowVersionApiVersionRuntime__c); + System.Assert.isNull(logEntry.FlowVersionNumber__c); + System.Assert.isNull(logEntry.FlowVersionRunInMode__c); } @IsTest @@ -45,16 +48,19 @@ private class LogEntryHandler_Tests_Flow { insert logEntry; logEntry = getLogEntry(); - System.Assert.areEqual(EXAMPLE_FLOW_API_NAME, logEntry.OriginLocation__c, 'Origin Location was not null.'); - System.Assert.areEqual('Flow', logEntry.OriginType__c, 'OriginType was not flow.'); - System.Assert.areEqual(flowDefinitionView.ActiveVersionId, logEntry.FlowActiveVersionId__c, 'FlowActiveVersionId was incorrect.'); - System.Assert.areEqual(flowDefinitionView.Description, logEntry.FlowDescription__c, 'FlowDescription was incorrect.'); - System.Assert.areEqual(flowDefinitionView.DurableId, logEntry.FlowDurableId__c, 'FlowDurableId was incorrect.'); - System.Assert.areEqual(flowDefinitionView.Label, logEntry.FlowLabel__c, 'FlowLabel was incorrect'); - System.Assert.areEqual(flowDefinitionView.LastModifiedBy, logEntry.FlowLastModifiedByName__c, 'FlowLastModifiedByName was incorrect.'); - System.Assert.areEqual(flowDefinitionView.LastModifiedDate, logEntry.FlowLastModifiedDate__c, 'FlowLastModifiedDate was incorrect.'); - System.Assert.areEqual(flowDefinitionView.ProcessType, logEntry.FlowProcessType__c, 'FlowProcessType was incorrect.'); - System.Assert.areEqual(flowDefinitionView.TriggerType, logEntry.FlowTriggerType__c, 'FlowTriggerType was incorrect.'); + System.Assert.areEqual(EXAMPLE_FLOW_API_NAME, logEntry.OriginLocation__c); + System.Assert.areEqual('Flow', logEntry.OriginType__c); + System.Assert.areEqual(flowDefinitionView.ActiveVersionId, logEntry.FlowActiveVersionId__c); + System.Assert.areEqual(flowDefinitionView.Description, logEntry.FlowDescription__c); + System.Assert.areEqual(flowDefinitionView.DurableId, logEntry.FlowDurableId__c); + System.Assert.areEqual(flowDefinitionView.Label, logEntry.FlowLabel__c); + System.Assert.areEqual(flowDefinitionView.LastModifiedBy, logEntry.FlowLastModifiedByName__c); + System.Assert.areEqual(flowDefinitionView.LastModifiedDate, logEntry.FlowLastModifiedDate__c); + System.Assert.areEqual(flowDefinitionView.ProcessType, logEntry.FlowProcessType__c); + System.Assert.areEqual(flowDefinitionView.RecordTriggerType, logEntry.FlowRecordTriggerType__c); + System.Assert.areEqual(flowDefinitionView.TriggerOrder, logEntry.FlowTriggerOrder__c); + System.Assert.areEqual(flowDefinitionView.TriggerObjectOrEvent.QualifiedApiName, logEntry.FlowTriggerSObjectType__c); + System.Assert.areEqual(flowDefinitionView.TriggerType, logEntry.FlowTriggerType__c); System.Assert.areEqual( 'v' + flowVersion.ApiVersionRuntime + '.0', logEntry.FlowVersionApiVersionRuntime__c, @@ -74,6 +80,9 @@ private class LogEntryHandler_Tests_Flow { FlowLastModifiedByName__c, FlowLastModifiedDate__c, FlowProcessType__c, + FlowRecordTriggerType__c, + FlowTriggerSObjectType__c, + FlowTriggerOrder__c, FlowTriggerType__c, FlowVersionApiVersionRuntime__c, FlowVersionNumber__c, @@ -89,7 +98,20 @@ private class LogEntryHandler_Tests_Flow { private static FlowDefinitionView getFlowDefinitionView() { return [ - SELECT ActiveVersionId, ApiName, Description, DurableId, Label, LastModifiedBy, LastModifiedDate, ManageableState, ProcessType, TriggerType + SELECT + ActiveVersionId, + ApiName, + Description, + DurableId, + Label, + LastModifiedBy, + LastModifiedDate, + ManageableState, + ProcessType, + RecordTriggerType, + TriggerObjectOrEvent.QualifiedApiName, + TriggerOrder, + TriggerType FROM FlowDefinitionView WHERE ApiName = :EXAMPLE_FLOW_API_NAME AND IsActive = TRUE ]; diff --git a/nebula-logger/recipes/lwc/loggerLWCDemo/loggerLWCDemo.js b/nebula-logger/recipes/lwc/loggerLWCDemo/loggerLWCDemo.js index 7a8b2928b..a55955377 100644 --- a/nebula-logger/recipes/lwc/loggerLWCDemo/loggerLWCDemo.js +++ b/nebula-logger/recipes/lwc/loggerLWCDemo/loggerLWCDemo.js @@ -134,6 +134,7 @@ export default class LoggerLWCDemo extends LightningElement { console.log('running saveLog for btn'); this.logger.setScenario(this.scenario); console.log(this.logger); - this.logger.saveLog('QUEUEABLE'); + // this.logger.saveLog('QUEUEABLE'); + this.logger.saveLog(); } } diff --git a/package.json b/package.json index 1d28d3d5d..8a0b32c82 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "nebula-logger", - "version": "4.10.5", + "version": "4.10.6", "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 612e082a1..81e4ec382 100644 --- a/sfdx-project.json +++ b/sfdx-project.json @@ -13,9 +13,9 @@ "package": "Nebula Logger - Core", "path": "./nebula-logger/core", "definitionFile": "./config/scratch-orgs/base-scratch-def.json", - "versionNumber": "4.10.5.NEXT", - "versionName": "New Custom Index for Origin Location Field", - "versionDescription": "Added a custom index on the field LogEntry__c.OriginLocation__c (using the new CustomIndex metadatatype) to improve queries & reports that filter on this field", + "versionNumber": "4.10.6.NEXT", + "versionName": "More Log__c and LogEntry__c fields", + "versionDescription": "Added more fields to capture additional Flow details, organization details, and browser details via logger LWC", "releaseNotesUrl": "https://github.com/jongpie/NebulaLogger/releases", "unpackagedMetadata": { "path": "./nebula-logger/extra-tests" @@ -146,6 +146,7 @@ "Nebula Logger - Core@4.10.3-logger-settings-start-and-end-times": "04t5Y0000023SAfQAM", "Nebula Logger - Core@4.10.4-new-logger-home-page": "04t5Y0000023SC7QAM", "Nebula Logger - Core@4.10.5-new-custom-index-for-origin-location-field": "04t5Y0000023SCHQA2", + "Nebula Logger - Core@4.10.6-more-log__c-and-logentry__c-fields": "04t5Y0000023SCqQAM", "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",