Universal Logging for Typescript/JavaScript
Getting Started
Reference Manual
Plugins
FAQ's
v1.x
GitHub
Getting Started
Reference Manual
Plugins
FAQ's
v1.x
GitHub
  • Reference Manual
    • Introduction & Lifecycle
    • Log Class
    • Data Getters
    • Modifiers
    • Terminators
    • Global Store
    • Tools
    • Configuration
    • Middleware
    • Formatters
    • Unit Testing

Modifiers

Once you have an Adze log instance you can now start applying modifiers. Modifiers are methods that alter the log in some way and then return the log instance so that you may chain more modifiers or terminate the instance. Keep in mind, some modifiers have a dependency on the presence of a label and labels rely on GlobalStore.

assert

This modifier accepts an assertion boolean expression and will only print if the boolean expression fails (is a falsy value).

MDN Docs

Interface

class Log {
  public assert(expression: boolean): Log;
}

Example

import adze from 'adze';

const x = 2;
const y = 3;

// Let's assert that x and y should be equal
adze.assert(x === y).log('X does not equal Y');

// This log will not print because the assertion passes
adze.assert(x === 2).log('X does not equal 2');

// Let's look at the output with emoji's enabled
adze.withEmoji.assert(x === y).log('X does not equal Y');

Browser Output

assert modifier example browser output

Server Output

assert modifier example server Output

closeThread

This modifier closes a thread by deleting its tracked context from a shared label group.

This is used primarily in conjunction with a label and the thread terminator for implementing Threading.

This is not a standard API.

Interface

class Log {
  public get closeThread(): Log;
}

Example

import adze, { setup } from 'adze';

function add(a: number, b: number) {
  const answer = a + b;
  adze.label('foo').thread('added', { a, b, answer });
  return answer;
}

function subtract(x: number, y: number) {
  const answer = x - y;
  adze.label('foo').thread('subtracted', { x, y, answer });
  return answer;
}

add(1, 2);
subtract(4, 3);

adze.label('foo').dump.info('Results from our thread');
adze.label('foo').closeThread.info('Closing the foo thread.');
adze.label('foo').dump.info('Dumping the thread context after closing it.');

Browser Output

close thread modifier example browser output

Server Output

close thread modifier example server output

count

The count modifier tells the log to increment a counter associated to the log's label.

MDN Docs

Interface

class Log {
  public get count(): Log;
}

Example

import adze from 'adze';

for (let i = 0; i < 5; i += 1) {
  adze.label('my-counter').count.log('Counting iterations.');
}

Browser Output

Count modifier output

Server Output

Count modifier server output

countClear

The countClear modifier completely clears the count from a label. Rather than setting the count to 0 it instead becomes null.

WARNING

This method is deliberately a modifier rather than a terminator because it forces you to write a log that gives you insight into when a counter was cleared. It also makes the countClear log recallable from the global store in the order it was created.

This is not a standard API.

Interface

class Log {
  public get countClear(): Log;
}

Example

import adze from 'adze';

for (let i = 0; i < 4; i += 1) {
  adze.label('my-counter').count.log('Counting iterations.');
}

adze.label('my-counter').countClear.log('Clearing the counter.');

adze.label('my-counter').log('A log with the my-counter label but no count.');

Output

count clear modifier example output

countReset

The countReset modifier resets the counter associated to the log's label to 0.

WARNING

This method is deliberately a modifier rather than a terminator because it forces you to write a log that gives you insight into when a counter was reset. It also makes the countReset log recallable from the global store in the order it was created.

MDN Docs

Interface

class Log {
  public get countReset(): Log;
}

Example

import adze from 'adze';

for (let i = 0; i < 4; i += 1) {
  adze.label('my-counter').count.log('Counting iterations.');
}

adze.label('my-counter').countReset.log('Resetting the counter.');

for (let i = 0; i < 4; i += 1) {
  adze.label('my-counter').count.log('Counting iterations again.');
}

Browser Output

count reset modifier example browser output

Server Output

count reset modifier example server output

dir

The dir modifier transforms the output of the log by directing it to use the console.dir() method for printing purposes only.

WARNING

Logs that use dir as a modifier should only be given a single argument which is usually an object. If multiple arguments are given, behavior may differ between browser and server environments. Refer to the MDN docs for more details.

MDN Docs

Interface

class Log {
  public get dir(): Log;
}

Example

import adze from 'adze';

adze.dir.log({ foo: 'bar' });

