Welp as the name states I been thinking about taking a crack at logging with a web-socket connection using this lib: https://github.com/openresty/lua-resty-websocket, my plugin ended up being a morph of the http logger(to format the data) and websocket logic:
schema.lua
return {
fields = {
websocket_connect = { required = true, default = "wss://<host>:<port>/<path>", type="string"}
}
}
handler.lua
local basic_serializer = require "kong.plugins.kong-websocket-log.basic"
local BasePlugin = require "kong.plugins.base_plugin"
local cjson = require "cjson"
local client = require "resty.websocket.client"
local string_format = string.format
local cjson_encode = cjson.encode
local KongWebSocketLog = BasePlugin:extend()
KongWebSocketLog.PRIORITY = 12
KongWebSocketLog.VERSION = "0.1.0"
local function log(premature, conf, body, name)
if premature then
return
end
name = "[" .. name .. "] "
if kong.ctx.plugin.wb_status == nil then
local kong.ctx.plugin.wb, err = client:new()
local ok, err = kong.ctx.plugin.wb:connect(conf.websocket_connect)
if not ok then
ngx.log(ngx.ERR, name .. "failed to connect: " .. err)
kong.ctx.plugin.wb_status = nil
return
else
kong.ctx.plugin.wb_status = "success"
end
end
--Already have active websocket connection
if kong.ctx.plugin.wb_status == "success" then
local bytes, err = kong.ctx.plugin.wb:send_text(data)
if not bytes then
ngx.log(ngx.ERR, name .. "failed to send frame: ", err)
kong.ctx.plugin.wb_status = nil
return
end
end
end
function KongWebSocketLog:new(name)
KongWebSocketLog.super.new(self, name or "kong-websocket-log")
end
function KongWebSocketLog:serialize(ngx, conf)
return cjson_encode(basic_serializer.serialize(ngx))
end
function KongWebSocketLog:log(conf)
KongWebSocketLog.super.log(self)
local ok, err = ngx.timer.at(0, log, conf, self:serialize(ngx, conf), self._name)
if not ok then
ngx.log(ngx.ERR, "[" .. self._name .. "] failed to create timer: ", err)
end
end
return KongWebSocketLog
Basically my goal in mind is for the Kong node to share 1 active websocket connection for the plugin to utilize for high throughput of logging API transactions. Do we think this will work or need more tweaks? I will be testing it out probably over the next few days.
Other enhancements I may make: additional options, possible timeout configuration.
Once its working will open source in a repo and get it out there for the world .