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

Configuration

Adze is a completely configurable library by design that comes with sensible defaults. There are two primary configurations to understand; the log configuration and the Global Store configuration. In this section we'll take a look at each configuration and explain each property in detail.

User Configuration

This configuration is generated when you use modifiers or when you pass in a configuration object with the seal or sealTag terminators.

UserConfiguration Interface

interface UserConfiguration {
  activeLevel?: Level | number;
  cache?: boolean;
  cacheSize?: number;
  dump?: boolean;
  filters?: Filters;
  format?: string;
  formatters: Record<string, FormatterConstructor>;
  levels: Record<string, LevelConfig>;
  meta?: Record<string, any>;
  middleware?: Middleware[];
  silent?: boolean;
  showTimestamp?: boolean;
  timestampFormatter?: (date: Date) => string;
  withEmoji?: boolean;
}

type Level = 'alert' | 'error' | 'warn' | 'info' | 'fail' | 'success' | 'log' | 'debug' | 'verbose';

UserConfiguration Property Descriptions

Property NameDefault ValueDescription
activeLevel"log"Set the maximum log level that will be rendered.
cachefalseAllows the Global Store to cache logs for later recall.
cacheSize300The maximum number of logs that will be cached. This is to prevent memory leaks. This only applies if cache is true.
dumpfalseTells logs to add any associated thread data to the log output.
filtersundefinedControls filtering of logs by level, label, or namespace.
format"pretty"Sets the format of how logs will be generated.
formatters{ pretty, json, common, standard }Key / value pairs of formatter names to Formatter classes. Comes with four built in. Pretty, JSON, Common, and Standard.
levels{ [levelName: string]: LevelConfiguration }Level Configuration for each log level, including custom log levels.
meta{}Series of user defined key/value pairs of meta data to attach to logs.
middlewareMiddleware[]Array of middleware instances that will be used during the each log's lifecycle.
silentfalseSilent logs will not print but will still be evaluated and trigger listeners and middleware hooks.
showTimestampfalseInstructs logs to record and print the timestamp of when they were generated.
timestampFormatterundefinedA callback function for taking a log Date object and returning a timestamp with the preferred custom formatting.
withEmojifalseTells formatters that they are allowed to print an emoji with the output.

Setup Function

When a log is created, if a Global Store does not already exist, it will be automatically created. You can also set one up and configure it manually by using the setup() function.

The setup function accepts a UserConfiguration object that acts as a global configuration override for all logs. When setup is called, it also returns a reference to the Global Store which you can use for adding log listeners or removing them.

Setup Example

import adze, { setup } from 'adze';

const store = setup({
  cache: true,
});

store.addListener('*', (log) => {
  // Do something with the log data here...
});

LevelConfiguration

The LevelConfiguration type is used for creating or modifying log level configurations. Each default log level also has a LevelConfiguration associated with it by default in the levels property of the UserConfiguration.

LevelConfiguration Interface

Refer to the picocolors documentation for information about terminal style values.

interface LevelConfiguration {
  levelName: string;
  level: number;
  style: string;
  terminalStyle: ConsoleStyle[];
  method: Method;
  emoji: string;
}

Custom Level Example

You can use the UserConfiguration levels property with a LevelConfiguration to add a custom level.

import adze, { setup } from 'adze';

setup({
  activeLevel: 1337,
  levels: {
    leetLevel: {
      levelName: 'leetLevel',
      level: 1337,
      method: 'log',
      style:
        'font-size: 12px; border-radius: 4px; padding-right: 10px; background: linear-gradient(to right, #ffcafc, #ff02f2); color: #fff; border-color: #e3bbbb;',
      terminalStyle: ['white', 'bgMagenta'],
      emoji: '👾',
    },
  },
});

adze.withEmoji.custom('leetLevel', 'This is an example leetLevel log!');

Browser Output

Example of a custom level named leet level in a browser

Server Output

