Search

    Minimalistic Logging Facade (beta)

    cds.log (module name) Logger

    Returns a trace logger for the given module if trace is switched on for it, otherwise returns null. All cds runtime packages use this method for their trace and debug output.

    It can also be used in applications as follows.

    const LOG = cds.log('sql')
    LOG._info && LOG.info ('whatever', you, 'like...')
    

    You can also specify alternate module names: const LOG = cds.log('db|sql')

    You can set log levels per module via cds.env.log.levels = { <module>: <level> }:

    cds.env.log.levels = { app: 'warn', db: 'debug' }
    

    Learn more about cds.env.

    Further, tracing can be switched on/off through env variable DEBUG. Set it to a comma-separated list of modules to switch on tracing. Set it to ‘all’ or ‘y’ to switch on tracing for all modules.

    Arguments

    • module: the module for which a logger is requested
    • level?: the log level to enable -> 0=off, 1=error, 2=warn, 3=info, 4=debug, 5=trace, default: 3
    • prefix?: a prefix to prepend to each log output, default: [cds.<module>] -

    Capture Stack Trace with SQLite

    With env variable DEBUG set to ‘sqlite’, you can activate capturing the stack trace on the way to executing a query.

    Logger factory cds.log.Logger

    Constructs a new logger with the method signature of { trace, debug, log, info, warn, error } (cf. console). Additionally, the returned logger indicates which levels are active through a corresponding underscored property, for example, cds.log('sqlite')._debug is truth if the logger for module “sqlite” is set to at least debug level.

    The default implementation maps to console.error(), which prints to stderr. You can assign different implementations by exchanging the factory with your own, for example, in order to integrate advanced logging frameworks such as winston.

    Arguments

    • module: the module for which a logger is requested
    • level: the log level to enable -> 0=off, 1=error, 2=warn, 3=info, 4=debug, 5=trace
    • prefix?: a prefix to prepend to each log output, default: [cds] -

    Example

    cds.log.Logger = (module, level, prefix) => {
      const logger = winston.createLogger(...)
      Object.assign(logger, {
        level,
        _trace: false,
        _debug: false,
        _info: false,
        _warn: true,
        _error: true
      })
      return logger
    }
    

    Log Formatter cds.log.format

    You can provide a custom log formatter function by setting cds.log.format programmatically as shown, for example in your custom server.js.

    The formatter shall return an array of arguments, which are passed to the logger (for example, console.log()):

    cds.log.format = (module, level, ...args) => {
      return [`${module} //>`, util.format(...args)]
    }
    

    Out-of-the-box Log Formatting

    Log formatting can best be illustrated by examples. Hence, we look at the following example dummy logs from the CAP SFLIGHT app context, in which a warning with multiple arguments is issued and the request subsequently rejected with an error:

    const cds = require('@sap/cds')
    const LOG = cds.log('travel-service')
    
    class TravelService extends cds.ApplicationService {
    init() {
    
      this.before('READ', 'Travel', req => {
        LOG.warn('I will throw a test error.', { Do: 'not' }, 'panic.')
        req.reject('I will provoke a test error to be thrown.')
      })
    
      [...]
    
    }}
    

    Default Formatter

    During development, we want short messages in the console with clickable stack traces in case of errors. You should not be overloaded with information that is additionally obfuscated by a bad rendering. Hence, console.log(), that makes use of util.format() out of the box, with raw arguments is a good choice.

    The default log formatter does exactly that, prepending the list of arguments with [<module> -]. The following screenshot shows the log output for the previous warning and rejection with the default log formatter.

    Default Formatter Output

    Kibana-Friendly Formatter

    In production, DevOps typically consume application logs via dashboards such as Kibana or Grafana. Hence, the log output needs to be formatted in a way that enables the respective dashboard technology to optimally support the user, for example, filtering for logs of specific levels, modules, status, etc.

    The Kibana-friendly log formatter constructs a loggable object from the passed arguments as well as cds.context and the headers of the incoming request (if available).

    Currently, in production, the Kibana-friendly log formatter can be activated via cds.env.features.kibana_formatter. In the future, the Kibana-friendly formatter will become the default when running in SAP BTP when bound to an instance of the SAP Application Logging Service for the Cloud Foundry Environment.

    The following screenshot shows the log output for the rejection in the previous example with the Kibana-friendly log formatter.

    Kibana-friendly Formatter Output

    Request and Log Correlation

    Unfortunately, there is no standard correlation ID header. x-correlation-id and x-request-id are the most commonly used, but SAP products often use x-correlationid (that is, without the second hyphen) and SAP BTP uses x-vcap-request-id when logging incoming requests.

    As CAP aims to be platform independent, we check an array of headers (or generate a new ID if none hits) and ensure the value available at cds.context.id as well as req.headers['x-correlation-id']:

    const { headers: h } = req
    cds.context.id = h['x-correlation-id'] || h['x-correlationid']
      || h['x-request-id'] || h['x-vcap-request-id']
      || uuid()
    req.headers['x-correlation-id'] = cds.context.id
    

    The following screenshot shows an example for log correlation in Kibana .

    Default Formatter Output

    Module Names Used by the Runtime

    Component Module Name(s)
    ApplicationService app
    HanaDatabase db|sql|hana
    SQLiteDatabase db|sql|sqlite
    MessagingService messaging
    RemoteService remote
    OData protocol adapter odata
    REST protocol adapter rest
    Show/Hide Beta Features