Software /
code /
prosody
Comparison
core/loggingmanager.lua @ 7134:b7b6b1d01224
loggingmanager: Refactor the console log sink to re-use the stdout sink which in turn uses the file sink (tailcalls!)
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Thu, 04 Feb 2016 17:33:16 +0100 |
parent | 7133:ac142f5209d9 |
child | 7135:0b614b7333f1 |
comparison
equal
deleted
inserted
replaced
7133:ac142f5209d9 | 7134:b7b6b1d01224 |
---|---|
8 | 8 |
9 | 9 |
10 local format = string.format; | 10 local format = string.format; |
11 local setmetatable, rawset, pairs, ipairs, type = | 11 local setmetatable, rawset, pairs, ipairs, type = |
12 setmetatable, rawset, pairs, ipairs, type; | 12 setmetatable, rawset, pairs, ipairs, type; |
13 local io_open, io_write = io.open, io.write; | 13 local stdout = io.stdout; |
14 local io_open = io.open; | |
14 local math_max, rep = math.max, string.rep; | 15 local math_max, rep = math.max, string.rep; |
15 local os_date = os.date; | 16 local os_date = os.date; |
16 local getstyle, getstring = require "util.termcolours".getstyle, require "util.termcolours".getstring; | 17 local getstyle, getstring = require "util.termcolours".getstyle, require "util.termcolours".getstring; |
17 | 18 |
18 -- COMPAT: This should no longer be needed since the addition of setvbuf calls | 19 -- COMPAT: This should no longer be needed since the addition of setvbuf calls |
168 prosody.events.add_handler("config-reloaded", reload_logging); | 169 prosody.events.add_handler("config-reloaded", reload_logging); |
169 | 170 |
170 --- Definition of built-in logging sinks --- | 171 --- Definition of built-in logging sinks --- |
171 | 172 |
172 -- Null sink, must enter log_sink_types *first* | 173 -- Null sink, must enter log_sink_types *first* |
173 function log_sink_types.nowhere() | 174 local function log_to_nowhere() |
174 return function () return false; end; | 175 return function () return false; end; |
175 end | 176 end |
176 | 177 log_sink_types.nowhere = log_to_nowhere; |
177 -- Column width for "source" (used by stdout and console) | 178 |
178 local sourcewidth = 20; | 179 local function log_to_file(sink_config, logfile) |
179 | 180 logfile = logfile or io_open(sink_config.filename, "a+"); |
180 function log_sink_types.stdout(sink_config) | 181 if not logfile then |
182 return log_to_nowhere(sink_config); | |
183 end | |
184 local write = logfile.write; | |
185 | |
181 local timestamps = sink_config.timestamps; | 186 local timestamps = sink_config.timestamps; |
182 | 187 |
183 if timestamps == true then | 188 if timestamps == true then |
184 timestamps = default_timestamp; -- Default format | 189 timestamps = default_timestamp; -- Default format |
185 end | 190 end |
186 | 191 |
187 if sink_config.buffer_mode ~= false then | 192 if sink_config.buffer_mode ~= false then |
188 io.stdout:setvbuf(sink_config.buffer_mode or "line"); | |
189 end | |
190 | |
191 return function (name, level, message, ...) | |
192 sourcewidth = math_max(#name+2, sourcewidth); | |
193 local namelen = #name; | |
194 if timestamps then | |
195 io_write(os_date(timestamps), " "); | |
196 end | |
197 if ... then | |
198 io_write(name, rep(" ", sourcewidth-namelen), level, "\t", format(message, ...), "\n"); | |
199 else | |
200 io_write(name, rep(" ", sourcewidth-namelen), level, "\t", message, "\n"); | |
201 end | |
202 end | |
203 end | |
204 | |
205 do | |
206 local do_pretty_printing = true; | |
207 | |
208 local logstyles = {}; | |
209 if do_pretty_printing then | |
210 logstyles["info"] = getstyle("bold"); | |
211 logstyles["warn"] = getstyle("bold", "yellow"); | |
212 logstyles["error"] = getstyle("bold", "red"); | |
213 end | |
214 function log_sink_types.console(sink_config) | |
215 -- Really if we don't want pretty colours then just use plain stdout | |
216 if not do_pretty_printing then | |
217 return log_sink_types.stdout(sink_config); | |
218 end | |
219 | |
220 local timestamps = sink_config.timestamps; | |
221 | |
222 if timestamps == true then | |
223 timestamps = default_timestamp; -- Default format | |
224 end | |
225 | |
226 if sink_config.buffer_mode ~= false then | |
227 io.stdout:setvbuf(sink_config.buffer_mode or "line"); | |
228 end | |
229 | |
230 return function (name, level, message, ...) | |
231 sourcewidth = math_max(#name+2, sourcewidth); | |
232 local namelen = #name; | |
233 | |
234 if timestamps then | |
235 io_write(os_date(timestamps), " "); | |
236 end | |
237 io_write(name, rep(" ", sourcewidth-namelen)); | |
238 io_write(getstring(logstyles[level], level)); | |
239 if ... then | |
240 io_write("\t", format(message, ...), "\n"); | |
241 else | |
242 io_write("\t", message, "\n"); | |
243 end | |
244 end | |
245 end | |
246 end | |
247 | |
248 local empty_function = function () end; | |
249 function log_sink_types.file(sink_config) | |
250 local log = sink_config.filename; | |
251 local logfile = io_open(log, "a+"); | |
252 if not logfile then | |
253 return empty_function; | |
254 end | |
255 | |
256 if sink_config.buffer_mode ~= false then | |
257 logfile:setvbuf(sink_config.buffer_mode or "line"); | 193 logfile:setvbuf(sink_config.buffer_mode or "line"); |
258 end | |
259 | |
260 local write = logfile.write; | |
261 | |
262 local timestamps = sink_config.timestamps; | |
263 | |
264 if timestamps == nil or timestamps == true then | |
265 timestamps = default_timestamp; -- Default format | |
266 end | 194 end |
267 | 195 |
268 return function (name, level, message, ...) | 196 return function (name, level, message, ...) |
269 if timestamps then | 197 if timestamps then |
270 write(logfile, os_date(timestamps), " "); | 198 write(logfile, os_date(timestamps), " "); |
271 end | 199 end |
272 if ... then | 200 if ... then |
273 write(logfile, name, "\t", level, "\t", format(message, ...), "\n"); | 201 write(logfile, name, level, "\t", format(message, ...), "\n"); |
274 else | 202 else |
275 write(logfile, name, "\t" , level, "\t", message, "\n"); | 203 write(logfile, name, level, "\t", message, "\n"); |
276 end | 204 end |
277 end; | 205 end |
278 end | 206 end |
207 log_sink_types.file = log_to_file; | |
208 | |
209 -- Column width for "source" (used by stdout and console) | |
210 local sourcewidth = 20; | |
211 | |
212 local function log_to_stdout(sink_config) | |
213 if not sink_config.timestamps then | |
214 sink_config.timestamps = false; | |
215 end | |
216 local logtofile = log_to_file(sink_config, stdout); | |
217 return function (name, level, message, ...) | |
218 sourcewidth = math_max(#name+2, sourcewidth); | |
219 name = name .. rep(" ", sourcewidth-#name); | |
220 return logtofile(name, level, message, ...); | |
221 end | |
222 end | |
223 log_sink_types.stdout = log_to_stdout; | |
224 | |
225 local do_pretty_printing = true; | |
226 | |
227 local logstyles; | |
228 if do_pretty_printing then | |
229 logstyles = {}; | |
230 logstyles["info"] = getstyle("bold"); | |
231 logstyles["warn"] = getstyle("bold", "yellow"); | |
232 logstyles["error"] = getstyle("bold", "red"); | |
233 end | |
234 | |
235 local function log_to_console(sink_config) | |
236 -- Really if we don't want pretty colours then just use plain stdout | |
237 local logstdout = log_to_stdout(sink_config); | |
238 if not do_pretty_printing then | |
239 return logstdout; | |
240 end | |
241 return function (name, level, message, ...) | |
242 local logstyle = logstyles[level]; | |
243 if logstyle then | |
244 level = getstring(logstyle, level); | |
245 end | |
246 return logstdout(name, level, message, ...); | |
247 end | |
248 end | |
249 log_sink_types.console = log_to_console; | |
279 | 250 |
280 local function register_sink_type(name, sink_maker) | 251 local function register_sink_type(name, sink_maker) |
281 local old_sink_maker = log_sink_types[name]; | 252 local old_sink_maker = log_sink_types[name]; |
282 log_sink_types[name] = sink_maker; | 253 log_sink_types[name] = sink_maker; |
283 return old_sink_maker; | 254 return old_sink_maker; |