Example of a custom level named leet level in a terminal

Default Level Override Example

All default log levels can have their settings overridden by passing a LevelConfiguration with a key and levelName of the same name. You can use the default log level configuration generator functions to get a base configuration for modifying.

import adze, { setup } from 'adze';

setup({
  levels: {
    error: {
      levelName: 'error',
      level: 1,
      method: 'error',
      style: 'color: purple; background: white;', // <- changing the error style to use purple text.
      terminalStyle: ['magenta', 'bgWhite'],
      emoji: 'đŸ”Ĩ',
    },
  },
});

adze.withEmoji.error('This is an error log with overridden style configuration.');

Browser Output

Example of the default error level with overridden configuration in the browser

Server Output

Example of the default error level with overridden configuration in the server


Styling

All of Adze default level configurations come with default styling. These can be overridden by providing a LevelConfiguration with a matching key to the default log level in the levels property.

When creating custom levels or overriding existing configuration, you may want to apply custom styles or emoji's. Below are the values used for the default log levels.

Default Browser Styles

This is a comprehensive list of the default browser styles. If you notice, these styles use padding-right for spacing and alignment. It is a painful way to do this, but due to the different ways each browser handles log styling, the only consistent way for them to align on the right is to use manual padding numbers. The goal of the default styles was to make them as consistent as possible across browsers.

For more information: MDN Docs - refer to "Styling console output" section

Default Level Styles

NOTE: The default styles use template string interpolation to change the padding based on the browser environment. These functions are also exported from adze.

