Introduction

OstroJS has extensive logging services to help you learn more about what's going on in your application. You may log messages to files, the system error log, or even Slack to inform your entire team.

OstroJS makes use of the Monolog library, which has support for a number of advanced log handlers. OstroJS makes configuring these handlers a breeze, enabling you to mix and match them to tailor the log processing in your application.

Configuration

The config/logging.js configuration file contains all of the settings for your application's logging system. This file allows you to set your application's log channels, so have a look at all of the choices and channels available. Below, we'll go through a few popular choices.

When logging messages, OstroJS uses the stack channel by default. The stack channel combines many log channels into a single channel. Check out the documents below for additional information on stack construction.

Configuring The Channel Name

Monolog is started by default with a "channel name" that corresponds to the current context, such as production or local. Add a name option to your channel's setup to modify this value:

'stack' : {
    'driver' : 'stack',
    'name' : 'channel-name',
    'channels' : ['single', 'slack'],
},

Available Channel Drivers

NameDescription
stackA wrapper to facilitate creating "multi-channel" channels
singleA single file or path based logger channel (StreamHandler)
dailyA RotatingFileHandler based Monolog driver which rotates daily
syslogA SyslogHandler based Monolog driver
errorlogA ErrorLogHandler based Monolog driver
customA driver that calls a specified factory to create a channel

Configuring The Slack Channel

A url configuration option is required for the slack channel. This URL should be the same as the incoming webhook URL you set up for your Slack team. Slack will only receive logs that are critical or higher by default, but you may change this in your logging configuration file.

Building Log Stacks

The stack driver, as previously noted, allows you to merge many log channels into a single log channel. Let's look at an example setup that you could see in a production application to demonstrate how to utilise log stacks:

 'channels' : {
        'stack' : {
            'driver' : 'stack',
            'channels' : ['single'],
            'ignore_exceptions' : false,
        },
        
        'single' : {
            'driver' : 'single',
            'path' : storage_path(`logs/ostro.log`),
            'level' : 'debug',
        },

        'daily' : {
            'driver' : 'daily',
            'path' : storage_path(`logs/ostro-%DATE%.log`),
            'date_pattern' : 'YYYY-MM-DD',
            'level' : 'debug',
            'days' : 30,
        },
      
        'console':{
            'driver' : 'console',
            'level' : 'debug',
        },
        'syslog' : {
            'driver' : 'syslog',
            'level' : 'debug',
        },
    },

Let's take a closer look at this setup. First, observe how our stack channel uses the channels option to combine two additional channels: syslog and slack. As a result, when it comes to logging messages, both of these channels will be able to do so.

Log Levels

In the example above, observe the level configuration option on the syslog and slack channel setups. This option specifies the minimum "level" at which a message must be in order for the channel to log it. OstroJS's logging services are powered by Monolog, which supports all of the RFC 5424 log levels: emergency, alert, critical, error, warning, notice, info, and debug.

Assume we're logging a message with the debug method:

Log.debug('An informational message.');

The syslog channel will write the message to the system log based on our settings; but, because the error message is not critical or above, it will not be forwarded to Slack. However, because the emergency level is higher than our minimum level threshold for both channels, an emergency message will be delivered to both the system log and Slack:

Log.emergency('The system is down!');

Writing Log Messages

The Log fa├žade may be used to write data to the logs. As previously stated, the logger supports the RFC 5424 specification's eight logging levels: emergency, alert, critical, error, warning, notice, info, and debug:

Log.emergency($message);
Log.alert($message);
Log.critical($message);
Log.error($message);
Log.warning($message);
Log.notice($message);
Log.info($message);
Log.debug($message);

To log a message for the associated level, you can use any of these techniques. The message will be written to the default log channel as specified in your config/logging.js configuration file by default:

const Controller = require('~/app/http/controllers/controller')
const User = require('~/app/models/user')
const Log = require('@ostro/support/facades/log')
class UserController extends Controller {
    /**
     * Show the profile for the given user.
     *
     */
    async showProfile({params, view}) {
        Log.info('Showing user profile for user: '+params.id);

        return view('user.profile', {'user' : await User.findOrFail(params.id)});
    }
}
module.exports = UserController

Contextual Information

The log methods can also take an array of contextual data. With the log message, these contextual data will be prepared and displayed:

Log.info('User failed to login.', {'id' : $user.id});

Writing To Specific Channels

You might want to log a message to a channel other than the default one for your application. You may get and log to any channel configured in your configuration file using the channel method on the Log facade:

Log.channel('slack').info('Something happened!');