Files
koreader/frontend/logger.lua
NiLuJe 5c24470ea9 Logger: Use serpent instead of dump (#9588)
* Persist: support serpent, and use by default over dump (as we assume consistency > readability in Persist).
* Logger/Dbg: Use serpent instead of dump to dump tables (it's slightly more compact, honors __tostring, and will tag tables with their ref, which can come in handy when debugging).
* Dbg: Don't duplicate Logger's log function, just use it directly.
* Fontlist/ConfigDialog: Use serpent for the debug dump.
* Call `os.setlocale(C, "numeric")` on startup instead of peppering it around dump calls. It's process-wide, so it didn't make much sense.
* Trapper: Use LuaJIT's serde facilities instead of dump. They're more reliable in the face of funky input, much faster, and in this case, the data never makes it to human eyes, so a human-readable format didn't gain us anything.
2022-10-06 02:21:03 +02:00

124 lines
2.9 KiB
Lua

--[[--
Logger module.
See @{Logger.levels} for list of supported levels.
Example:
local logger = require("logger")
logger.info("Something happened.")
logger.err("House is on fire!")
]]
local serpent = require("ffi/serpent")
local isAndroid, android = pcall(require, "android")
local DEFAULT_DUMP_LVL = 10
--- Supported logging levels
-- @table Logger.levels
-- @field dbg debug
-- @field info informational (default level)
-- @field warn warning
-- @field err error
local LOG_LVL = {
dbg = 1,
info = 2,
warn = 3,
err = 4,
}
local LOG_PREFIX = {
dbg = "DEBUG",
info = "INFO ",
warn = "WARN ",
err = "ERROR",
}
local noop = function() end
local serpent_opts = {
maxlevel = DEFAULT_DUMP_LVL,
indent = " ",
nocode = true,
}
local Logger = {
levels = LOG_LVL,
}
local log
if isAndroid then
local ANDROID_LOG_FNS = {
dbg = android.LOGV,
info = android.LOGI,
warn = android.LOGW,
err = android.LOGE,
}
log = function(log_lvl, ...)
local line = {}
for _, v in ipairs({...}) do
if type(v) == "table" then
table.insert(line, serpent.block(v, serpent_opts))
else
table.insert(line, tostring(v))
end
end
return ANDROID_LOG_FNS[log_lvl](table.concat(line, " "))
end
else
log = function(log_lvl, ...)
local line = {
os.date("%x-%X"),
LOG_PREFIX[log_lvl],
}
for _, v in ipairs({...}) do
if type(v) == "table" then
table.insert(line, serpent.block(v, serpent_opts))
else
table.insert(line, tostring(v))
end
end
-- NOTE: Either we add the LF to the table and we get an extra space before it because of table.concat,
-- or we pass it to write after a comma, and it generates an extra write syscall...
-- That, or just rewrite every logger call to handle spacing themselves ;).
table.insert(line, "\n")
return io.write(table.concat(line, " "))
end
end
local LVL_FUNCTIONS = {
dbg = function(...) return log("dbg", ...) end,
info = function(...) return log("info", ...) end,
warn = function(...) return log("warn", ...) end,
err = function(...) return log("err", ...) end,
}
--[[--
Set logging level. By default, level is set to info.
@int new_lvl new logging level, must be one of the levels from @{Logger.levels}
@usage
Logger:setLevel(Logger.levels.warn)
]]
function Logger:setLevel(new_lvl)
for lvl_name, lvl_value in pairs(LOG_LVL) do
if new_lvl <= lvl_value then
self[lvl_name] = LVL_FUNCTIONS[lvl_name]
else
self[lvl_name] = noop
end
end
end
-- For dbg's sake
function Logger.LvDEBUG(...)
return log("dbg", ...)
end
Logger:setLevel(LOG_LVL.info)
return Logger