Logging

When working with any application, the necessity for logging is there and nothing is worse then missing or bad logging. Core provides developers with the ability to specify what should be logged and if necessary, to create their own logger for things like remote log storage.

The default logger that ships with ARK Core is an implementation of pino with support for console and file streams.

Prerequisites

Before we start, we need to establish what a few recurring variables and imports in this document refer to when they are used.

1import { app } from "@arkecosystem/core-kernel";
  • The app import refers to the application instance which grants access to the container, configurations, system information and more.

Usage

The application logger is accessible through the log property of the app instance. The logger contract that is provided by ARK Core follows the log levels defined in the RFC 5424 specification .

Get an instance of the Logger

1const logger: Contracts.Kernel.Log.Logger = app.get<Contracts.Kernel.Log.Logger>(Container.Identifiers.LogService)

Logging an emergency message

1logger.emergency('Hello World');

Logging an alert message

1logger.alert('Hello World');

Logging a critical message

1logger.critical('Hello World');

Logging an error message

1logger.error('Hello World');

Logging a warning message

1logger.warning('Hello World');

Logging a notice message

1logger.notice('Hello World');

Logging an info message

1logger.info('Hello World');

Logging a debug message

1logger.debug('Hello World');

Extending

As explained in a previous article, it is possible to extend Core services due to the fact that a Manager pattern is used. Lets go over a quick example of how you could implement your own logger.

Implementing the Driver

Implementing a new driver is as simple as importing the logger contract that needs to be satisfied and implement the methods specified in it.

1import { Contracts } from "@arkecosystem/core-kernel";
2 
3export class ConsoleLogger implements Contracts.Logger {
4 protected logger: Console;
5 
6 public async make(): Promise<Contracts.Logger> {
7 this.logger = console;
8 
9 return this;
10 }
11 
12 public emergency(message: any): void {
13 this.logger.error(message);
14 }
15 
16 public alert(message: any): void {
17 this.logger.error(message);
18 }
19 
20 public critical(message: any): void {
21 this.logger.error(message);
22 }
23 
24 public error(message: any): void {
25 this.logger.error(message);
26 }
27 
28 public warning(message: any): void {
29 this.logger.warn(message);
30 }
31 
32 public notice(message: any): void {
33 this.logger.info(message);
34 }
35 
36 public info(message: any): void {
37 this.logger.info(message);
38 }
39 
40 public debug(message: any): void {
41 this.logger.debug(message);
42 }
43}

Implementing the service provider

Now that we have implemented our console driver for the log service, we can create a service provider to register it.

1import { Container, Contracts, Providers, Services } from "@arkecosystem/core-kernel";
2 
3export class ServiceProvider extends Providers.ServiceProvider {
4 public async register(): Promise<void> {
5 const logManager: Services.Log.LogManager = this.app.get<Services.Log.LogManager>(
6 Container.Identifiers.LogManager,
7 );
8 
9 await logManager.extend("console", async () =>
10 this.app.resolve<Contracts.Log.Logger>(ConsoleLogger).make(this.config().all()),
11 );
12 
13 logManager.setDefaultDriver("console");
14 }
15}
  1. We retrieve an instance of the log manager that is responsible for managing log drivers.
  2. We call the extend method with an asynchronous function which is responsible for creating the logger instance.
  3. We call the setDefaultDriver method which will tell Core to use console as the new default logger.

If you do not call setDefaultDriver you’ll need to manually retrieve the console logger instance via app.get<LogManager>(LogManager).driver("console").

Last updated 2 years ago
Edit Page
Share: