【问题标题】:Trying to get status code from access_by_lua_file试图从 access_by_lua_file 获取状态码
【发布时间】:2022-08-13 06:09:50
【问题描述】:

我正在尝试从响应应用程序获取状态代码并将其发送到 access_by_lua_file ngx.status 或 ngx.var.status 中的外部 api 位始终返回 0 或 000。我使用 log_by_lua_file 并获取状态代码作为我的响应应用程序,但我可以\'不将其发送到外部 api,因为 API 功能被禁用是否有另一种方法来获取状态代码并将其发送到外部 api

这是我的示例代码

日志记录.lua

local request_time = ngx.now() - ngx.req.start_time()
local data = {
    request_method = ngx.var.request_method,
    user_agent = ngx.var.http_user_agent,
    request_time = request_time,
    status = ngx.var.status,
    url = \"http://\" .. ngx.var.host .. ngx.var.request_uri,
    ip = ngx.var.remote_addr,
    time = ngx.var.time_iso8601,
    path = ngx.var.request_uri
}

local httpc = require(\"resty.http\").new()
local output = cjson.encode(data)
ngx.log(ngx.ERR, ngx.status, ngx.var.status)
ngx.ctx.status_code = ngx.var.status
ngx.ctx.request_method = ngx.var.request_method
ngx.ctx.user_agent = ngx.var.user_agent
ngx.ctx.request_time = ngx.var.request_time
ngx.ctx.url = \"http://\" .. ngx.var.host .. ngx.var.request_uri
ngx.ctx.ip = ngx.var.remote_addr

-- ngx.location.capture(\"http://127.0.0.1:3232/api/create-log\", { method = ngx.HTTP_POST, body = output })
-- ngx.location.capture_multi({\"http://127.0.0.1:3232/api/create-log\", { method = \"POST\", body = output}})

ngx.log(ngx.ERR, \"dasdsadas \", ngx.var.status, \" \", ngx.status, \" \", ngx.var.upstream_status)

local res, err = httpc:request_uri(\"http://127.0.0.1:3232/api/create-log\", {
    method = \"POST\",
    body = output,                    
    headers = {
        [\"Content-Type\"] = \"application/json\",
    },
})


if not res then
    ngx.log(ngx.ERR, \"request failed: \", err)
end

nginx.conf

worker_processes auto;
events {
    worker_connections 1024;
}

http {
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    default_type application/octet-stream;

    log_format json_output \'{\"time_local\": \"$time_local\", \'
        \'\"path\": \"$request_uri\", \'
        \'\"url\": \"http://$host$request_uri\",\'
        \'\"ip\": \"$remote_addr\", \'
        \'\"time\": \"$time_iso8601\", \'
        \'\"user_agent\": \"$http_user_agent\", \'
        \'\"user_id_got\": \"$uid_got\", \'
        \'\"user_id_set\": \"$uid_set\", \'
        \'\"remote_user\": \"$remote_user\", \'
        \'\"request\": \"$request\", \'
        \'\"status\": \"$status\", \'
        \'\"body_bytes_sent\": \"$body_bytes_sent\", \'
        \'\"request_time\": \"$request_time\", \'
        \'\"request_method\": \"$request_method\",\'
        \'\"http_referrer\": \"$http_referer\" }\';

    
    init_by_lua_block {
        cjson = require(\"cjson\")
    }
    error_log logs/error.log error;

    server {
        listen 8080;
        access_log logs/access2.log json_output;

        location /hello {
            add_header Access-Control-Allow-Headers \"Content-Type, Authorization, X-Requested-With, Cache-Control, Accept, Origin, X-Session-ID, Host\";
            add_header Access-Control-Allow-Methods \"OPTIONS, GET, POST, PUT, HEAD, DELETE, OPTIONS, TRACE, CONNECT\";
            add_header Access-Control-Allow-Origin \"*\";

            if ($request_method = OPTIONS) {
                return 200;
            }

            if ($request_method = HEAD) {
                return 200;
            }

            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header Host $host;
            proxy_set_header Connection \"upgrade\";
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            access_by_lua_file lua/logging.lua;
            proxy_pass http://127.0.0.1:3131;
        }

        location = /favicon.ico {
            log_not_found off;
        }
    }
}

    标签: nginx logging lua openresty


    【解决方案1】:

    access_by_lua 在向上游发起请求之前运行。因此,不会设置状态代码,默认为 0。 https://stackoverflow.com/a/62202290/9090571

    响应及其状态码在 content_by_lua、header_filter_by_lua、body_filter_by_lua 或 log_by_lua 中可用,但您将无法直接发起 httpc 请求,因为 API 功能已禁用。

    有一个我之前使用过的已知解决方法 https://github.com/openresty/lua-nginx-module#ngxtimerat

    local function push_data(request_method, http_user_agent, status, full_uri, args, remote_addr, time_iso8601, request_uri,request_time)
        local data = {
            request_method = request_method,
            user_agent = http_user_agent,
            status = status,
            full_uri = full_uri,
            args = args,
            ip = remote_addr,
            time = time_iso8601,
            path = request_uri,
            request_time = request_time,
        }
    
        local cjson = require "cjson"
        local output = cjson.encode(data)
    
        local httpc = require("/usr/local/openresty/nginx/resty/http").new()
        local res, err = httpc:request_uri("http://127.0.0.1:3232/api/create-log", {
            method = "POST",
            body = output,
            headers = {
                ["Content-Type"] = "application/json",
            },
        })
    
        if not res then
            ngx.log(ngx.ERR, "request failed: ", err)
        end
    end
    
    local ok, err = ngx.timer.at(0, push_data,
            ngx.var.request_method,
            ngx.var.http_user_agent,
            ngx.var.status,
            "http://" .. ngx.var.host .. ngx.var.uri,
            ngx.var.args,
            ngx.var.remote_addr,
            ngx.var.time_iso8601,
            ngx.var.request_uri,
            ngx.now() - ngx.req.start_time()
            -- any other variables you need to set
    )
    if not ok then
        ngx.log(ngx.ERR, "failed to create timer: ", err)
        return
    end
    

    或者,您也可以使用https://github.com/cloudflare/lua-resty-logger-socket,尽管它可能没有得到维护并且有很多未解决的问题。

    【讨论】:

      猜你喜欢
      • 2018-09-02
      • 2022-01-24
      • 2019-03-18
      • 2019-01-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-06
      相关资源
      最近更新 更多