Skip to content

A simple logger for "lazy" developers that use lots of console.log() in their code and never remove them

License

Notifications You must be signed in to change notification settings

msalafia/deblog

Repository files navigation

Deblog.js

GitHub package.json version npm

Deblog.js is a simple and flexible wrapper of the console object that allows the definition of custom methods for logging purposes, defining mnemonic names, customized tags for logging messages ed severity log levels.

The best feature of Deblog is that allows the developer to define which one of the logging methods created should print or not.

Motivation

How many times you write console.log() in your code and never remove them because you are too lazy to do that or just because you think they will be useful in future for debugging purpose?

If you are that kind of lazy javascript developer that uses lots of compulsive console.logs() in the code that will never be removed, Deblog is made for you.

You can configure the Deblog instance for your project defining specific logging methods with a mnemonic name depending on the case they will be used. You can also customize them with a tag that will be attached as an header of the logged message. All of these logging methods (named logs in the context of Deblog.js) provides a flag to enable or disable them. Therefore, in the future, when you don't need a particular log in your console, you can simply change its flag in the Deblog instance configuration.

Quickstart

To install Deblog in an npm project you can simply run:

npm install deblog

In order to create an instace of Deblog you just import the method createDeblog() from the package and call it providing a proper configuration for your needs:

import { createDeblog } from "deblog";

const configuration = {
  logs: [
    {
      name: "foo",
      level: "debug",
      tag: "FOO -",
      enabled: true,
    },
    {
      name: "bar",
      level: "log",
      tag: `BAR -`,
      timestamp: () => `[${new Date(Date.now()).toLocaleTimeString()}]`,
    },
  ],
};

let dlog = createDeblog(configuration);

In the example above, we are configuring the deblog instance saved in the variable dlog in order to expose two custom logging methods named foo and bar, respectively. We are also specifying that the log foo will provide a logging level of debug, whilst the log bar will provide a logging level of log. The logging levels here are just the names of the methods that will be called on the console object wrapped by the deblog instance. Therefore, console.debug() and console.log() will be called for each call of dlog.foo() and dlog.bar(), respectively.

Both logging methods are configured with a tag that will be printed at the beginning of each print in the console. As you can see for the foo log, you can define a custom function that returns a string representing a timestamp that will be printed before the tag. Furthermore, both logs are enabled using the enabled property in the configuration. Omitting such a property will enable the log by default.

Once created, a Deblog instance can be used like this:

dlog.foo("An big bad error here:", { error: "I am a big bad error" });

dlog.bar("Still executing this code");

This will produce the following output:

FOO - An big bad error here: { error: 'I am a big bad error' }
[17:11:56] BAR - Still executing this code

Silencing logs

A Deblog instance provides convenient methods to stop either some or all of the logs defined by the user ti print in the console.

You can use the methods:

  • disableAllBut(...args): It silences all the logs defined in the deblog instance, except the ones with the names provided as the arguments. All the logs can be restored to the previous value provided in the configurations with the method restoreAll()
  • <log>.disable(): a method defined for each logging method configured in the Deblog instance. It silences the prints in the console generated by log where this method is called. The log can be restored to the value configured in the Deblog instance with the log method <log>.restore(). The method <log>.enable() enables (really?!?!) the prints in the console generated by the log where this method is called.

Silencing methods are quite useful in case you want to focus on a particular log print in a code section, disabling all the other ones or some of them.

An example of silencing methods:

//...import and configuration missing

let dlog = createDeblog(configuration);

dlog.disableAllBut("bar"); // Silencing all logs but bar

dlog.foo("1 Connection Error"); // Will not be logged
dlog.bar("I'm here!");
dlog.foo("2 Connection Error"); // Will not be logged
dlog.bar("I just need bar logs here");

dlog.restoreAll();

dlog.bar("4 Connection Error"); // Will be logged

dlog.bar.disable();

dlog.bar("5 Connection Error"); // Will not be logged

This will produce the following output:

[21:08:07] BAR - I'm here!
[21:08:07] BAR - I just need bar logs here
[21:08:07] BAR - 4 Connection Error

Deblog Configuration object

{
  id?: string
  persist?: boolean
  logs: [
    {
      name: string,
      level: "log" | "debug" | "info" | "warn" | "error",
      tag?: string,
      timestamp?: boolean | (() => string)
      enabled?: boolean //default: true
    }
  ]
}

A deblog configuration object is structured with the following properties:

  • id: It defines the unique name for this deblog instance. It's optional and, if it is not provided, an id will be automatically generated.
  • persist: A flag indicating whether the deblog instance should be saved in the Deblog internal repository. See the section "Deblog Repository". It's optional and the default falue is "false".
  • logs: An array of log configuration objects (described in the reminder). It's optional and the default value is "[]".

A log configuration is structured with the following properties:

  • name: A string representing the name of the logging method that will be exposed by the deblog instance.
  • level: The method that will be called on the console object. The only allowed values are "log" | "debug" | "info" | "warn" | "error". For commodity, you can import and use the enumeration LogLevels to assign a proper value to this property.
  • tag: A string to be attached at the beginning of the log line printed in the console.
  • timestamp: It is used to configure a timestamp before the tag and the message of the log. When true is provided, a timestamp is generated using [${(new Date()).toLocaleTimeString()}]. You can also provide a function returning a string to customize your timestamp format or decide whatever to return. The default value is false.
  • enabled: Specifies if the logging method will print in the console when it will be called.

Deblog Repository

Instances of deblog can be persisted in an internal Deblog repository which is just a Map containing all the deblog instances created with the configuration property persist: true. The repository uses the deblog instance id property as a key.

You can always retrieve a deblog instance using the convenient methods exposed by Deblog.js:

  • getDeblog(id: string): IDeblog
  • getDeblogs(): IDeblog[]

An example here:

const dlog = createDeblog(configuration);

dlog.foo("The id of the Deblog instance is:", dlog.id);

let dlog2 = getDeblog("my-deblog");

console.log("Same instance?:", dlog === dlog2);

const dlog3 = createDeblog({
  id: "new-deblog",
  persist: true,
  logs: [
    {
      name: "shout",
      level: "log",
      tag: "SHOUT -",
    },
  ],
});

console.log("All saved logs:", getDeblogs().length); // length: 2

clearDeblogs(); // clear the Deblog repository

console.log("All saved logs:", getDeblogs().length); // length: 0

dlog.foo("I am still alive!"); // This will be logged anyways. clearDeblogs() doesn't delete deblog instances saved in your variables.

As shown, the method clearDeblogs clears the Deblog Repository but doesn't destroy the instances. Therefore, deblog instances in your variables still exists and works.

Note for Typescript

Since the logging methods are dynamically defined by the user, the intellisense cannot autocomplete them. For this reason, the method createDeblog() has been defined as generics for convenience (i.e., createDeblog<T extends IDynamicLogs>()).

in this way, you can define a type containing all your custom logging methods and pass to the method createDeblog as generic parameter.

interface MyLogs extends IDynamicLogs {
  wwm: TLog;
  vsm: TLog;
}

let log = createDeblog<MyLogs>(configuration);

// Also

let log = createDeblog<{
  wwm: TLog;
  vsm: TLog;
}>(configuration);

About

A simple logger for "lazy" developers that use lots of console.log() in their code and never remove them

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published