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→OK、404→Not Found、500→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 参考
ElogsConfig.customLogFormat— 模板字符串ElogsConfig.timestamp—string | { format: string }ElogsConfig.useColors/ip/showIp/logQueryParams/service/slowThreshold/verySlowThreshold/showContextTree/contextDepthFormatContext— per-logger 提升的格式常量(token set、template、useColors、thresholds)