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;