发布于

AI总结: 本文介绍了一个基于Nginx的Lua脚本,该脚本用于捕获和记录HTTP请求和响应的详细信息。脚本通过设置不同范围的配置(http、server、location),并定义了一个白名单来过滤日志记录的接口,以减少日志的数量。脚本中包括了请求头、请求体、响应头和响应体的捕获和记录。 优化建议: 1. 考虑将白名单的配置外部化,以便于维护和扩展,避免在代码中硬编码。 2. 增加对异常情况的处理,比如请求体过大或文件读取错误时的日志记录。 3. 使用更高效的字符串拼接方法,例如使用表来构建字符串,减少内存占用。 4. 考虑增加日志级别的配置,以便在不同环境中灵活调整日志的详细程度。 5. 增加注释,提升代码可读性,便于其他开发者理解和维护。

可以将配置放到http, server, location下, 用于不同范围 需修改白名单whitelist, 只打印关心的接口, 防止日志太多

    # 初始化变量
    set $req_headers "";
    set $req_body "";
    set $resp_headers "";
    set $resp_body "";

    access_by_lua_block {
        -- 捕获请求头
        local headers = ngx.req.get_headers()
        local headers_str = ""
        for k, v in pairs(headers) do
            headers_str = headers_str .. "  " .. k .. ": " .. v .. "\n"
        end
        ngx.var.req_headers = headers_str

        -- 捕获请求体
        ngx.req.read_body()
        local body = ngx.req.get_body_data()
        if not body then
            local file = ngx.req.get_body_file()
            if file then
                local f = io.open(file, "rb")
                body = f:read("*all")
                f:close()
            end
        end
        ngx.var.req_body = body or "-"
    }

    body_filter_by_lua_block {
        local chunk = ngx.arg[1]
        if chunk then
            ngx.var.resp_body = (ngx.var.resp_body or "") .. chunk
        end
    }

    log_by_lua_block {
        -- 定义白名单 URI
        local whitelist = {
            ["/translate"] = true,
            ["/test2"] = true
        }
        -- 获取当前请求的 URI
        local uri = ngx.var.uri
        -- 检查是否在白名单中
        if whitelist[uri] then
            local resp_headers = ngx.resp.get_headers()
            local headers_str = ""
            for k, v in pairs(resp_headers) do
                headers_str = headers_str .. "  " .. k .. ": " .. v .. "\n"
            end
            ngx.var.resp_headers = headers_str

            local log_entry = string.format(
                "\nRequest: %s\nHeaders: \n%sBody: %s\n\nResponse Status: %s\nHeaders: \n%sBody: %s\n",
                ngx.var.request,
                ngx.var.req_headers,
                ngx.var.req_body,
                ngx.var.status,
                ngx.var.resp_headers,
                ngx.var.resp_body or "-"
            )

            ngx.log(ngx.INFO, log_entry)
        else
            ngx.log(ngx.INFO, uri)
        end
    }