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

@danor-lib/hades

v8.0.1

Published

Log library based on log4js-node

Readme

[!TIP] 本文档由 AI 阅读代码后生成。中文版本已经过本人初步审校。英文版本基于中文版本由 AI 翻译生成。如有问题或更好的文档,欢迎提交 Issue。
This document is generated by AI after reading the code. The Chinese version has been preliminarily reviewed by the author. The English version is AI-translated based on the Chinese version. If you have any issues or a better version of the documentation, please feel free to submit an Issue.

简体中文 | English

@danor-lib/hades

Version License

基于 log4js-node 的日志库,预封装了统一输出格式、终端强调样式、文件轮换等默认特性。 A logging library based on log4js-node, pre‑packaged with a unified output format, terminal highlighting styles, file rotation, and other default features.

设计理念

传统的日志库通常只提供基础的级别过滤和输出通道。Hades 的设计目标是:

  • 统一格式 — 所有日志遵循 where → what → result(在哪里、做了什么、结果如何)的三段式结构,让日志可读、可检索。
  • 强调语义 — 通过 ~[](术语/名词)和 ~{}(值)两种控制字符语法,让日志中的关键信息在终端中自动高亮。
  • 开箱即用 — 默认同时输出到控制台和文件,文件支持按大小自动轮换;无需额外配置即可获得生产级的日志体验。
  • 上下文复用 — 通过 Melinoe(预设 where)和 Zagreus(预设 where + what)减少同一上下文中频繁传参的冗余。

基础示例

import { Hades } from '@danor-lib/hades';

// --- 创建 Hades 实例 ---
const G = new Hades({ name: 'my-app', dirn: './logs' });

// --- 按 where → what → result 输出日志 ---
G.info('数据库', '连接', '✔ ~[目标]~{localhost:3306}');
// 输出: [01-07 14:30:00:123][信息] 数据库 => 连接  ✔ 目标[localhost:3306]

G.warn('缓存模块', '命中率低', '~[命中率]~{35%}');
// 输出: [01-07 14:30:01:456][警告] 缓存模块 => 命中率低  ~命中率[35%]

// --- 输出错误(自动保存堆栈到 <name>.stack.log) ---
G.error('~[接口]~{api/version}', '请求失败', new Error('连接超时'));
// 控制台: [01-07 14:30:02:789][错误] 接口[api/version] => 请求失败  ✘ 发生错误 --> 连接超时
// 文件 my-app.stack.log: 完整堆栈信息

// --- 内联更新(进度条场景) ---
for (let i = 0; i <= 100; i += 10) {
  G.infoU('任务', '处理中', `~{${i}%}`);
}
G.infoD('任务', '处理完成', '✔');

日志格式

Hades 的所有日志统一格式为:

[时间][等级] where => what  result
  • where — 发生位置/模块
  • what — 执行的动作/事件
  • result — 结果/附加信息

建议:无论使用哪个日志等级,都推荐遵循 where → what → result 的思路组织日志内容。这样日志在视觉上一致,便于阅读和检索。

核心概念

日志等级与使用时机

Hades 提供 7 个日志等级,每个等级有明确的使用场景和对应的终端颜色:

| 等级 | 方法 | 颜色 | 使用场景 | | :------ | :------- | :----- | :------------------------------------------------------------------------- | | trace | .trace | 蓝色 | 高频低级数据,如循环中的 i。不应提交到生产代码,调试完立即删除 | | debug | .debug | 青色 | 低频计算结果,如函数返回值或不重要的心跳信息 | | info | .info | 绿色 | 常规摘要或可处理的预期异常数据 | | warn | .warn | 黄色 | 可能导致异常但程序可恢复的运营数据,如启动时数据库连接超时(后续可重连) | | error | .error | 红色 | 异常逻辑和意外错误,如插入数据库时缺少必要字段导致业务中断 | | fatal | .fatal | 洋红色 | 导致程序退出的关键日志,如未处理的异常或文件读写错误 | | mark | .mark | 灰色 | 与运行状态无关的必要说明。除非日志关闭,否则始终输出,如版权声明和注意事项 |

强调格式 ~[]~{}

Hades 预置了两种基于控制字符的强调格式,在终端中会自动渲染为样式文本:

| 语法 | 用途 | 渲染效果(高亮开启时) | 渲染效果(高亮关闭时) | | :---- | :-------- | :--------------------- | :----------------------- | | ~[] | 名词/术语 | 下划线 + 粗体 | 原文本(移除 ~[]) | | ~{} | 值/数据 | 白色 + 方括号包裹 | 方括号包裹(移除 ~{}) |

