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-- luacheck: ignore 213/level
9
10local pairs = pairs;
11local ipairs = ipairs;
12local require = require;
13
14local _ENV = nil;
15-- luacheck: std none
16
17local level_sinks = {};
18
19local make_logger;
20
21local 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	return function (level, message, ...)
28			if level == "debug" then
29				return log_debug(message, ...);
30			elseif level == "info" then
31				return log_info(message, ...);
32			elseif level == "warn" then
33				return log_warn(message, ...);
34			elseif level == "error" then
35				return log_error(message, ...);
36			end
37		end
38end
39
40function make_logger(source_name, level)
41	local level_handlers = level_sinks[level];
42	if not level_handlers then
43		level_handlers = {};
44		level_sinks[level] = level_handlers;
45	end
46
47	local logger = function (message, ...)
48		for i = 1,#level_handlers do
49			level_handlers[i](source_name, level, message, ...);
50		end
51	end
52
53	return logger;
54end
55
56local function reset()
57	for level, handler_list in pairs(level_sinks) do
58		-- Clear all handlers for this level
59		for i = 1, #handler_list do
60			handler_list[i] = nil;
61		end
62	end
63end
64
65local function add_level_sink(level, sink_function)
66	if not level_sinks[level] then
67		level_sinks[level] = { sink_function };
68	else
69		level_sinks[level][#level_sinks[level] + 1 ] = sink_function;
70	end
71end
72
73local function add_simple_sink(simple_sink_function, levels)
74	local format = require "util.format".format;
75	local function sink_function(name, level, msg, ...)
76		return simple_sink_function(name, level, format(msg, ...));
77	end
78	for _, level in ipairs(levels or {"debug", "info", "warn", "error"}) do
79		add_level_sink(level, sink_function);
80	end
81end
82
83return {
84	init = init;
85	make_logger = make_logger;
86	reset = reset;
87	add_level_sink = add_level_sink;
88	add_simple_sink = add_simple_sink;
89	new = make_logger;
90};
91