njs可通过$upstream_response_time分类响应时间并设置$log_tier变量,结合log_format中if=指令实现按档输出不同详细度日志:≤100ms精简、100–500ms增加耗时与请求长度、>500ms追加trace_id等字段。

NJS 本身不支持直接修改日志格式或动态切换 log_format,也无法在运行时重载日志级别(如 nginx 的 error_log 级别是静态配置)。但你可以利用 NJS 捕获请求响应时间,并结合自定义变量 + 条件日志记录,实现“按响应时间分档输出不同详细程度日志”的效果——这本质上是**动态控制日志内容的丰富度,而非改变全局日志级别**。
核心思路:用 $upstream_response_time 触发日志字段条件输出
nginx 原生提供 $upstream_response_time 变量(毫秒级,含小数),NJS 可读取它并计算、分类,再通过 js_set 输出一个标记变量(如 $log_level_hint),最后在 log_format 中用 if= 指令控制是否记录某些字段(例如完整 header、body 截断、trace_id 等)。
- 响应 ≤ 100ms → 记录精简日志(仅 status、uri、time_iso8601)
- 100ms
- 响应 > 500ms → 额外记录 $http_x_request_id、$upstream_addr、完整 $request
步骤一:定义 NJS 函数生成日志分级提示变量
在 http 块中引入脚本:
js_import conf.d/loglevel.js; js_set $log_tier loglevel.tier; js_set $log_detail loglevel.detail;
对应 conf.d/loglevel.js 内容:
function tier(r) {
const t = parseFloat(r.variables.upstream_response_time || '0');
if (t function detail(r) {
const t = parseFloat(r.variables.upstream_response_time || '0');
if (t > 0.5) {
return r.variables.http_x_request_id || '-';
}
return '-';
}
步骤二:配置多层级日志格式(使用 if= 条件字段)
定义一个支持条件字段的 log_format:
详细的 Three.js 3D 图形参考,涵盖场景设置、相机、几何体、材质、光照、动画、控制器、加载器、数学工具和调试。
log_format tiered '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'$upstream_response_time '
'$request_length '
'$log_tier '
'"$log_detail" '
'$http_user_agent';
⚠️ 注意:$log_detail 在 fast/normal 场景下值为 '-',不会额外增加体积;只有 slow 请求才填入真实 request_id,实现“按需记录”。
若需更精细控制(如只在 slow 时记录 $request),可改用 map + 多个变量组合,或借助 access_log ... if= 分流到不同文件(但会增加磁盘 I/O)。
步骤三:配合采样降低高负载影响
高频慢请求仍可能撑爆日志。建议叠加轻量采样逻辑(不依赖外部库):
- 在 NJS 中对
$log_tier === 'slow'的请求,用Math.abs(hash($request_uri + $msec)) % 100模拟 1% 采样 - 仅当采样命中且 tier === 'slow' 时,才赋值真实
$log_detail,否则保持 '-' - 避免在 NJS 中做复杂加密或实时统计,防止阻塞 worker 进程
不复杂但容易忽略:这个方案不改动 nginx 日志系统底层,完全基于变量和格式控制,零 reload、零模块依赖,适合生产环境灰度上线。










