Skip to content

How to use a pino logger instance on nodemailer

Why use pino logger on nodemailer?

Nodemailer has debug options available in order to log transaction events and SMTP traffic messages, these options are "logger" which can receive a boolean true or false, if this option is set to true then transaction events are printed on console, this option can also receive a logger instance which needs to be bunyan compatible. The other option is "debug" which can receive a boolean true or false, if this option is set to true then SMTP traffic messages are printed

Getting started

First we need to create a new folder an initialize a node project

mkdir NodemailerPinoLogger
cd NodemailerPinoLogger
npm init -y

Installing npm modules

This is a list of all the packages needed and the reason why we will install them:

"express" (npm install express): Simplifies the creation of RESTful APIs 
using Node
"pino" (npm install pino): Logging framework for Node.js 
using Node
"nodemailer" (npm install nodemailer): is a module for Node.js applications to allow email sending
using Node

Initializing server

Now we will create our express server so we could test a nodemailer instance using pino logger, first create an app.js file

// ./app.js

// Import express
const express = require("express");
// Import pino and create logger instance
const logger = require('pino')()
// Import nodemailer
const nodemailer = require("nodemailer");

// Create nodemailer transport
const transporter = nodemailer.createTransport({
    // Use your own SMPT host
    host: "",
    port: 465,
    secure: true, // Use `true` for port 465, `false` for all other ports
    // Use your auth credentials for the SMTP server
    auth: {
        user: "",
        pass: "",
    },
    // Pass pino logger instance to transport logger option
    logger,
    // Set debug option to true
    debug: true,
    
});

const app = express();

app.use(express.json());

// Route to check server is working
app.get("/", (req, res) => {
    logger.info("logger working")
    res.status(200).send('Working');
})

// Route used to send email and test logger
app.get("/send-email", async (req, res) => {
    // Use created transport to send email
    logger.info("logger working")
    transporter.sendMail({
        from: 'jhony.gutidiaz@gmail.com', // sender address
        to: "oliverbravo45@gmail.com", // list of receivers
        subject: "Test email", // Subject line
        text: "Test message", // plain text body
    });
    res.status(200).send('Email sent');
})

module.exports = app;

now create a new file called index.js on the base of the project. We will use the app from above to listen for new requests

// ./index.js

const app = require("./app");

// Port that will be uses to listen to requests
const port = process.env.PORT || 3015;

/**
 * Listen on port 3015
 */
app.listen(port, () => {
    console.log(`App listening on port ${port}!`);
});

now if you passed correct SMTP credentials and go to the following endpoint http://localhost:3015/send-email you will see on the console nodemailer transaction events and SMTP traffic messages, moments after you should receive the test email

GitHub repository

In this repository https://github.com/obravocedillo/NodemailerPinoLogger you can find the code implementing all the solutions mentioned.