Making Your Console Logs Elegant With Consola

Written by murtuzaalisurti | Published 2023/11/17
Tech Story Tags: javascript | terminal | console | nodejs | how-to-use-consola | improving-console-logs | consola-guide | node.js-console-package

TLDRConsola is a Node.js console package that lets you create and log console logs.via the TL;DR App

Console logs are not always well structured and eye-pleasing. Unpleasant and messy console takes away from the bliss of a developer. I recently came across a package named consola which does exactly this — making consoles meaningful and elegant.

It has browser support, pausing and resuming logs, prompt support and other useful features.

Installation

You can install it by using npm, yarn or pnpm.

npm i consola

Trying it out

Spin up a new node/express app and start exploring.

Basics

For a quick hands on experience, in your node application, throw an explicit error and then log it with the help of consola.

import { consola } from "consola"

try {
    throw Error("Unexpected error")
} catch (error) {
    consola.error(error)
}

consola.error("Error...")
consola.info("Info...")
consola.warn("Warning...")
consola.log("Logged...")

New Instance

You can create a new consola instance with the help of the createConsola method and use that instead of the default global instance.

import { createConsola } from "consola"

const logger = createConsola({
    level: 0, // error/fatal logs
    fancy: true,
    formatOptions: {
        date: true,
        columns: 20
    },
})

logger.info("Info...") // this WON'T work
logger.error("Error...") // this will work

Set the log level to selectively allow only certain types of logs. Log level of 0 means only FATAL and ERROR logs are logged. The default log level is 3.

Reporters

Reporters are representations of logs in the terminal. Consola (v3.2.3) provides 3 reporters out of the box, namely, basic, fancy and browser. They are configured based on log levels on the global consola instance.

To add a custom reporter to your newly created instance, you can use the reporters property which is an array of reporters.

import { LogLevels, consola, createConsola } from "consola"

const infoLogger = createConsola({
    fancy: true,
    formatOptions: {
        date: true,
        columns: 20
    },
    reporters: [
        {
            log: (log) => {
                if (log.level === LogLevels.info) {
                    consola.info(JSON.stringify({
                        date: new Date().toLocaleString("default", { dateStyle: "full" }),
                        logs: new Array().concat(log.args.map((l, i) => `${l}${i < log.args.length - 1 ? `,` : ``}`)).join(" "),
                    }, null, 4))
                } else {
                    consola.error(
                        new Error("invalid log method")
                    )
                }
            }
        }
    ]
})

Now, when you use any logging method on this instance, it will only log for the info method and throw an error for other methods. You just created a custom info message logger which you can further modify however you want.

// for the above instance
infoLogger.error("Won't work") ❌
infoLogger.info("Will work") ✔️

Multiple reporters per instance are also supported allowing you to separate logs into desired representations.

reporters: [
    {
        log: (log) => {
            if (log.level === LogLevels.info) {
                consola.info(JSON.stringify({
                    date: new Date().toLocaleString("default", { dateStyle: "full" }),
                    logs: new Array().concat(log.args.map((l, i) => `${l}${i < log.args.length - 1 ? `,` : ``}`)).join(" "),
                }, null, 4))
            } else {
                consola.error(
                    new Error("invalid log method")
                )
            }
        }
    },
    {
        log: (log) => {
            createConsola({
                fancy: true,
                formatOptions: {
                    date: false
                }
            }).log(log)
        }
    }
]

Methods such as addReporter, setReporters and removeReporter are available to handle reporters for an instance.

Wrapping native console method with consola instance

Doing so will redirect all the native console.log calls to the specified consola instance.

infoLogger.wrapConsole()
// consola instance `infoLogger` will print the table
console.table(["Info", "Second Info"])

restoreConsole will restore the native functionality of console.log and won't redirect to consola instance.

There are several util methods present in consola/utils which you can use to further customize the logs.

Prompts

Prompts are supported in consola with the help of clack, a tool to build command-line apps. Check this out for some prompt examples in consola.

Conclusion

Correctly and elegantly representing console logs is an important task if you want to improve developer productivity and consola helps you with just that.

Also published here.


Written by murtuzaalisurti | Software Engineer & Content Creator
Published by HackerNoon on 2023/11/17