-
Notifications
You must be signed in to change notification settings - Fork 2.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: server info #2884
feat: server info #2884
Changes from all commits
34276cb
d298474
24de385
e35a156
6bea303
91e524a
1dbcd68
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,6 +18,7 @@ local require = require | |
local core = require("apisix.core") | ||
local route = require("resty.radixtree") | ||
local plugin = require("apisix.plugin") | ||
|
||
local ngx = ngx | ||
local get_method = ngx.req.get_method | ||
local ngx_time = ngx.time | ||
|
@@ -29,6 +30,7 @@ local reload_event = "/apisix/admin/plugins/reload" | |
local ipairs = ipairs | ||
local error = error | ||
local events | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ditto not related to this title of PR |
||
local MAX_REQ_BODY = 1024 * 1024 * 1.5 -- 1.5 MiB | ||
|
||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
-- | ||
-- 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. | ||
-- | ||
local server_info = require("apisix.server_info") | ||
local core = require("apisix.core") | ||
|
||
local plugin_name = "server-info" | ||
local schema = { | ||
type = "object", | ||
additionalProperties = false, | ||
} | ||
|
||
|
||
local _M = { | ||
version = 0.1, | ||
priority = 1000, | ||
name = plugin_name, | ||
schema = schema, | ||
} | ||
|
||
|
||
local function get_server_info() | ||
local server_info, err = server_info.get() | ||
if not server_info then | ||
core.log.error("failed to get server_info: ", err) | ||
return 500, err | ||
end | ||
|
||
return 200, core.json.encode(server_info) | ||
end | ||
|
||
|
||
function _M.check_schema(conf) | ||
local ok, err = core.schema.check(schema, conf) | ||
if not ok then | ||
return false, err | ||
end | ||
|
||
return true | ||
end | ||
|
||
|
||
function _M.api() | ||
return { | ||
{ | ||
methods = {"GET"}, | ||
uri = "/apisix/server_info", | ||
handler = get_server_info, | ||
}, | ||
} | ||
end | ||
|
||
|
||
return _M |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,168 @@ | ||
-- | ||
-- 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. | ||
-- | ||
local require = require | ||
local core = require("apisix.core") | ||
|
||
local type = type | ||
local ngx_time = ngx.time | ||
|
||
local boot_time = os.time() | ||
local internal_status = ngx.shared.internal_status | ||
|
||
local _M = {} | ||
|
||
if not internal_status then | ||
error("lua_shared_dict \"internal_status\" not configured") | ||
end | ||
|
||
|
||
local function is_privileged() | ||
local process_type = require("ngx.process").type() | ||
return process_type == "privileged agent" or process_type == "single" | ||
end | ||
|
||
-- server information will be saved into shared memory only if the key | ||
-- "server_info" not exist if excl is true. | ||
local function save(data, excl) | ||
local handler = excl and internal_status.add or internal_status.set | ||
|
||
local ok, err = handler(internal_status, "server_info", data) | ||
if not ok then | ||
if excl and err == "exists" then | ||
return true | ||
end | ||
|
||
return nil, err | ||
end | ||
|
||
return true | ||
end | ||
|
||
|
||
local function encode_and_save(server_info, excl) | ||
local data, err = core.json.encode(server_info) | ||
if not data then | ||
return nil, err | ||
end | ||
|
||
return save(data, excl) | ||
end | ||
|
||
|
||
local function report() | ||
local server_info, err = _M.get() | ||
if not server_info then | ||
core.log.error("failed to get server_info: ", err) | ||
return nil, err | ||
end | ||
|
||
if server_info.etcd_version == "unknown" then | ||
local res, err = core.etcd.server_version() | ||
if not res then | ||
core.log.error("failed to fetch etcd version: ", err) | ||
return nil, err | ||
|
||
elseif type(res.body) ~= "table" then | ||
core.log.error("failed to fetch etcd version: bad version info") | ||
return nil, "bad etcd version info" | ||
else | ||
server_info.etcd_version = res.body.etcdcluster | ||
end | ||
end | ||
|
||
server_info.last_report_time = ngx_time() | ||
|
||
local data, err = core.json.encode(server_info) | ||
if not data then | ||
core.log.error("failed to encode server_info: ", err) | ||
return nil, err | ||
end | ||
|
||
local key = "/data_plane/server_info/" .. server_info.id | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we can not use how about There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The key /nodes/server_info/{node_id} is good, but why CP also writes the server info? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
local ok, err = core.etcd.set(key, data, 180) | ||
if not ok then | ||
core.log.error("failed to report server info to etcd: ", err) | ||
return nil, err | ||
end | ||
|
||
local ok, err = save(data, false) | ||
if not ok then | ||
core.log.error("failed to encode and save server info: ", err) | ||
return nil, err | ||
end | ||
end | ||
|
||
|
||
local function uninitialized_server_info() | ||
return { | ||
etcd_version = "unknown", | ||
hostname = core.utils.gethostname(), | ||
id = core.id.get(), | ||
version = core.version.VERSION, | ||
up_time = ngx_time() - boot_time, | ||
last_report_time = -1, | ||
} | ||
end | ||
|
||
|
||
function _M.init_worker() | ||
if not is_privileged() then | ||
return | ||
end | ||
|
||
local ok, err = encode_and_save(uninitialized_server_info(), true) | ||
if not ok then | ||
core.log.error("failed to encode and save server info: ", err) | ||
end | ||
|
||
local opts = { | ||
check_interval = 5, -- in seconds | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. and we should allow the user to specify this field There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I still think 10 mins is too long, also for now, all the basic server info are static (except the What about 1 min or 2 mins? |
||
} | ||
|
||
if core.config ~= require("apisix.core.config_etcd") then | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. need some comment for why call |
||
return | ||
end | ||
|
||
-- only launch timer to report server info when config cener is etcd. | ||
local timer, err = core.timer.new("server info", report, opts) | ||
if not timer then | ||
core.log.error("failed to create timer to report server info ", err) | ||
end | ||
end | ||
|
||
|
||
function _M.get() | ||
local data, err = internal_status:get("server_info") | ||
if err ~= nil then | ||
return nil, err | ||
end | ||
|
||
if not data then | ||
return uninitialized_server_info() | ||
end | ||
|
||
local server_info, err = core.json.decode(data) | ||
if not server_info then | ||
return nil, err | ||
end | ||
|
||
server_info.up_time = ngx_time() - boot_time | ||
return server_info | ||
end | ||
|
||
|
||
return _M |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
revert this line