Software /
code /
prosody
File
util/logger.lua @ 2511:a81c710b1708
prosodyctl: Don't display message about failing to start Prosody is daemonizing is disabled (if daemonizing is disabled then Prosody is stopped by the time control returns to prosodyctl, which then can't see Prosody running)
author | Matthew Wild <mwild1@gmail.com> |
---|---|
date | Thu, 28 Jan 2010 15:05:30 +0000 |
parent | 1523:841d61be198f |
child | 2923:b7049746bd29 |
line wrap: on
line source
-- Prosody IM -- Copyright (C) 2008-2009 Matthew Wild -- Copyright (C) 2008-2009 Waqas Hussain -- -- This project is MIT/X11 licensed. Please see the -- COPYING file in the source package for more information. -- local pcall = pcall; local config = require "core.configmanager"; local log_sources = config.get("*", "core", "log_sources"); local find = string.find; local ipairs, pairs, setmetatable = ipairs, pairs, setmetatable; module "logger" local name_sinks, level_sinks = {}, {}; local name_patterns = {}; -- Weak-keyed so that loggers are collected local modify_hooks = setmetatable({}, { __mode = "k" }); local make_logger; local outfunction = nil; function init(name) if log_sources then local log_this = false; for _, source in ipairs(log_sources) do if find(name, source) then log_this = true; break; end end if not log_this then return function () end end end local log_debug = make_logger(name, "debug"); local log_info = make_logger(name, "info"); local log_warn = make_logger(name, "warn"); local log_error = make_logger(name, "error"); --name = nil; -- While this line is not commented, will automatically fill in file/line number info local namelen = #name; return function (level, message, ...) if outfunction then return outfunction(name, level, message, ...); end if level == "debug" then return log_debug(message, ...); elseif level == "info" then return log_info(message, ...); elseif level == "warn" then return log_warn(message, ...); elseif level == "error" then return log_error(message, ...); end end end function make_logger(source_name, level) local level_handlers = level_sinks[level]; if not level_handlers then level_handlers = {}; level_sinks[level] = level_handlers; end local source_handlers = name_sinks[source_name]; -- All your premature optimisation is belong to me! local num_level_handlers, num_source_handlers = #level_handlers, source_handlers and #source_handlers; local logger = function (message, ...) if source_handlers then for i = 1,num_source_handlers do if source_handlers[i](source_name, level, message, ...) == false then return; end end end for i = 1,num_level_handlers do level_handlers[i](source_name, level, message, ...); end end -- To make sure our cached lengths stay in sync with reality modify_hooks[logger] = function () num_level_handlers, num_source_handlers = #level_handlers, source_handlers and #source_handlers; end; return logger; end function setwriter(f) local old_func = outfunction; if not f then outfunction = nil; return true, old_func; end local ok, ret = pcall(f, "logger", "info", "Switched logging output successfully"); if ok then outfunction = f; ret = old_func; end return ok, ret; end function add_level_sink(level, sink_function) if not level_sinks[level] then level_sinks[level] = { sink_function }; else level_sinks[level][#level_sinks[level] + 1 ] = sink_function; end for _, modify_hook in pairs(modify_hooks) do modify_hook(); end end function add_name_sink(name, sink_function, exclusive) if not name_sinks[name] then name_sinks[name] = { sink_function }; else name_sinks[name][#name_sinks[name] + 1] = sink_function; end for _, modify_hook in pairs(modify_hooks) do modify_hook(); end end function add_name_pattern_sink(name_pattern, sink_function, exclusive) if not name_patterns[name_pattern] then name_patterns[name_pattern] = { sink_function }; else name_patterns[name_pattern][#name_patterns[name_pattern] + 1] = sink_function; end end _M.new = make_logger; return _M;