X-Git-Url: https://git.enpas.org/?a=blobdiff_plain;ds=sidebyside;f=core%2Floggingmanager.lua;h=4154e1a7b3131656091ae2e6376c553fde185a4b;hb=9a42b61e1f6522baf13a72f10d4c9fc24d1325f1;hp=36f83861ff89c04aef73b057a0ebdf48e3db4f3c;hpb=5d6afacc4f8552448a60efbf54782d1a4976ca81;p=prosody.git diff --git a/core/loggingmanager.lua b/core/loggingmanager.lua index 36f83861..4154e1a7 100644 --- a/core/loggingmanager.lua +++ b/core/loggingmanager.lua @@ -1,3 +1,11 @@ +-- 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 format, rep = string.format, string.rep; local pcall = pcall; @@ -6,18 +14,28 @@ local tostring, setmetatable, rawset, pairs, ipairs, type = tostring, setmetatable, rawset, pairs, ipairs, type; local io_open, io_write = io.open, io.write; local math_max, rep = math.max, string.rep; -local os_getenv = os.getenv; +local os_date, os_getenv = os.date, os.getenv; local getstyle, getstring = require "util.termcolours".getstyle, require "util.termcolours".getstring; -local config = require "core.configmanager"; +if os.getenv("__FLUSH_LOG") then + local io_flush = io.flush; + local _io_write = io_write; + io_write = function(...) _io_write(...); io_flush(); end +end +local config = require "core.configmanager"; +local eventmanager = require "core.eventmanager"; local logger = require "util.logger"; +local debug_mode = config.get("*", "core", "debug"); + +_G.log = logger.init("general"); module "loggingmanager" -- The log config used if none specified in the config file local default_logging = { { to = "console" } }; - +local default_file_logging = { { to = "file", levels = { min = (debug_mode and "debug") or "info" }, timestamps = true } }; +local default_timestamp = "%b %d %T"; -- The actual config loggingmanager is using local logging_config = config.get("*", "core", "log") or default_logging; @@ -26,6 +44,8 @@ local log_sink_types = setmetatable({}, { __newindex = function (t, k, v) rawset local get_levels; local logging_levels = { "debug", "info", "warn", "error", "critical" } +-- Put a rule into action. Requires that the sink type has already been registered. +-- This function is called automatically when a new sink type is added [see apply_sink_rules()] local function add_rule(sink_config) local sink_maker = log_sink_types[sink_config.to]; if sink_maker then @@ -63,8 +83,9 @@ local function add_rule(sink_config) end end --- Search for all rules using a particular sink type, --- and apply them +-- Search for all rules using a particular sink type, and apply +-- them. Called automatically when a new sink type is added to +-- the log_sink_types table. function apply_sink_rules(sink_type) if type(logging_config) == "table" then for _, sink_config in pairs(logging_config) do @@ -72,9 +93,17 @@ function apply_sink_rules(sink_type) add_rule(sink_config); end end - elseif type(logging_config) == "string" and sink_type == "file" then + elseif type(logging_config) == "string" and (not logging_config:match("^%*")) and sink_type == "file" then -- User specified simply a filename, and the "file" sink type -- was just added + for _, sink_config in pairs(default_file_logging) do + sink_config.filename = logging_config; + add_rule(sink_config); + sink_config.filename = nil; + end + elseif type(logging_config) == "string" and logging_config:match("^%*(.+)") == sink_type then + -- Log all levels (debug+) to this sink + add_rule({ levels = { min = "debug" }, to = sink_type }); end end @@ -111,6 +140,7 @@ end --- Definition of built-in logging sinks --- +-- Null sink, must enter log_sink_types *first* function log_sink_types.nowhere() return function () return false; end; end @@ -119,9 +149,18 @@ end local sourcewidth = 20; function log_sink_types.stdout() + local timestamps = config.timestamps; + + if timestamps == true then + timestamps = default_timestamp; -- Default format + end + return function (name, level, message, ...) sourcewidth = math_max(#name+2, sourcewidth); local namelen = #name; + if timestamps then + io_write(os_date(timestamps), " "); + end if ... then io_write(name, rep(" ", sourcewidth-namelen), level, "\t", format(message, ...), "\n"); else @@ -145,9 +184,19 @@ do return log_sink_types.stdout(config); end + local timestamps = config.timestamps; + + if timestamps == true then + timestamps = default_timestamp; -- Default format + end + return function (name, level, message, ...) sourcewidth = math_max(#name+2, sourcewidth); local namelen = #name; + + if timestamps then + io_write(os_date(timestamps), " "); + end if ... then io_write(name, rep(" ", sourcewidth-namelen), getstring(logstyles[level], level), "\t", format(message, ...), "\n"); else @@ -157,15 +206,37 @@ do end end +local empty_function = function () end; function log_sink_types.file(config) local log = config.filename; local logfile = io_open(log, "a+"); if not logfile then - return function () end + return empty_function; + end + local write, flush = logfile.write, logfile.flush; + + eventmanager.add_event_hook("reopen-log-files", function () + if logfile then + logfile:close(); + end + logfile = io_open(log, "a+"); + if not logfile then + write, flush = empty_function, empty_function; + else + write, flush = logfile.write, logfile.flush; + end + end); + + local timestamps = config.timestamps; + + if timestamps == nil or timestamps == true then + timestamps = default_timestamp; -- Default format end - local write, format, flush = logfile.write, format, logfile.flush; return function (name, level, message, ...) + if timestamps then + write(logfile, os_date(timestamps), " "); + end if ... then write(logfile, name, "\t", level, "\t", format(message, ...), "\n"); else