From f6e28650762a946560e7631ea4bb831daa589830 Mon Sep 17 00:00:00 2001 From: patrick Date: Sun, 21 Jun 2026 12:11:33 +0800 Subject: [PATCH] fix(logger): respect request body expr in origin logs --- apisix/utils/log-util.lua | 88 ++++++++++++++--------------------- t/core/log-util.t | 97 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 132 insertions(+), 53 deletions(-) create mode 100644 t/core/log-util.t diff --git a/apisix/utils/log-util.lua b/apisix/utils/log-util.lua index 4551b8c68dce..f0ab4d5b1403 100644 --- a/apisix/utils/log-util.lua +++ b/apisix/utils/log-util.lua @@ -169,6 +169,28 @@ end _M.latency_details_in_ms = latency_details_in_ms +local function should_log_req_body(conf, ctx) + if not conf.include_req_body then + return false + end + + if not conf.include_req_body_expr then + return true + end + + if not conf.request_expr then + local request_expr, err = expr.new(conf.include_req_body_expr) + if not request_expr then + core.log.error('generate request expr err ', err) + return false + end + conf.request_expr = request_expr + end + + return conf.request_expr:eval(ctx.var) +end + + local function get_full_log(ngx, conf) local ctx = ngx.ctx.api_ctx local var = ctx.var @@ -227,37 +249,14 @@ local function get_full_log(ngx, conf) log.response.body = ctx.resp_body end - if conf.include_req_body then - - local log_request_body = true - - if conf.include_req_body_expr then - - if not conf.request_expr then - local request_expr, err = expr.new(conf.include_req_body_expr) - if not request_expr then - core.log.error('generate request expr err ' .. err) - return log - end - conf.request_expr = request_expr - end - - local result = conf.request_expr:eval(ctx.var) - - if not result then - log_request_body = false - end - end - - if log_request_body then - local max_req_body_bytes = conf.max_req_body_bytes or MAX_REQ_BODY - local body, err = get_request_body(max_req_body_bytes) - if err then - core.log.error("fail to get request body: ", err) - return - end - log.request.body = body + if should_log_req_body(conf, ctx) then + local max_req_body_bytes = conf.max_req_body_bytes or MAX_REQ_BODY + local body, err = get_request_body(max_req_body_bytes) + if err then + core.log.error("fail to get request body: ", err) + return end + log.request.body = body end return log @@ -337,10 +336,12 @@ function _M.get_req_original(ctx, conf) end core.table.insert(data, "\r\n") - if conf.include_req_body then + if should_log_req_body(conf, ctx) then local max_req_body_bytes = conf.max_req_body_bytes or MAX_REQ_BODY local req_body = get_request_body(max_req_body_bytes) - core.table.insert(data, req_body) + if req_body then + core.table.insert(data, req_body) + end end return core.table.concat(data, "") @@ -432,27 +433,8 @@ end function _M.check_and_read_req_body(conf, ctx) - if conf.include_req_body then - local should_read_body = true - if conf.include_req_body_expr then - if not conf.request_expr then - local request_expr, err = expr.new(conf.include_req_body_expr) - if not request_expr then - core.log.error('generate request expr err ', err) - return - end - conf.request_expr = request_expr - end - - local result = conf.request_expr:eval(ctx.var) - - if not result then - should_read_body = false - end - end - if should_read_body then - req_read_body() - end + if should_log_req_body(conf, ctx) then + req_read_body() end end diff --git a/t/core/log-util.t b/t/core/log-util.t new file mode 100644 index 000000000000..1fc094516c48 --- /dev/null +++ b/t/core/log-util.t @@ -0,0 +1,97 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +use t::APISIX 'no_plan'; + +repeat_each(1); +no_long_string(); +no_root_location(); + +run_tests; + +__DATA__ + +=== TEST 1: origin request log skips body when include_req_body_expr is false +--- config + location /t { + content_by_lua_block { + ngx.req.read_body() + + local log_util = require("apisix.utils.log-util") + local ctx = { + var = { + request = ngx.var.request, + arg_log_body = ngx.var.arg_log_body, + } + } + local conf = { + include_req_body = true, + include_req_body_expr = { + {"arg_log_body", "==", "yes"} + } + } + + local entry = log_util.get_req_original(ctx, conf) + if entry:find("hidden request body", 1, true) then + ngx.say("body logged") + return + end + + ngx.say("body skipped") + } + } +--- request +POST /t?log_body=no +hidden request body +--- response_body +body skipped + + + +=== TEST 2: origin request log keeps body when include_req_body_expr is true +--- config + location /t { + content_by_lua_block { + ngx.req.read_body() + + local log_util = require("apisix.utils.log-util") + local ctx = { + var = { + request = ngx.var.request, + arg_log_body = ngx.var.arg_log_body, + } + } + local conf = { + include_req_body = true, + include_req_body_expr = { + {"arg_log_body", "==", "yes"} + } + } + + local entry = log_util.get_req_original(ctx, conf) + if entry:find("visible request body", 1, true) then + ngx.say("body logged") + return + end + + ngx.say("body skipped") + } + } +--- request +POST /t?log_body=yes +visible request body +--- response_body +body logged