Signale

👋 可扩展的日志记录器

Header

Build Status

描述

Signale 的核心是可扩展和可配置的,可将其用于日志记录、状态报告以及处理其他 Node 模块和应用的输出渲染方式。

您可以使用以下语言阅读本文档 Albanian - Shqip, English, German - Deutsch.

浏览 contributing guidelines 以了解如何将该文档翻译成其他语言。

亮点

目录

安装

npm install signale

使用

默认记录器

导入 signale 即可开始用任意的默认记录器。

查看所有可用的默认记录器。
- `await` - `complete` - `error` - `debug` - `fatal` - `fav` - `info` - `note` - `pause` - `pending` - `star` - `start` - `success` - `warn` - `watch` - `log`


const signale = require('signale');

signale.success('Operation successful');
signale.debug('Hello', 'from', 'L59');
signale.pending('Write release notes for %s', '1.2.0');
signale.fatal(new Error('Unable to acquire lock'));
signale.watch('Recursively watching build directory...');
signale.complete({prefix: '[task]', message: 'Fix issue #59', suffix: '(@klaudiosinani)'});
Default Loggers

自定义记录器

要创建自定义记录器,先定义一个 options 对象,在其 types 属性中填入记录器相关数据,然后将该对象作为参数传递给新的 signale 实例。

const {Signale} = require('signale');

const options = {
  disabled: false,
  interactive: false,
  stream: process.stdout,
  scope: 'custom',
  types: {
    remind: {
      badge: '**',
      color: 'yellow',
      label: 'reminder'
    },
    santa: {
      badge: '🎅',
      color: 'red',
      label: 'santa'
    }
  }
};

const custom = new Signale(options);
custom.remind('Improve documentation.');
custom.santa('Hoho! You have an unused variable on L45.');
Custom Loggers

下面是一个覆盖默认记录器 errorsuccess 的例子

const {Signale} = require('signale');

const options = {
  types: {
    error: {
      badge: '!!',
      label: 'fatal error'
    },
    success: {
      badge: '++',
      label: 'huge success'
    }
  }
};

const signale = new Signale();
signale.error('Default Error Log');
signale.success('Default Success Log');

const custom = new Signale(options);
custom.error('Custom Error Log');
custom.success('Custom Success Log');
Default Loggers

options 对象可以包含以下任何属性: disabled, interactive, stream, scope and types.

disabled

禁用所创建实例的所有日志记录功能。

interactive

将所创建实例的所有记录器切换到交互模式

stream

写入数据的目标可以是单个有效的 输出流(Writable stream) 或包含多个有效输出流的数组。

scope

记录器的作用域名称。

types

持有自定义记录器和默认记录器的配置。

badge

与记录器对应的徽章图标。

label

用于标识记录器类型的标签。

color

标签的颜色,可以是 chalk 支持的任何前景色。

局部记录器

要从头创建局部记录器,需在 options 对象的 scope 属性中定义作用域名,然后将其作为一个参数传递给新的 signale 实例。

const {Signale} = require('signale');

const options = {
  scope: 'global scope'
};

const global = new Signale(options);
global.success('Successful Operation');
Scope Vanilla

可以使用 scope() 函数基于现有的记录器创建局部记录器,该函数将返回新的signale实例,该实例继承已有实例的所有自定义记录器、计时器、流、配置、禁用状态和交互模式信息。

const signale = require('signale');

const global = signale.scope('global scope');
global.success('Hello from the global scope');

function foo() {
  const outer = global.scope('outer', 'scope');
  outer.success('Hello from the outer scope');
  
  setTimeout(() => {
    const inner = outer.scope('inner', 'scope'); 
    inner.success('Hello from the inner scope');
  }, 500);
}

foo();
Scope Existing

交互式记录器

要初始化交互式记录器,请创建一个新的 signale 实例,并将 interactive 属性设置为 true。 进入交互模式时,之前来自交互式记录器的消息,会被后面来自相同实例中相同或不同的记录器的消息所覆盖。 请注意来自常规记录器的常规消息不会被交互式记录器覆盖。

const {Signale} = require('signale');

const interactive = new Signale({interactive: true, scope: 'interactive'});

interactive.await('[%d/4] - Process A', 1);

setTimeout(() => {
  interactive.success('[%d/4] - Process A', 2);
  setTimeout(() => {
    interactive.await('[%d/4] - Process B', 3);
    setTimeout(() => {
      interactive.error('[%d/4] - Process B', 4);
      setTimeout(() => {}, 1000);
    }, 1000);
  }, 1000);
}, 1000);
Interactive Mode

