Console logging in Deno

Mayank C
Tech Tonic

--

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);
string
console.table(i);
1
console.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: 14ms
console.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

--

--