summaryrefslogtreecommitdiff
path: root/lua/99/logger/logger.lua
diff options
context:
space:
mode:
authorThePrimeAgain <theprimeagain@theprimeagain.com>2025-11-24 10:16:49 -0700
committerThePrimeAgain <theprimeagain@theprimeagain.com>2025-11-24 10:16:49 -0700
commit65da89fa675807e4ade0bbe7e8f8404f991ec6a9 (patch)
tree652fa4880a3a6761760feb6f6c2c604bbbf321ab /lua/99/logger/logger.lua
parent2094e1907b6dc759f6639d557e591746db60ea41 (diff)
downloada4-65da89fa675807e4ade0bbe7e8f8404f991ec6a9.tar.xz
a4-65da89fa675807e4ade0bbe7e8f8404f991ec6a9.zip
99
Diffstat (limited to 'lua/99/logger/logger.lua')
-rw-r--r--lua/99/logger/logger.lua152
1 files changed, 152 insertions, 0 deletions
diff --git a/lua/99/logger/logger.lua b/lua/99/logger/logger.lua
new file mode 100644
index 0000000..0d3a6d9
--- /dev/null
+++ b/lua/99/logger/logger.lua
@@ -0,0 +1,152 @@
+local levels = require("srs.logger.level")
+
+--- @class LoggerConfig
+--- @field type? "file" | "print"
+--- @field path? string
+--- @field level? number
+
+--- @param ... any[]
+--- @return string
+local function stringifyArgs(...)
+ 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")
+
+ if type(value) == "table" then
+ if type(value.to_string) == "function" then
+ value = value:to_string()
+ else
+ value = vim.inspect(value)
+ end
+ elseif type(value) == "string" then
+ value = string.format('"%s"', value)
+ else
+ value = tostring(value)
+ end
+
+ table.insert(out, string.format("%s=%s", key, value))
+ end
+ return table.concat(out, " ")
+end
+
+--- @class LoggerSink
+--- @field write_line fun(LoggerSink, string): nil
+
+--- @class FileSink : LoggerSink
+--- @field fd number
+local FileSink = {}
+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
+
+ 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
+end
+
+--- @class PrintSink : LoggerSink
+local PrintSink = {}
+PrintSink.__index = PrintSink
+
+--- @return LoggerSink
+function PrintSink:new()
+ return setmetatable({}, self)
+end
+
+--- @param str string
+function PrintSink:write_line(str)
+ local _ = self
+ print(str)
+end
+
+--- @class Logger
+--- @field level number
+--- @field sink LoggerSink
+local Logger = {}
+Logger.__index = Logger
+
+--- @param level number?
+function Logger:new(level)
+ level = level or levels.FATAL
+ return setmetatable({
+ sink = PrintSink:new(),
+ level = level,
+ }, self)
+end
+
+--- @param path string
+--- @return Logger
+function Logger:file_sink(path)
+ self.sink = FileSink:new(path)
+ return self
+end
+
+--- @param level number
+--- @return Logger
+function Logger:set_level(level)
+ self.level = level
+ return self
+end
+
+function Logger:_log(level, msg, ...)
+ if self.level > level then
+ return
+ end
+
+ local args = stringifyArgs(...)
+ local line = string.format("[%s]: %s %s", levels.levelToString(level), msg, args)
+ self.sink:write_line(line)
+end
+
+--- @param msg string
+--- @param ... any
+function Logger:info(msg, ...)
+ self:_log(levels.INFO, msg, ...)
+end
+
+--- @param msg string
+--- @param ... any
+function Logger:warn(msg, ...)
+ self:_log(levels.WARN, msg, ...)
+end
+
+--- @param msg string
+--- @param ... any
+function Logger:debug(msg, ...)
+ self:_log(levels.DEBUG, msg, ...)
+end
+
+--- @param msg string
+--- @param ... any
+function Logger: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")
+end
+
+local module_logger = Logger:new(levels.DEBUG)
+
+return module_logger