local helpers = require "spec.helpers" local uuid = require "kong.tools.uuid" local cjson = require "cjson" local strip = require("kong.tools.string").strip local splitn = require("kong.tools.string").splitn for _, strategy in helpers.each_strategy() do describe("Plugin: syslog (log) [#" .. strategy .. "]", function() local proxy_client local proxy_client_grpc local platform lazy_setup(function() local bp = helpers.get_db_utils(strategy, { "routes", "services", "plugins", }) local route1 = bp.routes:insert { hosts = { "logging.test" }, } local route2 = bp.routes:insert { hosts = { "logging2.test" }, } local route3 = bp.routes:insert { hosts = { "logging3.test" }, } local route4 = bp.routes:insert { hosts = { "logging4.test" }, } bp.plugins:insert { route = { id = route1.id }, name = "syslog", config = { log_level = "info", successful_severity = "warning", client_errors_severity = "warning", server_errors_severity = "warning", }, } bp.plugins:insert { route = { id = route2.id }, name = "syslog", config = { log_level = "err", successful_severity = "warning", client_errors_severity = "warning", server_errors_severity = "warning", }, } bp.plugins:insert { route = { id = route3.id }, name = "syslog", config = { log_level = "warning", successful_severity = "warning", client_errors_severity = "warning", server_errors_severity = "warning", }, } bp.plugins:insert { route = { id = route4.id }, name = "syslog", config = { log_level = "warning", successful_severity = "warning", client_errors_severity = "warning", server_errors_severity = "warning", custom_fields_by_lua = { new_field = "return 123", route = "return nil", -- unset route field }, }, } -- grpc [[ local grpc_service = bp.services:insert { name = "grpc-service", url = helpers.grpcbin_url, } local grpc_route1 = bp.routes:insert { service = grpc_service, hosts = { "grpc_logging.test" }, } local grpc_route2 = bp.routes:insert { service = grpc_service, hosts = { "grpc_logging2.test" }, } local grpc_route3 = bp.routes:insert { service = grpc_service, hosts = { "grpc_logging3.test" }, } bp.plugins:insert { route = { id = grpc_route1.id }, name = "syslog", config = { log_level = "info", successful_severity = "warning", client_errors_severity = "warning", server_errors_severity = "warning", }, } bp.plugins:insert { route = { id = grpc_route2.id }, name = "syslog", config = { log_level = "err", successful_severity = "warning", client_errors_severity = "warning", server_errors_severity = "warning", }, } bp.plugins:insert { route = { id = grpc_route3.id }, name = "syslog", config = { log_level = "warning", successful_severity = "warning", client_errors_severity = "warning", server_errors_severity = "warning", }, } -- grpc ]] local ok, _, stdout = helpers.execute("uname") assert(ok, "failed to retrieve platform name") platform = strip(stdout) assert(helpers.start_kong({ database = strategy, nginx_conf = "spec/fixtures/custom_nginx.template", })) proxy_client_grpc = helpers.proxy_client_grpc() end) lazy_teardown(function() helpers.stop_kong() end) before_each(function() proxy_client = assert(helpers.proxy_client()) end) after_each(function() if proxy_client then proxy_client:close() end end) local function do_test(host, expecting_same, grpc) local uuid = uuid.uuid() local ok, resp if not grpc then local response = assert(proxy_client:send { method = "GET", path = "/request", headers = { host = host, sys_log_uuid = uuid, } }) assert.res_status(200, response) else ok, resp = proxy_client_grpc({ service = "hello.HelloService.SayHello", body = { greeting = "world!" }, opts = { [" -H"] = "'Content-Type: text/plain'", ["-H"] = "'sys_log_uuid: " .. uuid .. "'", ["-authority"] = ("%s"):format(host), } }) assert.truthy(ok, resp) assert.truthy(resp) end if platform == "Darwin" then local _, _, stdout = assert(helpers.execute("syslog -k Sender kong | tail -1")) local msg = string.match(stdout, "{.*}") local json = cjson.decode(msg) if expecting_same then assert.equal(uuid, json.request.headers["sys-log-uuid"]) else assert.not_equal(uuid, json.request.headers["sys-log-uuid"]) end resp = stdout elseif expecting_same then -- wait for file writing helpers.pwait_until(function() local _, _, stdout = assert(helpers.execute("sudo find /var/log -type f -mmin -5 | grep syslog")) assert.True(#stdout > 0) local files, count = splitn(stdout, "\n") assert.True(count > 0) if files[count] == "" then table.remove(files) end local tmp = {} -- filter out suspicious files for _, file in ipairs(files) do local _, stderr, stdout = assert(helpers.execute("file " .. file)) assert(stdout, stderr) assert.True(#stdout > 0, stderr) --[[ to avoid file like syslog.2.gz because syslog must be a text file --]] if stdout:find("text", 1, true) then table.insert(tmp, file) end end files = tmp local matched = false for _, file in ipairs(files) do --[[ we have to run grep with sudo on Github Action because of the `Permission denied` error -- ]] local cmd = string.format("sudo grep '\"sys_log_uuid\":\"%s\"' %s", uuid, file) local ok, _, stdout = helpers.execute(cmd) if ok then matched = true resp = stdout break end end assert(matched, "uuid not found in syslog") end, 5) end return resp end it("logs to syslog if log_level is lower", function() do_test("logging.test", true) end) it("does not log to syslog if log_level is higher", function() do_test("logging2.test", false) end) it("logs to syslog if log_level is the same", function() do_test("logging3.test", true) end) it("logs custom values", function() local resp = do_test("logging4.test", true) assert.matches("\"new_field\".*123", resp) assert.not_matches("\"route\"", resp) end) it("logs to syslog if log_level is lower #grpc", function() do_test("grpc_logging.test", true, true) end) it("does not log to syslog if log_level is higher #grpc", function() do_test("grpc_logging2.test", false, true) end) it("logs to syslog if log_level is the same #grpc", function() do_test("grpc_logging3.test", true, true) end) end) end