Skip to content

Commit

Permalink
feat(debug-mode): add dynamic debug mode (apache#5012)
Browse files Browse the repository at this point in the history
  • Loading branch information
tzssangglass authored Sep 22, 2021
1 parent 009a9ca commit c4c9b1f
Show file tree
Hide file tree
Showing 8 changed files with 463 additions and 7 deletions.
44 changes: 39 additions & 5 deletions apisix/debug.lua
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,13 @@
local require = require
local yaml = require("tinyyaml")
local log = require("apisix.core.log")
local json = require("apisix.core.json")
local profile = require("apisix.core.profile")
local lfs = require("lfs")
local inspect = require("inspect")
local io = io
local ngx = ngx
local re_find = ngx.re.find
local get_headers = ngx.req.get_headers
local type = type
local pairs = pairs
local setmetatable = setmetatable
Expand Down Expand Up @@ -123,15 +124,24 @@ local function apple_new_fun(module, fun_name, file_path, hook_conf)

function mt.__call(self, ...)
local arg = {...}
local http_filter = debug_yaml.http_filter
local api_ctx = ngx.ctx.api_ctx
local enable_by_hook = not (http_filter and http_filter.enable)
local enable_by_header_filter = (http_filter and http_filter.enable)
and (api_ctx and api_ctx.enable_dynamic_debug)
if hook_conf.is_print_input_args then
log[log_level]("call require(\"", file_path, "\").", fun_name,
"() args:", json.delay_encode(arg, true))
if enable_by_hook or enable_by_header_filter then
log[log_level]("call require(\"", file_path, "\").", fun_name,
"() args:", inspect(arg))
end
end

local ret = {self.fun_org(...)}
if hook_conf.is_print_return_value then
log[log_level]("call require(\"", file_path, "\").", fun_name,
"() return:", json.delay_encode(ret, true))
if enable_by_hook or enable_by_header_filter then
log[log_level]("call require(\"", file_path, "\").", fun_name,
"() return:", inspect(ret))
end
end
return unpack(ret)
end
Expand Down Expand Up @@ -199,6 +209,30 @@ local function sync_debug_status(premature)
end


local function check()
if not debug_yaml or not debug_yaml.http_filter then
return false
end

local http_filter = debug_yaml.http_filter
if not http_filter or not http_filter.enable_header_name or not http_filter.enable then
return false
end

return true
end

function _M.dynamic_debug(api_ctx)
if not check() then
return
end

if get_headers()[debug_yaml.http_filter.enable_header_name] then
api_ctx.enable_dynamic_debug = true
end
end


function _M.enable_debug()
if not debug_yaml or not debug_yaml.basic then
return false
Expand Down
3 changes: 3 additions & 0 deletions apisix/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ local upstream_util = require("apisix.utils.upstream")
local ctxdump = require("resty.ctxdump")
local ipmatcher = require("resty.ipmatcher")
local ngx_balancer = require("ngx.balancer")
local debug = require("apisix.debug")
local ngx = ngx
local get_method = ngx.req.get_method
local ngx_exit = ngx.exit
Expand Down Expand Up @@ -355,6 +356,8 @@ function _M.http_access_phase()

core.ctx.set_vars_meta(api_ctx)

debug.dynamic_debug(api_ctx)

local uri = api_ctx.var.uri
if local_conf.apisix and local_conf.apisix.delete_uri_tail_slash then
if str_byte(uri, #uri) == str_byte("/") then
Expand Down
3 changes: 3 additions & 0 deletions conf/debug.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@
#
basic:
enable: false
http_filter:
enable: false # enable or disable this feature
enable_header_name: X-APISIX-Dynamic-Debug # the header name of dynamic enable
hook_conf:
enable: false # enable or disable this feature
name: hook_phase # the name of module and function list
Expand Down
22 changes: 22 additions & 0 deletions docs/en/latest/architecture-design/debug-mode.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,3 +83,25 @@ hook_phase: # Module Function List, Name: hook_phase
- http_log_phase
#END
```

### Enable Advanced Debug Mode Dynamically

The advanced debug mode can take effect in particular requests by dynamic rule.

Example:

```yaml
http_filter:
enable: true # Enable/Disable Advanced Debug Mode Dynamically
enable_header_name: X-APISIX-Dynamic-Debug # Trace for the request with this header
......
#END
```

Dynamically enable advanced debugging mode in a particular request like this:

```shell
curl 127.0.0.1:9090/hello --header 'X-APISIX-Dynamic-Debug: foo'
```

Notice: We can not hook the `apisix.http_access_phase` module for particular requests, since whether the advanced debug mode is enabled is determined after these requests enter such phase.
22 changes: 22 additions & 0 deletions docs/zh/latest/architecture-design/debug-mode.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,3 +85,25 @@ hook_phase: # 模块函数列表,名字:hook_phase
- http_log_phase
#END
```

### 动态高级调试模式

动态高级调试模式是基于高级调试模式,可以由单个请求动态开启高级调试模式。设置 `conf/debug.yaml` 中的选项。

示例:

```yaml
http_filter:
enable: true # 是否动态开启高级调试模式
enable_header_name: X-APISIX-Dynamic-Debug # 追踪携带此 header 的请求
......
#END
```

动态开启高级调试模式,示例:

```shell
curl 127.0.0.1:9090/hello --header 'X-APISIX-Dynamic-Debug: foo'
```

注意:动态高级调试模式无法调试 `apisix.http_access_phase`, 模块(因为请求进入 `apisix.http_access_phase` 模块后,才会判断是否动态开启高级调试模式)。
1 change: 1 addition & 0 deletions rockspec/apisix-master-0.rockspec
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ dependencies = {
"ext-plugin-proto = 0.3.0",
"casbin = 1.26.0",
"api7-snowflake = 2.0-1",
"inspect == 3.1.1",
}

build = {
Expand Down
Loading

0 comments on commit c4c9b1f

Please sign in to comment.