Releases: jongpie/NebulaLogger
v4.15.0 - Winter '25 Release
Managed Package Release - v4.15.0
This release is for both the unlocked package (as always), as well as the managed package! You can see everything that's changed between v4.14.0
and v4.15.0
by reviewing:
- The v4.15.0 milestone to see all of the issues & pull requests that are included in the this release.
- The diff between v4.14.0 and v4.15.0 to see all of the code & metadata changes that have been committed since the last managed package release.
For orgs that are upgrading to this version of the managed package: There are several enhancements & bugfixes in this release (listed below). A few of the notable highlights:
- 🥳Added support for OmniStudio logging
- 🥳Added support for loosely-coupled dependencies (especially useful for package developers/ISVs/consultants)
- 🥳Added a new & improved
getLogger()
function in JavaScript that replaces the now-deprecatedcreateLogger()
functioncreateLogger()
will continue to be supported, but it's recommended that everyone migrates to the newgetLogger()
function instead
Double Feature: Support for OmniStudio Logging + Loosely-Coupled Dependencies
✅✅Release v4.14.10
: With the new Apex class Nebula.CallableLogger
, 2 great enhancements have been added to Nebula Logger:
- It's now even easier for ISVs, consultants, and package developers to optionally leverage Nebula Logger when its available in your customers' orgs
- OmniStudio logging is now provided out of the box
These 2 enhancements are made possible by having the Nebula.CallableLogger
class implement Apex's Callable
interface.
- The
Nebula.CallableLogger
class was originally released in the unlocked package inv4.14.10
- It was further enhanced in
v4.14.16
For more details on using Nebula.CallableLogger
, check out these wiki pages:
Apex Logging Enhancements
For the method Nebula.Logger.setAsyncContext()
:
- ✅Release
v4.14.15
: Enhanced queueableFinalizerContext
logging messages - 🐞Release
v4.14.11
: Bugfix to updateNebula.Logger.setAsyncContext()
behavior to only set the context the first time a non-null context value is provided
For the class Nebula.LogEntryEventBuilder
:
- ✅Release
v4.14.18
by @alanjaouen: AddsetRecord(System.Iterable<Id> recordsIds)
method overload toNebula.LogEntryEventBuilder
for easily logging instances ofSet<Id>
andList<Id>
- Add some changes related to
HttpRequest
logging viasetHttpRequestDetails()
- ✅Release
v4.14.8
: Added the ability to captureHttpRequest
headers via new method overloadsetHttpRequestDetails(System.HttpRequest request, List<String> headersToLog)
- 🐞Release
v4.14.12
: Deprecated & replacedNebula__HttpRequestEndpoint__c
fields with newNebula__HttpRequestEndpointAddress__c
fields so that endpoints longer than 255 characters can be stored
- ✅Release
For custom field mappings (originally released in release v4.13.14
):
- ✅Release
v4.14.14
: Added new static Apex method overloadsNebula.Logger.setField()
For automatic Apex code snippets (originally released in release v4.13.1
):
- 🐞Release
v4.14.9
: Bugfix to auto-truncate Apex code snippets stored inNebula__LogEntry__c
fields.- Previously, the code snippet was only limited by the number of lines of code - but for Apex classes & triggers that have very looooooooooooong code on some lines, the code snippet could cause the JSON value to exceed the corresponding field's max length
JavaScript Logging Enhancements
- ✅
⚠️ Releasev4.14.13
: Added a new synchronous JavaScript functiongetLogger()
+ deprecated async functioncreateLogger()
- ✅Release
v4.14.4
: Added the option to automatically call Salesforce'slightning-logger
LWC when logging via lightning components- Note: for orgs without Event Monitoring (or with Event Monitoring disabled), essentially nothing will actually happen when this feature is enabled in Nebula Logger in your orgs. It's a fully optional feature specifically for orgs that do have Event Monitoring.
- When Event Monitoring is available & configured, using this feature creates a "Lightning Logger" event in Event Monitoring. These events & the
lightning-logger
LWC were made generally available (GA) in Salesforce's Spring '24 release. - This is controlled using the new field
Nebula__LoggerSettings__c.Nebula__IsJavaScriptLightningLoggerEnabled__c
, and is disabled/false
by default
- ✅Release
v4.14.6
: Custom Field Mappings Support for Lightning Components- Additional enhancements were also added
- ✅Release
v4.14.17
: Added more details inNebula/logger
LWC'sconsole
statements - 🐞Release
v4.14.2
: Bugfix in the pipeline so that Jest test failures are properly surfaced/correctly cause a pipeline failure
Data Masking
- 🐞Release
v4.14.7
: Fixed an issue with the regular expression used in the included data masking rule for US Social Security Numbers (SSNs). It now uses a more targeted regular expression for identifying SSNs to mask.- Previously, the rule was not restrictive enough in the regular expression used in
SensitiveDataRegEx__c
, which resulted in the rule masking some values that it should have ignored.
- Previously, the rule was not restrictive enough in the regular expression used in
Nebula Logger
Console App Changes
- ✅Release
v4.14.5
: AddedNebula/loggerSettings
LWC to the app's utility bar - 🐞Release
v4.14.3
: Bugfix to correct the visibility rules for the tab "Related Record Details" on flexipageNebula__LogEntryRecordPage
Core Unlocked Package Release - v4.15.0
These changes are new for both the unlocked package and the managed package.
Winter '25 Release Upgrade
- Bumped all metadata to API
v62.0
(Winter '25 release)- Also updated the list of picklist values in several 'API version' picklist fields on
Log__c
andLogEntry__c
- Also updated the list of picklist values in several 'API version' picklist fields on
- Resolved #733 by updating all 5 record flexipages to use the new dynamic highlights component (released in Salesforce's Winter '25 release) in place of compact layouts.
- The compact layouts are still included in the repo, but they're now considered deprecated.
Log__c
Object Changes
- Updated the flexipage
LogRecordPage
to use the newer component 'dynamic related list - single' instead of the older component 'related list - single' for displaying related lists - Updated the order of fields shown on the
LogEntry__c
related list to haveLoggingLevel__c
as one of the first fields (instead of as one of the last fields) - Updated all list views to have the existing field
Log__c.ProfileLink__c
- Added new list views
AllChildLogs
: shows any logs that have a parent log set usingLogger.setParentLogTransactionId(String)
(based onLog__c.ParentLogLink__c != null
)AllImpersonatedLogs
: shows any logs where an admin was impersonating the logging user (based onLog__c.ImpersonatedByUsernameLink__c != null
)
LogEntry__c
Object Changes
- Updated the flexipage
LogEntryRecordPage
to use the newer component 'dynamic related list - single' instead of the older component 'related list - single' for displaying related lists - Added 3 new formula fields on
LogEntry__c
that reference the existing formula fields onLog__c
so that the same data can easily be shown in list views, etc.:ImpersonatedByUsernameLink__c
ParentLogLink__c
ProfileLink__c
- Updated all list views to have the existing field
Log__c.ProfileLink__c
- Added new list views
AllERRORLogEntries
: shows any records whereLogEntry__c.LoggingLevel__c == 'ERROR'
- This is very similar to the existing list view
AllERRORandWARNLogEntries
that shows bothERROR
andWARN
- This is very similar to the existing list view
AllImpersonatedLogEntries
: shows any log entries where an admin was impersonating th...
Added setRecord() Overload for List<Id> and Set<Id> Parameters
Thanks to @alanjaouen for working on these changes & @jamessimone for reviewing! (See PR #792)
Core Unlocked Package Changes
Added a new overload setRecord(System.Iterable<Id> recordsIds)
in LogEntryEventBuilder
to make it easy to log instances of List<Id>
and Set<Id>
. Nebula Logger automatically sets details about the logged IDs on LogEntry__c
, just as it does when calling the method overloads setRecord(SObject record)
, setRecord(List<SObject> records)
, and setRecord(Id recordId)
Example usage:
// Use List<Id>
List<Id> userIdList = new List<Id>{ System.UserInfo.getUserId() };
Logger.info('Example entry that uses List<Id>').setRecord(userIdList);
// Use Set<Id>
Set<Id> userIdSet = new Set<Id>{ System.UserInfo.getUserId() };
Logger.info('Example entry that uses Set<Id>').setRecord(userIdSet);
Installation Info
Core Unlocked Package - no namespace
Full Changelog: v4.14.17...v4.14.18
- SF CLI:
sf package install --wait 20 --security-type AdminsOnly --package 04t5Y0000015ocbQAA
- SFDX CLI:
sfdx force:package:install --wait 20 --securitytype AdminsOnly --package 04t5Y0000015ocbQAA
- Sandbox: https://test.salesforce.com/packaging/installPackage.apexp?p0=04t5Y0000015ocbQAA
- Production: https://login.salesforce.com/packaging/installPackage.apexp?p0=04t5Y0000015ocbQAA
Added more details in logger LWC's console statements
Core Unlocked Package Changes
When using the logger
LWC and JavaScript console logging is enabled (via LoggerSettings__c.IsJavaScriptConsoleLoggingEnabled__c
), Nebula Logger automatically calls functions in the browser's console
so devs can easily see the generated log entry directly in their browser (instead of having to find it in LogEntry__c
). This release improves the component log entry JSON that's printed using console
statements - the stringified object now includes more details, such as details about the logged error/exception (when an error is logged), any tags added to the entry, and the user's localized version of the entry's timestamp
.
- This includes a change to how Nebula Logger internally calls the browser's
console
functions: now,console
functions are called with a 1 second delay (usingsetTimeout()
) so that additional details can be added to the log entry (using the builder methods) before the log entry is stringified & printed out. This may not be a perfect solution, but seems to work in most cases of using the JS builder methods.
To show the difference in the changes, this JavaScript was used to generate some example log entries:
this.logger.setScenario('Some demo scenario')
const someError = new TypeError('oops');
this.logger.error('Hello, world!')
.setExceptionDetails(someError)
.setField({ SomeLogEntryField__c: 'some text from loggerLWCGetLoggerImportDemo' })
.addTags(['Tag-one', 'Another tag here']);
In the screenshot below, 2 versions of the output are shown:
- Before:
- No details are included in the output about the error, the tags, or the custom field mappings.
- The timestamp is only shown in UTC.
- After:
- The output now includes details about any errors/exceptions logged using the builder function
setExceptionDetails()
.- Previously the output only included the logged message - no details were included about the logged exception/error, which made it much harder to troubleshoot whatever the relevant error was 🙃
- The error output includes details about the metadata source, making it easy to tell if the error was caused by another LWC, an Apex controller method, or an Apex trigger.
- When devs use any of Nebula Logger's optional JS features (scenarios, tags, and custom field mappings), the details are automatically included in the
console
statements' output - For devs that do not leverage these optional features, the relevant properties are automatically excluded from the
console
output. This keeps the output slimmer & easier to read. - Each entry's timestamp is now shown both in UTC time (using
new Date().toISOString()
) and in the user's local format (usingnew Date().toLocaleString()
). This makes it a little easier for devs to troubleshoot exactly when an entry was generated in their browser.
- The output now includes details about any errors/exceptions logged using the builder function
Installation Info
Core Unlocked Package - no namespace
Full Changelog: v4.14.16...v4.14.17
- SF CLI:
sf package install --wait 20 --security-type AdminsOnly --package 04t5Y0000015ocRQAQ
- SFDX CLI:
sfdx force:package:install --wait 20 --securitytype AdminsOnly --package 04t5Y0000015ocRQAQ
- Sandbox: https://test.salesforce.com/packaging/installPackage.apexp?p0=04t5Y0000015ocRQAQ
- Production: https://login.salesforce.com/packaging/installPackage.apexp?p0=04t5Y0000015ocRQAQ
CallableLogger Enhancements
Thanks to @aBerean2 for some great feedback on logging in OmniStudio (see discussion #785)!
Core Unlocked Package Changes
Added 3 enhancements to the CallableLogger
class (used for OmniStudio logging & loosely-coupled dependencies)
-
Resolved #788 - It now automatically appends OmniStudio's input data for OmniScript steps as JSON to the
Message__c
fields onLogEntryEvent__e
andLogEntry__c
.-
In the screenshot below, a simple OmniScript has been setup with 2 steps (each of which shows some inputs), with logging actions after each step:
-
It now automatically stores the JSON from each of the steps & appends it to the message. Long-term, it might make sense to create a new field to store this data, but for now, appending it to
Message__c
is a quick & easy way to capture the JSON.
-
-
The
newEntry
action now supports setting the parent log transaction ID, using the optional argumentparentLogTransactionId
. -
Transaction details are now returned in the output for all actions:
transactionId
: The current transaction ID, returned fromLogger.getTransactionId()
parentLogTransactionId
: The parent log transaction ID (ornull
if no parent has been set), returned fromLogger.getParentLogTransactionId()
requestId
: The Salesforce-generated request ID, returned fromSystem.Request.getCurrent().getRequestId()
Installation Info
Core Unlocked Package - no namespace
Full Changelog: v4.14.15...v4.14.16
- SF CLI:
sf package install --wait 20 --security-type AdminsOnly --package 04t5Y0000015ocHQAQ
- SFDX CLI:
sfdx force:package:install --wait 20 --securitytype AdminsOnly --package 04t5Y0000015ocHQAQ
- Sandbox: https://test.salesforce.com/packaging/installPackage.apexp?p0=04t5Y0000015ocHQAQ
- Production: https://login.salesforce.com/packaging/installPackage.apexp?p0=04t5Y0000015ocHQAQ
Enhanced Queueable FinalizerContext logging messages
-
Utilizes Nebula Logger system messages framework to internally log info about different Apex async contexts and provides more information in the body of the associated log entry (as well as what prints to the Apex debug console) for Queueable finalizers:
-
Added methods in
Logger_Tests
to validate that an INFO log entry is auto-generated for async contexts (when system messages are enabled). This also includes a few changes for handling Exception instances not being serializable & adding some test helper methods -
Re-ran prettier on README.md to fix some code formatting
Added new Apex method & JavaScript function Logger.setField()
Many thanks to @surajp for sharing some awesome perspectives & suggestions for improving custom field mappings!
Custom field mappings were introduced a few months ago for Apex in v4.13.14
, and for lightning components in v4.14.16
. Both releases provided the ability to set custom fields on individual log entries - but in situations where a custom field should be set on every generated log entry, setting the field on each entry was very repetitive & tedious & repetitive. It was also repetitive.
- This release adds the ability to now set fields once per transaction (in Apex) or once per component instance (in JavaScript) - all subsequent log entries will then automatically have your custom field values applied.
- Individual log entries can still have additional field values set & mapped, giving you multiple options for setting your custom fields.
Core Unlocked Package Changes
New Apex Method Logger.setField()
Resolved #769 by adding a new static method, Logger.setField()
. This gives Apex developers a way to set field(s) once per transaction, and the fields will be auto-populated on all LogEntryEvent__e
records generated in that transaction.
-
The
setField()
method has 2 overloads (same as the instance method overloadsLogEntryEventBuilder.setField()
that were introduced in releasev4.13.14
)Logger.setField(Schema.SObjectField field, Object fieldValue)
- useful for easily setting the value for a single fieldLogger.setField(Map<Schema.SObjectField, Object> fieldToValue)
- useful for setting the value for multiple fields
-
The new method supplements the functionality introduced in release
v4.13.14
, as shown below:// 🥳New! // Set a custom field on all LogEntryEvent__e records in a transaction, // using static method Logger.setField() Logger.setField(LogEntryEvent__e.Some_Custom_Field__c, 'the value for all generated entries') // ℹ️Existing - introduced in v4.13.14 // Set a custom field on a single LogEntryEvent__e record, // using instance method LogEntryEventBuilder.setField() Logger.info('hello, world').setField(LogEntryEvent__e.Another_Custom_Field__c, 'the value for this specific entry');
New JavaScript Function logger.setField()
Added JavaScript support for setting fields once per component instance, using logger.setField()
. This is the JS equivalent of the new Apex method Logger.setField()
(above).
export default class LoggerLWCImportDemo extends LightningElement {
logger = getLogger();
connectedCallback() {
// 🥳New!
// Set My_Field__c on every log entry event created in this component with the same value
this.logger.setField({My_Field__c, 'some value that applies to any subsequent entry'});
// ℹ️Existing - introduced in v4.14.6
this.logger.warn('hello, world - "a value" set for Some_Other_Field__c').setField({ Some_Other_Field__c: 'a value' });
}
}
Installation Info
Core Unlocked Package - no namespace
Full Changelog: v4.14.13...v4.14.14
- SF CLI:
sf package install --wait 20 --security-type AdminsOnly --package 04t5Y0000015oWIQAY
- SFDX CLI:
sfdx force:package:install --wait 20 --securitytype AdminsOnly --package 04t5Y0000015oWIQAY
- Sandbox: https://test.salesforce.com/packaging/installPackage.apexp?p0=04t5Y0000015oWIQAY
- Production: https://login.salesforce.com/packaging/installPackage.apexp?p0=04t5Y0000015oWIQAY
New synchronous JavaScript function getLogger() + deprecated async function createLogger()
This release is focused on several enhancements & bugfixes for logging in JavaScript (aura & lightning web components). Thanks to @jamessimone for reviewing & discussing the changes for this release, and thanks to @srikanth3107 for reporting issue #776!
Core Unlocked Package Changes
New getLogger()
function
Partially fixed #728 by adding a new function getLogger()
in logger
LWC that can be called synchronously, and deprecated the async function createLogger()
- This simplifies how developers use the
logger
LWC, and avoids some lingering JavaScript (JS) stack trace issues that occur inasync
functions - The function
createLogger()
is still supported & functional, but it's now considered deprecated since it requires usingawait
(which is no longer necessary withgetLogger()
)
Note
This does not truly "fix" or improve the stack trace parsing used in async
functions, and async
functions will continue to have inaccurate function names reported in some browsers (typically, eval
is listed as the function name). This is a ongoing challenge in JavaScript due to what info is/isn't available in stack traces in some browsers (most notably, webkit browsers like Chrome & Edge).
But with the new getLogger()
function, Nebula Logger no longer requires the use of async
/ await
- and often the only reason developers were using async
/ await
was to be able to use Nebula Logger. In these situations, developers can eliminate async
/ await
, and the resulting log entries will have accurate JS function names.
Example: Old createLogger()
Usage
Previously, JS developers had to use async
, await
, and truthy checks to ensure that Nebula Logger's LWC had finished being loaded. This resulted in more complexity for developers, who just want to be able to log some stuff 😢
import { createLogger } from 'c/logger';
export default class LoggerDemo extends LightningElement {
logger;
// Some lifecycle event (typically connectedCallback()) has to run async & await createLogger()
async connectedCallback() {
this.logger = await createLogger();
this.logger.info('Hello, world');
this.logger.saveLog();
}
// @wire functions run around the same time as connectedCallback(), but there's no guaranteed order
// This result in some logging requiring truthy checks using the safe navigator "?.", and some loss of logging data could occur
@wire(returnSomeString)
wiredReturnSomeString({ error, data }) {
this.logger?.info('>>> logging inside a wire function, if the logger is loaded');
if (data) {
this.logger?.info('>>> wire function return value: ' + data);
}
if (error) {
this.logger?.error('>>> wire function error: ' + JSON.stringify(error));
}
}
}
Example: New getLogger()
Usage
Now, await
is no longer needed, and a logger
instance can be immediately initialized & used. This results in less code, and happier developers 🥳
import { getLogger } from 'c/logger';
export default class LoggerDemo extends LightningElement {
logger = getLogger();
connectedCallback() {
// Immediately use this.logger - no await, no truthy checks
this.logger.info('Hello, world');
this.logger.saveLog();
}
}
@wire(returnSomeString)
wiredReturnSomeString({ error, data }) {
// Immediately use this.logger - no await, no truthy checks
this.logger.info('>>> logging inside a wire function');
if (data) {
this.logger.info('>>> wire function return value: ' + data);
}
if (error) {
this.logger.error('>>> wire function error: ' + JSON.stringify(error));
}
}
}
New exception()
function
Resolved #763 by adding a JS function equivalent to the Apex method Logger.exception()
. Both of these do 3 things in 1 line of code:
- Log an exception
- Save the log
- Rethrow the exception
Previously in JS, this would have been 3 lines of code:
this.logger.error('An error occurred').setExceptionDetails(someJSError);
this.logger.saveLog();
throw someJSError;
Now, 1 line of code provides the same functionality:
this.logger.exception('An error occurred', someJSError);
More Improvements for JS Stack Trace Parsing
Fixed #776 by updating logic in loggerStackTrace.js
to better handle parsing when lightning debug mode is disabled
Previously, stack traces worked when debug mode was enabled, but was still inaccurate in some browsers when debug mode was off due to some subtle differences in the generated stack traces.
Installation Info
Core Unlocked Package - no namespace
Full Changelog: v4.14.12...v4.14.13
- SF CLI:
sf package install --wait 20 --security-type AdminsOnly --package 04t5Y0000015oW3QAI
- SFDX CLI:
sfdx force:package:install --wait 20 --securitytype AdminsOnly --package 04t5Y0000015oW3QAI
- Sandbox: https://test.salesforce.com/packaging/installPackage.apexp?p0=04t5Y0000015oW3QAI
- Production: https://login.salesforce.com/packaging/installPackage.apexp?p0=04t5Y0000015oW3QAI
Deprecated & replaced HttpRequestEndpoint__c fields with new HttpRequestEndpointAddress__c fields
Thanks to @ILambuRI for reporting this issue!
Core Unlocked Package Changes
Fixed #768 by deprecating the HttpRequestEndpoint__c
fields on LogEntryEvent__e
and LogEntry__c
, and replaced them with new HttpRequestEndpointAddress__c
fields that have a much longer max length (2,000 vs 255).
HttpRequestEndpoint__c
fields are now considered deprecated since they're not capable of storing the full value of long endpoints- The
HttpRequestEndpoint__c
fields will continue to be populated for the time being, and the value is now auto-truncated to 255 characters to fix theSTRING_TOO_LONG
error that was reported in #768 - The
businessStatus
on the fields has been updated toDeprecateCandidate
- The
inlineHelpText
on the fields has been update toDeprecated: instead use the field HttpRequestEndpointAddress__c
- The
label
on the fields has been update toDEPRECATED: HTTP Request Endpoint
- The
- Updated
LogEntryRecordPage
flexipage to have bothHttpRequestEndpoint__c
(existing) andHttpRequestEndpointAddress__c
fields- Both fields will be shown for now, and eventually
HttpRequestEndpoint__c
will be removed
- Both fields will be shown for now, and eventually
Related context: this is essentially the same issue & solution used in release v4.13.15
for the now-deprecated text(255) fields BrowserUrl__c
not being long enough, and they were replaced with new long textarea(2000) field BrowserAddress__c
(PR #720). It's probably worth reviewing all of the text fields in the data model (especially some of the older fields) to see if it would make sense to take the same approach for any other existing fields.
Installation Info
Core Unlocked Package - no namespace
Full Changelog: v4.14.11...v4.14.12
- SF CLI:
sf package install --wait 20 --security-type AdminsOnly --package 04t5Y0000015oV0QAI
- SFDX CLI:
sfdx force:package:install --wait 20 --securitytype AdminsOnly --package 04t5Y0000015oV0QAI
- Sandbox: https://test.salesforce.com/packaging/installPackage.apexp?p0=04t5Y0000015oV0QAI
- Production: https://login.salesforce.com/packaging/installPackage.apexp?p0=04t5Y0000015oV0QAI
Bugfix: Updated Logger.setAsyncContext() behavior
Core Unlocked Package Changes
- Updated the behavior of
Logger.setAsyncContext()
to only set the context the first time a non-null context value is provided- Previously, subsequent calls would overwrite the context value, which wasn't really the intended behavior - it's intended to be used to set context at the beginning of a transaction
Pipeline Changes
- Made some optimizations in
build.yml
so some steps don't run on draft PRs
Installation Info
Core Unlocked Package - no namespace
Full Changelog: v4.14.10...v4.14.11
- SF CLI:
sf package install --wait 20 --security-type AdminsOnly --package 04t5Y0000015oUgQAI
- SFDX CLI:
sfdx force:package:install --wait 20 --securitytype AdminsOnly --package 04t5Y0000015oUgQAI
- Sandbox: https://test.salesforce.com/packaging/installPackage.apexp?p0=04t5Y0000015oUgQAI
- Production: https://login.salesforce.com/packaging/installPackage.apexp?p0=04t5Y0000015oUgQAI
Double Feature: OmniStudio Logging + Loosely-Coupled Dependency Support
This release is a fun one - with one new Apex class, 2 great enhancements have been added to Nebula Logger
- It's now even easier for ISVs, consultants, and package developers to optionally leverage Nebula Logger when its available in your customers' orgs
- OmniStudio logging is now provided out of the box
Many thanks to @tscottdev for originally opening #371, as well as providing a very helpful sample implementation... and then waiting 2 years for me to finally be convinced that adding a Callable
implementation is a great enhancement 😅
Thanks as well to all of the feedback & interest people have provided about adding support for OmniStudio logging, and to @jamessimone for the help with setting up a usable OmniStudio scratch org for testing
Core Unlocked Package Changes
New Support for Using Nebula Logger as a Loosely-Coupled Dependency
Resolved #371 by introducing a new CallableLogger
Apex class that implements Apex's Callable interface - see the new wiki page for full docs.
This class provides dynamic access to Nebula Logger's core features - ISVs, consultants, and package developers can use this to optionally leverage Nebula Logger in a customer's org when it's available, without requiring a package dependency. For example, this sample code can be executed in any Salesforce org - and when Nebula Logger is available, 2 log entries will be saved.
// Dynamically create a instance Nebula Logger's Callable Apex class (if it's available)
Type nebulaLoggerCallableType = Type.forName('Nebula', 'CallableLogger') ?? Type.forName('CallableLogger');
Callable nebulaLoggerCallable = (Callable) nebulaLoggerCallableType?.newInstance();
if (nebulaLoggerCallable == null) {
return;
}
// Example action: Add a basic "hello, world!" INFO entry
Map<String, Object> infoEntryInput = new Map<String, Object>{
'loggingLevel' => System.LoggingLevel.INFO,
'message' => 'hello, world!'
};
nebulaLoggerCallable.call('newEntry', infoEntryInput);
// Example action: Add an ERROR entry with an Apex exception
Exception someException = new DmlException('oops');
Map<String, Object> errorEntryInput = new Map<String, Object>{
'exception' => someException,
'loggingLevel' => LoggingLevel.ERROR,
'message' => 'An unexpected exception was thrown'
};
nebulaLoggerCallable.call('newEntry', errorEntryInput);
// Example: Save any pending log entries
nebulaLoggerCallable.call('saveLog', null);
New Support for OmniStudio Logging
Resolved #644 by adding support for logging in OmniStudio, using the new CallableLogger
Apex class - see the new wiki page for full docs. The included CallableLogger
Apex class can be used in 2 places within OmniStudio:
-
OmniIntegrationProcedure
metadata
Once you've added logging in OmniStudio, any log entries generated in OmniStudio can be seen using the LogEntry__c
object's included list view AllOmniStudioLogEntries
Slack Plugin Package Changes
Fixed #764 by correcting the logic used in SlackLoggerPlugin
to format text fields containing line breaks
Thanks to @kacrouse for reporting this issue & providing the fix 🥳
Documentation Changes
Started rewriting & consolidating all documentation to live just in the wiki. Currently, content is split across the wiki, README.md
, and the GitHub Pages site
README.md
has been updated to link to wiki pages (instead of putting all content directly intoREADME.md
)- Eventually most of the content current in
README.md
will be removed/moved to the wiki
Pipeline Changes
- Renamed all of the scratch definition files (again 😅 )
- Updated
build.yml
so that 2 additional scratch orgs (6 total) are used for automated testing in the pipeline- "Advanced" scratch org (formerly called the 'dev' scratch org) - existing scratch org, but was not previously used by the pipeline
- "OmniStudio" scratch org - new scratch definition file, used to validate that queries on
OmniProcess
work correctly, and to validate that sampleOmniScript
andOmniIntegrationProcedure
metadata that leverageCallableLogger
can successfully be deployed
Installation Info
Core Unlocked Package - no namespace
- SF CLI:
sf package install --wait 20 --security-type AdminsOnly --package 04t5Y0000015oTdQAI
- SFDX CLI:
sfdx package install --apex-compile package --wait 20 --security-type AdminsOnly --package 04t5Y0000015oTdQAI
- Sandbox: https://test.salesforce.com/packaging/installPackage.apexp?p0=04t5Y0000015oTdQAI
- Production: https://login.salesforce.com/packaging/installPackage.apexp?p0=04t5Y0000015oTdQAI
Slack Unlocked Package Plugin - no namespace
- SF CLI:
sf package install --wait 20 --security-type AdminsOnly --package 04t5Y0000015oTTQAY
- SFDX CLI:
sfdx package install --apex-compile package --wait 20 --security-type AdminsOnly --package 04t5Y0000015oTTQAY
- Sandbox: https://test.salesforce.com/packaging/installPackage.apexp?p0=04t5Y0000015oTTQAY
- Production: https://login.salesforce.com/packaging/installPackage.apexp?p0=04t5Y0000015oTTQAY