Browser Output

dir modifier browser output

Server Output

dir modifier server output

dirxml

The dirxml modifier transforms the output of the log by directing it to use the console.dirxml() method for printing purposes only. This is mainly useful for logging out DOM elements.

WARNING

Logs that use dirxml as a modifier should only be given a single argument which is usually a DOM Element or other XML object. If multiple arguments are given, behavior may differ between browser and server environments. Refer to the MDN docs for more details.

MDN Docs

dirxml Interface

class Log {
  public get dirxml(): Log;
}

Example

import adze from 'adze';

// create a new div element
const newDiv = document.createElement('div');
newDiv.setAttribute('id', 'test');
// and give it some content
const newContent = document.createTextNode('Hi there and greetings!');
// add the text node to the newly created div
newDiv.appendChild(newContent);

adze.dirxml.log(newDiv);

dump

This modifier instructs the labeled log to print the context values from a thread.

Refer to the threading section of the Getting Started guide for more information.

This modifier is dependent upon having a label.

This is not a standard API.

Interface

class Log {
  public get dump(): Log;
}

Example

import adze, { setup } from 'adze';

const store = setup();

// Creating a GlobalStore listener is a great way to get meta data from your
// threaded logs to write to disk or pass to another plugin, library,
// or service.
store.addListener('*', (log) => {
  // Do something with `log.data?.label?.context.added` or `log.data?.label?.context.subtracted`.
});

function add(a: number, b: number) {
  const answer = a + b;
  adze.label('foo').thread('added', { a, b, answer });
  return answer;
}

function subtract(x: number, y: number) {
  const answer = x - y;
  adze.label('foo').thread('subtracted', { x, y, answer });
  return answer;
}

add(1, 2);
subtract(4, 3);

adze.label('foo').dump.info('Results from our thread');

Browser Output

dump modifier example browser output

Server Output

dump modifier example server output

format

The format modifier sets the formatter that will be used for the log. This can also be used in conjunction with the seal or sealTag terminators to create specifically formatted child loggers.

This is not a standard API.

Interface

class Log {
  public format(format: string): Log;
}

Example

import adze from 'adze';

adze.format('standard').log('Logging a JSON formatted message.');

Browser Output

format modifier browser output

Server Output

format modifier server output

group

The group modifier starts an uncollapsed group of logs. This means that all subsequent logs will be nested beneath this log until a groupEnd log occurs.

MDN Docs

Interface

class Log {
  public get group(): Log;
}

Example

import adze from 'adze';

// Some info about our app.
const version = 'v1.0.0';
const browser = 'firefox';

adze.group.info('App Information');
adze.info(`Version: ${version}`);
adze.info(`Browser: ${browser}`);
adze.groupEnd.info();

Browser Output

group modifier example browser output

Server Output

group modifier example server output

groupCollapsed

The groupCollapsed modifier starts an collapsed group of logs. This means that all subsequent logs will be nested beneath this log until a groupEnd log occurs.

WARNING

This will not be collapsed in a terminal environment since there is no way to uncollapse it.

MDN Docs

Interface

class Log {
  public get groupCollapsed(): Log;
}

Example

import adze from 'adze';

// Some info about our app.
const version = 'v1.0.0';
const browser = 'firefox';

adze.groupCollapsed.info('App Information');
adze.info(`Version: ${version}`);
adze.info(`Browser: ${browser}`);
adze.groupEnd.info();

Browser Output

groupCollapsed modifier example output

Server Output

groupCollapsed modifier server example output

groupEnd

The groupEnd modifier ends a log group. Any logs following a groupEnd will no longer be grouped.

MDN Docs

Interface

class Log {
  public get groupEnd(): Log;
}

Example

import adze from 'adze';

// Some info about our app.
const version = 'v1.0.0';
const browser = 'firefox';

adze.group.info('App Information');
adze.info(`Version: ${version}`);
adze.info(`Browser: ${browser}`);
adze.groupEnd.info(); // <-- Ends the group

adze.info('Some other information...');

Browser Output

groupEnd modifier example browser output

Server Output

groupEnd modifier example server output

if

This modifier accepts a boolean expression and will only print if the boolean expression passes (is a truthy value). This modifier is the opposite behavior of the assert modifier.

This is not a standard API.

Interface

class Log {
  public if(expression: boolean): Log;
}

Example

import adze from 'adze';

const x = 2;
const y = 3;

