Skip to content

Log Lifecycle

A log can have several forms throughout the lifecycle:

The log lifecycle includes following stages:

Logger initialization

Apex class logger

The logger in an apex class should be initialized using getLogger and with the correct type. Add the static modifier to enable logging from static methods.

⚠ The use of an incorrect type will break information about the method name, line number, etc.

public class AccountService {
    private static ok.Logger logger = ok.Logger.getLogger(AccountService.class);
}

Apex trigger logger

Similar to the Apex class, the trigger logger will be initialized simply with getTriggerLogger.

⚠ A trigger code is a top-level Apex, and its code should be wrapped in a try-catch-finally-publish block with error logging and publishing. The exception should be rethrown to roll back the transaction.

trigger AccountTrigger on Account(before insert) {
    ok.Logger logger = ok.Logger.getTriggerLogger();
    try {
        Domain.triggerHandler(Accounts.class);
    } catch (Exception e) {
        logger.error().addException(e).log('Unexpected error in trigger.');
        throw e;
    } finally {
        ok.Logger.publish();
    }
}

Anonymous apex logger

If you have some automated Apex scripts, you can also log from there using the anonymous block logger.

ok.Logger logger = ok.Logger.getAnonymousBlockLogger();

Flow logger

See Flow Logging.

LWC logger

See LWC Logging.

Build Log Data

First, you need to create a ok.Log — an Apex data class. The following methods on the ok.Logger instance will create a corresponding ok.Log instance:

  • logger.error().log(message);
  • logger.warn().log(message);
  • logger.info().log(message);
  • logger.debug().log(message);
  • logger.fine().log(message);
  • logger.finer().log(message);
  • logger.finest().log(message);
  • logger.logDatabaseFailures(List<Database.*>) - Log Database Errors
  • logger.publishExternalLogs() - Log External

Enhance the log by chaining various methods on the ok.Log; see all available methods in the ok.Log reference.

Basic logging example:

public class SpaceshipController {
    private static ok.Logger logger = ok.Logger.getLogger(SpaceshipController.class);
    private Spaceship__c spaceship;

    public Boolean prepareForHyperspaceJump() {
        Id pilotId = UserInfo.getUserId();
        Boolean isAuthorized = isHyperspaceJumpAuthorized(pilotId);
        if (!isAuthorized) {
            // WARNING log.
            logger.warn().linkSObject(spaceship).linkSObject2(pilotId).log('Pilot is not authorized.');
            return false;
        }
        // INFO log.
        logger.info().addPayloadJson(spaceship.getEngineStatus()).log('Hyperspace jump is ready.');
        return true;
    }
}

See more Logging Examples.

Register Logs for Publishing

Once you include all the information in the log, you can call .log(message) method to register the log. During registration, a log event is constructed and printed to the console if system debugging is enabled. You should treat the log object as read-only once you register it.

logger.error().log('Hello Message.');

Publish Log Events

Publish logs by calling publish. This method will publish the ok__Log_Event__e immediately.

⚠ Publish should be called only at the top-level Apex to bulkify the DML operation.

ok.Logger.publish();

Log Records Creation

Once the ok__Log_Event__e events are published, they are consumed by a platform event trigger and saved in the database as ok__Log__c records.

⚠ Avoid triggers on the ok__Log__c object, as such triggers can cause a loss of the logs. Instead, develop a custom plugin.

Plugins (optional)

Plugins gives you a flexibility to consume and process ok__Log_Event__e events in real-time.

See Plugin Development.

Persist Logs (optional)

Salesforce is not optimized to store a large volume of data, such as logs. Consider scheduling a log cleaner to prune old logs and connecting an external application like Splunk to persist and conduct further analysis.

Consume Log Records (optional)

Coming soon!