### Example: LogMessage with list of inputs Source: https://jongpie.github.io/NebulaLogger/metadata-reference/logger-engine/logmessage Example usage of the LogMessage constructor with a list of inputs, formatting a placeholder with a list element. ```apex String unformattedMessage = 'my string with 1 input: {0}'; List arguments = new List{ System.now() }; String formattedMessage = new LogMessage(unformattedMessage, arguments).getMessage(); ``` -------------------------------- ### Example: LogMessage with three inputs Source: https://jongpie.github.io/NebulaLogger/metadata-reference/logger-engine/logmessage Example usage of the LogMessage constructor with three inputs, formatting three placeholders in the message. ```apex String unformattedMessage = 'my string with 3 inputs: {0} and then {1} and finally {2}'; String formattedMessage = new LogMessage(unformattedMessage, 'something', 'something else', 'one more').getMessage(); ``` -------------------------------- ### Example: LogMessage with one input Source: https://jongpie.github.io/NebulaLogger/metadata-reference/logger-engine/logmessage Example usage of the LogMessage constructor with one input, formatting a date into the message. ```apex String formattedMessage = new LogMessage('Today is {0}', System.today()).getMessage(); ``` -------------------------------- ### Open the org Source: https://jongpie.github.io/NebulaLogger/contributing/local-setup Opens the scratch org in the browser to verify the installation. ```bash sf org open --target-org nl-dev ``` -------------------------------- ### Example: LogMessage with two inputs Source: https://jongpie.github.io/NebulaLogger/metadata-reference/logger-engine/logmessage Example usage of the LogMessage constructor with two inputs, formatting two placeholders in the message. ```apex String unformattedMessage = 'my string with 2 inputs: {0} and {1}'; String formattedMessage = new LogMessage(unformattedMessage, 'something', 'something else').getMessage(); ``` -------------------------------- ### Verify unlocked package install Source: https://jongpie.github.io/NebulaLogger/getting-started/install-unlocked Lists installed packages for the target org. After install, you should see 'Nebula Logger - Core' at the installed version; if not, check Setup > Installed Packages for errors. ```bash sf package installed list --target-org ``` -------------------------------- ### start(configuration, input) Source: https://jongpie.github.io/NebulaLogger/metadata-reference/plugins/big-object-archiving/plugins/logentryarchiveplugin Skips deleting LogEntryTag__c records to include tags in archiving. ```APIDOC ## start(configuration, input) ### Description Skips directly deleting `LogEntryTag__c` records in `LogBatchPurger` so that the tags can be included when `LogEntry__c` records are archived into `LogEntryArchive__b`. ### Signature ```apex public void start(LoggerPlugin__mdt configuration, LoggerBatchableContext input) ``` ### Parameters - **configuration** (LoggerPlugin__mdt) - Required - The instance of `LoggerPlugin__mdt` configured for this specific plugin. - **input** (LoggerBatchableContext) - Required - The instance of `LoggerBatchableContext`, provided by the logging system. ### Return Type void ``` -------------------------------- ### Install managed package in production with sf package install Source: https://jongpie.github.io/NebulaLogger/getting-started/install-managed Installs the Nebula Logger managed package in a production org using the Salesforce CLI. Uses the same package ID and options as the sandbox install. Replace with your production org alias. ```bash sf package install --target-org --wait 30 --security-type AdminsOnly --package 04tg7000000GZbJAAW ``` -------------------------------- ### Install Nebula Logger Agent Skills with npx skills add Source: https://jongpie.github.io/NebulaLogger/ai-agent-skills/installing Run from the project root to install the Nebula Logger Agent Skills. Copies the skills into a local skills/ directory and updates skills.sh.json to register them. ```bash npx skills add jongpie/NebulaLogger ``` -------------------------------- ### Install unlocked package in production Source: https://jongpie.github.io/NebulaLogger/getting-started/install-unlocked Installs the unlocked package in a production org. Uses the production-specific package ID and the recommended AdminsOnly security type. ```bash sf package install --target-org --wait 20 --security-type AdminsOnly --package 04tg7000000HNrRAAW ``` -------------------------------- ### Install managed package in sandbox with sf package install Source: https://jongpie.github.io/NebulaLogger/getting-started/install-managed Installs the Nebula Logger managed package in a sandbox org using the Salesforce CLI. Uses the package ID 04tg7000000GZbJAAW, waits up to 30 minutes, and sets security type to AdminsOnly. Replace with your sandbox org alias. ```bash sf package install --target-org --wait 30 --security-type AdminsOnly --package 04tg7000000GZbJAAW ``` -------------------------------- ### Install unlocked package in sandbox Source: https://jongpie.github.io/NebulaLogger/getting-started/install-unlocked Installs the unlocked package in a sandbox org. Uses the sandbox-specific package ID and the recommended AdminsOnly security type. ```bash sf package install --target-org --wait 20 --security-type AdminsOnly --package 04tg7000000HNrRAAW ``` -------------------------------- ### Clone and install dependencies Source: https://jongpie.github.io/NebulaLogger/contributing/local-setup Clones the NebulaLogger repository and installs npm dependencies, which includes Salesforce CLI, sfdx-lwc-jest, Prettier, ESLint, and other build/test tools. ```bash git clone https://github.com/jongpie/NebulaLogger.git cd NebulaLogger npm install ``` -------------------------------- ### start Method Source: https://jongpie.github.io/NebulaLogger/metadata-reference/plugins/big-object-archiving/plugins/logentryarchiveplugin Skips directly deleting LogEntryTag__c records in LogBatchPurger so that the tags can be included when LogEntry__c records are archived into LogEntryArchive__b. ```apex public void start(LoggerPlugin__mdt configuration, LoggerBatchableContext input) ``` -------------------------------- ### Create org-default LoggerSettings__c record in Apex Source: https://jongpie.github.io/NebulaLogger/getting-started/post-install-setup Creates an org-default LoggerSettings__c record via Apex. Drop the Nebula__ prefix if you installed the unlocked package. Note: older references may mention DefaultLoggingLevel__c; the active field is LoggingLevel__c. ```apex Nebula__LoggerSettings__c settings = new Nebula__LoggerSettings__c( SetupOwnerId = UserInfo.getOrganizationId(), IsEnabled__c = true, LoggingLevel__c = 'INFO', DefaultSaveMethod__c = 'EVENT_BUS', DefaultNumberOfDaysToRetainLogs__c = 30 ); insert settings; ``` -------------------------------- ### Log a message with a record using the fluent interface Source: https://jongpie.github.io/NebulaLogger/logging-guide/apex Shows three equivalent ways to log a message with a record: using the overload, a builder variable, or chaining. The example queries the current user and logs it at debug level, then saves the log with Logger.saveLog(). Chaining is the most common pattern in the codebase. ```Apex User currentUser = [SELECT Id, Name, Username FROM User WHERE Id = :UserInfo.getUserId()]; // Overload Logger.debug('User loaded', currentUser); // Builder variable LogEntryEventBuilder builder = Logger.debug('User loaded'); builder.setRecord(currentUser); // Chained Logger.debug('User loaded').setRecord(currentUser); Logger.saveLog(); ``` -------------------------------- ### Create a scratch org Source: https://jongpie.github.io/NebulaLogger/contributing/local-setup Creates a scratch org using the base scratch definition file with alias nl-dev, sets it as default, and sets duration to 7 days. Adjust the definition file as needed. ```bash sf org create scratch --definition-file config/scratch-orgs/base-scratch-def.json --alias nl-dev --set-default --duration-days 7 ``` -------------------------------- ### Deploy plugins (optional) Source: https://jongpie.github.io/NebulaLogger/contributing/local-setup Deploys a specific plugin (e.g., Slack) to the scratch org. Each plugin lives under nebula-logger/plugins//plugin/. ```bash sf project deploy start --source-dir ./nebula-logger/plugins/slack/plugin/slack --target-org nl-dev ``` -------------------------------- ### Declare Nebula Logger as a hard dependency in sfdx-project.json Source: https://jongpie.github.io/NebulaLogger/for-package-developers/hard-dependency Add this dependencies entry to your sfdx-project.json to hard-require Nebula Logger. Salesforce enforces the dependency at install time, so customers without Nebula Logger cannot install your package until they install it. Adjust the version to whatever you tested against. ```json { "packageDirectories": [ { "path": "force-app", "package": "YourPackage", "versionNumber": "1.0.0.NEXT", "dependencies": [ { "package": "Nebula Logger - Core@4.19.2-0" } ] } ] } ``` -------------------------------- ### Run all tests Source: https://jongpie.github.io/NebulaLogger/contributing/testing Runs all tests: first test:lwc, then test:apex. ```bash npm test ``` -------------------------------- ### Deploy the core Source: https://jongpie.github.io/NebulaLogger/contributing/local-setup Deploys the core NebulaLogger code to the scratch org using the nl-dev target. ```bash sf project deploy start --source-dir ./nebula-logger/core --target-org nl-dev ``` -------------------------------- ### Run static analysis individually Source: https://jongpie.github.io/NebulaLogger/contributing/testing Runs static analysis individually for Apex and LWC. ```bash npm run scan:apex npm run scan:lwc ``` -------------------------------- ### saveLog is async: await before returning from an async handler Source: https://jongpie.github.io/NebulaLogger/logging-guide/lwc `saveLog()` returns a Promise. Await it when subsequent code depends on the save being complete, for example in a `finally` block. ```JavaScript async handleSave() { try { // work } catch (error) { this.logger.error('Save failed').setExceptionDetails(error); } finally { await this.logger.saveLog(); } } ``` -------------------------------- ### Add tags to a log entry in LWC Source: https://jongpie.github.io/NebulaLogger/logging-guide/tags In LWC, chain .addTag() off the info() call and then call saveLog(). The example shows adding two tags and setting a record before saving. ```javascript this.logger.info('Payment submitted').addTag('payment').addTag('checkout').setRecord(this.paymentId); await this.logger.saveLog(); ``` -------------------------------- ### Verify LogRetentionDate__c is set after saveLog Source: https://jongpie.github.io/NebulaLogger/retention/retention-dates Verifies that a log record gets a non-null LogRetentionDate__c after saving. If the assertion fails, check LoggerSettings__c.DefaultNumberOfDaysToRetainLogs__c for the user's hierarchy or an enabled LoggerScenarioRule__mdt with IsLogRetentionOverrideEnabled__c = false. ```apex Logger.info('Test entry'); Logger.saveLog(); // After Test.stopTest() / saveLog completes Log__c latest = [SELECT LogRetentionDate__c FROM Log__c ORDER BY CreatedDate DESC LIMIT 1]; System.Assert.isNotNull(latest.LogRetentionDate__c); ``` -------------------------------- ### Run static analysis Source: https://jongpie.github.io/NebulaLogger/contributing/testing Runs sf code-analyzer for both Apex (PMD) and LWC (ESLint + SLDS linter). CI treats any severity 1-3 violation as failure. ```bash npm run scan ``` -------------------------------- ### Set a scenario in Apex with Logger.setScenario() Source: https://jongpie.github.io/NebulaLogger/logging-guide/scenarios Call Logger.setScenario() once at the start of a transaction to assign a scenario name to the entire transaction. Every LogEntry__c in the resulting Log__c will have Scenario__c set to the provided value. Use Logger.saveLog() to persist the log. ```apex Logger.setScenario('Order Fulfillment'); Logger.info('Started'); // work Logger.info('Completed'); Logger.saveLog(); ``` -------------------------------- ### Verify docs with npm run docs:verify Source: https://jongpie.github.io/NebulaLogger/contributing/pr-conventions Verify that the docs are up-to-date before pushing. Passes if the docs are already up-to-date; fails and prints the diff if not. ```bash npm run docs:verify ``` -------------------------------- ### Aura controller using logger.info and logger.saveLog Source: https://jongpie.github.io/NebulaLogger/logging-guide/aura Use component.find('logger') to get the logger instance, then call level methods like info() and saveLog(). The handleRender function logs when the component renders, and logButtonClick logs a button click with an added tag. ```JavaScript ({ handleRender: function (component) { const logger = component.find('logger'); logger.info('Aura component initialized'); logger.saveLog(); }, logButtonClick: function (component, event) { const logger = component.find('logger'); logger.info('Save button clicked').addTag('user-action'); logger.saveLog(); } }); ``` -------------------------------- ### execute(configuration, input) Source: https://jongpie.github.io/NebulaLogger/metadata-reference/plugins/big-object-archiving/plugins/logentryarchiveplugin Handles converting LogEntryEvent__e records into LogEntryArchive__b records. ```APIDOC ## execute(configuration, input) ### Description Handles converting Logger's buffer of `LogEntryEvent__e` records into `LogEntryArchive__b` records for any user with the included custom save method 'BIG_OBJECT'. ### Signature ```apex public void execute(LoggerPlugin__mdt configuration, LoggerTriggerableContext input) ``` ### Parameters - **configuration** (LoggerPlugin__mdt) - Required - The instance of `LoggerPlugin__mdt` configured for this specific plugin. - **input** (LoggerTriggerableContext) - Required - The instance of `LoggerTriggerableContext`, provided by the logging system. ### Return Type void ``` -------------------------------- ### Schedule log purge batch with LogBatchPurgeScheduler Source: https://jongpie.github.io/NebulaLogger/getting-started/post-install-setup Schedules the log purge batch job to run daily at 2:00 AM. Verify in Setup > Scheduled Jobs; the job should appear as 'Nebula Logger - Daily Purge'. Without this step, retention dates are set but nothing acts on them. ```apex String cronExpression = '0 0 2 * * ?'; // Every day at 2:00 AM System.schedule('Nebula Logger - Daily Purge', cronExpression, new LogBatchPurgeScheduler()); ``` -------------------------------- ### execute(configuration, input, loggerRecords) Source: https://jongpie.github.io/NebulaLogger/metadata-reference/plugins/big-object-archiving/plugins/logentryarchiveplugin Converts LogEntry__c records into LogEntryArchive__b records. ```APIDOC ## execute(configuration, input, loggerRecords) ### Description Converts any `LogEntry__c` records into `LogEntryArchive__b` records. ### Signature ```apex public void execute(LoggerPlugin__mdt configuration, LoggerBatchableContext input, List loggerRecords) ``` ### Parameters - **configuration** (LoggerPlugin__mdt) - Required - The instance of `LoggerPlugin__mdt` configured for this specific plugin. - **input** (LoggerBatchableContext) - Required - The instance of `LoggerBatchableContext`, provided by the logging system. - **loggerRecords** (List) - Required - The list of `SObject` scope records provided by `LogBatchPurger`. ### Return Type void ``` -------------------------------- ### Apex: Set custom field values on log entries Source: https://jongpie.github.io/NebulaLogger/logging-guide/extending-the-data-model Shows how to set custom field values in Apex. Use Logger.setField() for transaction-wide values and the instance method on LogEntryEventBuilder for per-entry values. The example sets My_Field__c for all entries and Some_Other_Field__c for two specific entries, then saves the log. ```apex // Transaction-wide - every entry in this transaction gets My_Field__c set Logger.setField(LogEntryEvent__e.My_Field__c, 'some value that applies to the whole Apex transaction'); // Per-entry - only these two entries get Some_Other_Field__c set Logger.warn('First entry').setField(LogEntryEvent__e.Some_Other_Field__c, 'a value'); Logger.warn('Second entry').setField(LogEntryEvent__e.Some_Other_Field__c, 'different value'); Logger.info('Third entry with no custom field value'); Logger.saveLog(); ``` -------------------------------- ### Run LWC tests Source: https://jongpie.github.io/NebulaLogger/contributing/testing Runs LWC tests. ```bash npm run test:lwc ``` -------------------------------- ### Generate docs with npm run docs:fix Source: https://jongpie.github.io/NebulaLogger/contributing/pr-conventions Run the docs generation script after changing a public/global Apex or LWC API. Commit the updated Markdown files under docs/src/content/docs/metadata-reference/. ```bash npm run docs:fix ``` -------------------------------- ### Control logging level in tests with LoggerSettings__c Source: https://jongpie.github.io/NebulaLogger/logging-guide/testing Use this test setup to force a specific logging level (e.g., FINEST) in test context. Nebula Logger honors LoggerSettings__c in tests, so create a user-scoped setting record with the desired LoggingLevel__c. This is standard hierarchy custom setting behavior. ```apex @TestSetup static void setup() { LoggerSettings__c settings = new LoggerSettings__c( SetupOwnerId = UserInfo.getUserId(), IsEnabled__c = true, LoggingLevel__c = 'FINEST' ); insert settings; } ```