diff options
Diffstat (limited to 'lua/99/logger/logger.lua')
| -rw-r--r-- | lua/99/logger/logger.lua | 351 |
1 files changed, 175 insertions, 176 deletions
diff --git a/lua/99/logger/logger.lua b/lua/99/logger/logger.lua index fdc010a..b2dc37b 100644 --- a/lua/99/logger/logger.lua +++ b/lua/99/logger/logger.lua @@ -17,29 +17,29 @@ local max_requests_in_logger_cache = MAX_REQUEST_DEFAULT --- @param ... any --- @return table<string, any> local function to_args(...) - local count = select("#", ...) - local out = {} - assert( - count % 2 == 0, - "you cannot call logging with an odd number of args. e.g: msg, [k, v]..." - ) - for i = 1, count, 2 do - local key = select(i, ...) - local value = select(i + 1, ...) - assert(type(key) == "string", "keys in logging must be strings") - assert(out[key] == nil, "key collision in logs: " .. key) - out[key] = value - end - return out + local count = select("#", ...) + local out = {} + assert( + count % 2 == 0, + "you cannot call logging with an odd number of args. e.g: msg, [k, v]..." + ) + for i = 1, count, 2 do + local key = select(i, ...) + local value = select(i + 1, ...) + assert(type(key) == "string", "keys in logging must be strings") + assert(out[key] == nil, "key collision in logs: " .. key) + out[key] = value + end + return out end --- @param log_statement table<string, any> --- @param args table<string, any> local function put_args(log_statement, args) - for k, v in pairs(args) do - assert(log_statement[k] == nil, "key collision in logs: " .. k) - log_statement[k] = v - end + for k, v in pairs(args) do + assert(log_statement[k] == nil, "key collision in logs: " .. k) + log_statement[k] = v + end end --- @class LoggerSink @@ -50,12 +50,12 @@ local VoidSink = {} VoidSink.__index = VoidSink function VoidSink.new() - return setmetatable({}, VoidSink) + return setmetatable({}, VoidSink) end --- @param _ string function VoidSink:write_line(_) - _ = self + _ = self end --- @class FileSink : LoggerSink @@ -66,23 +66,23 @@ FileSink.__index = FileSink --- @param path string --- @return LoggerSink function FileSink:new(path) - local fd, err = vim.uv.fs_open(path, "w", 493) - if not fd then - error("unable to file sink", err) - end + local fd, err = vim.uv.fs_open(path, "w", 493) + if not fd then + error("unable to file sink", err) + end - return setmetatable({ - fd = fd, - }, self) + return setmetatable({ + fd = fd, + }, self) end --- @param str string function FileSink:write_line(str) - local success, err = vim.uv.fs_write(self.fd, str .. "\n") - if not success then - error("unable to write to file sink", err) - end - vim.uv.fs_fsync(self.fd) + local success, err = vim.uv.fs_write(self.fd, str .. "\n") + if not success then + error("unable to write to file sink", err) + end + vim.uv.fs_fsync(self.fd) end --- @class PrintSink : LoggerSink @@ -91,13 +91,13 @@ PrintSink.__index = PrintSink --- @return LoggerSink function PrintSink:new() - return setmetatable({}, self) + return setmetatable({}, self) end --- @param str string function PrintSink:write_line(str) - local _ = self - print(str) + local _ = self + print(str) end --- @class _99.Logger.RequestLogs @@ -115,259 +115,258 @@ Logger.__index = Logger --- @param level number? --- @return _99.Logger function Logger:new(level) - level = level or levels.FATAL - return setmetatable({ - sink = VoidSink:new(), - level = level, - print_on_error = false, - extra_params = {}, - }, self) + level = level or levels.FATAL + return setmetatable({ + sink = VoidSink:new(), + level = level, + print_on_error = false, + extra_params = {}, + }, self) end --- @return _99.Logger function Logger:clone() - local params = {} - for k, v in pairs(self.extra_params) do - params[k] = v - end - return setmetatable({ - sink = self.sink, - level = self.level, - print_on_error = self.print_on_error, - extra_params = params, - }, Logger) + local params = {} + for k, v in pairs(self.extra_params) do + params[k] = v + end + return setmetatable({ + sink = self.sink, + level = self.level, + print_on_error = self.print_on_error, + extra_params = params, + }, Logger) end --- @param path string --- @return _99.Logger function Logger:file_sink(path) - self.sink = FileSink:new(path) - return self + self.sink = FileSink:new(path) + return self end --- @return _99.Logger function Logger:void_sink() - self.sink = VoidSink:new() - return self + self.sink = VoidSink:new() + return self end --- @return _99.Logger function Logger:print_sink() - self.sink = PrintSink:new() - return self + self.sink = PrintSink:new() + return self end --- @param area string --- @return _99.Logger function Logger:set_area(area) - local new_logger = self:clone() - new_logger.extra_params["Area"] = area - return new_logger + local new_logger = self:clone() + new_logger.extra_params["Area"] = area + return new_logger end --- @param xid number --- @return _99.Logger function Logger:set_id(xid) - local new_logger = self:clone() - new_logger.extra_params["id"] = xid - return new_logger + local new_logger = self:clone() + new_logger.extra_params["id"] = xid + return new_logger end --- @param level number --- @return _99.Logger function Logger:set_level(level) - self.level = level - return self + self.level = level + return self end --- @return _99.Logger function Logger:on_error_print_message() - self.print_on_error = true - return self + self.print_on_error = true + return self end --- @param opts _99.Logger.Options? function Logger:configure(opts) - if not opts then - return - end + if not opts then + return + end - if opts.level then - self:set_level(opts.level) - end + if opts.level then + self:set_level(opts.level) + end - if opts.type == "print" then - self:print_sink() - elseif opts.type == "file" then - assert( - opts.path, - "if you choose file for logger, you must have a path specified" - ) - self:file_sink(opts.path) - else - self:void_sink() - end + if opts.type == "print" then + self:print_sink() + elseif opts.type == "file" then + assert( + opts.path, + "if you choose file for logger, you must have a path specified" + ) + self:file_sink(opts.path) + else + self:void_sink() + end - if opts.print_on_error then - self:on_error_print_message() - end + if opts.print_on_error then + self:on_error_print_message() + end - max_requests_in_logger_cache = opts.max_requests_cached - or MAX_REQUEST_DEFAULT + max_requests_in_logger_cache = opts.max_requests_cached or MAX_REQUEST_DEFAULT end --- @param line string function Logger:_cache_log(line) - local id = self.extra_params.id - if not id then - return - end + local id = self.extra_params.id + if not id then + return + end - local cache = logger_cache[id] - local new_cache = false - if not cache then - cache = { - last_access = time.now(), - logs = {}, - } - logger_cache[id] = cache - table.insert(logger_list, id) - new_cache = true - end - cache.last_access = time.now() - table.insert(cache.logs, line) - table.sort(logger_list, function(a, b) - assert( - logger_cache[a] and logger_cache[b], - "logger list is out of sync with logger cache: " - .. tostring(a) - .. " and " - .. tostring(b) - ) - local a_time = logger_cache[a].last_access - local b_time = logger_cache[b].last_access - return a_time > b_time - end) + local cache = logger_cache[id] + local new_cache = false + if not cache then + cache = { + last_access = time.now(), + logs = {}, + } + logger_cache[id] = cache + table.insert(logger_list, id) + new_cache = true + end + cache.last_access = time.now() + table.insert(cache.logs, line) + table.sort(logger_list, function(a, b) + assert( + logger_cache[a] and logger_cache[b], + "logger list is out of sync with logger cache: " + .. tostring(a) + .. " and " + .. tostring(b) + ) + local a_time = logger_cache[a].last_access + local b_time = logger_cache[b].last_access + return a_time > b_time + end) - if not new_cache then - return - end + if not new_cache then + return + end - Logger._trim_cache() + Logger._trim_cache() end --- This is a _TEST ONLY_ function. you should not call this function outside --- of unit tests function Logger.reset() - logger_cache = {} - max_requests_in_logger_cache = MAX_REQUEST_DEFAULT + logger_cache = {} + max_requests_in_logger_cache = MAX_REQUEST_DEFAULT end --- @return string[][] function Logger.logs() - local out = {} - for _, id in ipairs(logger_list) do - local request_logs = logger_cache[id] - table.insert(out, request_logs.logs) - end - return out + local out = {} + for _, id in ipairs(logger_list) do + local request_logs = logger_cache[id] + table.insert(out, request_logs.logs) + end + return out end --- @param level number ---@param msg string ---@param ... any function Logger:_log(level, msg, ...) - if self.level > level then - return - end + if self.level > level then + return + end - local log_statement = { - level = levels.levelToString(level), - msg = msg, - } + local log_statement = { + level = levels.levelToString(level), + msg = msg, + } - put_args(log_statement, to_args(...)) - put_args(log_statement, self.extra_params) + put_args(log_statement, to_args(...)) + put_args(log_statement, self.extra_params) - assert(log_statement["id"], "every log must have an id associated with it") + assert(log_statement["id"], "every log must have an id associated with it") - local json_string = vim.json.encode(log_statement) - if self.print_on_error and level == levels.ERROR then - print(json_string) - end + local json_string = vim.json.encode(log_statement) + if self.print_on_error and level == levels.ERROR then + print(json_string) + end - self:_cache_log(json_string) - self.sink:write_line(json_string) + self:_cache_log(json_string) + self.sink:write_line(json_string) end --- @param msg string --- @param ... any function Logger:info(msg, ...) - self:_log(levels.INFO, msg, ...) + self:_log(levels.INFO, msg, ...) end --- @param msg string --- @param ... any function Logger:warn(msg, ...) - self:_log(levels.WARN, msg, ...) + self:_log(levels.WARN, msg, ...) end --- @param msg string --- @param ... any function Logger:debug(msg, ...) - self:_log(levels.DEBUG, msg, ...) + self:_log(levels.DEBUG, msg, ...) end --- @param msg string --- @param ... any function Logger:error(msg, ...) - self:_log(levels.ERROR, msg, ...) + self:_log(levels.ERROR, msg, ...) end --- @param msg string --- @param ... any function Logger:fatal(msg, ...) - self:_log(levels.FATAL, msg, ...) - assert(false, "fatal msg recieved: " .. msg, ...) + self:_log(levels.FATAL, msg, ...) + assert(false, "fatal msg recieved: " .. msg, ...) end --- @param test any ---@param msg string ---@param ... any function Logger:assert(test, msg, ...) - if not test then - self:fatal(msg, ...) - end + if not test then + self:fatal(msg, ...) + end end function Logger._trim_cache() - local count = 0 - local oldest = nil - local oldest_key = nil - for k, log in pairs(logger_cache) do - if oldest == nil or log.last_access < oldest.last_access then - oldest = log - oldest_key = k - end - count = count + 1 + local count = 0 + local oldest = nil + local oldest_key = nil + for k, log in pairs(logger_cache) do + if oldest == nil or log.last_access < oldest.last_access then + oldest = log + oldest_key = k end + count = count + 1 + end - if count > max_requests_in_logger_cache then - assert(oldest_key, "oldest key must exist") - logger_cache[oldest_key] = nil + if count > max_requests_in_logger_cache then + assert(oldest_key, "oldest key must exist") + logger_cache[oldest_key] = nil - for i, id in ipairs(logger_list) do - if id == oldest_key then - table.remove(logger_list, i) - break - end - end + for i, id in ipairs(logger_list) do + if id == oldest_key then + table.remove(logger_list, i) + break + end end + end end function Logger.set_max_cached_requests(count) - max_requests_in_logger_cache = count - Logger._trim_cache() + max_requests_in_logger_cache = count + Logger._trim_cache() end local module_logger = Logger:new(levels.DEBUG) |
