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 963e299 bugfix: passed the copied `api_ctx`, it may be freed if the
`api_ctx` (#2002)
963e299 is described below
commit 963e29951d38d60659c98e2961400c6b6738c4bb
Author: YuanSheng Wang <[email protected]>
AuthorDate: Thu Aug 6 10:20:34 2020 +0800
bugfix: passed the copied `api_ctx`, it may be freed if the `api_ctx`
(#2002)
* bugfix: passed the copied `api_ctx`, it may be freed if the `api_ctx`
was called in back timer async.
Fixed #1935.
---
apisix/plugins/syslog.lua | 33 ++++++++++++-------
t/plugin/syslog.t | 81 +++++++++++++++++++++++------------------------
2 files changed, 61 insertions(+), 53 deletions(-)
diff --git a/apisix/plugins/syslog.lua b/apisix/plugins/syslog.lua
index 7b96a2e..d2c46b9 100644
--- a/apisix/plugins/syslog.lua
+++ b/apisix/plugins/syslog.lua
@@ -14,6 +14,7 @@
-- See the License for the specific language governing permissions and
-- limitations under the License.
--
+
local core = require("apisix.core")
local log_util = require("apisix.utils.log-util")
local batch_processor = require("apisix.utils.batch-processor")
@@ -26,6 +27,7 @@ local stale_timer_running = false;
local timer_at = ngx.timer.at
local tostring = tostring
+
local schema = {
type = "object",
properties = {
@@ -47,10 +49,12 @@ local schema = {
required = {"host", "port"}
}
+
local lrucache = core.lrucache.new({
ttl = 300, count = 512
})
+
local _M = {
version = 0.1,
priority = 401,
@@ -58,30 +62,30 @@ local _M = {
schema = schema,
}
+
function _M.check_schema(conf)
return core.schema.check(schema, conf)
end
+
function _M.flush_syslog(logger)
local ok, err = logger:flush(logger)
if not ok then
core.log.error("failed to flush message:", err)
end
+
+ return ok
end
-local function send_syslog_data(conf, log_message)
+
+local function send_syslog_data(conf, log_message, api_ctx)
local err_msg
local res = true
- -- fetch api_ctx
- local api_ctx = ngx.ctx.api_ctx
- if not api_ctx then
- core.log.error("invalid api_ctx cannot proceed with sys logger plugin")
- return core.response.exit(500)
- end
-
-- fetch it from lrucache
- local logger, err = lrucache(api_ctx.conf_type .. "#" .. api_ctx.conf_id,
api_ctx.conf_version,
+ local logger, err = lrucache(
+ api_ctx.conf_type .. "#" .. api_ctx.conf_id,
+ api_ctx.conf_version,
logger_socket.new, logger_socket, {
host = conf.host,
port = conf.port,
@@ -93,7 +97,8 @@ local function send_syslog_data(conf, log_message)
retry_interval = conf.retry_interval,
pool_size = conf.pool_size,
tls = conf.tls,
- })
+ }
+ )
if not logger then
res = false
@@ -110,6 +115,7 @@ local function send_syslog_data(conf, log_message)
return res, err_msg
end
+
-- remove stale objects from the memory after timer expires
local function remove_stale_objects(premature)
if premature then
@@ -126,8 +132,9 @@ local function remove_stale_objects(premature)
stale_timer_running = false
end
+
-- log phase in APISIX
-function _M.log(conf)
+function _M.log(conf, ctx)
local entry = log_util.get_full_log(ngx, conf)
if not entry.route_id then
@@ -149,6 +156,7 @@ function _M.log(conf)
end
-- Generate a function to be executed by the batch processor
+ local cp_ctx = core.table.clone(ctx)
local func = function(entries, batch_max_size)
local data, err
if batch_max_size == 1 then
@@ -161,7 +169,7 @@ function _M.log(conf)
return false, 'error occurred while encoding the data: ' .. err
end
- return send_syslog_data(conf, data)
+ return send_syslog_data(conf, data, cp_ctx)
end
local config = {
@@ -186,4 +194,5 @@ function _M.log(conf)
end
+
return _M
diff --git a/t/plugin/syslog.t b/t/plugin/syslog.t
index 05a5cd1..c82dcd2 100644
--- a/t/plugin/syslog.t
+++ b/t/plugin/syslog.t
@@ -19,6 +19,7 @@ use t::APISIX 'no_plan';
repeat_each(1);
no_long_string();
no_root_location();
+
run_tests;
__DATA__
@@ -169,7 +170,7 @@ hello world
location /t {
content_by_lua_block {
local plugin = require("apisix.plugins.syslog")
- local logger_socket = require "resty.logger.socket"
+ local logger_socket = require("resty.logger.socket")
local logger, err = logger_socket:new({
host = "127.0.0.1",
port = 5044,
@@ -188,13 +189,16 @@ hello world
local ok, err = plugin.flush_syslog(logger)
if not ok then
- ngx.say(err)
+ ngx.say("failed to flush syslog: ", err)
+ return
end
ngx.say("done")
}
}
--- request
GET /t
+--- response_body
+done
--- no_error_log
[error]
@@ -206,62 +210,57 @@ GET /t
content_by_lua_block {
local t = require("lib.test_admin").test
local code, body = t('/apisix/admin/routes/1',
- ngx.HTTP_PUT,
- [[{
- "plugins": {
- "syslog": {
- "host" : "127.0.0.1",
- "port" : 5044,
- "flush_limit" : 1
- }
- },
- "upstream": {
- "nodes": {
- "127.0.0.1:1980": 1
- },
- "type": "roundrobin"
- },
- "uri": "/hello"
- }]],
+ ngx.HTTP_PUT,
[[{
- "node": {
- "value": {
- "plugins": {
- "syslog": {
- "host" : "127.0.0.1",
- "port" : 5044,
- "flush_limit" : 1
- }
- },
- "upstream": {
- "nodes": {
- "127.0.0.1:1980": 1
- },
- "type": "roundrobin"
- },
- "uri": "/hello"
+ "plugins": {
+ "syslog": {
+ "host" : "127.0.0.1",
+ "port" : 5044,
+ "flush_limit" : 1,
+ "timeout": 1
+ }
+ },
+ "upstream": {
+ "nodes": {
+ "127.0.0.1:1980": 1
},
- "key": "/apisix/routes/1"
+ "type": "roundrobin"
},
- "action": "set"
+ "uri": "/hello"
}]]
- )
+ )
if code >= 300 then
ngx.status = code
end
-
ngx.say(body)
+ -- wait etcd sync
+ ngx.sleep(0.5)
+
local http = require "resty.http"
local httpc = http.new()
local uri = "http://127.0.0.1:" .. ngx.var.server_port .. "/hello"
local res, err = httpc:request_uri(uri, {method = "GET"})
+ if not res then
+ ngx.say("failed request: ", err)
+ return
+ end
+
+ if res.status >= 300 then
+ ngx.status = res.status
+ end
+ ngx.print(res.body)
+
+ -- wait flush log
+ ngx.sleep(2.5)
}
}
--- request
-GET /hello
+GET /t
+--- response_body
+passed
hello world
--- no_error_log
[error]
---- wait: 0.2
+--- timeout: 5