// Print the log if x equals 2
adze.if(x === 2).log('X equals 2');

// This log will not print because the if fails
adze.if(x === y).log('X does not equal Y');

// Let's look at the output with emoji's enabled
adze.withEmoji.if(y === 3).log('Y equals 3');

Browser Output

if modifier example browser output

Server Output

if modifier example server output

label

Applies an identifying label to a log. All logs that share the same label will be linked together in the Global Store. This enables global tracking for modifiers that require a label as a prerequisite.

These are the modifiers and terminators that require a label to be useful:

  • count
  • countReset
  • countClear
  • closeThread
  • thread
  • time
  • timeNow
  • timeEnd

This is not a standard API.

Interface

class Log {
  public label(name: string): Log;
}

Example

import adze from 'adze';

// Labels can be applied in any order in a modifier chain
adze.label('foo').count.log('Foo');
adze.count.label('foo').log('Bar');

Browser Output

label modifier example output

Server Output

label modifier server example output

meta

The meta modifier allows you to attach meta data to your log instance. You can then retrieve it at a later time from within a log listener or by calling the data() method on a log instance.

This is not a standard API.

Interface

class Log {
  // Types are Overloaded
  public meta<T>(key: string, val: T): Log;
  public meta<KV extends [string, any]>(...[key, val]: KV): Log;
}

Basic Example

import adze, { setup } from 'adze';

// Let's create a super important message to attach as meta data
const info = 'Hello World!';

adze.meta({ message: 'Hello world!' }).log('This log contains an important message.');

Example with Generic Type (TS Only)

import adze, { setup, type JsonLogFormatMeta } from 'adze';

// We'll setup our logger to output JSON.
setup({
  format: 'json',
});

adze
  // The type here ⬇️ ensures that you input the values required by the JSON formatter.
  .meta<JsonLogFormatMeta>({ hostname: 'localhost', name: 'myapp' })
  .log('This log contains an important message.');

Example with Listener

import adze, { setup } from 'adze';

// Let's optionally create a GlobalStore to show the use of meta data on listeners
const store = setup();

// We'll listen only to logs of level 6 which is "log"
store.addListener('log', (log) => {
  adze.info("My log's meta data!", log.data?.meta);
});

adze.meta({ message: 'Hello world!' }).log('This log contains an important message.');

Browser Output from Listener

meta modifier browser output with listener output

Server Output from Listener

meta modifier server output with listener output

namespace / ns

This modifier adds one or more namespaces to a log. These are mainly used as human readable group identifiers but are also useful for filtering logs and for identifying logs from a log listener. This modifier does not do any special grouping under the hood.

Multiple calls to the namespace modifier are additive by nature and will not overwrite previously applied namespaces. This is especially useful when working with sealed child loggers.

The ns() method is just a shorter alias for namespace().

This is not a standard API.

Interface

class Log {
  public namespace(...ns: string[]): Log;
  public ns(...ns: string[]): Log;
}

Example

import adze from 'adze';

adze.namespace('tix-123').log('Important info for a feature.');
adze
  .namespace('tix-123', 'tix-456', 'tix-789')
  .log('Multiple namespace entry simplified by the restof operator.');

// ns() is a shorthand alias for namespace()
adze.ns('tix-456').log('More info');

// Multiple calls to namespace/ns are additive
adze.ns('foo').ns('bar', 'baz').log('This log has all applied namespaces.');

Browser Output

namespace modifier example browser output

Server Output

namespace modifier server example output

Namespaces with Constraints

Adze also supports passing a constraints type when sealing a new logger or when calling the setup function. This is beneficial because it will force users to add any new namespace to the central constraints type. This will make it easier to filter namespaces throughout your application because you will only have a single place to reference to understand what namespaces are being used.

import adze, { setup } from 'adze';

// First we will create our app namespace constraints.
type AllowedNamespaces = 'foo' | 'bar' | 'hello' | 'world';

// We can apply it when we call the `setup` function, or...
setup<AllowedNamespaces>();

// Alternatively, we can apply the namespace constraint type when sealing a child logger.
const logger = adze.seal<AllowedNamespaces>();

// Now when we define namespaces for a log a type error will be thrown if the
// namespace provided isn't in the allowedNamespaces union type.
logger.ns('foo', 'bar', 'baz').fail('This is not allowed.');
//                      ~~~~~
// Argument of type '"baz"' is not assignable to parameter of type '"foo" | "bar" | "hello" | "world"'.