Level NameemojiStyle
alert🚨padding-right: ${isChrome() ? '32' : '26'}px; font-size: 12px; border-radius: 4px; background: linear-gradient(to right, #fc8585, #fc2323); color: #fff; border-color: #b70101;
errorđŸ”Ĩpadding-right: ${isChrome() ? '32' : '26'}px; font-size: 12px; border-radius: 4px; background: linear-gradient(to right, #fff, #ffd1d1); color: #a4000f; border-color: #e3bbbb;
warn🔔font-size: 12px; border-radius: 4px; background: linear-gradient(to right, #fff, #fff0a8); color: #715100; border-color: #e3d696; padding-right: ${isChrome() ? '38' : '44'}px;
infoâ„šī¸padding-right: ${isSafari() ? '49' : '52'}px; font-size: 12px; border-radius: 4px; background: linear-gradient(to right, #d8ebff, #b2d7ff); color: #465464; border-color: #96b5d7;
fail❌padding-right: ${isChrome() ? '52' : '44'}px; font-size: 12px; border-radius: 4px; background: linear-gradient(to right, #ffe8e8, #ffd1d1); color: #a4000f; border-color: #e3bbbb;
success🎉font-size: 12px; border-radius: 4px; padding-right: 30px; background: linear-gradient(to right, #e6f6e4, #ceedc9); color: #4e594d; border-color: #b7d1b3;
logđŸĒĩfont-size: 12px; border-radius: 4px; padding-right: 60px; background: linear-gradient(to right, #ecedef, #d9dce0); color: #333435; border-color: #bfc1c5;
debug🐞font-size: 12px; padding-right: 44px; border-right: 1px solid #d9dce0; color: #465464; border-color: #999999;
verboseđŸ’Ŧfont-size: 12px; padding-right: 31px; color: #999999;


Default Server Styles

Adze styling for the server makes use of a library named picocolors. picocolors exposes several formatting functions for server text styling that Adze exposes in its configuration.

For a list of styles available for use with picocolors, refer to the picocolors styles documentation.

Default Level Styles

Level NameemojiStyle
alert🚨['white', 'bold', 'bgRed']
errorđŸ”Ĩ['bgRed', 'white']
warn🔔['bgYellow', 'white']
infoâ„šī¸['bgBlue', 'white']
fail❌['bgRed', 'white']
success🎉['bgGreen', 'white']
logđŸĒĩ['bgGray', 'white']
debug🐞['bgBlack', 'white']
verboseđŸ’Ŧ['italic', 'black']


Default Level Style Functions

Each default level has a corresponding function for getting the styles that can be imported. This can simplify applying small tweaks to the default log level configurations.

Level NameStyle
alertgetAlertConfig
errorgetErrorConfig
warngetWarnConfig
infogetInfoConfig
failgetFailConfig
successgetSuccessConfig
loggetLogConfig
debuggetDebugConfig
verbosegetVerboseConfig

Level Style Function Example

import adze, { setup, getAlertConfig } from 'adze';

const alert = getAlertConfig({
  emoji: '😭',
});

setup({
  levels: {
    alert,
  },
});

adze.withEmoji.alert('A customized alert log.');

Browser Output

customized alert log browser example

Server Output

customized alert log server example



Filters

Filters determine whether logs are allowed to print to the developer console/server based on their log level, label, or namespace. When filtering levels, you can provide a level selector data type.

Each filter type can specify and include or exclude statement. Include tells Adze to only render logs that are included in the value set. Exclude says to not render any logs that are included in the value set. If both are specified, include takes precedence over exclude in case of conflicts.

Interface

interface Filters {
  level?: FilterConfig<LevelSelector>;
  label?: FilterConfig;
  namespace?: FilterConfig;
}

interface FilterConfig<T = string[]> {
  type: 'include' | 'exclude';
  values: T;
}

Example

import adze, { setup } from 'adze';

setup({
  filters: {
    namespaces: {
      type: 'include',
      values: ['foo'],
    },
  },
});

adze.ns('foo').success('I should print.');
adze.ns('foo', 'bar').success('I should print.');
adze.ns('bar').fail('I should not print.');
adze.fail('I should not print because I do not have a namespace.');

Browser Output

customized alert log browser example

Server Output

customized alert log server example



Customized Timestamps

The timestampFormatter configuration option accepts a callback function that is executed each time a log needs to generate a timestamp.

By default, Adze will generate an ISO 8601 formatted timestamp, but you can use this function to generate a customized timestamp to whatever format you desire.

Interface

type TimestampFormatter = (date: Date) => string;

Example

import adze, { setup } from 'adze';

setup({
  timestampFormatter: (date: Date) => '07/04/1776',
});

adze.timestamp.success('America has achieved independence!');

Browser Output

customized timestamp browser example

Server Output

customized timestamp server example



LevelSelector Type

In various places in the Adze library, a LevelSelector value is required. It is used in:

  • Configuration.activeLevel
  • Configuration.filters
  • GlobalStore.addListener
  • GlobalStore.tools.filterByLevel

The LevelSelector type is a user friendly way of selecting one or more log levels.

Interface

type LevelSelector =
  | '*'
  | string
  | number
  | string[]
  | number[]
  | [number, '-', number]
  | [string, '-', string];

Example

import adze, { setup } from 'adze';

const store = setup();

// Add a listener that selects ALL log levels.
store.addListener('*', (log: Log) => {
  /* Do something */
});

// Add a listener that selects a single log level by name.
store.addListener('info', (log: Log) => {
  /* Do something with info logs */
});

// Add a listener that selects both alert and error log levels by name.
store.addListener(['alert', 'error'], (log: Log) => {
  /* Do something with the alert and error logs */
});

// Or select a range of values by their name.
store.addListener(['alert', '-', 'warn'], (log: Log) => {
  /* Do something with the alert, error, and warn logs */
});

// Alternatively, select alert and error logs by their level values.
store.addListener([0, 1], (log: Log) => {
  /* Do something with the alert and error logs */
});

// Or select a range of logs by their level values.
store.addListener([0, '-', 3], (log: Log) => {
  /* Do something with the alert, error, warn, and info logs */
});
Edit this page
Last Updated:
Contributors: Andrew Stacy, Tiago Nobrega
Prev
Tools
Next
Middleware