Software /
code /
prosody
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 |
parent | 977:6f0bdf9e4dfb |
child | 1020: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; |