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.
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.
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
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 methodrestoreAll()
<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
{
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 enumerationLogLevels
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. Whentrue
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 isfalse
.enabled
: Specifies if the logging method will print in the console when it will be called.
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.
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);