输出流

默认情况下,所有 signale 实例都将其消息记录到 process.stdout 输出流。 可以通过 stream 属性进行修改以匹配您自己的选项,你可以在其中定义单个或多个有效的输出流,所有类型的记录器都将使用这些流来记录您的数据。 此外,可以专门为特定记录器类型定义一个或多个可写流,从而独立于其余记录器类型写入数据。

const {Signale} = require('signale');

const options = {
  stream: process.stderr, // 所有的记录器现在都会将数据写入 `process.stderr`
  types: {
    error: {
      // 只有 `error` 记录器会将数据同时写入 `process.stdout` 和 `process.stderr`
      stream: [process.stdout, process.stderr]
    }
  }
};

const signale = new Signale(options);
signale.success('Message will appear on `process.stderr`');
signale.error('Message will appear on both `process.stdout` & `process.stderr`');
Writable Streams

计时器

计时器由 time()timeEnd() 函数管理。 可以使用标签在初始化时唯一标识一个计时器,如果没有提供则计时器将自动分配一个。 此外,调用没有指定标签的 timeEnd() 函数将终止最近一个初始化时没有指定标签的计时器。

const signale = require('signale');

signale.time('test');
signale.time();
signale.time();

setTimeout(() => {
  signale.timeEnd();
  signale.timeEnd();
  signale.timeEnd('test');
}, 500);
Timers

配置

全局

package.json 中的 signale 命名空间下定义选项以启用全局配置。

以下说明了所有可用选项及其各自的默认值。

{
  "signale": {
    "coloredInterpolation": false,
    "displayScope": true,
    "displayBadge": true,
    "displayDate": false,
    "displayFilename": false,
    "displayLabel": true,
    "displayTimestamp": false,
    "underlineLabel": true,
    "underlineMessage": false,
    "underlinePrefix": false,
    "underlineSuffix": false,
    "uppercaseLabel": false
  }
}
浏览所有可用选项的详细信息。 ##### `coloredInterpolation` - 类型: `Boolean` - 默认值: `false` 以彩色的方式显示用于替换字符串插值上的占位符标记参数。 ##### `displayScope` - 类型: `Boolean` - 默认值: `true` 显示记录器的作用域名称。 ##### `displayBadge` - 类型: `Boolean` - 默认值: `true` 显示记录器的徽章图标。 ##### `displayDate` - 类型: `Boolean` - 默认值: `false` 以 `YYYY-MM-DD` 的格式显示当前本地日期。 ##### `displayFilename` - 类型: `Boolean` - 默认值: `false` 显示记录器消息来源的文件名。 ##### `displayLabel` - 类型: `Boolean` - 默认值: `true` 显示记录器的标签。 ##### `displayTimestamp` - 类型: `Boolean` - 默认值: `false` 以 `HH:MM:SS` 的格式显示当前本地时间。 ##### `underlineLabel` - 类型: `Boolean` - 默认值: `true` 给记录器的标签添加下划线。 ##### `underlineMessage` - 类型: `Boolean` - 默认值: `false` 给记录器的消息内容添加下划线。 ##### `underlinePrefix` - 类型: `Boolean` - 默认值: `false` 给记录器的前缀添加下划线。 ##### `underlineSuffix` - 类型: `Boolean` - 默认值: `false` 给记录器的后缀添加下划线。 ##### `uppercaseLabel` - 类型: `Boolean` - 默认值: `false` 以大写的方式显示记录器的标签。

本地

要启用本地配置,请在您的 signale 实例上调用 config() 函数。本地配置将始终覆盖从 package.json 继承的任何预先存在的配置。

在以下示例中, foo.js 文件中的记录器将在其自己的配置下运行,从而覆盖 package.json 文件中的配置。

// foo.js
const signale = require('signale');

// 覆盖任何存在于 `package.json` 的配置
signale.config({
  displayFilename: true,
  displayTimestamp: true,
  displayDate: false
}); 

signale.success('Hello from the Global scope');
Local Config

此外,局部记录器可以拥有自己的独立配置,以覆盖父实例或继承自 package.json 的配置。

// foo.js
const signale = require('signale');

signale.config({
  displayFilename: true,
  displayTimestamp: true,
  displayDate: false
});

signale.success('Hello from the Global scope');

