Software / code / prosody
Comparison
core/loggingmanager.lua @ 1021:f9122efeaadd
core.loggingmanager: Filled out most code, and cleaned up
| author | Matthew Wild <mwild1@gmail.com> |
|---|---|
| date | Tue, 21 Apr 2009 20:30:29 +0100 |
| parent | 1016:73afe3e30e97 |
| child | 1024:1bcc8ca57a7c |
comparison
equal
deleted
inserted
replaced
| 1020:8bf71f8bd0d1 | 1021:f9122efeaadd |
|---|---|
| 7 local math_max = math.max; | 7 local math_max = math.max; |
| 8 | 8 |
| 9 local logger = require "util.logger"; | 9 local logger = require "util.logger"; |
| 10 | 10 |
| 11 -- Global log function, because some people are too | 11 -- Global log function, because some people are too |
| 12 -- lazy to get their own | 12 -- lazy to get their own... |
| 13 _G.log = logger.init("general"); | 13 _G.log = logger.init("general"); |
| 14 | 14 |
| 15 -- Disable log output, needs to read from config | 15 local log_sink_types = {}; |
| 16 -- logger.setwriter(function () end); | 16 local get_levels; |
| 17 | 17 |
| 18 local getstyle, getstring = require "util.termcolours".getstyle, require "util.termcolours".getstring; | 18 --- Main function to read config, create the appropriate sinks and tell logger module |
| 19 local do_pretty_printing = not os.getenv("WINDIR"); | 19 function setup_logging(log) |
| 20 | 20 log = log or config.get("*", "core", "log") or default_logging; |
| 21 local logstyles = {}; | 21 -- Set default logger |
| 22 | 22 if type(log) == "string" then |
| 23 --TODO: This should be done in config, but we don't have proper config yet | 23 if not log:match("^%*") then |
| 24 if do_pretty_printing then | 24 end |
| 25 logstyles["info"] = getstyle("bold"); | 25 elseif type(log) == "table" then |
| 26 logstyles["warn"] = getstyle("bold", "yellow"); | 26 -- Advanced configuration chosen |
| 27 logstyles["error"] = getstyle("bold", "red"); | 27 for i, sink_config in ipairs(log) do |
| 28 end | 28 local sink_maker = log_sink_types[sink_config.to]; |
| 29 | 29 if sink_maker then |
| 30 local sourcewidth = 20; | 30 if sink_config.levels and not sink_config.source then |
| 31 local math_max, rep = math.max, string.rep; | 31 -- Create sink |
| 32 local function make_default_log_sink(level) | 32 local sink = sink_maker(sink_config); |
| 33 return function (name, _level, message, ...) | 33 |
| 34 sourcewidth = math_max(#name+2, sourcewidth); | 34 -- Set sink for all chosen levels |
| 35 local namelen = #name; | 35 for level in pairs(get_levels(sink_config.levels)) do |
| 36 if ... then | 36 logger.add_level_sink(level, sink); |
| 37 io_write(name, rep(" ", sourcewidth-namelen), getstring(logstyles[level], level), "\t", format(message, ...), "\n"); | 37 end |
| 38 else | 38 elseif sink_config.source and not sink_config.levels then |
| 39 io_write(name, rep(" ", sourcewidth-namelen), getstring(logstyles[level], level), "\t", message, "\n"); | 39 logger.add_name_sink(sink_config.source, sink_maker(sink_config)); |
| 40 elseif sink_config.source and sink_config.levels then | |
| 41 local levels = get_levels(sink_config.levels); | |
| 42 local sink = sink_maker(sink_config); | |
| 43 logger.add_name_sink(sink_config.source, | |
| 44 function (name, level, ...) | |
| 45 if levels[level] then | |
| 46 return sink(name, level, ...); | |
| 47 end | |
| 48 end); | |
| 49 else | |
| 50 -- All sources | |
| 51 end | |
| 52 else | |
| 53 -- No such sink type | |
| 54 end | |
| 40 end | 55 end |
| 41 end | 56 end |
| 42 end | 57 end |
| 43 | 58 |
| 44 -- Set default sinks | 59 --- Definition of built-in logging sinks --- |
| 45 logger.add_level_sink("debug", make_default_log_sink("debug")); | 60 local math_max, rep = math.max, string.rep; |
| 46 logger.add_level_sink("info", make_default_log_sink("info")); | |
| 47 logger.add_level_sink("warn", make_default_log_sink("warn")); | |
| 48 logger.add_level_sink("error", make_default_log_sink("error")); | |
| 49 | 61 |
| 62 -- Column width for "source" (used by stdout and console) | |
| 63 | |
| 64 function log_sink_types.nowhere() | |
| 65 return function () return false; end; | |
| 66 end | |
| 67 | |
| 68 local sourcewidth = 20; | |
| 69 | |
| 70 function log_sink_types.stdout() | |
| 71 return function (name, level, message, ...) | |
| 72 sourcewidth = math_max(#name+2, sourcewidth); | |
| 73 local namelen = #name; | |
| 74 if ... then | |
| 75 io_write(name, rep(" ", sourcewidth-namelen), level, "\t", format(message, ...), "\n"); | |
| 76 else | |
| 77 io_write(name, rep(" ", sourcewidth-namelen), level, "\t", message, "\n"); | |
| 78 end | |
| 79 end | |
| 80 end | |
| 81 | |
| 82 do | |
| 83 local getstyle, getstring = require "util.termcolours".getstyle, require "util.termcolours".getstring; | |
| 84 local do_pretty_printing = not os.getenv("WINDIR"); | |
| 85 | |
| 86 local logstyles = {}; | |
| 87 if do_pretty_printing then | |
| 88 logstyles["info"] = getstyle("bold"); | |
| 89 logstyles["warn"] = getstyle("bold", "yellow"); | |
| 90 logstyles["error"] = getstyle("bold", "red"); | |
| 91 end | |
| 92 function log_sink_types.console(config) | |
| 93 -- Really if we don't want pretty colours then just use plain stdout | |
| 94 if not do_pretty_printing then | |
| 95 return log_sink_types.stdout(config); | |
| 96 end | |
| 97 | |
| 98 return function (name, level, message, ...) | |
| 99 sourcewidth = math_max(#name+2, sourcewidth); | |
| 100 local namelen = #name; | |
| 101 if ... then | |
| 102 io_write(name, rep(" ", sourcewidth-namelen), getstring(logstyles[level], level), "\t", format(message, ...), "\n"); | |
| 103 else | |
| 104 io_write(name, rep(" ", sourcewidth-namelen), getstring(logstyles[level], level), "\t", message, "\n"); | |
| 105 end | |
| 106 end | |
| 107 end | |
| 108 end | |
| 109 | |
| 110 function log_sink_types.file(config) | |
| 111 local log = config.filename; | |
| 112 local logfile = io.open(log, "a+"); | |
| 113 if not logfile then | |
| 114 return function () end | |
| 115 end | |
| 116 | |
| 117 local write, format, flush = logfile.write, string.format, logfile.flush; | |
| 118 return function (name, level, message, ...) | |
| 119 if ... then | |
| 120 write(logfile, name, "\t", level, "\t", format(message, ...), "\n"); | |
| 121 else | |
| 122 write(logfile, name, "\t" , level, "\t", message, "\n"); | |
| 123 end | |
| 124 flush(logfile); | |
| 125 end; | |
| 126 end | |
| 127 | |
| 128 function log_sink_types.syslog() | |
| 129 end | |
| 130 | |
| 131 --- Helper function to get a set of levels given a "criteria" table | |
| 132 local logging_levels = { "debug", "info", "warn", "error", "critical" } | |
| 133 | |
| 134 function get_levels(criteria, set) | |
| 135 set = set or {}; | |
| 136 if type(criteria) == "string" then | |
| 137 set[criteria] = true; | |
| 138 return set; | |
| 139 end | |
| 140 local min, max = criteria.min, criteria.max; | |
| 141 if min or max then | |
| 142 local in_range; | |
| 143 for _, level in ipairs(logging_levels) do | |
| 144 if min == level then | |
| 145 set[level] = true; | |
| 146 in_range = true; | |
| 147 elseif max == level then | |
| 148 set[level] = true; | |
| 149 return set; | |
| 150 elseif in_range then | |
| 151 set[level] = true; | |
| 152 end | |
| 153 end | |
| 154 end | |
| 155 | |
| 156 for _, level in ipairs(criteria) do | |
| 157 set[level] = true; | |
| 158 end | |
| 159 return set; | |
| 160 end | |
| 161 | |
| 162 --- Set up logging | |
| 163 setup_logging(); | |
| 164 |