Skip to content
Elogs
Esc
navigateopen⌘Jpreview
On this page

Custom Formatting

自定义日志消息格式、token 集合、颜色和时间戳

customLogFormat 模板字符串控制每条 access log 的渲染。模板里出现哪些 {token},Elogs 就计算哪些 —— 没出现的 token 在 hot path 上完全不跑(process.hrtime、颜色包装等)。

基本用法

import { createElogs } from '@eastgold15/elogs'

createElogs({
  config: {
    customLogFormat: '{now} {level} {duration} {method} {pathname} {status}',
  },
})

不设置 customLogFormat 时,Elogs 用内置默认:

🦊 {now} {level} {duration} {method} {pathname} {status} {message} {ip} {context}

🦊 是字面量 emoji,不是 token —— 直接出现在模板里原样输出。

可用 token

Token 渲染值
{now} 时间戳(受 timestamp 配置控制)
{epoch} Unix 毫秒时间戳(整数)
{level} 日志级别;开启颜色时按级别背景色 chip
{method} HTTP method;开启颜色时按方法着色(GET 绿、POST 蓝、DELETE 红 等)
{pathname} 请求路径;{path} 是别名
{query} 原始 query 字符串(如 ?id=123)
{status} 响应状态码;开启颜色时按状态范围着色(2xx 绿、4xx 黄、5xx 红)
{statusText} 状态文本(404 → Not Found);未识别时为空
{duration} 请求耗时(12ms / 1.5s / 11s)
{message} 自定义消息文本
{ip} 客户端 IP(x-forwarded-for / x-real-ip);开启 ip: true 才渲染
{context} context JSON 字符串(仅当 showContextTree: false;默认 tree 模式留空)
{speed} 极慢请求标记,duration >= verySlowThreshold 时追加 ⚡ <pathname>
{service} 占位符 —— 不会替换为服务名;service 配置在主行前以 [name] 前缀渲染
{requestId} 占位符 —— 当前固定为空,留作未来扩展

token 解析大小写不敏感({RequestId} 等价 {requestid}),但 token 本身的拼写要跟 replacements 表对上才能替换,否则保留为字面量。

示例

极简

customLogFormat: '{method} {pathname} {status}'
GET /api/users 200

带服务名前缀 + emoji

{service} token 不会被替换 —— 服务名通过 service 配置项以 [name] 前缀加在主行最前面:

createElogs({
  config: {
    service: 'my-api',
    customLogFormat: '🦊 {now} {level} {duration} {method} {pathname} {status} {message}',
  },
})

输出(非 TTY 或 useColors: false):

[my-api] 🦊 2025-04-13T15:00:19.123Z INFO 12ms GET /api/users 200 User viewed profile

颜色终端上,{level} 在背景色 chip 里,{method} 按方法着色,{status} 按状态范围着色。

状态文本

customLogFormat: '{method} {pathname} {status} {statusText}'
GET /api/users 200 OK
DELETE /api/users/42 404 Not Found

{statusText} 内部用一张固定的代码→文本表(200→OK404→Not Found500→Internal Server Error 等)。未识别的状态码渲染为空字符串。

慢请求 + 极慢请求

createElogs({
  config: {
    customLogFormat: '{now} {level} {duration} {method} {pathname} {status} {message}{speed}',
    slowThreshold: 500,        // 耗时 ≥ 500ms → 末尾追加 ⚡ slow
    verySlowThreshold: 1000,   // 耗时 ≥ 1s   → {speed} 渲染为 ⚡ /api/...
  },
})
  • slowThreshold —— 主行末尾无条件追加 ⚡ slow(不依赖 token)
  • verySlowThreshold —— {speed} token 渲染为 ⚡ <pathname>(可选,只在你模板里写 {speed} 才生效)

两者不冲突:{speed} 优先;{speed} 不出现时,如果 duration >= slowThreshold 仍会追加 ⚡ slow

包含 query string

默认 pathname 不带 query。logQueryParams: true 后,{pathname} 会拼上 query:

createElogs({
  config: {
    logQueryParams: true,
    customLogFormat: '{method} {pathname}',
  },
})
GET /api/users?page=2

如果只想单独显示 query 不混入 {pathname},直接用 {query} token。

显示客户端 IP

createElogs({
  config: {
    ip: true, // 或 showIp: true(legacy 别名)
    customLogFormat: '{method} {pathname} {status} {ip}',
  },
})

IP 从 x-forwarded-for 第一段或 x-real-ip 取;本地测试无这些 header 时为空。

时间戳

import type { ElogsConfig } from '@eastgold15/elogs'

const config: ElogsConfig = {
  customLogFormat: '{now} {level} {method} {pathname}',
  timestamp: 'yyyy-mm-dd HH:MM:ss',
}

timestamp 字段:

  • 字符串 —— 模板,支持 yyyy / mm / dd / HH / MM / ss / SSS 占位
  • { format: string } 对象 —— 等价,但用对象字面量(方便和别的 config 一起构建)
  • 不设置 —— new Date().toISOString()(2025-04-13T15:00:19.123Z)
const config: ElogsConfig = {
  timestamp: { format: 'yyyy-mm-dd HH:MM:ss.SSS' },
}

{epoch}Date.now() 拿 Unix 毫秒 —— 不受 timestamp 配置影响。

颜色

createElogs({
  config: {
    useColors: true, // 默认 true,且仅 TTY 生效
  },
})
  • useColors: true + TTY —— 开启颜色
  • useColors: false —— 强制关闭(写到 file / 转发到其它服务时通常关闭)
  • useColors: true 但非 TTY(pipe / 重定向)—— 自动关闭,避免 ANSI 码污染日志文件

chalk 负责颜色 背景色 chip、method 按动词着色、status 按范围着色、pathname 白亮、duration 灰。

错误日志的格式

customLogFormat 同时作用于 access log 和 error log。logger.handleHttpError(...) 走的是同一 emit 管道,渲染逻辑一致。错误响应里 data.message 是错误信息(填到 {message}),data.status 是 HTTP 状态码(填到 {status})。{context} 在错误日志里会渲染 error.name / error.message 等。

性能

模板里没出现的 token 完全跳过。比如:

  • 模板里没 {duration} —— 不会跑 process.hrtime
  • 模板里没 {speed} —— 不会比较 verySlowThreshold
  • 模板里没 {ip} —— 不会读 x-forwarded-for / x-real-ip
  • 模板里没 {query} —— 不会解析 URL search

代价是首次创建 logger 时(per logger 实例)解析一次 TOKEN_PATTERN = /\{([a-zA-Z]+)\}/g,把出现过的 token 存到 Set<string>,后续 emit 只检查 set。热路径上零正则、零字符串扫描。

最佳实践

  • 生产模板保持简洁 —— 留给下游日志聚合器(Grafana / Datadog)做可视化
  • 慢请求标记靠 slowThreshold + {speed} —— 比手动在模板里写 duration > 500 干净
  • 写文件时显式 useColors: false —— 避免 ANSI 码混进文件
  • logQueryParams: true 谨慎 —— query 可能含敏感 token(API key / 签名),结合 autoRedact
  • 不要在模板里拼 PII —— email: {email} 这类用 context 配合 autoRedact 走,别直接进模板字符串
  • {epoch} 给机器读,{now} 给人读 —— 同一行可同时放两个,自动化解析 {epoch},肉眼读 {now}

API 参考

Last updated on August 15, 2026

Was this page helpful?