This is an automated email from the ASF dual-hosted git repository. membphis pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/apisix.git
The following commit(s) were added to refs/heads/master by this push: new bdd00e1 feat: support ctx.var to get service_name and route_name (#3036) bdd00e1 is described below commit bdd00e1f55fd13cd3d2b12656ec1dc2d4e3f6e0b Author: Yuelin Zheng <52862365+firstsaw...@users.noreply.github.com> AuthorDate: Thu Dec 17 22:26:25 2020 +0800 feat: support ctx.var to get service_name and route_name (#3036) close #2982 --- apisix/core/ctx.lua | 6 + apisix/init.lua | 2 + doc/plugins/http-logger.md | 12 +- doc/zh-cn/plugins/http-logger.md | 12 +- t/core/ctx.t | 321 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 351 insertions(+), 2 deletions(-) diff --git a/apisix/core/ctx.lua b/apisix/core/ctx.lua index 4451c4b..962a270 100644 --- a/apisix/core/ctx.lua +++ b/apisix/core/ctx.lua @@ -174,6 +174,12 @@ do elseif key == "consumer_name" then val = ngx.ctx.api_ctx and ngx.ctx.api_ctx.consumer_name + elseif key == "route_name" then + val = ngx.ctx.api_ctx and ngx.ctx.api_ctx.route_name + + elseif key == "service_name" then + val = ngx.ctx.api_ctx and ngx.ctx.api_ctx.service_name + else val = get_var(key, t._request) end diff --git a/apisix/init.lua b/apisix/init.lua index 5a4b075..1b9c62c 100644 --- a/apisix/init.lua +++ b/apisix/init.lua @@ -413,6 +413,7 @@ function _M.http_access_phase() api_ctx.conf_version = route.modifiedIndex .. "&" .. service.modifiedIndex api_ctx.conf_id = route.value.id .. "&" .. service.value.id api_ctx.service_id = service.value.id + api_ctx.service_name = service.value.name if enable_websocket == nil then enable_websocket = service.value.enable_websocket @@ -424,6 +425,7 @@ function _M.http_access_phase() api_ctx.conf_id = route.value.id end api_ctx.route_id = route.value.id + api_ctx.route_name = route.value.name local up_id = route.value.upstream_id if up_id then diff --git a/doc/plugins/http-logger.md b/doc/plugins/http-logger.md index 3129c79..01e3888 100644 --- a/doc/plugins/http-logger.md +++ b/doc/plugins/http-logger.md @@ -87,10 +87,20 @@ hello, world | Name | Type | Requirement | Default | Valid | Description | | ---------------- | ------- | ----------- | ------------- | ------- | ---------------------------------------------------------------------------------------- | -| log_format | object | optional | {"host": "$host", "@timestamp": "$time_iso8601", "client_ip": "$remote_addr"} | | Log format declared as JSON object. Only string is supported in the `value` part. If the value starts with `$`, the value is [Nginx variable](http://nginx.org/en/docs/varindex.html). | +| log_format | object | optional | {"host": "$host", "@timestamp": "$time_iso8601", "client_ip": "$remote_addr"} | | Log format declared as JSON object. Only string is supported in the `value` part. If the value starts with `$`, it means to get `APISIX` variables or [Nginx variable](http://nginx.org/en/docs/varindex.html). | Note that the metadata configuration is applied in global scope, which means it will take effect on all Route or Service which use http-logger plugin. +**APISIX Variables** + +| Variable Name | Description | Usage Example | +|------------------|-------------------------|----------------| +| route_id | id of `route` | $route_id | +| route_name | name of `route` | $route_name | +| service_id | id of `service` | $service_id | +| service_name | name of `service` | $service_name | +| consumer_name | username of `consumer` | $consumer_name | + ### Example ```shell diff --git a/doc/zh-cn/plugins/http-logger.md b/doc/zh-cn/plugins/http-logger.md index 832465f..b25545f 100644 --- a/doc/zh-cn/plugins/http-logger.md +++ b/doc/zh-cn/plugins/http-logger.md @@ -87,7 +87,17 @@ hello, world | 名称 | 类型 | 必选项 | 默认值 | 有效值 | 描述 | | ---------------- | ------- | ------ | ------------- | ------- | ------------------------------------------------ | -| log_format | object | 可选 | {"host": "$host", "@timestamp": "$time_iso8601", "client_ip": "$remote_addr"} | | 以 Hash 对象方式声明日志格式。对 value 部分,仅支持字符串。如果是以`$`开头,则表明是要获取 [Nginx 内置变量](http://nginx.org/en/docs/varindex.html)。特别的,该设置是全局生效的,意味着指定 log_format 后,将对所有绑定 http-logger 的 Route 或 Service 生效。 | +| log_format | object | 可选 | {"host": "$host", "@timestamp": "$time_iso8601", "client_ip": "$remote_addr"} | | 以 JSON 对象方式声明日志格式。对 value 部分,仅支持字符串。如果是以 `$` 开头,则表明是要获取 __APISIX__ 变量或 [Nginx 内置变量](http://nginx.org/en/docs/varindex.html)。特别的,该设置是全局生效的,意味着指定 log_format 后,将对所有绑定 http-logger 的 Route 或 Service 生效。 | + +**APISIX 变量** + +| 变量名 | 描述 | 使用示例 | +|------------------|-------------------------|----------------| +| route_id | `route` 的 id | $route_id | +| route_name | `route` 的 name | $route_name | +| service_id | `service` 的 id | $service_id | +| service_name | `service` 的 name | $service_name | +| consumer_name | `consumer` 的 username | $consumer_name | ### 设置日志格式示例 diff --git a/t/core/ctx.t b/t/core/ctx.t index a69cb13..482f93e 100644 --- a/t/core/ctx.t +++ b/t/core/ctx.t @@ -588,3 +588,324 @@ hello world consumer_name: consumer_name is nil --- no_error_log [error] + + + +=== TEST 23: add plugin metadata `service_name` +--- config + location /t { + content_by_lua_block { + local t = require("lib.test_admin").test + local code, body = t('/apisix/admin/plugin_metadata/http-logger', + ngx.HTTP_PUT, + [[{ + "log_format": { + "service_name": "$service_name" + } + }]], + [[{ + "node": { + "value": { + "log_format": { + "service_name": "$service_name" + } + } + }, + "action": "set" + }]] + ) + + ngx.status = code + ngx.say(body) + } + } +--- request +GET /t +--- response_body +passed +--- no_error_log +[error] + + + +=== TEST 24: add `http-logger` plugin on service +--- config + location /t { + content_by_lua_block { + local t = require("lib.test_admin").test + local code, body = t('/apisix/admin/services/1', + ngx.HTTP_PUT, + [[{ + "name": "ctx_var-support-service_name", + "plugins": { + "http-logger": { + "uri": "http://127.0.0.1:1980/log", + "batch_max_size": 1, + "max_retry_count": 1, + "retry_delay": 2, + "buffer_duration": 2, + "concat_method": "json" + } + }, + "upstream": { + "nodes": { + "127.0.0.1:1980": 1 + }, + "type": "roundrobin" + } + }]] + ) + + if code >= 300 then + ngx.status = code + end + ngx.say(body) + } + } +--- request +GET /t +--- response_body +passed +--- no_error_log +[error] + + + +=== TEST 25: route binding service and concat_method is json +--- config + location /t { + content_by_lua_block { + local t = require("lib.test_admin").test + local code, body = t('/apisix/admin/routes/1', + ngx.HTTP_PUT, + [[{ + "service_id": 1, + "upstream": { + "nodes": { + "127.0.0.1:1982": 1 + }, + "type": "roundrobin" + }, + "uri": "/hello" + }]] + ) + + if code >= 300 then + ngx.status = code + end + ngx.say(body) + } + } +--- request +GET /t +--- response_body +passed +--- no_error_log +[error] + + + +=== TEST 26: hit route and report http logger +--- request +GET /hello +--- response_body +hello world +--- error_log eval +qr/request log: \{"route_id":"1","service_id":"1","service_name":"ctx_var-support-service_name"\}/ + + + +=== TEST 27: log_format is configured with `service_name`, but there is no matching service +--- config + location /t { + content_by_lua_block { + local t = require("lib.test_admin").test + local code, body = t('/apisix/admin/routes/1', + ngx.HTTP_PUT, + [[{ + "plugins": { + "http-logger": { + "uri": "http://127.0.0.1:1980/log", + "batch_max_size": 1, + "max_retry_count": 1, + "retry_delay": 2, + "buffer_duration": 2, + "concat_method": "json" + } + }, + "upstream": { + "nodes": { + "127.0.0.1:1982": 1 + }, + "type": "roundrobin" + }, + "uri": "/hello" + }]] + ) + + if code >= 300 then + ngx.status = code + end + ngx.say(body) + } + } +--- request +GET /t +--- response_body +passed +--- no_error_log +[error] + + + +=== TEST 28: hit route but there is no matching service +--- request +GET /hello +--- response_body +hello world +--- error_log eval +qr/request log: \{"route_id":"1"\}/ + + + +=== TEST 29: add plugin metadata `route_name` +--- config + location /t { + content_by_lua_block { + local t = require("lib.test_admin").test + local code, body = t('/apisix/admin/plugin_metadata/http-logger', + ngx.HTTP_PUT, + [[{ + "log_format": { + "route_name": "$route_name" + } + }]], + [[{ + "node": { + "value": { + "log_format": { + "route_name": "$route_name" + } + } + }, + "action": "set" + }]] + ) + + ngx.status = code + ngx.say(body) + } + } +--- request +GET /t +--- response_body +passed +--- no_error_log +[error] + + + +=== TEST 30: sanity, batch_max_size=1 and concat_method is json +--- config + location /t { + content_by_lua_block { + local t = require("lib.test_admin").test + local code, body = t('/apisix/admin/routes/1', + ngx.HTTP_PUT, + [[{ + "name": "ctx_var-support-route_name", + "plugins": { + "http-logger": { + "uri": "http://127.0.0.1:1980/log", + "batch_max_size": 1, + "max_retry_count": 1, + "retry_delay": 2, + "buffer_duration": 2, + "concat_method": "json" + } + }, + "upstream": { + "nodes": { + "127.0.0.1:1982": 1 + }, + "type": "roundrobin" + }, + "uri": "/hello" + }]] + ) + + if code >= 300 then + ngx.status = code + end + ngx.say(body) + } + } +--- request +GET /t +--- response_body +passed +--- no_error_log +[error] + + + +=== TEST 31: hit route and report http logger +--- request +GET /hello +--- response_body +hello world +--- error_log eval +qr/request log: \{"route_id":"1","route_name":"ctx_var-support-route_name"\}/ + + + +=== TEST 32: missing `name` field, batch_max_size=1 and concat_method is json +--- config + location /t { + content_by_lua_block { + local t = require("lib.test_admin").test + local code, body = t('/apisix/admin/routes/1', + ngx.HTTP_PUT, + [[{ + "plugins": { + "http-logger": { + "uri": "http://127.0.0.1:1980/log", + "batch_max_size": 1, + "max_retry_count": 1, + "retry_delay": 2, + "buffer_duration": 2, + "concat_method": "json" + } + }, + "upstream": { + "nodes": { + "127.0.0.1:1982": 1 + }, + "type": "roundrobin" + }, + "uri": "/hello" + }]] + ) + + if code >= 300 then + ngx.status = code + end + ngx.say(body) + } + } +--- request +GET /t +--- response_body +passed +--- no_error_log +[error] + + + +=== TEST 33: hit route and report http logger +--- request +GET /hello +--- response_body +hello world +--- error_log eval +qr/request log: \{"route_id":"1"\}/