Mercurial > prosody-hg
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 |
| parents | ac142f5209d9 |
| children | 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; |