G.info('服务器', '启动', '✔ ~[监听端口]~{8080}');
// 高亮: [时间][信息] 服务器 => 启动  ✔ 监听端口(下划线粗体)[8080](白色)
// 关闭: [时间][信息] 服务器 => 启动  ✔ 监听端口[8080]
  • 关闭高亮(willHighlight: false)时,~[]~{} 的控制字符会被自动移除,保留纯文本语义。
  • 需要输出原始 ~[~{ 时,使用反斜杠转义:\~[ \~{
  • where部分一般不推荐单独使用~[],除非需要和值一起输出

输出模式

每个日志等级都有三种输出变体:

| 后缀 | 示例 | 行为 | 适用场景 | | :--- | :---------- | :------------------------------- | :-------------------------- | | 无 | .debug() | 普通输出,结尾换行 | 常规日志 | | U | .debugU() | 内联更新(回车不换行) | 进度条、实时状态更新 | | D | .debugD() | 结束内联更新(换行,结束当前行) | 配合 U 系列,标记更新完成 |

// 进度条示例
for (let i = 0; i <= 100; i += 20) {
  G.infoU('下载', '进度', `~{${i}%}`);  // 同一行不断刷新
}
G.infoD('下载', '完成', '✔');            // 结束并换行

错误与堆栈日志

  • .error() / .fatal() 支持直接传入 Error 对象。
  • 传入 Error 时,控制台仅输出错误消息摘要,完整堆栈会自动写入 <name>.stack.log 文件。
  • 支持 Error.cause 链:如果错误有 cause 属性,会递归输出整个因果链。
const cause = new Error('DNS解析失败');
const error = new Error('连接超时', { cause });

G.error('~[网络]', '请求失败', error);
// 控制台:
//   [时间][错误] 网络 => 请求失败  ✘ 发生错误 --> 连接超时
//      --> DNS解析失败
// 文件 logs/my-app.stack.log:
//   Error: 连接超时
//       at ...
//   Caused by: Error: DNS解析失败
//       at ...

fatalE — 输出并退出

.fatalE(code, where, what, ...infos) 会在输出日志后立即调用 process.exit(code) 退出进程。

G.fatalE(1, '启动', '~[配置]缺失', '缺少必要字段 ~{db.host}');
// 输出 fatal 日志后进程退出,退出码为 1

构造函数

new Hades(options?)

创建一个 Hades 实例。

  • 参数 options {Object} — 可选。所有属性均为可选。

| 选项 | 类型 | 默认值 | 说明 | | :----------------------- | :-------- | :--------------------- | :---------------------------------------------------------------------- | | name | string | 'default' | 实例名称,同时作为日志文件名前缀 | | level | string | 'all' | 最低日志等级,低于此等级的日志不输出 | | dirn | string | process.cwd() | 日志文件存储目录。不指定则不保存到文件,仅控制台输出 | | eol | string | os.EOL | 日志文件的换行符 | | templateTime | string | 'MM-DD HH:mm:ss:SSS' | 时间格式模板,语法见 dayjs | | sizeFileLogMax | number | 20971520(20MB) | 单个日志文件的最大字节数,超出后自动轮换 | | numberFileLogBackupMax | number | 0 | 保留的旧日志文件数量,0 表示不保留 | | willHighlight | boolean | true | 是否启用 ~[] / ~{} 强调格式的高亮渲染 | | willColorLevel | boolean | true | 是否根据日志等级输出不同颜色 | | willOutputInitInfo | boolean | true | 是否在初始化完成后输出一条 info 日志 | | willConsoleOutputError | boolean | false | 是否在控制台输出错误堆栈(默认仅写入文件) | | willInitImmediate | boolean | true | 是否在构造后立即初始化。设为 false 则需手动调用 .init() |

// 默认配置
const G = new Hades();

// 自定义名称和目录
const G = new Hades({ name: 'api-server', dirn: './logs' });

// 仅输出到控制台(不写文件)
const G = new Hades({ dirn: '' });

// 延迟初始化
const G = new Hades({ willInitImmediate: false });
G.level = 'debug';  // 在初始化前修改配置
G.init();

实例属性 / 方法

实例属性

| 属性 | 类型 | 说明 | | :--------------- | :-------------- | :-------------------------------- | | name | string | 实例名称 | | level | string | 最低日志等级 | | dirnLog | string | 日志文件存储目录 | | willHighlight | boolean | 是否启用强调格式高亮 | | willColorLevel | boolean | 是否启用等级颜色 | | texts | object | i18n 文本配置(详见下方高级特性) | | isInit | boolean | 是否已初始化 | | logger | Log4JS.Logger | 底层 log4js Logger 实例 |

init()

初始化日志系统(配置 appender、创建 Logger)。构造时若 willInitImmediatetrue 会自动调用。

  • 返回值Hades 实例,支持链式调用。
const log = new Hades({ willInitImmediate: false });
// ... 修改配置 ...
G.init();

reload()

异步重新加载日志系统。先关闭现有 Logger,再重新初始化。

  • 返回值Promise<Hades>
// SIGHUP 信号处理
process.on('SIGHUP', () => G.reload());

日志方法

所有日志方法签名统一为 (where, what, ...infos)

G.trace(where, what, ...infos);  // 蓝色
G.debug(where, what, ...infos);  // 青色
G.info(where, what, ...infos);   // 绿色
G.warn(where, what, ...infos);   // 黄色
G.error(where, what, ...infos);  // 红色
G.fatal(where, what, ...infos);  // 洋红色
G.mark(where, what, ...infos);   // 灰色

内联更新方法(U / D 变体)

每个等级都有对应的 U(更新)和 D(结束)变体,用于进度条等需要同行刷新的场景:

// U 系列:内联更新
G.debugU(where, what, ...infos);  // 回车不换行,持续刷新当前行
// D 系列:结束更新
G.debugD(where, what, ...infos);  // 输出后换行,结束内联更新

7 个等级 × 2 种变体 = 14 个方法:traceU/DdebugU/DinfoU/DwarnU/DerrorU/DfatalU/DmarkU/D

fatalE(code, where, what, ...infos)

输出 fatal 日志后立即退出进程。

  • 参数
    • code {number} — 退出码。
    • where {string}
    • what {string}
    • ...infos {any[]}
G.fatalE(1, '~[核心]', '不可恢复错误', new Error('内存不足'));
// 输出日志后 process.exit(1)

Melinoe 与 Zagreus — 上下文复用

在同一上下文中频繁输出日志时,每次都传 wherewhat 会很冗余。MelinoeZagreus 是 Hades 的轻量包装类,用于预设这些参数。

Melinoe — 预设 where

通过 G.where(where) 获取 Melinoe 实例,其日志方法省略 where 参数:

const dbLog = G.where('数据库');

dbLog.info('连接', '~[目标]~{localhost:3306}');
dbLog.error('查询失败', new Error('语法错误'));
// 等价于 G.info('数据库', '连接', '~[目标]~{localhost:3306}')

Melinoe 也支持 .what(what) 进一步链式生成 Zagreus

const dbConnectLog = G.where('数据库').what('连接');
dbConnectLog.info('~[目标]~{localhost:3306}');

Zagreus — 预设 where + what

通过 G.what(where, what)melinoe.what(what) 获取 Zagreus 实例,其日志方法仅需传 ...infos

const dbConnectLog = G.what('数据库', '连接');

dbConnectLog.info('~[目标]~{localhost:3306}');
dbConnectLog.error(new Error('超时'));
// 等价于 G.info('数据库', '连接', '~[目标]~{localhost:3306}')
// 等价于 G.error('数据库', '连接', new Error('超时'))

MelinoeZagreus 均支持完整的日志方法:普通(.info)、内联更新(.infoU)、结束更新(.infoD)以及 fatalE

高级特性

1. 文件轮换

当开启文件输出(指定 dirn)时,Hades 自动启用按大小轮换:

  • sizeFileLogMax 控制单个文件最大尺寸(默认 20MB)。
  • numberFileLogBackupMax 控制保留的旧文件数量(默认 0,不保留)。
  • 当日志文件超过大小限制时,自动创建新文件;旧文件以 <name>.log.<n> 命名(如 my-app.log.1)。
const log = new Hades({
  name: 'server',
  dirn: './logs',
  sizeFileLogMax: 1024 * 1024 * 10,  // 10MB
  numberFileLogBackupMax: 5,          // 保留最近5个旧文件
});

生成的文件结构:

logs/
├── server.log          ← 当前日志
├── server.log.1        ← 上一个
├── server.log.2        ← 更早的
├── ...
├── server.log.5
└── server.stack.log    ← 错误堆栈日志

2. 关闭强调格式高亮

在不支持 ANSI 控制字符的终端(如某些 CI 环境、文件重定向)中,建议关闭高亮:

const log = new Hades({ willHighlight: false });

关闭后,~[]~{} 的控制字符会被自动移除,仅保留纯文本语义。

3. 等级颜色

willColorLevel(默认 true)控制是否根据不同日志等级输出不同颜色。每个等级的颜色对应关系见上方「日志等级与使用时机」表格。

// 关闭颜色(适合输出到不支持颜色的终端)
const log = new Hades({ willColorLevel: false });

4. i18n 文本定制(texts

Hades.texts 用于控制日志中的固定文本,可随时替换以适配不同语言:

const log = new Hades({
  texts: {
    name: '日志',
    init: '初始化',
    'error-encounter': '捕获错误',
    level: {
      ALL: '全部', TRACE: '追踪', DEBUG: '调试',
      INFO: '信息', WARN: '警告', ERROR: '错误',
      FATAL: '致命', MARK: '标记', OFF: '关闭',
    },
  },
});

也可以在运行时动态替换:

G.texts['error-encounter'] = '发生异常';
G.texts.level.ERROR = '严重';

5. 仅控制台输出

设置 dirn 为空字符串或不传(默认为 process.cwd()),Hades 将仅输出到控制台,不写入文件:

// 不保存文件
const log = new Hades({ dirn: '' });

6. 自定义时间格式

通过 templateTime 自定义日志中的时间显示格式,语法兼容 dayjs

const log = new Hades({
  templateTime: 'YYYY-MM-DD HH:mm:ss',  // ISO 风格
  // templateTime: 'HH:mm:ss',          // 仅时间
});

7. 错误链(Error.cause

传入 error 等级的 Error 对象时,Hades 会自动展开 cause 链:

const root = new Error('文件不存在');
const mid = new Error('配置加载失败', { cause: root });
const top = new Error('启动失败', { cause: mid });

G.error('~[启动]', '初始化异常', top);
// 输出:
//   [时间][错误] 启动 => 初始化异常  ✘ 发生错误 --> 启动失败
//      --> 配置加载失败
//      --> 文件不存在

8. 转义字符

需要输出字面量 ~[~{ 时,使用反斜杠转义:

G.info('说明', '语法', '使用 \\~[术语\\] 和 \\~{值\\}');
// 输出: [时间][信息] 说明 => 语法  使用 ~[术语] 和 ~{值}

错误代码

| 代码 | 位置 | 描述 | 上下文数据 | | --------------------------------- | ------------------------------------------------------- | ----------------------------------------------------- | -------------------------- | | invalid-options | hades/Hades#constructor(options) | options 参数类型无效(必须为对象或 null) | { options } | | invalid-name | hades/Hades#constructor(options.name) | name 选项类型无效(必须为字符串) | { name } | | invalid-level | hades/Hades#constructor(options.level) | level 选项类型无效(必须为字符串) | { level } | | invalid-log-dirn | hades/Hades#constructor(options.dirn) | dirn 选项类型无效(必须为字符串) | { dirn } | | invalid-texts | hades/Hades#constructor(options.texts) | texts 选项类型无效(必须为对象) | { texts } | | invalid-eol | hades/Hades#constructor(options.eol) | eol 选项类型无效(必须为字符串) | { eol } | | invalid-time-template | hades/Hades#constructor(options.templateTime) | templateTime 选项类型无效(必须为字符串) | { templateTime } | | invalid-max-file-log-size | hades/Hades#constructor(options.sizeFileLogMax) | sizeFileLogMax 选项值无效(必须为正整数) | { sizeFileLogMax } | | invalid-max-backup-log-file | hades/Hades#constructor(options.numberFileLogBackup) | numberFileLogBackupMax 选项值无效(必须为非负整数) | { numberFileLogBackup } | | invalid-will-highlight | hades/Hades#constructor(options.willHighlight) | willHighlight 选项类型无效(必须为布尔值) | { willHighlight } | | invalid-will-level-colorful | hades/Hades#constructor(options.willColorLevel) | willColorLevel 选项类型无效(必须为布尔值) | { willColorLevel } | | invalid-will-output-init-info | hades/Hades#constructor(options.willOutputInitInfo) | willOutputInitInfo 选项类型无效(必须为布尔值) | { willOutputInitInfo } | | invalid-will-output-console-error | hades/Hades#constructor(options.willConsoleOutputError) | willConsoleOutputError 选项类型无效(必须为布尔值) | { willConsoleOutputError } | | invalid-will-init-immediate | hades/Hades#constructor(options.willInitImmediate) | willInitImmediate 选项类型无效(必须为布尔值) | { willInitImmediate } |