You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@apisix.apache.org by "yuqiquan (via GitHub)" <gi...@apache.org> on 2023/02/13 02:49:49 UTC
[GitHub] [apisix] yuqiquan opened a new issue, #8843: help request: use cjson.decode resolve router values failed
yuqiquan opened a new issue, #8843:
URL: https://github.com/apache/apisix/issues/8843
### Description
我想自定义个插件 ,提供一个control api接口获得apisix启动后缓存的路由信息,于是
```lua
local core = require("apisix.core")
local rotateutil = require("apisix.plugins.util.rotateutil")
local plugin = require("apisix.plugin")
local httpUtil = require("apisix.plugins.util.httputil")
local commonutil = require("apisix.plugins.util.commonutil")
local wafupdate = require("apisix.plugins.wafupdate")
local router = require("apisix.router")
local cjson = require("cjson.safe")
local ngx = ngx
local ngx_time = ngx.time
local ngx_update_time = ngx.update_time
local os_date = os.date
local json_decode = cjson.decode
local process = require("ngx.process")
local plugin_name = "info-report"
local INTERVAL = 3600 -- 默认轮询时间
local taskThreads = {}
local instance_taskThreads = {}
local resolveResult
-- 默认时是否执行
local isExcuteStarting = false
local ip
local openresty_version
local startTime
local fwd_dc
local schema = {
type = "object",
properties = {},
}
local _M = {
version = 1.0,
priority = -1700,
name = plugin_name,
schema = schema,
-- 这样设置全局
scope = "global",
}
-- 上报apisix实例信息
local function report_instance(args)
if args.isExcuting then
return
end
args.isExcuting = true
local ok,result = pcall(function()
ngx_update_time()
local now_time = ngx_time()
core.log.warn("plugin#info-report --- > report Apisix instance info ,now time : " ,os_date("%Y-%m-%d_%H-%M-%S",now_time))
local ip =ip
local fwd_dc = fwd_dc
-- 获得端口号
local local_conf = core.config.local_conf()
local port = local_conf.apisix.node_listen[1] or "9080"
-- 获取apisix 集群前缀
local prefix = local_conf.etcd.prefix
-- 设置etcd key值
local key = "/fwd/instance/".. fwd_dc .. "_" .. ip ..":" .. port
core.log.warn("key --- > ", key)
-- 设置etcd value值
local value = {}
value.ip = ip
value.port = port
value.fwd_dc = fwd_dc
value.openresty_version = openresty_version
value.apisix_version = core.version.VERSION
value.apisix_prefix = prefix
--------------------
--配置文件内容
local conf = {}
--plugins
local getPlugins = {}
for k,v in pairs(plugin.plugins) do
local info = {}
info.version = v.version
info.priority = v.priority
info.attr = v.attr
getPlugins[v.name] = info
end
conf.plugins = getPlugins
-- apisix
local apisix = {}
apisix.node_listen = local_conf.apisix.node_listen
apisix.extra_lua_path = local_conf.apisix.extra_lua_path
apisix.extra_lua_cpath = local_conf.apisix.extra_lua_cpath
apisix.proxy_cache = local_conf.apisix.proxy_cache
apisix.router = local_conf.apisix.router
local ssl = {}
ssl.listen = local_conf.apisix.ssl.listen
ssl.fallback_sni = local_conf.apisix.ssl.fallback_sni
apisix.ssl = ssl
apisix.enable_control = local_conf.apisix.enable_control
apisix.control = local_conf.apisix.control
conf.apisix = apisix
-- nginx_config
local nginx_config = {}
nginx_config.user = local_conf.nginx_config.user
nginx_config.main_configuration_snippet = local_conf.nginx_config.main_configuration_snippet
nginx_config.http_configuration_snippet = local_conf.nginx_config.http_configuration_snippet
nginx_config.http_server_configuration_snippet = local_conf.nginx_config.http_server_configuration_snippet
nginx_config.http_server_location_configuration_snippet = local_conf.nginx_config.http_server_location_configuration_snippet
nginx_config.http_admin_configuration_snippet = local_conf.nginx_config.http_admin_configuration_snippet
nginx_config.http_end_configuration_snippet = local_conf.nginx_config.http_end_configuration_snippet
nginx_config.stream_configuration_snippet = local_conf.nginx_config.stream_configuration_snippet
local http = {}
for k,v in pairs(local_conf.nginx_config.http) do
if k == "lua_shared_dict" then
http[k] = nil
else
http[k] = v
end
end
nginx_config.http = http
conf.nginx_config = nginx_config
-- etcd
local etcd = {}
etcd.host = local_conf.etcd.host
etcd.timeout = local_conf.etcd.timeout
etcd.user = local_conf.etcd.user
conf.etcd = etcd
-- ext-plugin
conf["ext-plugin"] = local_conf["ext-plugin"]
value.conf = conf
--cpu负载,内存占用
value.machine_info = commonutil.getMachineInfo()
--------------------------
ngx_update_time()
value.report_time = ngx_time()
-- 将value值存入etcd中
-- 存入值
local res, err = commonutil.insertEtcd(key,value)
if err then
core.log.error("etcd insert value failed , key ---> ", key," error ---> ",err)
end
end)
if not ok then
core.log.warn("report machine instance info occur error ---> ",result)
end
args.isExcuting = false
return
end
-- 上报具体应用信息
local function reportInfo(args)
if args.isExcuting then
return
end
args.isExcuting = true
local ok,result = pcall(function()
ngx_update_time()
local now_time = ngx_time()
core.log.warn("plugin#info-report --- > report info application ",args.name," ,now_time : " ,os_date("%Y-%m-%d_%H-%M-%S",now_time))
if args.name == "waf" then
-- 将waf所需信息存入etcd中
wafupdate.insertInfo(fwd_dc,ip)
end
end)
if not ok then
core.log.warn("report waf info occur error ---> ", result)
end
args.isExcuting = false
end
local function reportInstanceStarting(premature,args)
--core.log.warn("================= report Apisix Instance excute while apisix starting =====================")
if premature then
return
end
report_instance(args)
end
local function reportInfoStarting(premature,args)
--core.log.warn("================= report Application info excute while apisix starting =====================")
if premature then
return
end
reportInfo(args)
end
-- 解析插件配置属性,封装多个子任务
local function resolveInfo()
if not process.type() == "privileged agent" then
return true
end
-- 获取插件元数据配置信息
local attr = plugin.plugin_attr(plugin_name) or {}
ip = core.table.try_read_attr(core.config.local_conf(),"fwd","ip")
openresty_version = core.table.try_read_attr(core.config.local_conf(),"fwd","openresty_version")
fwd_dc = core.table.try_read_attr(core.config.local_conf(),"fwd","dc")
if (not ip) or (not openresty_version) or (not fwd_dc ) then
core.log.warn("APISIX instance required info is incomplete,info include : IP FWD_DC openresty_version")
return false
end
isExcuteStarting = attr.isExcuteStarting or isExcuteStarting
startTime = attr.startTime
local applications = attr.applications
local index = 1
if applications then
for k,v in pairs(applications) do
local taskThread = {}
taskThread.rotate_time = startTime
taskThread.interval = v.interval or INTERVAL
taskThread.f = reportInfo
local args = {}
args.name = k
taskThread.args = args
taskThreads[index] = taskThread
index = index + 1
end
end
local taskThread = {}
taskThread.rotate_time = startTime
taskThread.interval = attr.instance_interval or INTERVAL
taskThread.f = report_instance
taskThread.args = {}
instance_taskThreads[1] = taskThread
return true
end
function _M.init()
-- 让定时器开始启动
rotateutil.startRotate()
resolveResult = resolveInfo()
if not resolveResult then
core.log.error("plugin " .. plugin_name .. " atttr occur error,please check !")
return
end
-- 将这个插件的应用任务添加进定时器
rotateutil.register_task("plugin#info-report#instance",true,instance_taskThreads)
rotateutil.register_task("plugin#info-report",true,taskThreads)
-- 启动时默认执行
if isExcuteStarting and process.type() == "privileged agent" then
rotateutil.excuteWhileStart(reportInstanceStarting,instance_taskThreads)
rotateutil.excuteWhileStart(reportInfoStarting,taskThreads)
end
end
function _M.destroy()
if not resolveResult then
return
end
rotateutil.unregister_task("plugin#info-report#instance",true)
rotateutil.unregister_task("plugin#info-report",true)
end
local function getCacheInfo()
core.log.warn("获取当前缓存路由和证书信息")
-- 获取访问apisix admin api的token
local result = {}
local routes = {}
local ssls = {}
--路由信息
local routesvalues = router.router_http.user_routes.values
routesvalues = json_decode(core.json.encode(routesvalues,true))
for k, v in pairs(routesvalues) do
if v and type(v) == "table" then
local value = v.value
if value and type(value) == "table" then
table.insert(routes,value)
end
end
end
--证书信息
local sslsvalues, sslsversion = router.router_ssl.ssls()
sslsvalues = json_decode(core.json.encode(sslsvalues,true))
for k, v in pairs(sslsvalues) do
if v and type(v) == "table" then
local value = v.value
local sslInfo = {}
if value and type(value) == "table" then
sslInfo.id = value.id
sslInfo.snis = value.snis
sslInfo.status = value.status
sslInfo.validity_end = value.validity_end
table.insert(ssls,sslInfo)
end
end
end
result.routes = routes
result.ssls = ssls
return 200, result
end
function _M.control_api()
return {
{
methods = { "GET" },
uris = { "/v1/plugin/info-report/getCacheInfo" },
handler = getCacheInfo,
}
}
end
return _M
```
通过访问 ,一般情况下是没有问题的,但是有时候就会报错
` bad argument #1 to 'json_decode' (expected 1 argument)`
难道是encode结果有问题,是不是不应该这样解析
### Environment
- APISIX version (run `apisix version`): 2.15.0
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@apisix.apache.org.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix] An-DJ commented on issue #8843: help request: use cjson.decode resolve router values failed
Posted by "An-DJ (via GitHub)" <gi...@apache.org>.
An-DJ commented on issue #8843:
URL: https://github.com/apache/apisix/issues/8843#issuecomment-1427838107
@yuqiquan It seems that you could log the encode and decode contents to further find why. Maybe the argument is missing.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@apisix.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix] shreemaan-abhishek closed issue #8843: help request: use cjson.decode resolve router values failed
Posted by "shreemaan-abhishek (via GitHub)" <gi...@apache.org>.
shreemaan-abhishek closed issue #8843: help request: use cjson.decode resolve router values failed
URL: https://github.com/apache/apisix/issues/8843
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@apisix.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [apisix] shreemaan-abhishek commented on issue #8843: help request: use cjson.decode resolve router values failed
Posted by "shreemaan-abhishek (via GitHub)" <gi...@apache.org>.
shreemaan-abhishek commented on issue #8843:
URL: https://github.com/apache/apisix/issues/8843#issuecomment-1709452897
@yuqiquan you are getting that error because in your code:
```lua
sslsvalues = json_decode(core.json.encode(sslsvalues,true))
```
`json_decode` expects one parameter, but `core.json.encode` returns two values.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@apisix.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org