function foo() {
  // `fooLogger` 继承了 `signale` 的配置
  const fooLogger = signale.scope('foo scope');

  // 同时覆盖 `signale` 和 `package.json` 的配置
  fooLogger.config({
    displayFilename: true,
    displayTimestamp: false,
    displayDate: true
  });

  fooLogger.success('Hello from the Local scope');
}

foo();
Scope Config

API

signale.<logger>(message[, message]|messageObj|errorObj)

logger

可以是任何默认或自定义记录器。

message

可以是一个或多个逗号分隔的字符串。

const signale = require('signale');

signale.success('Successful operation');
//=> ✔  success  Successful operation

signale.success('Successful', 'operation');
//=> ✔  success  Successful operation

signale.success('Successful %s', 'operation');
//=> ✔  success  Successful operation
errorObj

可以是任意错误 (error) 对象。

const signale = require('signale');

signale.error(new Error('Unsuccessful operation'));
//=> ✖  error  Error: Unsuccessful operation
//        at Module._compile (module.js:660:30)
//        at Object.Module._extensions..js (module.js:671:10)
//        ...
messageObj

可以是包含 prefixmessagesuffix 属性的对象,prefix (前缀)和 suffix (后缀) 始终预先添加并附加到记录的 message (消息)里。

const signale = require('signale');

signale.complete({prefix: '[task]', message: 'Fix issue #59', suffix: '(@klaudiosinani)'});
//=> [task] ☒  complete  Fix issue #59 (@klaudiosinani)

signale.complete({prefix: '[task]', message: ['Fix issue #%d', 59], suffix: '(@klaudiosinani)'});
//=> [task] ☒  complete  Fix issue #59 (@klaudiosinani)

signale.scope(name[, name])

定义记录器的作用域名称。

name

可以是一个或多个用逗号分隔的字符串。

const signale = require('signale');

const foo = signale.scope('foo'); 
const fooBar = signale.scope('foo', 'bar');

foo.success('foo');
//=> [foo] › ✔  success  foo

fooBar.success('foo bar');
//=> [foo] [bar] › ✔  success  foo bar

signale.unscope()

清除记录器的作用域名称。

const signale = require('signale');

const foo = signale.scope('foo'); 

foo.success('foo');
//=> [foo] › ✔  success  foo

foo.unscope();

foo.success('foo');
//=> ✔  success  foo

signale.config(settingsObj)

设置实例的配置项以覆盖任意已存在的全局或本地配置。

settingsObj

可以持有任意配置选项

// foo.js
const signale = require('signale');

signale.config({
  displayFilename: true,
  displayTimestamp: true,
  displayDate: true
});

signale.success('Successful operations');
//=> [2018-5-15] [11:12:38] [foo.js] › ✔  success  Successful operations

signale.time([, label])

激活一个计时器并接受一个可选的标签。如果没有提供参数,计时器将自动生成一个唯一的标签。

返回与计时器标签相对应的字符串。

label

与计时器对应的标签。每个计时器必须有自己独有的标签。

const signale = require('signale');

signale.time();
//=> ▶  timer_0  Initialized timer...

signale.time();
//=> ▶  timer_1  Initialized timer...

signale.time('label');
//=> ▶  label    Initialized timer...

signale.timeEnd([, label])

取消激活给定标签对应的计时器。如果未提供标签,则将取消激活在未提供标签的情况下创建的最新的计时器。

返回一个 {label, span} 对象,该对象持有计时器的标签与总共运行时间。

label

与计时器对应的标签。每个计时器必须有自己独有的标签。

const signale = require('signale');

signale.time();
//=> ▶  timer_0  Initialized timer...

signale.time();
//=> ▶  timer_1  Initialized timer...

signale.time('label');
//=> ▶  label    Initialized timer...

signale.timeEnd();
//=> ◼  timer_1  Timer run for: 2ms

signale.timeEnd();
//=> ◼  timer_0  Timer run for: 2ms

signale.timeEnd('label');
//=> ◼  label    Timer run for: 2ms

signale.disable()

禁用特定实例包含的所有记录器的记录功能。

const signale = require('signale');

signale.success('foo');
//=> ✔  success  foo

signale.disable();

signale.success('foo');
//=>

signale.enable()

启用特定实例包含的所有记录器的记录功能。

const signale = require('signale');

signale.disable();

signale.success('foo');
//=>

signale.enable();

signale.success('foo');
//=> ✔  success  foo

开发

想知道如何参与到该项目的更多信息, 请阅读 contributing guidelines

相关项目

团队

许可

MIT