silent

The silent modifier allows a log to be terminated and cached but prevents it from printing to the console. Because the log is still processed, it will still trigger middleware hooks and listeners.

This is not a standard API.

Interface

class Log {
  public get silent(): Log;
}

Example

import adze from 'adze';

adze.log('Knock knock!');
adze.silent.log('Crickets...');
adze.log('I guess nobody is home :(');

Browser Output

example of silent log browser output

Server Output

example of silent log server output

table

The table modifier transforms the output of the log by directing it to use the console.table() method for printing purposes only.

MDN Docs

Interface

class Log {
  public get table(): Log;
}

Example

import adze from 'adze';

const tabular_data = [
  { firstName: 'Andrew', lastName: 'Stacy' },
  { firstName: 'Jim', lastName: 'Bob' },
];

adze.table.log(tabular_data);

Browser Output

table modifier browser output

Server Output

table modifier server output

time

This modifier starts a timer associated to the log's label. This is useful for taking performance measurements. A log with a time modifier must be followed by a log with a timeEnd modifier in order to get the final measurement.

This modifier is dependent upon having a label.

MDN Docs

Interface

class Log {
  public get time(): Log;
}

Example

import adze from 'adze';

// Let's create a timer for performance
adze.label('loop').time.log('Starting a timer.');

for (let i = 0; i < 10000; i += 1) {
  // Do a lot of stuff that takes time
}

// End the timer to get the loop performance
adze.label('loop').timeEnd.log('Performance of our loop.');

// Let's see the output with emoji's
adze.withEmoji.label('loop').timeEnd.log('Performance of our loop.');

Browser Output

time modifier example browser output

Server Output

time modifier example server output

timeEnd

This modifier ends a timer associated to the log's label. This is useful for taking performance measurements. A log with a timeEnd modifier must be preceded by a log with a time modifier in order to get the final measurement.

This modifier is dependent upon having a label.

MDN Docs

Interface

class Log {
  public get time(): Log;
}

Example

import adze from 'adze';

// Let's create a timer for performance
adze.label('loop').time.log('Starting a timer.');

for (let i = 0; i < 10000; i += 1) {
  // Do a lot of stuff that takes time
}

// End the timer to get the loop performance
adze.label('loop').timeEnd.log('Performance of our loop.');

// Let's see the output with emoji's
adze.withEmoji.label('loop').timeEnd.log('Performance of our loop.');

Browser Output

time end modifier example browser output

Server Output

time end modifier example server output

timeNow

This modifier logs the time elapsed since the page has loaded. This is useful for measuring page load performance rather than performance of a particular piece of code.

This modifier is not dependent upon a label.

This is not a standard API.

Interface

class Log {
  public get timeNow(): Log;
}

Example

import adze from 'adze';

for (let i = 0; i < 10000; i += 1) {
  // Do a lot of stuff that takes time
}

// Let's create a timer for performance
adze.timeNow.log('Recording the time elapsed since page load.');

// Let's see what it looks like with emoji's enabled.
adze.withEmoji.timeNow.log('Recording the time elapsed since page load.');

Browser Output

time now modifier example browser output

Server Output

time now modifier example server output

timestamp

This modifier instructs the log to render an ISO 8601 timestamp.

This is not a standard API.

Interface

class Log {
  public get timestamp(): Log;
}

Example

import adze from 'adze';

adze.timestamp.log('This log has a timestamp.');

Browser Output

timestamp modifier example browser output

Server Output

timestamp modifier example server output

trace

This modifier instructs the log to print a stacktrace using the standard console.trace() method.

WARNING

The styling for logs using this modifier varies by browser. Chrome will render the log message with proper styling while Firefox will only render the message unstyled.

MDN Docs

Interface

class Log {
  public get trace(): Log;
}

Example

import adze from 'adze';

adze.trace.log('Trying to find an issue...');

Browser Output

trace modifier example browser output

Server Output

trace modifier example server output

withEmoji

This modifier instructs the log to be printed with an emoji if the formatter supports it.

The only formatter that supports this out of the box is the pretty formatter.

This is not a standard API.

Interface

class Log {
  public get withEmoji(): Log;
}

Example

import adze from 'adze';

adze.withEmoji.log('Logging with an emoji!');

Browser Output

with emoji modifier example browser output

Server Output

with emoji modifier example server output

Edit this page
Last Updated:
Contributors: Andrew Stacy
Prev
Data Getters
Next
Terminators