npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

aliyun-livinglink-logger

v1.0.0

Published

logger

Readme

设计目标

  • 统一日志工具,收拢console信息
  • 开发过程,提供开发日志,方便调试和分析问题
  • 根据不同环境,实现日志差异配置
  • 提供染色、上报能力(规划中)
  • 提供场景回溯能力(规划中)

日志规范

日志级别

  1. Debug:开发调试级别
  2. Info:记录系统的正常运行状态,方便追踪程序的位置和参数,辅助warning/error的问题查找
  3. Warning:表示系统可能出现问题,虽不用立即处理,但需要及时查看以排除风险
  4. Error:程序发生错误,影响用户使用,必须立即处理

日志格式

[module]:[YY-MM-DD HH:mm:ss:SSS]:[LEVEL] - message
  • module 模块名,建议使用当前文件名
  • YY-MM-DD HH:mm:ss.SSS 详细时间格式
  • LEVEL 日志级别
  • message 日志内容
// 示例
[app.js]:[17-10-30 15:35:22:123]:[info] - app started

常见场景

各模块独立创建logger实例

每个模块创建自己的实例,可以做日志隔离、筛选、自定义配置
代码:

// 假设当前模块名为exampleModule
const log = logger('exampleModule');

// 可以正常使用
log.debug('example debug');

也可以用logger.create工厂方法

// 假设当前模块名为exampleModule
const log = logger.create({
    module: 'exampleModule',
	// 个性化配置
	
	// 定义日志标签,用于日志快速过滤
	label: ['biz']
});

// 可以正常使用
log.debug('example debug');

输出:

[exampleModule]:[17-10-30 15:35:22:123]:[debug] - example debug

关键函数入参/出参

将关键函数的入参和出参打印出来,能快速定位函数是否正常运作,该类日志通常为info级别

代码:

function keyFn(arg1, arg2){
	logger.info('keyFn args:', arg1, arg2);
	// do something with args
	
	logger.info('keyFn result:', ret);
	return ret;
}

输出:

[exampleModule]:[17-10-30 15:35:22:123]:[info] - keyFn args: arg1 arg2

注:

  • 多个参数在console中打印没有问题,但是上报时,需要做stringify

异步过程

异步过程容易出现异常,建议日志跟踪

代码:

// 三方调用一般为异步调用,增加唯一标识sn,方便与回调成对查看
const sn = logger.sn();

logger.info(sn, 'thunkFn args:', params);
thunkFn(params, function(err, res){
	if(err){
		logger.error(sn, 'thunkFn result:', err);
		// handle error
		return;
	}
	
	logger.info(sn, 'thunkFn result:', res);
});

输出:

[exampleModule]:[17-10-30 15:35:22:123]:[info] - [sn-123456] thunkFn args: params

...

[exampleModule]:[17-10-30 15:36:32:230]:[info] - [sn-123456] thunkFn result: res

注:

  • promise/generator/async等异步场景,日志范式同上

三方调用(服务/bridge等)

对三方的接口调用,必须记录日志,该类日志通常为info级别

  • 三方调用统一抽象为IO操作
  • 目前三方调用唯一通道为bridge,会默认打印日志
  • 日志范式同上异步过程

非可信输入/输出

  • encodeURIComponent
  • decodeURIComponent
  • JSON.parse
  • JSON.stringify
try {
  let name = decodeURIComponent(params.name);
}
catch(err) {
  logger.error(err);
  name = '';
}

SDK强制日志规范

  • 1.bridge调用
  • 2.全局Error捕获
  • 3.路由跳转信息,如 A->B->C->B->A, 方便复现和定位问题。

logger设计

全局接口和属性

logger.conf

全局配置

// logger.conf默认为logger.DEF_CONF.[process.ENV.NODE_ENV]
// 建议工程根据env,使用对应配置
logger.conf = {
	/**
	 * 日志打印级别
	 * @enums {Number} logger.LEVEL
	 * @default logger.LEVEL.WARNING
	 */
	level: logger.LEVEL.DEBUG,
	
	/**
	 * 日志输出位置,目前仅支持console
	 * @default logger.APPENDER.CONSOLE
	 */
	appender: logger.APPENDER.CONSOLE
};

logger(identifier[, options])

创建logger实例

const log = logger('moduleName');

// 日志打印时,自动带上模块名moduleName
// 可以通过logger.filter指定过滤条件
log.info('some msg');
const logWithConf = logger('moduleName', {
	/**
	 * 定义日志标签,用于日志快速过滤
	 * @type {[String]}
	 */
	label: ['biz', 'someModuleType']
});

// 日志打印时,自动带上模块名moduleName
// 可以通过logger.filter指定过滤条件
log.info('some msg');

logger.create({ module, label, ...options })

@deprecated 创建logger实例,同logger(identifier[, options])

logger.filter

日志过滤器

// 默认为空,不做过滤

// 通过传入label数组,指定要查看的日志
// 此处为只看label为sdk的日志
logger.filter = ['sdk'];

// 通过filter函数指定日志
logger.filter = function(inst){
	// 根据日志实例,判定是否显示
	return true;
};

logger.sn()

工具方法,生成日志id,用于异步场景的日志追踪

const sn = logger.sn(); // [sn-123456]

模块log的接口和属性

log.conf

// log的conf默认继承logger.conf
log.conf = {
	/**
	 * 定义日志标签,用于日志快速过滤
	 * @type {[String]}
	 */
	label: ['biz', 'someModuleType']
};

log.debug

log.debug(obj1, obj2, …)

log.debug({ a: 1 }, { b: 2 }, 'msg', true);

log.debug(msg, subst1, subst1, …)

log.debug('msg %d: %s', 1, 'msg content');

log.info

同log.debug

log.warning

同log.debug

log.error

同log.debug

日志实例

日志实例指,通过log的debug/info/warning/error产生的日志实例

const inst = log.debug('msg');

instance.module

模块名

instance.time

日志时间

instance.level

日志级别 debug/info/warning/error

instance.message

日志内容 @todo

常量

logger.LEVEL

日志级别常量定义

logger.DEF_CONF

logger.DEF_CONF.DEV

{
	level: logger.LEVEL.DEBUG,
	appender: logger.APPENDER.CONSOLE
}

logger.DEF_CONF.TEST

{
	level: logger.LEVEL.INFO,
	appender: logger.APPENDER.CONSOLE
}

logger.DEF_CONF.RELEASE

{
	level: logger.LEVEL.ERROR,
	appender: logger.APPENDER.CONSOLE
}

logger.APPENDER

  • logger.APPENDER.CONSOLE 使用console作为输出位置

上报、收集、查看(规划中)

日志回放和场景恢复(规划中)