| 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; |