【问题标题】:Nginx access log variables not set when the header-reading times out标头读取超时时未设置 Nginx 访问日志变量
【发布时间】:2018-02-14 02:12:00
【问题描述】:

有没有办法在 NGINX 重写阶段之前设置用户定义的变量并在访问日志中使用它们? 在某些错误场景中,例如下面定义的错误场景,我们最终会在设置任何用户变量之前进入访问日志阶段。

以下是我的访问日志格式示例:

log_format main '$remote_addr $server_addr $http_host $custom_destination_addr [$custom_request_time] ' ' "$request" $status $body_bytes_sent "$http_user_agent" ';

以“custom_”开头的字段是用户定义的变量。

当我发送以下具有非终止标头的 get 消息时;即,标题以“/r/n”而不是“/r/n/r/n”结尾:

get = "GET /Vod/mod/video16k_1.mp4 HTTP/1.1\r\nHost: 10.20.20.10:8585\r\nUser-Agent: HTTP Test Suite TestSuite/1.0.2\r\nAccept-Language: en-us,en;q=0.5\r\nAccept-Encoding: gzip,deflate\r\nConnection: keep-alive\r\n"

我在 error.log 中得到以下信息: [info] 28875#0: *1 客户端在读取客户端请求标头时超时(110:连接超时),客户端:10.20.20.128,服务器:,请求:“GET /Vod/mod/video16k_1.mp4 HTTP/1.1” ,主机:“10.20.20.10:8585”

然后,它会生成一个访问日志条目,其中所有用户定义的变量都未初始化:

2017/09/01 10:03:07 [警告] 28875#0: *1 在记录请求时使用未初始化的“custom_destination_addr”变量,客户端:10.20.20.128,服务器:,请求:“GET /Vod/mod/ video16k_1.mp4 HTTP/1.1",主机:"10.20.20.10:8585"

2017/09/01 10:03:07 [warn] 28875#0: *1 在记录请求时使用未初始化的“custom_request_time”变量,客户端:10.20.20.128,服务器:,请求:“GET /Vod/mod/ video16k_1.mp4 HTTP/1.1",主机:"10.20.20.10:8585"

访问日志条目:

10.20.20.128 10.20.20.10 10.20.20.10:8585 [] "GET /Vod/mod/video16k_1.mp4 HTTP/1.1" 408 0 "" "HTTP 测试套件 TestSuite/1.0.2"

当我正确设置标题“/r/n/r/n”的结尾时,访问日志就可以了。

因此,在上述错误情况下(读取标头超时),用户定义的访问日志变量将全部变为空。

这个问题是否有已知的解决方案,或者我们是否需要 NGIMX 中的新概念/功能来支持重写阶段之前的变量设置?

谢谢

【问题讨论】:

    标签: variables nginx configuration


    【解决方案1】:

    因为评论需要格式化,所以在回答中作为评论发布

    使用地图怎么样?

    map $custom_request_time $custom_request_time_log {
       default $custom_request_time;
       '' 'Not Available';
    }
    

    然后在日志中使用它?

    log_format main '$remote_addr $server_addr $http_host $custom_destination_addr [$custom_request_time_log] ' ' "$request" $status $body_bytes_sent "$http_user_agent" ';
    

    【讨论】:

    • 如果我必须在 log_by_lua 中使用 lua 代码进行一些时间格式化,你如何设置地图中变量的值?如果您能提供有关通过 lua 代码基于日志在地图中设置此值的详细信息,将不胜感激。
    • 您的代码需要使用ngx.var.custom_request_time设置custom_request_time,其余的将由地图处理
    • 我的基本问题是:是否可以在 NGINX 重写阶段之前为每个请求设置一个变量并在访问日志中使用该变量?
    • 如果你的意思是下一个请求,那么我怀疑,因为重写后会发送一个 301 并且会出现一个新的请求,所以访问日志可以使用 301 的变量,但不能用于下一个要求。其他可能的选择是将 PARAMS 添加到查询字符串或 cookie 或其他东西
    • 设置变量 ngx.var.custom_request_time (如你所建议)需要 nginx 经历重写阶段。如果请求处理在该阶段之前停止,则永远不会设置此变量。例如,当您发送没有结尾标头“/r/n/r/n”的请求时,就会发生这种情况
    猜你喜欢
    • 1970-01-01
    • 2017-04-01
    • 1970-01-01
    • 2015-01-27
    • 1970-01-01
    • 1970-01-01
    • 2013-10-15
    • 2020-12-01
    • 2013-09-15
    相关资源
    最近更新 更多