Let Google Hangouts contacts appear offline
[prosody.git] / util / logger.lua
1 -- Prosody IM
2 -- Copyright (C) 2008-2010 Matthew Wild
3 -- Copyright (C) 2008-2010 Waqas Hussain
4 -- 
5 -- This project is MIT/X11 licensed. Please see the
6 -- COPYING file in the source package for more information.
7 --
8
9 local pcall = pcall;
10
11 local find = string.find;
12 local ipairs, pairs, setmetatable = ipairs, pairs, setmetatable;
13
14 module "logger"
15
16 local name_sinks, level_sinks = {}, {};
17 local name_patterns = {};
18
19 local make_logger;
20
21 function init(name)
22         local log_debug = make_logger(name, "debug");
23         local log_info = make_logger(name, "info");
24         local log_warn = make_logger(name, "warn");
25         local log_error = make_logger(name, "error");
26
27         --name = nil; -- While this line is not commented, will automatically fill in file/line number info
28         local namelen = #name;
29         return function (level, message, ...)
30                         if level == "debug" then
31                                 return log_debug(message, ...);
32                         elseif level == "info" then
33                                 return log_info(message, ...);
34                         elseif level == "warn" then
35                                 return log_warn(message, ...);
36                         elseif level == "error" then
37                                 return log_error(message, ...);
38                         end
39                 end
40 end
41
42 function make_logger(source_name, level)
43         local level_handlers = level_sinks[level];
44         if not level_handlers then
45                 level_handlers = {};
46                 level_sinks[level] = level_handlers;
47         end
48
49         local source_handlers = name_sinks[source_name];
50         
51         local logger = function (message, ...)
52                 if source_handlers then
53                         for i = 1,#source_handlers do
54                                 if source_handlers[i](source_name, level, message, ...) == false then
55                                         return;
56                                 end
57                         end
58                 end
59                 
60                 for i = 1,#level_handlers do
61                         level_handlers[i](source_name, level, message, ...);
62                 end
63         end
64
65         return logger;
66 end
67
68 function reset()
69         for k in pairs(name_sinks) do name_sinks[k] = nil; end
70         for level, handler_list in pairs(level_sinks) do
71                 -- Clear all handlers for this level
72                 for i = 1, #handler_list do
73                         handler_list[i] = nil;
74                 end
75         end
76         for k in pairs(name_patterns) do name_patterns[k] = nil; end
77 end
78
79 function add_level_sink(level, sink_function)
80         if not level_sinks[level] then
81                 level_sinks[level] = { sink_function };
82         else
83                 level_sinks[level][#level_sinks[level] + 1 ] = sink_function;
84         end
85 end
86
87 function add_name_sink(name, sink_function, exclusive)
88         if not name_sinks[name] then
89                 name_sinks[name] = { sink_function };
90         else
91                 name_sinks[name][#name_sinks[name] + 1] = sink_function;
92         end
93 end
94
95 function add_name_pattern_sink(name_pattern, sink_function, exclusive)
96         if not name_patterns[name_pattern] then
97                 name_patterns[name_pattern] = { sink_function };
98         else
99                 name_patterns[name_pattern][#name_patterns[name_pattern] + 1] = sink_function;
100         end
101 end
102
103 _M.new = make_logger;
104
105 return _M;