diff --git a/README.md b/README.md index 17a34b5b1..96dbb6f5e 100644 --- a/README.md +++ b/README.md @@ -5,15 +5,15 @@ The most robust logger for Salesforce. Works with Apex, Lightning Components, Flow, Process Builder & Integrations. Designed for Salesforce admins, developers & architects. -## Unlocked Package - v4.12.8 +## Unlocked Package - v4.12.9 -[![Install Unlocked Package in a Sandbox](./images/btn-install-unlocked-package-sandbox.png)](https://test.salesforce.com/packaging/installPackage.apexp?p0=04t5Y000001Mk6cQAC) -[![Install Unlocked Package in Production](./images/btn-install-unlocked-package-production.png)](https://login.salesforce.com/packaging/installPackage.apexp?p0=04t5Y000001Mk6cQAC) +[![Install Unlocked Package in a Sandbox](./images/btn-install-unlocked-package-sandbox.png)](https://test.salesforce.com/packaging/installPackage.apexp?p0=04t5Y000001Mk7BQAS) +[![Install Unlocked Package in Production](./images/btn-install-unlocked-package-production.png)](https://login.salesforce.com/packaging/installPackage.apexp?p0=04t5Y000001Mk7BQAS) [![View Documentation](./images/btn-view-documentation.png)](https://jongpie.github.io/NebulaLogger/) -`sf package install --wait 20 --security-type AdminsOnly --package 04t5Y000001Mk6cQAC` +`sf package install --wait 20 --security-type AdminsOnly --package 04t5Y000001Mk7BQAS` -`sfdx force:package:install --wait 20 --securitytype AdminsOnly --package 04t5Y000001Mk6cQAC` +`sfdx force:package:install --wait 20 --securitytype AdminsOnly --package 04t5Y000001Mk7BQAS` --- diff --git a/docs/apex/Configuration/LoggerParameter.md b/docs/apex/Configuration/LoggerParameter.md index 4895f2a58..dca352184 100644 --- a/docs/apex/Configuration/LoggerParameter.md +++ b/docs/apex/Configuration/LoggerParameter.md @@ -98,6 +98,14 @@ Indicates if Nebula Logger will send an error email notification if any internal Indicates if Nebula Logger will store the header values when logging an instance of `System.HttpResponse`. Controlled by the custom metadata record `LoggerParameter.StoreHttpResponseHeaderValues`, or `true` as the default. Regardless of how this parameter is configured, Nebula Logger will still log the header keys of any instance of `System.HttpResponse` that is logged - this parameter only controls if the header values are stored. +#### `STORE_REST_REQUEST_HEADER_VALUES` → `Boolean` + +Indicates if Nebula Logger will store the header values when logging an instance of `System.RestRequest`. Controlled by the custom metadata record `LoggerParameter.StoreRestRequestHeaderValues`, or `true` as the default. Regardless of how this parameter is configured, Nebula Logger will still log the header keys of any instance of `System.RestRequest` that is logged - this parameter only controls if the header values are stored. + +#### `STORE_REST_RESPONSE_HEADER_VALUES` → `Boolean` + +Indicates if Nebula Logger will store the header values when logging an instance of `System.RestResponse`. Controlled by the custom metadata record `LoggerParameter.StoreRestResponseHeaderValues`, or `true` as the default. Regardless of how this parameter is configured, Nebula Logger will still log the header keys of any instance of `System.RestResponse` that is logged - this parameter only controls if the header values are stored. + #### `SYSTEM_DEBUG_MESSAGE_FORMAT` → `String` The merge-field syntax to use when calling System.debug(). Controlled by the custom metadata record `LoggerParameter.SystebugMessageFormat`, or `{OriginLocation__c}\n{Message__c}` as the default diff --git a/docs/apex/Logger-Engine/LogEntryEventBuilder.md b/docs/apex/Logger-Engine/LogEntryEventBuilder.md index c26b8a93a..2fa923b6a 100644 --- a/docs/apex/Logger-Engine/LogEntryEventBuilder.md +++ b/docs/apex/Logger-Engine/LogEntryEventBuilder.md @@ -565,6 +565,46 @@ LogEntryEventBuilder An instance of LogEntryEventBuilder with the given record. +#### `setRestRequestDetails(System.RestRequest request)` → `LogEntryEventBuilder` + +Sets the log entry event's REST Request fields + +##### Parameters + +| Param | Description | +| --------- | ------------------------------------ | +| `request` | The instance of `RestRequest` to log | + +##### Return + +**Type** + +LogEntryEventBuilder + +**Description** + +The same instance of `LogEntryEventBuilder`, useful for chaining methods + +#### `setRestResponseDetails(System.RestResponse response)` → `LogEntryEventBuilder` + +Sets the log entry event's REST Response fields + +##### Parameters + +| Param | Description | +| ---------- | ------------------------------------- | +| `response` | The instance of `RestResponse` to log | + +##### Return + +**Type** + +LogEntryEventBuilder + +**Description** + +The same instance of `LogEntryEventBuilder`, useful for chaining methods + #### `setTopics(List tags)` → `LogEntryEventBuilder` Deprecated - use `addTags(List<String> tags)` instead. This method will be removed in a future release diff --git a/nebula-logger/core/main/configuration/classes/LoggerParameter.cls b/nebula-logger/core/main/configuration/classes/LoggerParameter.cls index c6a45db4f..ae24508f2 100644 --- a/nebula-logger/core/main/configuration/classes/LoggerParameter.cls +++ b/nebula-logger/core/main/configuration/classes/LoggerParameter.cls @@ -350,6 +350,38 @@ public class LoggerParameter { private set; } + /** + * @description Indicates if Nebula Logger will store the header values when logging an instance of `System.RestRequest`. + * Controlled by the custom metadata record `LoggerParameter.StoreRestRequestHeaderValues`, or `true` as the default. + * Regardless of how this parameter is configured, Nebula Logger will still log the header keys of any instance of + * `System.RestRequest` that is logged - this parameter only controls if the header values are stored. + */ + public static final Boolean STORE_REST_REQUEST_HEADER_VALUES { + get { + if (STORE_REST_REQUEST_HEADER_VALUES == null) { + STORE_REST_REQUEST_HEADER_VALUES = getBoolean('StoreRestRequestHeaderValues', true); + } + return STORE_REST_REQUEST_HEADER_VALUES; + } + private set; + } + + /** + * @description Indicates if Nebula Logger will store the header values when logging an instance of `System.RestResponse`. + * Controlled by the custom metadata record `LoggerParameter.StoreRestResponseHeaderValues`, or `true` as the default. + * Regardless of how this parameter is configured, Nebula Logger will still log the header keys of any instance of + * `System.RestResponse` that is logged - this parameter only controls if the header values are stored. + */ + public static final Boolean STORE_REST_RESPONSE_HEADER_VALUES { + get { + if (STORE_REST_RESPONSE_HEADER_VALUES == null) { + STORE_REST_RESPONSE_HEADER_VALUES = getBoolean('StoreRestResponseHeaderValues', true); + } + return STORE_REST_RESPONSE_HEADER_VALUES; + } + private set; + } + /** * @description The merge-field syntax to use when calling System.debug(). * Controlled by the custom metadata record `LoggerParameter.SystemDebugMessageFormat`, or `{OriginLocation__c}\n{Message__c}` as the default diff --git a/nebula-logger/core/main/configuration/customMetadata/LoggerParameter.StoreHttpResponseHeaderValues.md-meta.xml b/nebula-logger/core/main/configuration/customMetadata/LoggerParameter.StoreHttpResponseHeaderValues.md-meta.xml index 14c46b4c6..b78092ae6 100644 --- a/nebula-logger/core/main/configuration/customMetadata/LoggerParameter.StoreHttpResponseHeaderValues.md-meta.xml +++ b/nebula-logger/core/main/configuration/customMetadata/LoggerParameter.StoreHttpResponseHeaderValues.md-meta.xml @@ -4,7 +4,7 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" > - + false Description__c diff --git a/nebula-logger/core/main/configuration/customMetadata/LoggerParameter.StoreRestRequestHeaderValues.md-meta.xml b/nebula-logger/core/main/configuration/customMetadata/LoggerParameter.StoreRestRequestHeaderValues.md-meta.xml new file mode 100644 index 000000000..eac2823a6 --- /dev/null +++ b/nebula-logger/core/main/configuration/customMetadata/LoggerParameter.StoreRestRequestHeaderValues.md-meta.xml @@ -0,0 +1,23 @@ + + + + false + + Description__c + When set to 'true' (default), Nebula Logger will store the header values of any instance of an RestRequest that is logged using the instance method LogEntryEventBuilder.setRestRequestDetails(). + +When set to 'false', the header values are not stored or referenced by Nebula Logger. + +Regardless of how this parameter is configured, Nebula Logger will still log the header keys of any instance of an RestRequest that is logged - this parameter only controls if the header values are stored. + + + Value__c + true + + diff --git a/nebula-logger/core/main/configuration/customMetadata/LoggerParameter.StoreRestResponseHeaderValues.md-meta.xml b/nebula-logger/core/main/configuration/customMetadata/LoggerParameter.StoreRestResponseHeaderValues.md-meta.xml new file mode 100644 index 000000000..6896588ea --- /dev/null +++ b/nebula-logger/core/main/configuration/customMetadata/LoggerParameter.StoreRestResponseHeaderValues.md-meta.xml @@ -0,0 +1,23 @@ + + + + false + + Description__c + When set to 'true' (default), Nebula Logger will store the header values of any instance of an RestResponse that is logged using the instance method LogEntryEventBuilder.setRestResponseDetails(). + +When set to 'false', the header values are not stored or referenced by Nebula Logger. + +Regardless of how this parameter is configured, Nebula Logger will still log the header keys of any instance of an RestResponse that is logged - this parameter only controls if the header values are stored. + + + Value__c + true + + diff --git a/nebula-logger/core/main/log-management/classes/LogEntryEventHandler.cls b/nebula-logger/core/main/log-management/classes/LogEntryEventHandler.cls index 4cff4a20c..aee8dc3a8 100644 --- a/nebula-logger/core/main/log-management/classes/LogEntryEventHandler.cls +++ b/nebula-logger/core/main/log-management/classes/LogEntryEventHandler.cls @@ -326,6 +326,20 @@ public without sharing class LogEntryEventHandler extends LoggerSObjectHandler { RecordSObjectClassification__c = logEntryEvent.RecordSObjectClassification__c, RecordSObjectType__c = logEntryEvent.RecordSObjectType__c, RecordSObjectTypeNamespace__c = logEntryEvent.RecordSObjectTypeNamespace__c, + RestRequestBody__c = logEntryEvent.RestRequestBody__c, + RestRequestBodyMasked__c = logEntryEvent.RestRequestBodyMasked__c, + RestRequestHeaderKeys__c = logEntryEvent.RestRequestHeaderKeys__c, + RestRequestHeaders__c = logEntryEvent.RestRequestHeaders__c, + RestRequestMethod__c = logEntryEvent.RestRequestMethod__c, + RestRequestParameters__c = logEntryEvent.RestRequestParameters__c, + RestRequestRemoteAddress__c = logEntryEvent.RestRequestRemoteAddress__c, + RestRequestResourcePath__c = logEntryEvent.RestRequestResourcePath__c, + RestRequestUri__c = logEntryEvent.RestRequestUri__c, + RestResponseBody__c = logEntryEvent.RestResponseBody__c, + RestResponseBodyMasked__c = logEntryEvent.RestResponseBodyMasked__c, + RestResponseHeaderKeys__c = logEntryEvent.RestResponseHeaderKeys__c, + RestResponseHeaders__c = logEntryEvent.RestResponseHeaders__c, + RestResponseStatusCode__c = logEntryEvent.RestResponseStatusCode__c, StackTrace__c = logEntryEvent.StackTrace__c, Timestamp__c = timestamp, TransactionEntryNumber__c = logEntryEvent.TransactionEntryNumber__c, diff --git a/nebula-logger/core/main/log-management/classes/LogEntryHandler.cls b/nebula-logger/core/main/log-management/classes/LogEntryHandler.cls index 92c4ab50f..05c2e5f43 100644 --- a/nebula-logger/core/main/log-management/classes/LogEntryHandler.cls +++ b/nebula-logger/core/main/log-management/classes/LogEntryHandler.cls @@ -273,6 +273,12 @@ public without sharing class LogEntryHandler extends LoggerSObjectHandler { logEntry.HasHttpResponseHeaders__c = logEntry.HttpResponseHeaders__c != null; logEntry.HasInlineTags__c = logEntry.Tags__c != null; logEntry.HasRecordJson__c = logEntry.RecordJson__c != null; + logEntry.HasRestRequestBody__c = logEntry.RestRequestBody__c != null; + logEntry.HasRestRequestHeaderKeys__c = logEntry.RestRequestHeaderKeys__c != null; + logEntry.HasRestRequestHeaders__c = logEntry.RestRequestHeaders__c != null; + logEntry.HasRestResponseBody__c = logEntry.RestResponseBody__c != null; + logEntry.HasRestResponseHeaderKeys__c = logEntry.RestResponseHeaderKeys__c != null; + logEntry.HasRestResponseHeaders__c = logEntry.RestResponseHeaders__c != null; logEntry.HasStackTrace__c = logEntry.StackTrace__c != null; } } 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 46381ad0a..e76aa72ae 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 @@ -657,6 +657,210 @@ Facet-6395ceae-5694-468a-911f-714456910736 Facet + + + + + uiBehavior + none + + Record.RestRequestResourcePath__c + RecordRestRequestResourcePath_cField + + + + + + uiBehavior + none + + Record.RestRequestUri__c + RecordRestRequestUri_cField + + + + + + uiBehavior + none + + Record.RestRequestMethod__c + RecordRestRequestMethod_cField + + + + + + uiBehavior + none + + Record.RestRequestRemoteAddress__c + RecordRestRequestRemoteAddress_cField + + + + + + uiBehavior + none + + Record.RestRequestParameters__c + RecordRestRequestParameters_cField + + + + + + uiBehavior + none + + Record.RestRequestHeaderKeys__c + RecordRestRequestHeaderKeys_cField + + + {!Record.HasRestRequestHeaders__c} + EQUAL + false + + + + + + + + uiBehavior + none + + Record.RestRequestHeaders__c + RecordRestRequestHeaders_cField + + + {!Record.HasRestRequestHeaderKeys__c} + EQUAL + true + + + + + + + + uiBehavior + none + + Record.RestRequestBody__c + RecordRestRequestBody_cField + + + + + + uiBehavior + none + + Record.RestRequestBodyMasked__c + RecordRestRequestBodyMasked_cField + + + Facet-6411b37c-0886-4766-a9c5-5ede0e60cb97 + Facet + + + + + + body + Facet-6411b37c-0886-4766-a9c5-5ede0e60cb97 + + flexipage:column + flexipage_column20 + + + Facet-f29c9a43-fb99-4d37-be66-925bb2bbeecb + Facet + + + + + + uiBehavior + none + + Record.RestResponseStatusCode__c + RecordRestResponseStatusCode_cField + + + + + + uiBehavior + none + + Record.RestResponseHeaderKeys__c + RecordRestResponseHeaderKeys_cField + + + {!Record.HasHttpResponseHeaders__c} + EQUAL + false + + + + + + + + uiBehavior + none + + Record.RestResponseHeaders__c + RecordRestResponseHeaders_cField + + + {!Record.HasRestResponseHeaders__c} + EQUAL + true + + + + + + + + uiBehavior + none + + Record.RestResponseBody__c + RecordRestResponseBody_cField + + + + + + uiBehavior + none + + Record.RestResponseBodyMasked__c + RecordRestResponseBodyMasked_cField + + + Facet-c8e76a2d-dfaa-4163-b3cf-bbe5fa9cbec8 + Facet + + + + + + body + Facet-c8e76a2d-dfaa-4163-b3cf-bbe5fa9cbec8 + + flexipage:column + flexipage_column19 + + + Facet-2181992b-5c3d-435c-a152-f9b0147323c2 + Facet + @@ -787,7 +991,7 @@ label - HTTP Request + HTTP Callout Request flexipage:fieldSection flexipage_fieldSection1 @@ -811,7 +1015,7 @@ label - HTTP Response + HTTP Callout Response flexipage:fieldSection flexipage_fieldSection10 @@ -834,6 +1038,66 @@ + + + + columns + Facet-f29c9a43-fb99-4d37-be66-925bb2bbeecb + + + horizontalAlignment + false + + + label + Apex REST Service Request + + flexipage:fieldSection + flexipage_fieldSection14 + + + {!Record.RestRequestResourcePath__c} + NE + + + + + + + + columns + Facet-2181992b-5c3d-435c-a152-f9b0147323c2 + + + horizontalAlignment + false + + + label + Apex REST Service Response + + flexipage:fieldSection + flexipage_fieldSection13 + + 1 OR 2 OR 3 + + {!Record.HasRestResponseBody__c} + EQUAL + true + + + {!Record.HasRestResponseHeaderKeys__c} + EQUAL + true + + + {!Record.HasRestResponseHeaders__c} + EQUAL + true + + + + Facet-7beef2bc-28d3-490f-96b8-7a8f85424802 Facet diff --git a/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/ExceptionMessage__c.field-meta.xml b/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/ExceptionMessage__c.field-meta.xml index 13af60bbe..5d2816b65 100644 --- a/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/ExceptionMessage__c.field-meta.xml +++ b/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/ExceptionMessage__c.field-meta.xml @@ -5,7 +5,7 @@ None false - 131072 + 5000 Confidential false false diff --git a/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/ExceptionStackTrace__c.field-meta.xml b/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/ExceptionStackTrace__c.field-meta.xml index f12374ca0..123f56902 100644 --- a/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/ExceptionStackTrace__c.field-meta.xml +++ b/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/ExceptionStackTrace__c.field-meta.xml @@ -5,7 +5,7 @@ None false - 131072 + 5000 Confidential true false diff --git a/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/FlowDescription__c.field-meta.xml b/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/FlowDescription__c.field-meta.xml index 935672cf1..2102f45ec 100644 --- a/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/FlowDescription__c.field-meta.xml +++ b/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/FlowDescription__c.field-meta.xml @@ -7,7 +7,7 @@ false Flow definition information, specified by the org’s admin. - 131072 + 5000 Confidential false false diff --git a/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/HasRestRequestBody__c.field-meta.xml b/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/HasRestRequestBody__c.field-meta.xml new file mode 100644 index 000000000..3e06ed26e --- /dev/null +++ b/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/HasRestRequestBody__c.field-meta.xml @@ -0,0 +1,13 @@ + + + HasRestRequestBody__c + Active + None + false + false + + Confidential + false + false + Checkbox + diff --git a/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/HasRestRequestHeaderKeys__c.field-meta.xml b/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/HasRestRequestHeaderKeys__c.field-meta.xml new file mode 100644 index 000000000..4f3c48de6 --- /dev/null +++ b/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/HasRestRequestHeaderKeys__c.field-meta.xml @@ -0,0 +1,13 @@ + + + HasRestRequestHeaderKeys__c + Active + None + false + false + + Confidential + false + false + Checkbox + diff --git a/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/HasRestRequestHeaders__c.field-meta.xml b/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/HasRestRequestHeaders__c.field-meta.xml new file mode 100644 index 000000000..ea2858f7b --- /dev/null +++ b/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/HasRestRequestHeaders__c.field-meta.xml @@ -0,0 +1,13 @@ + + + HasRestRequestHeaders__c + Active + None + false + false + + Confidential + false + false + Checkbox + diff --git a/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/HasRestResponseBody__c.field-meta.xml b/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/HasRestResponseBody__c.field-meta.xml new file mode 100644 index 000000000..f4ba5b12e --- /dev/null +++ b/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/HasRestResponseBody__c.field-meta.xml @@ -0,0 +1,13 @@ + + + HasRestResponseBody__c + Active + None + false + false + + Confidential + false + false + Checkbox + diff --git a/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/HasRestResponseHeaderKeys__c.field-meta.xml b/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/HasRestResponseHeaderKeys__c.field-meta.xml new file mode 100644 index 000000000..981c9e03c --- /dev/null +++ b/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/HasRestResponseHeaderKeys__c.field-meta.xml @@ -0,0 +1,13 @@ + + + HasRestResponseHeaderKeys__c + Active + None + false + false + + Confidential + false + false + Checkbox + diff --git a/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/HasRestResponseHeaders__c.field-meta.xml b/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/HasRestResponseHeaders__c.field-meta.xml new file mode 100644 index 000000000..6dc22c7bd --- /dev/null +++ b/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/HasRestResponseHeaders__c.field-meta.xml @@ -0,0 +1,13 @@ + + + HasRestResponseHeaders__c + Active + None + false + false + + Confidential + false + false + Checkbox + diff --git a/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/RestRequestBodyMasked__c.field-meta.xml b/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/RestRequestBodyMasked__c.field-meta.xml new file mode 100644 index 000000000..931546870 --- /dev/null +++ b/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/RestRequestBodyMasked__c.field-meta.xml @@ -0,0 +1,14 @@ + + + RestRequestBodyMasked__c + Active + None + false + false + Indicates if sensitive data was removed from the REST Request Body, using log entry data mask rules + + Confidential + false + false + Checkbox + diff --git a/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/RestRequestBody__c.field-meta.xml b/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/RestRequestBody__c.field-meta.xml new file mode 100644 index 000000000..d8b0dab71 --- /dev/null +++ b/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/RestRequestBody__c.field-meta.xml @@ -0,0 +1,14 @@ + + + RestRequestBody__c + Active + None + false + + 131072 + Confidential + false + false + LongTextArea + 5 + diff --git a/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/RestRequestHeaderKeys__c.field-meta.xml b/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/RestRequestHeaderKeys__c.field-meta.xml new file mode 100644 index 000000000..fefea861e --- /dev/null +++ b/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/RestRequestHeaderKeys__c.field-meta.xml @@ -0,0 +1,14 @@ + + + RestRequestHeaderKeys__c + Active + None + false + + 1000 + Confidential + false + false + LongTextArea + 5 + diff --git a/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/RestRequestHeaders__c.field-meta.xml b/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/RestRequestHeaders__c.field-meta.xml new file mode 100644 index 000000000..a3e61f3ec --- /dev/null +++ b/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/RestRequestHeaders__c.field-meta.xml @@ -0,0 +1,14 @@ + + + RestRequestHeaders__c + Active + None + false + + 5000 + Confidential + false + false + LongTextArea + 5 + diff --git a/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/RestRequestMethod__c.field-meta.xml b/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/RestRequestMethod__c.field-meta.xml new file mode 100644 index 000000000..fab2d28c8 --- /dev/null +++ b/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/RestRequestMethod__c.field-meta.xml @@ -0,0 +1,53 @@ + + + RestRequestMethod__c + Active + None + false + + false + Confidential + false + false + Picklist + + + false + + DELETE + false + + + + GET + false + + + + HEAD + false + + + + PATCH + false + + + + POST + false + + + + PUT + false + + + + TRACE + false + + + + + diff --git a/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/RestRequestParameters__c.field-meta.xml b/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/RestRequestParameters__c.field-meta.xml new file mode 100644 index 000000000..4a0803b4d --- /dev/null +++ b/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/RestRequestParameters__c.field-meta.xml @@ -0,0 +1,14 @@ + + + RestRequestParameters__c + Active + None + false + + 5000 + Confidential + false + false + LongTextArea + 5 + diff --git a/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/RestRequestRemoteAddress__c.field-meta.xml b/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/RestRequestRemoteAddress__c.field-meta.xml new file mode 100644 index 000000000..b25cdc132 --- /dev/null +++ b/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/RestRequestRemoteAddress__c.field-meta.xml @@ -0,0 +1,15 @@ + + + RestRequestRemoteAddress__c + Active + None + false + + 255 + false + Confidential + false + false + Text + false + diff --git a/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/RestRequestResourcePath__c.field-meta.xml b/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/RestRequestResourcePath__c.field-meta.xml new file mode 100644 index 000000000..77f46983e --- /dev/null +++ b/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/RestRequestResourcePath__c.field-meta.xml @@ -0,0 +1,15 @@ + + + RestRequestResourcePath__c + Active + None + false + + 255 + false + Confidential + false + false + Text + false + diff --git a/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/RestRequestUri__c.field-meta.xml b/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/RestRequestUri__c.field-meta.xml new file mode 100644 index 000000000..24a99037c --- /dev/null +++ b/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/RestRequestUri__c.field-meta.xml @@ -0,0 +1,15 @@ + + + RestRequestUri__c + Active + None + false + + 255 + false + Confidential + false + false + Text + false + diff --git a/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/RestResponseBodyMasked__c.field-meta.xml b/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/RestResponseBodyMasked__c.field-meta.xml new file mode 100644 index 000000000..e36d7d077 --- /dev/null +++ b/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/RestResponseBodyMasked__c.field-meta.xml @@ -0,0 +1,14 @@ + + + RestResponseBodyMasked__c + Active + None + false + false + Indicates if sensitive data was removed from the HTTP Response Body, using log entry data mask rules + + Confidential + false + false + Checkbox + diff --git a/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/RestResponseBody__c.field-meta.xml b/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/RestResponseBody__c.field-meta.xml new file mode 100644 index 000000000..a4680d9f0 --- /dev/null +++ b/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/RestResponseBody__c.field-meta.xml @@ -0,0 +1,14 @@ + + + RestResponseBody__c + Active + None + false + + 131072 + Confidential + false + false + LongTextArea + 5 + diff --git a/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/RestResponseHeaderKeys__c.field-meta.xml b/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/RestResponseHeaderKeys__c.field-meta.xml new file mode 100644 index 000000000..d077f4eae --- /dev/null +++ b/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/RestResponseHeaderKeys__c.field-meta.xml @@ -0,0 +1,14 @@ + + + RestResponseHeaderKeys__c + Active + None + false + + 1000 + Confidential + false + false + LongTextArea + 5 + diff --git a/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/RestResponseHeaders__c.field-meta.xml b/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/RestResponseHeaders__c.field-meta.xml new file mode 100644 index 000000000..05535c018 --- /dev/null +++ b/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/RestResponseHeaders__c.field-meta.xml @@ -0,0 +1,14 @@ + + + RestResponseHeaders__c + Active + None + false + + 5000 + Confidential + false + false + LongTextArea + 5 + diff --git a/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/RestResponseStatusCode__c.field-meta.xml b/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/RestResponseStatusCode__c.field-meta.xml new file mode 100644 index 000000000..e331f27ab --- /dev/null +++ b/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/RestResponseStatusCode__c.field-meta.xml @@ -0,0 +1,16 @@ + + + RestResponseStatusCode__c + Active + None + false + + 10 + false + 0 + Confidential + false + false + Number + false + diff --git a/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/StackTrace__c.field-meta.xml b/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/StackTrace__c.field-meta.xml index 5b19137a3..346af7733 100644 --- a/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/StackTrace__c.field-meta.xml +++ b/nebula-logger/core/main/log-management/objects/LogEntry__c/fields/StackTrace__c.field-meta.xml @@ -5,7 +5,7 @@ None false - 131072 + 5000 Confidential false 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 3f3243b50..2b60a09e5 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 @@ -408,6 +408,36 @@ LogEntry__c.HasRecordJson__c true + + false + LogEntry__c.HasRestRequestBody__c + true + + + false + LogEntry__c.HasRestRequestHeaderKeys__c + true + + + false + LogEntry__c.HasRestRequestHeaders__c + true + + + false + LogEntry__c.HasRestResponseBody__c + true + + + false + LogEntry__c.HasRestResponseHeaderKeys__c + true + + + false + LogEntry__c.HasRestResponseHeaders__c + true + false LogEntry__c.HasStackTrace__c @@ -823,6 +853,76 @@ LogEntry__c.RecordSObjectType__c true + + false + LogEntry__c.RestRequestBodyMasked__c + true + + + false + LogEntry__c.RestRequestBody__c + true + + + false + LogEntry__c.RestRequestHeaderKeys__c + true + + + false + LogEntry__c.RestRequestHeaders__c + true + + + false + LogEntry__c.RestRequestMethod__c + true + + + false + LogEntry__c.RestRequestParameters__c + true + + + false + LogEntry__c.RestRequestRemoteAddress__c + true + + + false + LogEntry__c.RestRequestResourcePath__c + true + + + false + LogEntry__c.RestRequestUri__c + true + + + false + LogEntry__c.RestResponseBodyMasked__c + true + + + false + LogEntry__c.RestResponseBody__c + true + + + false + LogEntry__c.RestResponseHeaderKeys__c + true + + + false + LogEntry__c.RestResponseHeaders__c + true + + + false + LogEntry__c.RestResponseStatusCode__c + true + false LogEntry__c.StackTrace__c diff --git a/nebula-logger/core/main/log-management/permissionsets/LoggerEndUser.permissionset-meta.xml b/nebula-logger/core/main/log-management/permissionsets/LoggerEndUser.permissionset-meta.xml index 27ce0ab25..d7bbc9b1f 100644 --- a/nebula-logger/core/main/log-management/permissionsets/LoggerEndUser.permissionset-meta.xml +++ b/nebula-logger/core/main/log-management/permissionsets/LoggerEndUser.permissionset-meta.xml @@ -193,7 +193,7 @@ LogEntry__c.FlowVersionRunInMode__c true - + false LogEntry__c.HasDatabaseResultJson__c true @@ -248,6 +248,36 @@ LogEntry__c.HasRecordJson__c true + + false + LogEntry__c.HasRestRequestBody__c + true + + + false + LogEntry__c.HasRestRequestHeaderKeys__c + true + + + false + LogEntry__c.HasRestRequestHeaders__c + true + + + false + LogEntry__c.HasRestResponseBody__c + true + + + false + LogEntry__c.HasRestResponseHeaderKeys__c + true + + + false + LogEntry__c.HasRestResponseHeaders__c + true + false LogEntry__c.HasStackTrace__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 5fcc2ddb8..683af9111 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 @@ -332,6 +332,36 @@ LogEntry__c.HasRecordJson__c true + + false + LogEntry__c.HasRestRequestBody__c + true + + + false + LogEntry__c.HasRestRequestHeaderKeys__c + true + + + false + LogEntry__c.HasRestRequestHeaders__c + true + + + false + LogEntry__c.HasRestResponseBody__c + true + + + false + LogEntry__c.HasRestResponseHeaderKeys__c + true + + + false + LogEntry__c.HasRestResponseHeaders__c + true + false LogEntry__c.HasStackTrace__c @@ -747,6 +777,76 @@ LogEntry__c.RecordSObjectType__c true + + false + LogEntry__c.RestRequestBodyMasked__c + true + + + false + LogEntry__c.RestRequestBody__c + true + + + false + LogEntry__c.RestRequestHeaderKeys__c + true + + + false + LogEntry__c.RestRequestHeaders__c + true + + + false + LogEntry__c.RestRequestMethod__c + true + + + false + LogEntry__c.RestRequestParameters__c + true + + + false + LogEntry__c.RestRequestRemoteAddress__c + true + + + false + LogEntry__c.RestRequestResourcePath__c + true + + + false + LogEntry__c.RestRequestUri__c + true + + + false + LogEntry__c.RestResponseBodyMasked__c + true + + + false + LogEntry__c.RestResponseBody__c + true + + + false + LogEntry__c.RestResponseHeaderKeys__c + true + + + false + LogEntry__c.RestResponseHeaders__c + true + + + false + LogEntry__c.RestResponseStatusCode__c + true + false LogEntry__c.StackTrace__c diff --git a/nebula-logger/core/main/logger-engine/classes/LogEntryEventBuilder.cls b/nebula-logger/core/main/logger-engine/classes/LogEntryEventBuilder.cls index c79498da0..133d8f491 100644 --- a/nebula-logger/core/main/logger-engine/classes/LogEntryEventBuilder.cls +++ b/nebula-logger/core/main/logger-engine/classes/LogEntryEventBuilder.cls @@ -575,7 +575,7 @@ global with sharing class LogEntryEventBuilder { this.logEntryEvent.HttpRequestBody__c = cleanedRequestBody; this.logEntryEvent.HttpRequestBodyMasked__c = requestBodyMasked; this.logEntryEvent.HttpRequestCompressed__c = request.getCompressed(); - this.logEntryEvent.HttpRequestEndpoint__c = truncateFieldValue(Schema.LogEntryEvent__e.HttpRequestEndpoint__c, request.getEndpoint()); + this.logEntryEvent.HttpRequestEndpoint__c = request.getEndpoint(); this.logEntryEvent.HttpRequestMethod__c = request.getMethod(); return this; } @@ -611,6 +611,90 @@ global with sharing class LogEntryEventBuilder { return this; } + /** + * @description Sets the log entry event's REST Request fields + * @param request The instance of `RestRequest` to log + * @return The same instance of `LogEntryEventBuilder`, useful for chaining methods + */ + global LogEntryEventBuilder setRestRequestDetails(System.RestRequest request) { + if (this.shouldSave() == false || request == null) { + return this; + } + + String stringifiedRequestBody = request.requestBody?.toString(); + String truncatedRequestBody = truncateFieldValue(Schema.LogEntryEvent__e..RestRequestBody__c, stringifiedRequestBody); + String cleanedRequestBody = applyDataMaskRules(this.userSettings.IsDataMaskingEnabled__c, truncatedRequestBody); + Boolean requestBodyMasked = cleanedRequestBody != truncatedRequestBody; + + String formattedHeaderKeysString; + String formattedHeadersString; + if (request.headers != null) { + formattedHeaderKeysString = String.join(request.headers.keySet(), NEW_LINE_DELIMITER); + if (LoggerParameter.STORE_REST_REQUEST_HEADER_VALUES) { + List headers = new List(); + for (String headerKey : request.headers.keySet()) { + headers.add(String.format(HTTP_HEADER_FORMAT, new List{ headerKey, request.headers.get(headerKey) })); + } + formattedHeadersString = String.join(headers, NEW_LINE_DELIMITER); + } + } + String formattedParametersString; + if (request.params != null) { + List parameters = new List(); + for (String headerKey : request.params.keySet()) { + parameters.add(String.format(HTTP_HEADER_FORMAT, new List{ headerKey, request.params.get(headerKey) })); + } + formattedParametersString = String.join(parameters, NEW_LINE_DELIMITER); + } + + this.logEntryEvent.RestRequestBody__c = cleanedRequestBody; + this.logEntryEvent.RestRequestBodyMasked__c = requestBodyMasked; + this.logEntryEvent.RestRequestHeaderKeys__c = formattedHeaderKeysString; + this.logEntryEvent.RestRequestHeaders__c = formattedHeadersString; + this.logEntryEvent.RestRequestMethod__c = request.httpMethod; + this.logEntryEvent.RestRequestParameters__c = formattedParametersString; + this.logEntryEvent.RestRequestRemoteAddress__c = request.remoteAddress; + this.logEntryEvent.RestRequestResourcePath__c = request.resourcePath; + this.logEntryEvent.RestRequestUri__c = request.requestURI; + return this; + } + + /** + * @description Sets the log entry event's REST Response fields + * @param response The instance of `RestResponse` to log + * @return The same instance of `LogEntryEventBuilder`, useful for chaining methods + */ + global LogEntryEventBuilder setRestResponseDetails(System.RestResponse response) { + if (this.shouldSave() == false || response == null) { + return this; + } + + String stringifiedResponseBody = response.responseBody?.toString(); + String truncatedResponseBody = truncateFieldValue(Schema.LogEntryEvent__e.RestResponseBody__c, stringifiedResponseBody); + String cleanedResponseBody = applyDataMaskRules(this.userSettings.IsDataMaskingEnabled__c, truncatedResponseBody); + Boolean responseBodyMasked = cleanedResponseBody != truncatedResponseBody; + + String formattedHeaderKeysString; + String formattedHeadersString; + if (response.headers != null) { + formattedHeaderKeysString = String.join(response.headers.keySet(), NEW_LINE_DELIMITER); + if (LoggerParameter.STORE_REST_RESPONSE_HEADER_VALUES) { + List headers = new List(); + for (String headerKey : response.headers.keySet()) { + headers.add(String.format(HTTP_HEADER_FORMAT, new List{ headerKey, response.headers.get(headerKey) })); + } + formattedHeadersString = String.join(headers, NEW_LINE_DELIMITER); + } + } + + this.logEntryEvent.RestResponseBody__c = cleanedResponseBody; + this.logEntryEvent.RestResponseBodyMasked__c = responseBodyMasked; + this.logEntryEvent.RestResponseHeaderKeys__c = formattedHeaderKeysString; + this.logEntryEvent.RestResponseHeaders__c = formattedHeadersString; + this.logEntryEvent.RestResponseStatusCode__c = response.statusCode; + return this; + } + /** * @description Appends the tag to the existing list of tags * @param tag The string to use as a tag for the current entry diff --git a/nebula-logger/core/main/logger-engine/classes/Logger.cls b/nebula-logger/core/main/logger-engine/classes/Logger.cls index e2bf62c14..3ebd76368 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.12.8'; + private static final String CURRENT_VERSION_NUMBER = 'v4.12.9'; 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(); 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 00ee3d021..db5f7651e 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.12.8'; +const CURRENT_VERSION_NUMBER = 'v4.12.9'; export default class Logger extends LightningElement { #loggerService = createLoggerService(); diff --git a/nebula-logger/core/main/logger-engine/objects/LogEntryEvent__e/fields/ExceptionMessage__c.field-meta.xml b/nebula-logger/core/main/logger-engine/objects/LogEntryEvent__e/fields/ExceptionMessage__c.field-meta.xml index 5fb7221cd..2575588ca 100644 --- a/nebula-logger/core/main/logger-engine/objects/LogEntryEvent__e/fields/ExceptionMessage__c.field-meta.xml +++ b/nebula-logger/core/main/logger-engine/objects/LogEntryEvent__e/fields/ExceptionMessage__c.field-meta.xml @@ -8,7 +8,7 @@ false false - 131072 + 5000 Confidential LongTextArea 8 diff --git a/nebula-logger/core/main/logger-engine/objects/LogEntryEvent__e/fields/ExceptionStackTrace__c.field-meta.xml b/nebula-logger/core/main/logger-engine/objects/LogEntryEvent__e/fields/ExceptionStackTrace__c.field-meta.xml index 7f027bdfe..86d028907 100644 --- a/nebula-logger/core/main/logger-engine/objects/LogEntryEvent__e/fields/ExceptionStackTrace__c.field-meta.xml +++ b/nebula-logger/core/main/logger-engine/objects/LogEntryEvent__e/fields/ExceptionStackTrace__c.field-meta.xml @@ -8,7 +8,7 @@ false false - 131072 + 5000 Confidential LongTextArea 8 diff --git a/nebula-logger/core/main/logger-engine/objects/LogEntryEvent__e/fields/RestRequestBodyMasked__c.field-meta.xml b/nebula-logger/core/main/logger-engine/objects/LogEntryEvent__e/fields/RestRequestBodyMasked__c.field-meta.xml new file mode 100644 index 000000000..fcea85296 --- /dev/null +++ b/nebula-logger/core/main/logger-engine/objects/LogEntryEvent__e/fields/RestRequestBodyMasked__c.field-meta.xml @@ -0,0 +1,14 @@ + + + RestRequestBodyMasked__c + Active + None + false + false + false + false + false + + Confidential + Checkbox + diff --git a/nebula-logger/core/main/logger-engine/objects/LogEntryEvent__e/fields/RestRequestBody__c.field-meta.xml b/nebula-logger/core/main/logger-engine/objects/LogEntryEvent__e/fields/RestRequestBody__c.field-meta.xml new file mode 100644 index 000000000..1ab88b7f8 --- /dev/null +++ b/nebula-logger/core/main/logger-engine/objects/LogEntryEvent__e/fields/RestRequestBody__c.field-meta.xml @@ -0,0 +1,15 @@ + + + RestRequestBody__c + Active + None + false + false + false + false + + 131072 + Confidential + LongTextArea + 5 + diff --git a/nebula-logger/core/main/logger-engine/objects/LogEntryEvent__e/fields/RestRequestHeaderKeys__c.field-meta.xml b/nebula-logger/core/main/logger-engine/objects/LogEntryEvent__e/fields/RestRequestHeaderKeys__c.field-meta.xml new file mode 100644 index 000000000..e76771556 --- /dev/null +++ b/nebula-logger/core/main/logger-engine/objects/LogEntryEvent__e/fields/RestRequestHeaderKeys__c.field-meta.xml @@ -0,0 +1,15 @@ + + + RestRequestHeaderKeys__c + Active + None + false + false + false + false + + 1000 + Confidential + LongTextArea + 5 + diff --git a/nebula-logger/core/main/logger-engine/objects/LogEntryEvent__e/fields/RestRequestHeaders__c.field-meta.xml b/nebula-logger/core/main/logger-engine/objects/LogEntryEvent__e/fields/RestRequestHeaders__c.field-meta.xml new file mode 100644 index 000000000..3b1008917 --- /dev/null +++ b/nebula-logger/core/main/logger-engine/objects/LogEntryEvent__e/fields/RestRequestHeaders__c.field-meta.xml @@ -0,0 +1,15 @@ + + + RestRequestHeaders__c + Active + None + false + false + false + false + + 5000 + Confidential + LongTextArea + 5 + diff --git a/nebula-logger/core/main/logger-engine/objects/LogEntryEvent__e/fields/RestRequestMethod__c.field-meta.xml b/nebula-logger/core/main/logger-engine/objects/LogEntryEvent__e/fields/RestRequestMethod__c.field-meta.xml new file mode 100644 index 000000000..8bfbda714 --- /dev/null +++ b/nebula-logger/core/main/logger-engine/objects/LogEntryEvent__e/fields/RestRequestMethod__c.field-meta.xml @@ -0,0 +1,16 @@ + + + RestRequestMethod__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/RestRequestParameters__c.field-meta.xml b/nebula-logger/core/main/logger-engine/objects/LogEntryEvent__e/fields/RestRequestParameters__c.field-meta.xml new file mode 100644 index 000000000..0c4b37c3d --- /dev/null +++ b/nebula-logger/core/main/logger-engine/objects/LogEntryEvent__e/fields/RestRequestParameters__c.field-meta.xml @@ -0,0 +1,15 @@ + + + RestRequestParameters__c + Active + None + false + false + false + false + + 5000 + Confidential + LongTextArea + 5 + diff --git a/nebula-logger/core/main/logger-engine/objects/LogEntryEvent__e/fields/RestRequestRemoteAddress__c.field-meta.xml b/nebula-logger/core/main/logger-engine/objects/LogEntryEvent__e/fields/RestRequestRemoteAddress__c.field-meta.xml new file mode 100644 index 000000000..b71bb8ebb --- /dev/null +++ b/nebula-logger/core/main/logger-engine/objects/LogEntryEvent__e/fields/RestRequestRemoteAddress__c.field-meta.xml @@ -0,0 +1,16 @@ + + + RestRequestRemoteAddress__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/RestRequestResourcePath__c.field-meta.xml b/nebula-logger/core/main/logger-engine/objects/LogEntryEvent__e/fields/RestRequestResourcePath__c.field-meta.xml new file mode 100644 index 000000000..c988340ea --- /dev/null +++ b/nebula-logger/core/main/logger-engine/objects/LogEntryEvent__e/fields/RestRequestResourcePath__c.field-meta.xml @@ -0,0 +1,16 @@ + + + RestRequestResourcePath__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/RestRequestUri__c.field-meta.xml b/nebula-logger/core/main/logger-engine/objects/LogEntryEvent__e/fields/RestRequestUri__c.field-meta.xml new file mode 100644 index 000000000..8e0a6c1f1 --- /dev/null +++ b/nebula-logger/core/main/logger-engine/objects/LogEntryEvent__e/fields/RestRequestUri__c.field-meta.xml @@ -0,0 +1,16 @@ + + + RestRequestUri__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/RestResponseBodyMasked__c.field-meta.xml b/nebula-logger/core/main/logger-engine/objects/LogEntryEvent__e/fields/RestResponseBodyMasked__c.field-meta.xml new file mode 100644 index 000000000..27af5350c --- /dev/null +++ b/nebula-logger/core/main/logger-engine/objects/LogEntryEvent__e/fields/RestResponseBodyMasked__c.field-meta.xml @@ -0,0 +1,14 @@ + + + RestResponseBodyMasked__c + Active + None + false + false + false + false + false + + Confidential + Checkbox + diff --git a/nebula-logger/core/main/logger-engine/objects/LogEntryEvent__e/fields/RestResponseBody__c.field-meta.xml b/nebula-logger/core/main/logger-engine/objects/LogEntryEvent__e/fields/RestResponseBody__c.field-meta.xml new file mode 100644 index 000000000..3c6337cda --- /dev/null +++ b/nebula-logger/core/main/logger-engine/objects/LogEntryEvent__e/fields/RestResponseBody__c.field-meta.xml @@ -0,0 +1,15 @@ + + + RestResponseBody__c + Active + None + false + false + false + false + + 131072 + Confidential + LongTextArea + 5 + diff --git a/nebula-logger/core/main/logger-engine/objects/LogEntryEvent__e/fields/RestResponseHeaderKeys__c.field-meta.xml b/nebula-logger/core/main/logger-engine/objects/LogEntryEvent__e/fields/RestResponseHeaderKeys__c.field-meta.xml new file mode 100644 index 000000000..14f7c4cc0 --- /dev/null +++ b/nebula-logger/core/main/logger-engine/objects/LogEntryEvent__e/fields/RestResponseHeaderKeys__c.field-meta.xml @@ -0,0 +1,15 @@ + + + RestResponseHeaderKeys__c + Active + None + false + false + false + false + + 1000 + Confidential + LongTextArea + 5 + diff --git a/nebula-logger/core/main/logger-engine/objects/LogEntryEvent__e/fields/RestResponseHeaders__c.field-meta.xml b/nebula-logger/core/main/logger-engine/objects/LogEntryEvent__e/fields/RestResponseHeaders__c.field-meta.xml new file mode 100644 index 000000000..8a71bf04f --- /dev/null +++ b/nebula-logger/core/main/logger-engine/objects/LogEntryEvent__e/fields/RestResponseHeaders__c.field-meta.xml @@ -0,0 +1,15 @@ + + + RestResponseHeaders__c + Active + None + false + false + false + false + + 5000 + Confidential + LongTextArea + 5 + diff --git a/nebula-logger/core/main/logger-engine/objects/LogEntryEvent__e/fields/RestResponseStatusCode__c.field-meta.xml b/nebula-logger/core/main/logger-engine/objects/LogEntryEvent__e/fields/RestResponseStatusCode__c.field-meta.xml new file mode 100644 index 000000000..7ecfddeb9 --- /dev/null +++ b/nebula-logger/core/main/logger-engine/objects/LogEntryEvent__e/fields/RestResponseStatusCode__c.field-meta.xml @@ -0,0 +1,17 @@ + + + RestResponseStatusCode__c + Active + None + false + false + false + false + + 10 + false + 0 + Confidential + Number + false + diff --git a/nebula-logger/core/main/logger-engine/objects/LogEntryEvent__e/fields/StackTrace__c.field-meta.xml b/nebula-logger/core/main/logger-engine/objects/LogEntryEvent__e/fields/StackTrace__c.field-meta.xml index 76c28134a..5ef09a2af 100644 --- a/nebula-logger/core/main/logger-engine/objects/LogEntryEvent__e/fields/StackTrace__c.field-meta.xml +++ b/nebula-logger/core/main/logger-engine/objects/LogEntryEvent__e/fields/StackTrace__c.field-meta.xml @@ -8,7 +8,7 @@ false false - 131072 + 5000 Confidential LongTextArea 8 diff --git a/nebula-logger/core/main/logger-engine/objects/LogEntryEvent__e/fields/Topics__c.field-meta.xml b/nebula-logger/core/main/logger-engine/objects/LogEntryEvent__e/fields/Topics__c.field-meta.xml index 0bb4a868c..8ae541cf1 100644 --- a/nebula-logger/core/main/logger-engine/objects/LogEntryEvent__e/fields/Topics__c.field-meta.xml +++ b/nebula-logger/core/main/logger-engine/objects/LogEntryEvent__e/fields/Topics__c.field-meta.xml @@ -8,7 +8,7 @@ false false - 131072 + 256 Confidential LongTextArea 8 diff --git a/nebula-logger/core/tests/configuration/classes/LoggerParameter_Tests.cls b/nebula-logger/core/tests/configuration/classes/LoggerParameter_Tests.cls index 9887e43ca..4553c6061 100644 --- a/nebula-logger/core/tests/configuration/classes/LoggerParameter_Tests.cls +++ b/nebula-logger/core/tests/configuration/classes/LoggerParameter_Tests.cls @@ -272,6 +272,28 @@ private class LoggerParameter_Tests { System.Assert.areEqual(mockValue, returnedValue); } + @IsTest + static void it_should_return_constant_value_for_store_rest_request_header_values() { + Boolean mockValue = false; + LoggerParameter__mdt mockParameter = new LoggerParameter__mdt(DeveloperName = 'StoreRestRequestHeaderValues', Value__c = JSON.serialize(mockValue)); + LoggerParameter.setMock(mockParameter); + + Boolean returnedValue = LoggerParameter.STORE_REST_REQUEST_HEADER_VALUES; + + System.Assert.areEqual(mockValue, returnedValue); + } + + @IsTest + static void it_should_return_constant_value_for_store_rest_response_header_values() { + Boolean mockValue = false; + LoggerParameter__mdt mockParameter = new LoggerParameter__mdt(DeveloperName = 'StoreRestResponseHeaderValues', Value__c = JSON.serialize(mockValue)); + LoggerParameter.setMock(mockParameter); + + Boolean returnedValue = LoggerParameter.STORE_REST_RESPONSE_HEADER_VALUES; + + System.Assert.areEqual(mockValue, returnedValue); + } + @IsTest static void it_should_return_constant_value_for_system_debug_message_format() { // The constant LoggerParameter.SYSTEM_DEBUG_MESSAGE_FORMAT is unique - its value should always be 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 149f4dd93..9b20e4386 100644 --- a/nebula-logger/core/tests/log-management/classes/LogEntryEventHandler_Tests.cls +++ b/nebula-logger/core/tests/log-management/classes/LogEntryEventHandler_Tests.cls @@ -1363,6 +1363,20 @@ private class LogEntryEventHandler_Tests { RecordSObjectClassification__c, RecordSObjectType__c, RecordSObjectTypeNamespace__c, + RestRequestBody__c, + RestRequestBodyMasked__c, + RestRequestHeaderKeys__c, + RestRequestHeaders__c, + RestRequestMethod__c, + RestRequestParameters__c, + RestRequestRemoteAddress__c, + RestRequestResourcePath__c, + RestRequestUri__c, + RestResponseBody__c, + RestResponseBodyMasked__c, + RestResponseHeaderKeys__c, + RestResponseHeaders__c, + RestResponseStatusCode__c, StackTrace__c, Tags__c, Timestamp__c, @@ -1685,18 +1699,51 @@ private class LogEntryEventHandler_Tests { logEntry.RecordSObjectTypeNamespace__c, 'logEntry.RecordSObjectTypeNamespace__c was not properly set' ); - System.Assert.areEqual(logEntryEvent.RecordId__c, logEntry.RecordId__c, 'logEntry.RecordId__c was not properly set'); - System.Assert.areEqual(logEntryEvent.RecordJson__c, logEntry.RecordJson__c, 'logEntry.RecordJson__c was not properly set'); + System.Assert.areEqual(logEntryEvent.RestRequestBody__c, logEntry.RestRequestBody__c, 'logEntry.RestRequestBody__c, was not properly set'); System.Assert.areEqual( - logEntryEvent.RecordSObjectClassification__c, - logEntry.RecordSObjectClassification__c, - 'logEntry.RecordSObjectClassification__c was not properly set' + logEntryEvent.RestRequestBodyMasked__c, + logEntry.RestRequestBodyMasked__c, + 'logEntry.RestRequestBodyMasked__c, was not properly set' ); - System.Assert.areEqual(logEntryEvent.RecordSObjectType__c, logEntry.RecordSObjectType__c, 'logEntry.RecordSObjectType__c was not properly set'); System.Assert.areEqual( - logEntryEvent.RecordSObjectTypeNamespace__c, - logEntry.RecordSObjectTypeNamespace__c, - 'logEntry.RecordSObjectTypeNamespace__c was not properly set' + logEntryEvent.RestRequestHeaderKeys__c, + logEntry.RestRequestHeaderKeys__c, + 'logEntry.RestRequestHeaderKeys__c, was not properly set' + ); + System.Assert.areEqual(logEntryEvent.RestRequestHeaders__c, logEntry.RestRequestHeaders__c, 'logEntry.RestRequestHeaders__c, was not properly set'); + System.Assert.areEqual(logEntryEvent.RestRequestMethod__c, logEntry.RestRequestMethod__c, 'logEntry.RestRequestMethod__c, was not properly set'); + System.Assert.areEqual( + logEntryEvent.RestRequestParameters__c, + logEntry.RestRequestParameters__c, + 'logEntry.RestRequestParameters__c, was not properly set' + ); + System.Assert.areEqual( + logEntryEvent.RestRequestRemoteAddress__c, + logEntry.RestRequestRemoteAddress__c, + 'logEntry.RestRequestRemoteAddress__c, was not properly set' + ); + System.Assert.areEqual( + logEntryEvent.RestRequestResourcePath__c, + logEntry.RestRequestResourcePath__c, + 'logEntry.RestRequestResourcePath__c, was not properly set' + ); + System.Assert.areEqual(logEntryEvent.RestRequestUri__c, logEntry.RestRequestUri__c, 'logEntry.RestRequestUri__c, was not properly set'); + System.Assert.areEqual(logEntryEvent.RestResponseBody__c, logEntry.RestResponseBody__c, 'logEntry.RestResponseBody__c was not properly set'); + System.Assert.areEqual( + logEntryEvent.RestResponseBodyMasked__c, + logEntry.RestResponseBodyMasked__c, + 'logEntry.RestResponseBodyMasked__c was not properly set' + ); + System.Assert.areEqual( + logEntryEvent.RestResponseHeaderKeys__c, + logEntry.RestResponseHeaderKeys__c, + 'logEntry.RestResponseHeaderKeys__c was not properly set' + ); + System.Assert.areEqual(logEntryEvent.RestResponseHeaders__c, logEntry.RestResponseHeaders__c, 'logEntry.RestResponseHeaders__c was not properly set'); + System.Assert.areEqual( + logEntryEvent.RestResponseStatusCode__c, + logEntry.RestResponseStatusCode__c, + 'logEntry.RestResponseStatusCode__c was not properly set' ); System.Assert.areEqual(logEntryEvent.StackTrace__c, logEntry.StackTrace__c, 'logEntry.StackTrace__c was not properly set'); System.Assert.areEqual(logEntryEvent.Timestamp__c, logEntry.Timestamp__c, 'logEntry.Timestamp__c was not properly set'); 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 f7fe91867..1df9a261c 100644 --- a/nebula-logger/core/tests/log-management/classes/LogEntryHandler_Tests.cls +++ b/nebula-logger/core/tests/log-management/classes/LogEntryHandler_Tests.cls @@ -373,6 +373,256 @@ private class LogEntryHandler_Tests { System.Assert.isTrue(matchingLogEntry.HasHttpResponseHeaders__c); System.Assert.isFalse(nonMatchingLogEntry.HasHttpResponseHeaders__c); } + + @IsTest + static void it_should_set_hasRestRequestBody_on_before_insert() { + LogEntry__c matchingLogEntry = new LogEntry__c(RestRequestBody__c = 'some value'); + LogEntry__c nonMatchingLogEntry = new LogEntry__c(RestRequestBody__c = null); + System.Assert.isNotNull(matchingLogEntry.RestRequestBody__c); + System.Assert.isNull(nonMatchingLogEntry.RestRequestBody__c); + + LoggerTriggerableContext context = new LoggerTriggerableContext( + Schema.LogEntry__c.SObjectType, + TriggerOperation.BEFORE_INSERT, + new List{ matchingLogEntry, nonMatchingLogEntry } + ); + new LogEntryHandler().overrideTriggerableContext(context).execute(); + + System.Assert.isTrue(matchingLogEntry.HasRestRequestBody__c); + System.Assert.isFalse(nonMatchingLogEntry.HasRestRequestBody__c); + } + + @IsTest + static void it_should_set_hasRestRequestBody_on_before_update() { + LogEntry__c matchingLogEntry = new LogEntry__c(RestRequestBody__c = 'some value', Id = LoggerMockDataCreator.createId(Schema.LogEntry__c.SObjectType)); + LogEntry__c nonMatchingLogEntry = new LogEntry__c(RestRequestBody__c = null, Id = LoggerMockDataCreator.createId(Schema.LogEntry__c.SObjectType)); + List updatedRecords = new List{ matchingLogEntry, nonMatchingLogEntry }; + System.Assert.isNotNull(matchingLogEntry.RestRequestBody__c); + System.Assert.isNull(nonMatchingLogEntry.RestRequestBody__c); + + LoggerTriggerableContext context = new LoggerTriggerableContext( + Schema.LogEntry__c.SObjectType, + TriggerOperation.BEFORE_UPDATE, + updatedRecords, + new Map(updatedRecords), + null + ); + new LogEntryHandler().overrideTriggerableContext(context).execute(); + + System.Assert.isTrue(matchingLogEntry.HasRestRequestBody__c); + System.Assert.isFalse(nonMatchingLogEntry.HasRestRequestBody__c); + } + + @IsTest + static void it_should_set_hasRestRequestHeaderKeys_on_before_insert() { + LogEntry__c matchingLogEntry = new LogEntry__c(RestRequestHeaderKeys__c = 'some value'); + LogEntry__c nonMatchingLogEntry = new LogEntry__c(RestRequestHeaderKeys__c = null); + System.Assert.isNotNull(matchingLogEntry.RestRequestHeaderKeys__c); + System.Assert.isNull(nonMatchingLogEntry.RestRequestHeaderKeys__c); + + LoggerTriggerableContext context = new LoggerTriggerableContext( + Schema.LogEntry__c.SObjectType, + TriggerOperation.BEFORE_INSERT, + new List{ matchingLogEntry, nonMatchingLogEntry } + ); + new LogEntryHandler().overrideTriggerableContext(context).execute(); + + System.Assert.isTrue(matchingLogEntry.HasRestRequestHeaderKeys__c); + System.Assert.isFalse(nonMatchingLogEntry.HasRestRequestHeaderKeys__c); + } + + @IsTest + static void it_should_set_hasRestRequestHeaderKeys_on_before_update() { + LogEntry__c matchingLogEntry = new LogEntry__c( + RestRequestHeaderKeys__c = 'some value', + Id = LoggerMockDataCreator.createId(Schema.LogEntry__c.SObjectType) + ); + LogEntry__c nonMatchingLogEntry = new LogEntry__c(RestRequestHeaderKeys__c = null, Id = LoggerMockDataCreator.createId(Schema.LogEntry__c.SObjectType)); + List updatedRecords = new List{ matchingLogEntry, nonMatchingLogEntry }; + System.Assert.isNotNull(matchingLogEntry.RestRequestHeaderKeys__c); + System.Assert.isNull(nonMatchingLogEntry.RestRequestHeaderKeys__c); + + LoggerTriggerableContext context = new LoggerTriggerableContext( + Schema.LogEntry__c.SObjectType, + TriggerOperation.BEFORE_UPDATE, + updatedRecords, + new Map(updatedRecords), + null + ); + new LogEntryHandler().overrideTriggerableContext(context).execute(); + + System.Assert.isTrue(matchingLogEntry.HasRestRequestHeaderKeys__c); + System.Assert.isFalse(nonMatchingLogEntry.HasRestRequestHeaderKeys__c); + } + + @IsTest + static void it_should_set_hasRestRequestHeaders_on_before_insert() { + LogEntry__c matchingLogEntry = new LogEntry__c(RestRequestHeaders__c = 'some value'); + LogEntry__c nonMatchingLogEntry = new LogEntry__c(RestRequestHeaders__c = null); + System.Assert.isNotNull(matchingLogEntry.RestRequestHeaders__c); + System.Assert.isNull(nonMatchingLogEntry.RestRequestHeaders__c); + + LoggerTriggerableContext context = new LoggerTriggerableContext( + Schema.LogEntry__c.SObjectType, + TriggerOperation.BEFORE_INSERT, + new List{ matchingLogEntry, nonMatchingLogEntry } + ); + new LogEntryHandler().overrideTriggerableContext(context).execute(); + + System.Assert.isTrue(matchingLogEntry.HasRestRequestHeaders__c); + System.Assert.isFalse(nonMatchingLogEntry.HasRestRequestHeaders__c); + } + + @IsTest + static void it_should_set_hasRestRequestHeaders_on_before_update() { + LogEntry__c matchingLogEntry = new LogEntry__c( + RestRequestHeaders__c = 'some value', + Id = LoggerMockDataCreator.createId(Schema.LogEntry__c.SObjectType) + ); + LogEntry__c nonMatchingLogEntry = new LogEntry__c(RestRequestHeaders__c = null, Id = LoggerMockDataCreator.createId(Schema.LogEntry__c.SObjectType)); + List updatedRecords = new List{ matchingLogEntry, nonMatchingLogEntry }; + System.Assert.isNotNull(matchingLogEntry.RestRequestHeaders__c); + System.Assert.isNull(nonMatchingLogEntry.RestRequestHeaders__c); + + LoggerTriggerableContext context = new LoggerTriggerableContext( + Schema.LogEntry__c.SObjectType, + TriggerOperation.BEFORE_UPDATE, + updatedRecords, + new Map(updatedRecords), + null + ); + new LogEntryHandler().overrideTriggerableContext(context).execute(); + + System.Assert.isTrue(matchingLogEntry.HasRestRequestHeaders__c); + System.Assert.isFalse(nonMatchingLogEntry.HasRestRequestHeaders__c); + } + + @IsTest + static void it_should_set_hasRestResponseBody_on_before_insert() { + LogEntry__c matchingLogEntry = new LogEntry__c(RestResponseBody__c = 'some value'); + LogEntry__c nonMatchingLogEntry = new LogEntry__c(RestResponseBody__c = null); + System.Assert.isNotNull(matchingLogEntry.RestResponseBody__c); + System.Assert.isNull(nonMatchingLogEntry.RestResponseBody__c); + + LoggerTriggerableContext context = new LoggerTriggerableContext( + Schema.LogEntry__c.SObjectType, + TriggerOperation.BEFORE_INSERT, + new List{ matchingLogEntry, nonMatchingLogEntry } + ); + new LogEntryHandler().overrideTriggerableContext(context).execute(); + + System.Assert.isTrue(matchingLogEntry.HasRestResponseBody__c); + System.Assert.isFalse(nonMatchingLogEntry.HasRestResponseBody__c); + } + + @IsTest + static void it_should_set_hasRestResponseBody_on_before_update() { + LogEntry__c matchingLogEntry = new LogEntry__c(RestResponseBody__c = 'some value', Id = LoggerMockDataCreator.createId(Schema.LogEntry__c.SObjectType)); + LogEntry__c nonMatchingLogEntry = new LogEntry__c(RestResponseBody__c = null, Id = LoggerMockDataCreator.createId(Schema.LogEntry__c.SObjectType)); + List updatedRecords = new List{ matchingLogEntry, nonMatchingLogEntry }; + System.Assert.isNotNull(matchingLogEntry.RestResponseBody__c); + System.Assert.isNull(nonMatchingLogEntry.RestResponseBody__c); + + LoggerTriggerableContext context = new LoggerTriggerableContext( + Schema.LogEntry__c.SObjectType, + TriggerOperation.BEFORE_UPDATE, + updatedRecords, + new Map(updatedRecords), + null + ); + new LogEntryHandler().overrideTriggerableContext(context).execute(); + + System.Assert.isTrue(matchingLogEntry.HasRestResponseBody__c); + System.Assert.isFalse(nonMatchingLogEntry.HasRestResponseBody__c); + } + + @IsTest + static void it_should_set_hasRestResponseHeaderKeys_on_before_insert() { + LogEntry__c matchingLogEntry = new LogEntry__c(RestResponseHeaderKeys__c = 'some value'); + LogEntry__c nonMatchingLogEntry = new LogEntry__c(RestResponseHeaderKeys__c = null); + System.Assert.isNotNull(matchingLogEntry.RestResponseHeaderKeys__c); + System.Assert.isNull(nonMatchingLogEntry.RestResponseHeaderKeys__c); + + LoggerTriggerableContext context = new LoggerTriggerableContext( + Schema.LogEntry__c.SObjectType, + TriggerOperation.BEFORE_INSERT, + new List{ matchingLogEntry, nonMatchingLogEntry } + ); + new LogEntryHandler().overrideTriggerableContext(context).execute(); + + System.Assert.isTrue(matchingLogEntry.HasRestResponseHeaderKeys__c); + System.Assert.isFalse(nonMatchingLogEntry.HasRestResponseHeaderKeys__c); + } + + @IsTest + static void it_should_set_hasRestResponseHeaderKeys_on_before_update() { + LogEntry__c matchingLogEntry = new LogEntry__c( + RestResponseHeaderKeys__c = 'some value', + Id = LoggerMockDataCreator.createId(Schema.LogEntry__c.SObjectType) + ); + LogEntry__c nonMatchingLogEntry = new LogEntry__c( + RestResponseHeaderKeys__c = null, + Id = LoggerMockDataCreator.createId(Schema.LogEntry__c.SObjectType) + ); + List updatedRecords = new List{ matchingLogEntry, nonMatchingLogEntry }; + System.Assert.isNotNull(matchingLogEntry.RestResponseHeaderKeys__c); + System.Assert.isNull(nonMatchingLogEntry.RestResponseHeaderKeys__c); + + LoggerTriggerableContext context = new LoggerTriggerableContext( + Schema.LogEntry__c.SObjectType, + TriggerOperation.BEFORE_UPDATE, + updatedRecords, + new Map(updatedRecords), + null + ); + new LogEntryHandler().overrideTriggerableContext(context).execute(); + + System.Assert.isTrue(matchingLogEntry.HasRestResponseHeaderKeys__c); + System.Assert.isFalse(nonMatchingLogEntry.HasRestResponseHeaderKeys__c); + } + + @IsTest + static void it_should_set_hasRestResponseHeaders_on_before_insert() { + LogEntry__c matchingLogEntry = new LogEntry__c(RestResponseHeaders__c = 'some value'); + LogEntry__c nonMatchingLogEntry = new LogEntry__c(RestResponseHeaders__c = null); + System.Assert.isNotNull(matchingLogEntry.RestResponseHeaders__c); + System.Assert.isNull(nonMatchingLogEntry.RestResponseHeaders__c); + + LoggerTriggerableContext context = new LoggerTriggerableContext( + Schema.LogEntry__c.SObjectType, + TriggerOperation.BEFORE_INSERT, + new List{ matchingLogEntry, nonMatchingLogEntry } + ); + new LogEntryHandler().overrideTriggerableContext(context).execute(); + + System.Assert.isTrue(matchingLogEntry.HasRestResponseHeaders__c); + System.Assert.isFalse(nonMatchingLogEntry.HasRestResponseHeaders__c); + } + + @IsTest + static void it_should_set_hasRestResponseHeaders_on_before_update() { + LogEntry__c matchingLogEntry = new LogEntry__c( + RestResponseHeaders__c = 'some value', + Id = LoggerMockDataCreator.createId(Schema.LogEntry__c.SObjectType) + ); + LogEntry__c nonMatchingLogEntry = new LogEntry__c(RestResponseHeaders__c = null, Id = LoggerMockDataCreator.createId(Schema.LogEntry__c.SObjectType)); + List updatedRecords = new List{ matchingLogEntry, nonMatchingLogEntry }; + System.Assert.isNotNull(matchingLogEntry.RestResponseHeaders__c); + System.Assert.isNull(nonMatchingLogEntry.RestResponseHeaders__c); + + LoggerTriggerableContext context = new LoggerTriggerableContext( + Schema.LogEntry__c.SObjectType, + TriggerOperation.BEFORE_UPDATE, + updatedRecords, + new Map(updatedRecords), + null + ); + new LogEntryHandler().overrideTriggerableContext(context).execute(); + + System.Assert.isTrue(matchingLogEntry.HasRestResponseHeaders__c); + System.Assert.isFalse(nonMatchingLogEntry.HasRestResponseHeaders__c); + } + @IsTest static void it_should_set_hasInlineTags_on_before_insert() { LogEntry__c matchingLogEntry = new LogEntry__c(Tags__c = 'some value'); diff --git a/nebula-logger/core/tests/logger-engine/classes/LogEntryEventBuilder_Tests.cls b/nebula-logger/core/tests/logger-engine/classes/LogEntryEventBuilder_Tests.cls index cc6105049..9f35f64f9 100644 --- a/nebula-logger/core/tests/logger-engine/classes/LogEntryEventBuilder_Tests.cls +++ b/nebula-logger/core/tests/logger-engine/classes/LogEntryEventBuilder_Tests.cls @@ -436,6 +436,46 @@ private class LogEntryEventBuilder_Tests { System.Assert.areEqual(expectedSanitizedString, builder.getLogEntryEvent().HttpResponseBody__c); } + @IsTest + static void it_should_apply_data_mask_rule_to_rest_request_body_when_enabled() { + LoggerSettings__c userSettings = getUserSettings(); + userSettings.IsDataMaskingEnabled__c = true; + LogEntryDataMaskRule__mdt rule = getSocialSecurityNumberDataMaskRule(); + rule.IsEnabled__c = true; + LogEntryEventBuilder.setMockDataMaskRule(rule); + String sensitiveString = 'Something, something, and my social is 400 11 9999 in case you want to steal my identity'; + String expectedSanitizedString = 'Something, something, and my social is XXX-XX-9999 in case you want to steal my identity'; + System.RestRequest restRequest = new System.RestRequest(); + restRequest.requestBody = Blob.valueOf(sensitiveString); + + LogEntryEventBuilder builder = new LogEntryEventBuilder(userSettings, System.LoggingLevel.INFO, true, new Set()); + builder.setRestRequestDetails(restRequest); + + System.Assert.isTrue(builder.getLogEntryEvent().RestRequestBodyMasked__c); + System.Assert.areNotEqual(sensitiveString, builder.getLogEntryEvent().RestRequestBody__c); + System.Assert.areEqual(expectedSanitizedString, builder.getLogEntryEvent().RestRequestBody__c); + } + + @IsTest + static void it_should_apply_data_mask_rule_to_rest_response_body_when_enabled() { + LoggerSettings__c userSettings = getUserSettings(); + userSettings.IsDataMaskingEnabled__c = true; + LogEntryDataMaskRule__mdt rule = getSocialSecurityNumberDataMaskRule(); + rule.IsEnabled__c = true; + LogEntryEventBuilder.setMockDataMaskRule(rule); + String sensitiveString = 'Something, something, and my social is 400 11 9999 in case you want to steal my identity'; + String expectedSanitizedString = 'Something, something, and my social is XXX-XX-9999 in case you want to steal my identity'; + System.RestResponse restResponse = new System.RestResponse(); + restResponse.responseBody = Blob.valueOf(sensitiveString); + + LogEntryEventBuilder builder = new LogEntryEventBuilder(userSettings, System.LoggingLevel.INFO, true, new Set()); + builder.setRestResponseDetails(restResponse); + + System.Assert.isTrue(builder.getLogEntryEvent().RestResponseBodyMasked__c); + System.Assert.areNotEqual(sensitiveString, builder.getLogEntryEvent().RestResponseBody__c); + System.Assert.areEqual(expectedSanitizedString, builder.getLogEntryEvent().RestResponseBody__c); + } + @IsTest static void it_should_truncate_message_for_long_logMessage() { LogEntryEventBuilder builder = new LogEntryEventBuilder(getUserSettings(), System.LoggingLevel.INFO, true, new Set()); @@ -1246,6 +1286,196 @@ private class LogEntryEventBuilder_Tests { ); } + @IsTest + static void it_should_skip_setting_rest_response_fields_when_response_is_null() { + LogEntryEventBuilder builder = new LogEntryEventBuilder(getUserSettings(), System.LoggingLevel.INFO, true, new Set()); + System.Assert.isNull(builder.getLogEntryEvent().RestResponseBody__c); + System.Assert.isNull(builder.getLogEntryEvent().RestResponseHeaderKeys__c); + System.Assert.isNull(builder.getLogEntryEvent().RestResponseHeaders__c); + System.Assert.isNull(builder.getLogEntryEvent().RestResponseStatusCode__c); + System.RestResponse response = null; + + builder.setRestResponseDetails(response); + + System.Assert.isNull(builder.getLogEntryEvent().RestResponseBody__c); + System.Assert.isNull(builder.getLogEntryEvent().RestResponseHeaderKeys__c); + System.Assert.isNull(builder.getLogEntryEvent().RestResponseHeaders__c); + System.Assert.isNull(builder.getLogEntryEvent().RestResponseStatusCode__c); + } + + @IsTest + static void it_should_set_rest_request_fields_when_storing_header_values_is_enabled() { + LoggerParameter__mdt mockParameter = new LoggerParameter__mdt(DeveloperName = 'StoreRestRequestHeaderValues', Value__c = String.valueOf(true)); + LoggerParameter.setMock(mockParameter); + System.Assert.isTrue(LoggerParameter.STORE_Rest_REQUEST_HEADER_VALUES); + LogEntryEventBuilder builder = new LogEntryEventBuilder(getUserSettings(), System.LoggingLevel.INFO, true, new Set()); + System.Assert.isNull(builder.getLogEntryEvent().RestRequestBody__c); + System.Assert.isNull(builder.getLogEntryEvent().RestRequestHeaderKeys__c); + System.Assert.isNull(builder.getLogEntryEvent().RestRequestHeaders__c); + System.Assert.isNull(builder.getLogEntryEvent().RestRequestMethod__c); + System.Assert.isNull(builder.getLogEntryEvent().RestRequestParameters__c); + System.Assert.isNull(builder.getLogEntryEvent().RestRequestRemoteAddress__c); + System.Assert.isNull(builder.getLogEntryEvent().RestRequestResourcePath__c); + System.Assert.isNull(builder.getLogEntryEvent().RestRequestUri__c); + System.RestRequest request = new System.RestRequest(); + request.httpMethod = 'GET'; + request.remoteAddress = '1.1.1.1'; + request.requestBody = Blob.valueOf('{hello:"world"}'); + request.requestURI = 'some-uri-value'; + request.resourcePath = '/some/resource/path'; + request.addHeader('some-header', 'some value'); + request.addParameter('some-parameter', 'some value'); + + builder.setRestRequestDetails(request); + + List formattedHeaders = new List(); + for (String headerKey : request.headers.keySet()) { + formattedHeaders.add(headerKey + ': ' + request.headers.get(headerKey)); + } + List formattedParameters = new List(); + for (String parameterKey : request.params.keySet()) { + formattedParameters.add(parameterKey + ': ' + request.params.get(parameterKey)); + } + System.Assert.areEqual(request.requestBody.toString(), builder.getLogEntryEvent().RestRequestBody__c); + System.Assert.areEqual(String.join(request.headers.keySet(), '\n'), builder.getLogEntryEvent().RestRequestHeaderKeys__c); + System.Assert.areEqual(String.join(formattedHeaders, '\n'), builder.getLogEntryEvent().RestRequestHeaders__c); + System.Assert.areEqual(request.httpMethod, builder.getLogEntryEvent().RestRequestMethod__c); + System.Assert.areEqual(String.join(formattedParameters, '\n'), builder.getLogEntryEvent().RestRequestParameters__c); + System.Assert.areEqual(request.remoteAddress, builder.getLogEntryEvent().RestRequestRemoteAddress__c); + System.Assert.areEqual(request.resourcePath, builder.getLogEntryEvent().RestRequestResourcePath__c); + System.Assert.areEqual(request.requestUri, builder.getLogEntryEvent().RestRequestUri__c); + } + + @IsTest + static void it_should_set_rest_request_fields_when_storing_header_values_is_disabled() { + LoggerParameter__mdt mockParameter = new LoggerParameter__mdt(DeveloperName = 'StoreRestRequestHeaderValues', Value__c = String.valueOf(false)); + LoggerParameter.setMock(mockParameter); + System.Assert.isFalse(LoggerParameter.STORE_REST_REQUEST_HEADER_VALUES); + LogEntryEventBuilder builder = new LogEntryEventBuilder(getUserSettings(), System.LoggingLevel.INFO, true, new Set()); + System.Assert.isNull(builder.getLogEntryEvent().RestRequestBody__c); + System.Assert.isNull(builder.getLogEntryEvent().RestRequestHeaderKeys__c); + System.Assert.isNull(builder.getLogEntryEvent().RestRequestHeaders__c); + System.Assert.isNull(builder.getLogEntryEvent().RestRequestMethod__c); + System.Assert.isNull(builder.getLogEntryEvent().RestRequestParameters__c); + System.Assert.isNull(builder.getLogEntryEvent().RestRequestRemoteAddress__c); + System.Assert.isNull(builder.getLogEntryEvent().RestRequestResourcePath__c); + System.Assert.isNull(builder.getLogEntryEvent().RestRequestUri__c); + System.RestRequest request = new System.RestRequest(); + request.httpMethod = 'GET'; + request.remoteAddress = '1.1.1.1'; + request.requestBody = Blob.valueOf('{hello:"world"}'); + request.requestURI = 'some-uri-value'; + request.resourcePath = '/some/resource/path'; + request.addHeader('some-header', 'some value'); + request.addParameter('some-parameter', 'some value'); + + builder.setRestRequestDetails(request); + + List formattedParameters = new List(); + for (String parameterKey : request.params.keySet()) { + formattedParameters.add(parameterKey + ': ' + request.params.get(parameterKey)); + } + System.Assert.areEqual(request.requestBody.toString(), builder.getLogEntryEvent().RestRequestBody__c); + System.Assert.areEqual(String.join(request.headers.keySet(), '\n'), builder.getLogEntryEvent().RestRequestHeaderKeys__c); + System.Assert.isNull(builder.getLogEntryEvent().RestRequestHeaders__c); + System.Assert.areEqual(request.httpMethod, builder.getLogEntryEvent().RestRequestMethod__c); + System.Assert.areEqual(String.join(formattedParameters, '\n'), builder.getLogEntryEvent().RestRequestParameters__c); + System.Assert.areEqual(request.remoteAddress, builder.getLogEntryEvent().RestRequestRemoteAddress__c); + System.Assert.areEqual(request.resourcePath, builder.getLogEntryEvent().RestRequestResourcePath__c); + System.Assert.areEqual(request.requestUri, builder.getLogEntryEvent().RestRequestUri__c); + } + + @IsTest + static void it_should_truncate_rest_request_body_field_when_string_is_too_long() { + LogEntryEventBuilder builder = new LogEntryEventBuilder(getUserSettings(), System.LoggingLevel.INFO, true, new Set()); + System.Assert.isNull(builder.getLogEntryEvent().RestRequestBody__c); + String excessivelyLongRequestBody = 'a'.repeat(Schema.LogEntryEvent__e.RestRequestBody__c.getDescribe().getLength() + 1); + System.RestRequest request = new System.RestRequest(); + request.requestBody = Blob.valueOf(excessivelyLongRequestBody); + + builder.setRestRequestDetails(request); + + System.Assert.areEqual( + excessivelyLongRequestBody.left(Schema.LogEntryEvent__e.RestRequestBody__c.getDescribe().getLength()), + builder.getLogEntryEvent().RestRequestBody__c, + 'Expected string length ' + + Schema.LogEntryEvent__e.RestRequestBody__c.getDescribe().getLength() + + ' for field RestRequestBody__c, actual length is ' + + builder.getLogEntryEvent().RestRequestBody__c.length() + ); + } + + @IsTest + static void it_should_set_rest_response_fields_when_storing_header_values_is_enabled() { + LoggerParameter__mdt mockParameter = new LoggerParameter__mdt(DeveloperName = 'StoreRestResponseHeaderValues', Value__c = String.valueOf(true)); + LoggerParameter.setMock(mockParameter); + System.Assert.isTrue(LoggerParameter.STORE_Rest_RESPONSE_HEADER_VALUES); + LogEntryEventBuilder builder = new LogEntryEventBuilder(getUserSettings(), System.LoggingLevel.INFO, true, new Set()); + System.Assert.isNull(builder.getLogEntryEvent().RestResponseBody__c); + System.Assert.isNull(builder.getLogEntryEvent().RestResponseHeaderKeys__c); + System.Assert.isNull(builder.getLogEntryEvent().RestResponseHeaders__c); + System.Assert.isNull(builder.getLogEntryEvent().RestResponseStatusCode__c); + System.RestResponse response = new System.RestResponse(); + response.addHeader('some-header', 'some value'); + response.responseBody = Blob.valueOf('{hello:"world"}'); + response.statusCode = 200; + + builder.setRestResponseDetails(response); + + List formattedHeaders = new List(); + for (String headerKey : response.headers.keySet()) { + formattedHeaders.add(headerKey + ': ' + response.headers.get(headerKey)); + } + System.Assert.areEqual(response.responseBody.toString(), builder.getLogEntryEvent().RestResponseBody__c); + System.Assert.areEqual(String.join(response.headers.keySet(), '\n'), builder.getLogEntryEvent().RestResponseHeaderKeys__c); + System.Assert.areEqual(String.join(formattedHeaders, '\n'), builder.getLogEntryEvent().RestResponseHeaders__c); + System.Assert.areEqual(response.statusCode, builder.getLogEntryEvent().RestResponseStatusCode__c); + } + + @IsTest + static void it_should_set_rest_response_fields_when_storing_header_values_is_disabled() { + LoggerParameter__mdt mockParameter = new LoggerParameter__mdt(DeveloperName = 'StoreRestResponseHeaderValues', Value__c = String.valueOf(false)); + LoggerParameter.setMock(mockParameter); + System.Assert.isFalse(LoggerParameter.STORE_REST_RESPONSE_HEADER_VALUES); + LogEntryEventBuilder builder = new LogEntryEventBuilder(getUserSettings(), System.LoggingLevel.INFO, true, new Set()); + System.Assert.isNull(builder.getLogEntryEvent().RestResponseBody__c); + System.Assert.isNull(builder.getLogEntryEvent().RestResponseHeaderKeys__c); + System.Assert.isNull(builder.getLogEntryEvent().RestResponseHeaders__c); + System.Assert.isNull(builder.getLogEntryEvent().RestResponseStatusCode__c); + System.RestResponse response = new System.RestResponse(); + response.responseBody = Blob.valueOf('Hello, world!'); + response.addHeader('someKey', 'some string value'); + response.addHeader('anotherKey', 'an amazing example value, wow'); + response.statusCode = 201; + + builder.setRestResponseDetails(response); + + System.Assert.areEqual(response.responseBody.toString(), builder.getLogEntryEvent().RestResponseBody__c); + System.Assert.areEqual(String.join(response.headers.keySet(), '\n'), builder.getLogEntryEvent().RestResponseHeaderKeys__c); + System.Assert.isNull(builder.getLogEntryEvent().RestResponseHeaders__c); + System.Assert.areEqual(response.statusCode, builder.getLogEntryEvent().RestResponseStatusCode__c); + } + + @IsTest + static void it_should_truncate_rest_response_body_field_when_string_is_too_long() { + LogEntryEventBuilder builder = new LogEntryEventBuilder(getUserSettings(), System.LoggingLevel.INFO, true, new Set()); + System.Assert.isNull(builder.getLogEntryEvent().RestResponseBody__c); + String excessivelyLongResponseBody = 'a'.repeat(Schema.LogEntryEvent__e.RestResponseBody__c.getDescribe().getLength() + 1); + System.RestResponse response = new System.RestResponse(); + response.responseBody = Blob.valueOf(excessivelyLongResponseBody); + + builder.setRestResponseDetails(response); + + System.Assert.areEqual( + excessivelyLongResponseBody.left(Schema.LogEntryEvent__e.RestResponseBody__c.getDescribe().getLength()), + builder.getLogEntryEvent().RestResponseBody__c, + 'Expected string length ' + + Schema.LogEntryEvent__e.RestResponseBody__c.getDescribe().getLength() + + ' for field RestResponseBody__c, actual length is ' + + builder.getLogEntryEvent().RestResponseBody__c.length() + ); + } + @IsTest static void it_should_set_tags_string_for_list_of_tags() { LogEntryEventBuilder builder = new LogEntryEventBuilder(getUserSettings(), System.LoggingLevel.INFO, true, new Set()); diff --git a/package.json b/package.json index 83f719f3b..cce601815 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "nebula-logger", - "version": "4.12.8", + "version": "4.12.9", "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/scripts/data/create-sample-log-entries.apex b/scripts/data/create-sample-log-entries.apex index c67f7615e..d38ef531d 100644 --- a/scripts/data/create-sample-log-entries.apex +++ b/scripts/data/create-sample-log-entries.apex @@ -10,7 +10,7 @@ Logger.setScenario('an example transaction scenario name'); Logger.getUserSettings().LoggingLevel__c = System.LoggingLevel.FINEST.name(); Logger.getUserSettings().IsDataMaskingEnabled__c = true; -User currentUser = [SELECT Id, Name, Username, Profile.Name FROM User WHERE Id = :System.UserInfo.getUserId()]; +Schema.User currentUser = [SELECT Id, Name, Username, Profile.Name FROM User WHERE Id = :System.UserInfo.getUserId()]; currentUser.AboutMe = 'I hope you dont leak my social, which is 400-11-9999, btw.'; // new ExampleClassWithLogging().doSomething(); diff --git a/sfdx-project.json b/sfdx-project.json index 2b3a23ce6..538e0c2c0 100644 --- a/sfdx-project.json +++ b/sfdx-project.json @@ -14,9 +14,9 @@ "path": "./nebula-logger/core", "definitionFile": "./config/scratch-orgs/base-scratch-def.json", "scopeProfiles": true, - "versionNumber": "4.12.8.NEXT", - "versionName": "Bugfix for HTTP Response Page Section Visibility", - "versionDescription": "Updated visibility rules on LogEntryRecordPage flexipage to show the HTTP Response section if status, body, or header keys are not null. Also added new-ish Analytics standard tab to the LoggerConsole app.", + "versionNumber": "4.12.9.NEXT", + "versionName": "RestRequest and RestResponse Logging Support", + "versionDescription": "Added new methods setRestRequestDetails() and setRestResponseDetails() in LogEntryEventBuilder that store RestRequest & RestResponse data in new fields on LogEntryEvent__e and LogEntry__c", "releaseNotesUrl": "https://github.com/jongpie/NebulaLogger/releases", "unpackagedMetadata": { "path": "./nebula-logger/extra-tests" @@ -166,6 +166,7 @@ "Nebula Logger - Core@4.12.6-bugfix-to-automatically-truncate-logentryevent__e-fields": "04t5Y000001Mk5UQAS", "Nebula Logger - Core@4.12.7-bugfix-for-lwc-stack-trace-parsing": "04t5Y000001Mk6IQAS", "Nebula Logger - Core@4.12.8-bugfix-for-http-response-page-section-visibility": "04t5Y000001Mk6cQAC", + "Nebula Logger - Core@4.12.9-restrequest-and-restresponse-logging-support": "04t5Y000001Mk7BQAS", "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",