Console logging in Deno
Purpose
Quite often, console.log
gets primarily used for logging any data on the console. Undoubtedly, console.log
would be the most popular logging function. It’s flexible too as it can log any kind of data. But console logging isn’t limited to console.log
. There are a lot more functions to log on console, some of them quite useful for certain use cases.
The Web Hypertext Application Technology Working Group (whatwg) has a living standard for advanced console logging (https://console.spec.whatwg.org/). As Deno follows the web standards wherever possible, Deno implements all the functionality proposed in the console specification.
In this article, we’ll go over all the console functions implemented by Deno along with some examples. We’ll see how Deno’s implementation differs from the browser’s (in some cases, the output is different from what is seen on the browser). The reason for the difference is that Deno logs on a simple console with no interactivity.
Logging functions
Deno’s core runtime comes with whatswg’s proposed console logging. There are a number of useful functions. Here is the list of functions present in the console object:
- assert: Checks a condition
- clear: Clears the console (wherever applicable and possible)
- count: Prints the number of times a label has been logged
- countReset: Resets the count of a label
- debug: Prints data on console if log level allows
- error: Prints data on console if log level allows
- warn: Prints data on console if log level allows
- info: Prints data on console if log level allows
- trace: Prints data on console if log level allows
- log: Prints data on console
- dir: Prints data on the console (normal format)
- dirxml: Same as dir
- group: Groups by indenting logging lines
- groupEnd: End an indentation group
- groupCollapsed: Same as group
- table: Prints object or array in tabular format
- time: Notes the timestamp for a given label
- timeEnd: Prints the time difference between time and timeEnd for a given label
- timeLog: Prints the current value of a timer
assert
The console.assert
is like a regular assert, except that it doesn’t raise an exception. This function takes a condition as input, and logs:
- Nothing if assertion has passed
- Assertion failed if assertion has failed
const a='abcd',
b='abcd',
c='abcde';console.assert(a===b);
//console.assert(b===c);
//Assertion failed
clear
The console.clear
function clears the console (like Linux clear
command). This is implementation dependent as clear
may not work on some operating systems.
console.clear();
//clears the console on Mac and Linux
count & countReset
The console.count
function prints the count of the number of times an input label has been used. In other words, it prints the label and the number of times the label has been logged. This is a useful replacement to logging statements like here 1/here 2/here 3
. The console.countReset
function resets the count of a label. This is useful in restarting the counting after a point.
const a=1;
console.count('here');
const b=await fetch('http://abc.com');
console.count('here');
const c=await Deno.readTextFile('/var/tmp/a.txt');
console.count('here');//here: 1
//here: 2
//here: 3----const a=1;
console.count('here');
const b=await fetch('http://abc.com');
console.count('here');
console.countReset('here');
const c=await Deno.readTextFile('/var/tmp/a.txt');
console.count('here');//here: 1
//here: 2
//here: 1
debug
The console.debug
function prints given data on the console if the logging level is set to at least debug.
const s='string', i=1, a=[1, 2, 'c'], b={ a: 1, c: { d: 'd'}};
console.debug(s);
console.debug(i);
console.debug(a);
console.debug(b);//string
//1
//[ 1, 2, "c" ]
//{ a: 1, c: { d: "d" } }
Usually, we’d expect a prefix like DEBUG
before the log statement, but Deno doesn’t print it. In the browser, console.debug
logs the data in a different color.
dir & dirxml
The console.dir
function prints the data on the console normally. As per spec, this function produces interactive dump of a JavaScript object. In console applications, that kind of interactivity is tough to implement. Therefore, Deno logs like a regular data.
const s='string', i=1, a=[1, 2, 'c'], b={ a: 1, c: { d: 'd'}};
console.dir(s);
console.dir(i);
console.dir(a);
console.dir(b);//string
//1
//[ 1, 2, "c" ]
//{ a: 1, c: { d: "d" } }
In Deno, console.dirxml
is just an alias for console.dir
, therefore the output is exactly the same.
warn
In Deno, console.warn
logs data on the console if the log level allows. The output is exactly the same as console.debug
.
error
In Deno, console.error
logs data on the console if the log level allows. The output is exactly the same as console.debug
.
info
In Deno, console.info
logs data on the console if the log level allows. The output is exactly the same as console.debug
.
trace
In Deno, console.trace
logs data on the console if the log level allows. The output is exactly the same as console.debug
.
log
In Deno, console.logs
logs data on the console. The output is exactly the same as console.debug
.
group, groupEnd & groupCollapsed
The console.group/groupEnd
functions are very useful in indenting related logging lines. A group can be started with console.group
function call. All the subsequent lines would be indented till:
- A new group is started with another
console.group
function call, or - The current group is ended with
console.groupEnd
function call
The grouping would keep increasing the indentation, while group ending would keep decreasing it.
const s='string', i=1, a=[1, 2, 'c'], b={ a: 1, c: { d: 'd'}};
console.debug(s);
console.debug(i);
console.group();
console.debug(a);
console.group();
console.debug(b);
console.groupEnd();
console.debug(b);
console.groupEnd();
console.debug(a);//outputstring
1
[ 1, 2, "c" ]
{ a: 1, c: { d: "d" } }
{ a: 1, c: { d: "d" } }
[ 1, 2, "c" ]
As can be seen in the above output, 1st, 2nd, and 6th lines are logged normally (no grouping). Lines 3rd and 5th are logged at indentation level 1, while the line 4th is logged at indentation level 2.
There is another function console.groupCollapsed
. This function is useful in creating collapsed groups that can be opened by the user. In the context of console, the behavior of groupCollapsed
is the same group
.
table
The console.table
function is useful in logging an object or an array in a tabular format. The algorithm in console.table
tries to fit in the data as best as possible. Sometimes too much diverse data leads to unexpected logging, and that’s okay. Otherwise, for simple objects or arrays or array of objects, console.table
works very well. For primitive types, it defaults to regular logger.
Let’s see some examples:
const s='string',
i=1,
a=[1, 2, 3],
b=['a', 'b', 'c'],
c=[{a: 1, b: 2, c: '3'}],
d={a: 1, c: { d: 'd'}},
e={a: [{b: 1, c: 2}, {d:3, e: 4}]};console.table(s);
stringconsole.table(i);
1console.table(a);
┌───────┬────────┐
│ (idx) │ Values │
├───────┼────────┤
│ 0 │ 1 │
│ 1 │ 2 │
│ 2 │ 3 │
└───────┴────────┘console.table(b);
┌───────┬────────┐
│ (idx) │ Values │
├───────┼────────┤
│ 0 │ "a" │
│ 1 │ "b" │
│ 2 │ "c" │
└───────┴────────┘console.table(c);
┌───────┬───┬───┬─────┐
│ (idx) │ a │ b │ c │
├───────┼───┼───┼─────┤
│ 0 │ 1 │ 2 │ "3" │
└───────┴───┴───┴─────┘console.table(d);
┌───────┬─────┬────────┐
│ (idx) │ d │ Values │
├───────┼─────┼────────┤
│ a │ │ 1 │
│ c │ "d" │ │
└───────┴─────┴────────┘console.table(e);
┌───────┬────────────────┬────────────────┐
│ (idx) │ 0 │ 1 │
├───────┼────────────────┼────────────────┤
│ a │ { b: 1, c: 2 } │ { d: 3, e: 4 } │
└───────┴────────────────┴────────────────┘
As we can see, console.table
works best with simple objects and arrays. For nested object, console.log
is better.
time, timeEnd & timeLog
The console.time/timeEnd
are useful functions in quickly measuring the time taken by a piece of code. The only drawback is that, these functions use low-res timers. Therefore, a piece of code that executes quickly may report 0ms, or the time would be rounded to the nearest millisecond.
The console.time
function is used to note down the timestamp for a given label. This function doesn’t print anything. The console.timeEnd
function calculates the time taken since console.time
for a given label. This function prints the total time taken by a piece of code. If no label is supplied, the difference is calculated from the last console.time
.
console.time();
for(let i=0; i<10000000; i++);
console.timeEnd();
//default: 14msconsole.time('a');
console.time('b');
for(let i=0; i<10000000; i++);
console.timeEnd('b');
console.time('c');
for(let i=0; i<30000000; i++);
console.timeEnd('c');
console.timeEnd('a');//b: 9ms
//c: 17ms
//a: 28ms
The console.timeLog
function prints the current value of a timer started with console.time
.
console.time('a');
console.timeLog('a');
for(let i=0; i<100000000; i++);
console.timeLog('a');
for(let i=0; i<100000000; i++);
console.timeLog('a');
for(let i=0; i<100000000; i++);
console.timeEnd('a');//a: 0ms
//a: 84ms
//a: 140ms
//a: 223ms