core/loggingmanager.lua

changeset 1021
f9122efeaadd
parent 1016
73afe3e30e97
child 1024
1bcc8ca57a7c
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

mercurial