Mercurial > prosody-hg
comparison util/logger.lua @ 1015:9e31e9397cff
util.logger: Revamped logger library, but backwards-compatible for users of logger.init()
| author | Matthew Wild <mwild1@gmail.com> |
|---|---|
| date | Tue, 21 Apr 2009 03:18:13 +0100 |
| parents | 6f0bdf9e4dfb |
| children | 8bf71f8bd0d1 |
comparison
equal
deleted
inserted
replaced
| 1007:c500d4cb7855 | 1015:9e31e9397cff |
|---|---|
| 4 -- | 4 -- |
| 5 -- This project is MIT/X11 licensed. Please see the | 5 -- This project is MIT/X11 licensed. Please see the |
| 6 -- COPYING file in the source package for more information. | 6 -- COPYING file in the source package for more information. |
| 7 -- | 7 -- |
| 8 | 8 |
| 9 local format, rep = string.format, string.rep; | |
| 10 local io_write = io.write; | |
| 11 local pcall = pcall; | 9 local pcall = pcall; |
| 12 local debug = debug; | |
| 13 local tostring = tostring; | |
| 14 local math_max = math.max; | |
| 15 | 10 |
| 16 local config = require "core.configmanager"; | 11 local config = require "core.configmanager"; |
| 17 local log_sources = config.get("*", "core", "log_sources"); | 12 local log_sources = config.get("*", "core", "log_sources"); |
| 18 | 13 |
| 19 local getstyle, getstring = require "util.termcolours".getstyle, require "util.termcolours".getstring; | |
| 20 local do_pretty_printing = not os.getenv("WINDIR"); | |
| 21 local find = string.find; | 14 local find = string.find; |
| 22 local ipairs = ipairs; | 15 local ipairs, pairs, setmetatable = ipairs, pairs, setmetatable; |
| 23 | 16 |
| 24 module "logger" | 17 module "logger" |
| 25 | 18 |
| 26 local logstyles = {}; | 19 local name_sinks, level_sinks = {}, {}; |
| 20 local name_patterns = {}; | |
| 27 | 21 |
| 28 --TODO: This should be done in config, but we don't have proper config yet | 22 -- Weak-keyed so that loggers are collected |
| 29 if do_pretty_printing then | 23 local modify_hooks = setmetatable({}, { __mode = "k" }); |
| 30 logstyles["info"] = getstyle("bold"); | |
| 31 logstyles["warn"] = getstyle("bold", "yellow"); | |
| 32 logstyles["error"] = getstyle("bold", "red"); | |
| 33 end | |
| 34 | 24 |
| 35 local sourcewidth = 20; | 25 local make_logger; |
| 36 | |
| 37 local outfunction = nil; | 26 local outfunction = nil; |
| 38 | 27 |
| 39 function init(name) | 28 function init(name) |
| 40 if log_sources then | 29 if log_sources then |
| 41 local log_this = false; | 30 local log_this = false; |
| 47 end | 36 end |
| 48 | 37 |
| 49 if not log_this then return function () end end | 38 if not log_this then return function () end end |
| 50 end | 39 end |
| 51 | 40 |
| 41 local log_debug = make_logger(name, "debug"); | |
| 42 local log_info = make_logger(name, "info"); | |
| 43 local log_warn = make_logger(name, "warn"); | |
| 44 local log_error = make_logger(name, "error"); | |
| 45 | |
| 52 --name = nil; -- While this line is not commented, will automatically fill in file/line number info | 46 --name = nil; -- While this line is not commented, will automatically fill in file/line number info |
| 53 local namelen = #name; | 47 local namelen = #name; |
| 54 return function (level, message, ...) | 48 return function (level, message, ...) |
| 55 if outfunction then return outfunction(name, level, message, ...); end | 49 if outfunction then return outfunction(name, level, message, ...); end |
| 56 | 50 |
| 57 sourcewidth = math_max(#name+2, sourcewidth); | 51 if level == "debug" then |
| 58 if ... then | 52 return log_debug(message, ...); |
| 59 io_write(name, rep(" ", sourcewidth-namelen), getstring(logstyles[level], level), "\t", format(message, ...), "\n"); | 53 elseif level == "info" then |
| 60 else | 54 return log_info(message, ...); |
| 61 io_write(name, rep(" ", sourcewidth-namelen), getstring(logstyles[level], level), "\t", message, "\n"); | 55 elseif level == "warn" then |
| 56 return log_warn(message, ...); | |
| 57 elseif level == "error" then | |
| 58 return log_error(message, ...); | |
| 59 end | |
| 60 end | |
| 61 end | |
| 62 | |
| 63 function make_logger(source_name, level) | |
| 64 local level_handlers = level_sinks[level]; | |
| 65 if not level_handlers then | |
| 66 level_handlers = {}; | |
| 67 level_sinks[level] = level_handlers; | |
| 68 end | |
| 69 | |
| 70 local source_handlers = name_sinks[source_name]; | |
| 71 | |
| 72 -- All your premature optimisation is belong to me! | |
| 73 local num_level_handlers, num_source_handlers = #level_handlers, source_handlers and #source_handlers; | |
| 74 | |
| 75 local logger = function (message, ...) | |
| 76 if source_handlers then | |
| 77 for i = 1,num_source_handlers do | |
| 78 if source_handlers(source_name, level, message, ...) == false then | |
| 79 return; | |
| 62 end | 80 end |
| 63 end | 81 end |
| 82 end | |
| 83 | |
| 84 for i = 1,num_level_handlers do | |
| 85 level_handlers[i](source_name, level, message, ...); | |
| 86 end | |
| 87 end | |
| 88 | |
| 89 -- To make sure our cached lengths stay in sync with reality | |
| 90 modify_hooks[logger] = function () num_level_handlers, num_source_handlers = #level_handlers, source_handlers and #source_handlers; end; | |
| 91 | |
| 92 return logger; | |
| 64 end | 93 end |
| 65 | 94 |
| 66 function setwriter(f) | 95 function setwriter(f) |
| 67 local old_func = outfunction; | 96 local old_func = outfunction; |
| 68 if not f then outfunction = nil; return true, old_func; end | 97 if not f then outfunction = nil; return true, old_func; end |
| 72 ret = old_func; | 101 ret = old_func; |
| 73 end | 102 end |
| 74 return ok, ret; | 103 return ok, ret; |
| 75 end | 104 end |
| 76 | 105 |
| 106 function add_level_sink(level, sink_function) | |
| 107 if not level_sinks[level] then | |
| 108 level_sinks[level] = { sink_function }; | |
| 109 else | |
| 110 level_sinks[level][#level_sinks[level] + 1 ] = sink_function; | |
| 111 end | |
| 112 | |
| 113 for _, modify_hook in pairs(modify_hooks) do | |
| 114 modify_hook(); | |
| 115 end | |
| 116 end | |
| 117 | |
| 118 function add_name_sink(name, sink_function, exclusive) | |
| 119 if not name_sinks[name] then | |
| 120 name_sinks[name] = { sink_function }; | |
| 121 else | |
| 122 name_sinks[name][#name_sinks[name] + 1] = sink_function; | |
| 123 end | |
| 124 | |
| 125 for _, modify_hook in pairs(modify_hooks) do | |
| 126 modify_hook(); | |
| 127 end | |
| 128 end | |
| 129 | |
| 130 function add_name_pattern_sink(name_pattern, sink_function, exclusive) | |
| 131 if not name_patterns[name_pattern] then | |
| 132 name_patterns[name_pattern] = { sink_function }; | |
| 133 else | |
| 134 name_patterns[name_pattern][#name_patterns[name_pattern] + 1] = sink_function; | |
| 135 end | |
| 136 end | |
| 137 | |
| 138 _M.new = make_logger; | |
| 139 | |
| 77 return _M; | 140 return _M; |
