Skip to main content
Version: 2.x

Setup and use logging

Front-Commerce uses the winston library for logging. This guide explains how to configure it and use it in your own code.

When you need to log something in a javascript environment, the first thing that comes to mind is obviously console.log. But the issue with it is that you won't be able access it in the long term. Especially since some Node.js server environments don't keep a trace of the stdout/stderr of your application.

To avoid this, we're using a custom logging interface based on winston (a well-known logging solution in the Node.js ecosystem). It allows you to create a logger and configure it in your my-module/config/logging.js file to send your logs to different systems.

Use the base loggers

There are three default loggers coming with Front-Commerce:

server logger

Reports any message sent through the default winston import in express routes

winston.info({
message: `Customer returned from ${methodCode} (${actionName})`,
date: format(new Date()),
});

client logger

Reports any log message from the client side

import logHandler from "utils/logHandler";

logHandler.getLogger().error(e);

access logger

Logs automatically any request incoming on your server

Configure the loggers

Without configuration, a logger does nothing. You need to configure what to do with the message reported by the different loggers.

my-module/config/logging.js
module.exports = {
server: [
{
type: "file",
filename: "server.log",
},
],
payment: [
{
type: "file",
filename: "payment.log",
},
],
client: [
{
type: "file",
filename: "client.log",
},
],
access: [
{
type: "file",
filename: "access.log",
},
],
security: [
{
type: "file",
filename: "security.log",
},
],
};

In this example, we've told the logging system to output every message in four files server.log, payment.log, client.log, access.log that will be accessible in the logs/ folder of your application.

But how does this work?

In fact, the object that we exports tells the logging system that for each logger (identified by the keys of the object), we will add an array of transports.

This means that for each logger, each message will be sent using these transports. Currently, the following types of logger transports are supported in Front-Commerce:

  • type: "file": it will append the message to a file in your server's filesystem.
    The only option available is filename which is the name of the file that will be put in the logs folder of your project.
  • type: "sentry": it will send the message to a sentry instance. Sentry is a tool that will make it easier to triage errors and assign some of your team members to their resolution.
    The only option available is options which is the object given to the transport lib winston-sentry-log
  • type: "console": it will send the message to stdout/stderr. This is intended for customers that already have a log collection system (centralized logging for kubernetes or a cloud platform).
  • type: "custom": You can provide your own winston.transports configuration within the transport attribute. This is intended for customers that need more control on the logging strategies.

Add a new logger

Splitting your messages in the four default loggers (access, client, server, payment) might be enough. But in some cases, you may want to move the messages into another logger to make it either to follow what happens for a specific feature.

Important

The new loggers you will create are only available server side. If you need to use this logger from the client side, you will need to either create a GraphQL mutation or a custom HTTP endpoint. This will allow the client to send a message to the server which will then be able to log it.

To do so, you can add a new custom logger

my-module/config/logging.js
module.exports = {
// ... the rest of your logger configuration
myLoggerName: [
{
type: "file",
filename: "server.log",
},
],
};

By doing this, you've configured your logger. But you still need to use it by importing the loggingService that will let you create the logger.

import loggingService from "server/core/logs/loggingService";

const logger = loggingService.createLogger("myLoggerName");

This will then be used just like the winston API: logger.log(type, message, data).

Log to the console

You can redirect all your logs to the console with the following code

my-module/config/logging.js
module.exports = {
server: [
{
type: "console",
},
],
payment: [
{
type: "console",
},
],
client: [
{
type: "console",
},
],
access: [
{
type: "console",
},
],
security: [
{
type: "console",
},
],
};

Automatic logging configuration

You can also automate the logging configuration based on whether the application is deployed on our cloud offer (V2) or not using the following my-module/config/logging.js

const makeLogAccordingToEnv = (filename) =>
process.env.FRONT_COMMERCE_CLOUD_VERSION === "2"
? { type: "console" }
: { type: "file", filename };

module.exports = {
server: [makeLogAccordingToEnv("server.log")],
client: [makeLogAccordingToEnv("client.log")],
access: [makeLogAccordingToEnv("access.log")],
payment: [makeLogAccordingToEnv("payment.log")],
security: [makeLogAccordingToEnv("security.log")],
};

Custom logger implementation

You can implement a custom logger like the following example

my-module/config/logging.js
const winston = require("winston");

module.exports = {
server: [
{
type: "custom",
transport: new winston.transports.Console({
format: winston.format.simple(),
}),
},
],
};

See available Winston transports for more details