必须关闭 daemon 模式并重定向 access_log 至 /dev/stdout,同时定义含 $request_uri、$request_time 和 $upstream_response_time 的 log_format;否则日志将无法输出至标准流或缺失关键字段。

在 Docker 环境中让 Nginx 的 access_log 输出到标准输出(/dev/stdout),同时保留关键字段如请求路径($request_uri)、响应耗时($request_time)和上游耗时($upstream_response_time),核心在于两件事:一是确保日志写入标准流而非文件,二是使用包含所需变量的自定义格式。
必须关闭守护进程并重定向日志目标
Nginx 默认以 daemon 模式运行,会脱离终端上下文,导致无法可靠输出到容器 stdout/stderr。因此需强制前台运行:
- 在
nginx.conf的全局块(main context)中添加:daemon off; - 将
access_log显式指向/dev/stdout,例如:access_log /dev/stdout enhanced; - 错误日志建议单独走 stderr:
error_log /dev/stderr warn;,便于日志分类采集
定义含路径与耗时字段的自定义 log_format
默认的 combined 格式不包含 $request_time 或 $upstream_response_time,也不区分原始路径与重写后路径。推荐在 http 块中定义一个增强格式:
在 Linux 上通过 Docker 运行 OpenClaw,并使用 Tailscale 实现远程访问。⚠️ 涉及 sudo、Docker、Tailscale和凭证挂载——请先查阅安全章节...
-
$request_uri记录原始请求路径(含 query string),比$uri更完整 -
$request_time表示从读取第一个字节到发送完响应的总耗时(秒,精度毫秒) -
$upstream_response_time只在启用proxy_pass时有效,反映后端真实响应延迟 - 可加入
$scheme、$server_name、$http_x_forwarded_for等上下文字段
示例配置:
log_format enhanced '$remote_addr - $remote_user [$time_local] ' '"$request_method $request_uri $server_protocol" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" $request_time $upstream_response_time ' '$http_x_forwarded_for $scheme $server_name';确保 location 级别配置不覆盖或遗漏格式
access_log 指令作用域为 http、server 或 location。若在 server 块中已启用 access_log /dev/stdout enhanced;,则子 location 会继承该设置;但若某 location 中显式写了 access_log off; 或指定了其他路径/格式,就会屏蔽全局配置。
- 检查所有
location块,避免出现access_log off;或未声明格式的access_log /some/file.log; - 如需对特定路径(如静态资源)降级日志,可用
log_not_found off;或map+log_if过滤,而非关闭整个 access_log - 若使用了
rewrite或try_files,$request_uri仍保持原始值,而$uri是内部重写后的路径——记录前者更能还原客户端真实请求
验证输出是否含完整字段且无截断
容器启动后,用 docker logs 查看实时输出,确认每条日志都包含预期字段:
- 发起测试请求:
curl -v "http://localhost:8080/api/test?x=1" - 观察日志中是否出现类似:
"GET /api/test?x=1 HTTP/1.1" 200 123 ... 0.023 0.018 - 注意
$request_time和$upstream_response_time为浮点数,单位秒;若为短横(-),说明未命中 upstream 或变量未启用 - 若发现字段为空(如
$upstream_response_time总是-),检查是否配置了proxy_pass,且后端服务可达










