comparison mod_sentry/mod_sentry.lua @ 4283:2ae71126e379

mod_sentry: New module to forward errors to a Sentry server
author Matthew Wild <mwild1@gmail.com>
date Tue, 08 Dec 2020 15:34:53 +0000
parents
children 2c73544e33ea
comparison
equal deleted inserted replaced
4282:281a864e7472 4283:2ae71126e379
1 module:set_global();
2
3 local sentry_lib = module:require "sentry";
4
5 local hostname;
6 local have_pposix, pposix = pcall(require, "util.pposix");
7 if have_pposix and pposix.uname then
8 hostname = pposix.uname().nodename;
9 end
10
11 local loggingmanager = require "core.loggingmanager";
12 local format = require "util.format".format;
13
14 local default_config = assert(module:get_option("sentry"), "Please provide a 'sentry' configuration option");
15 default_config.server_name = default_config.server_name or hostname or "prosody";
16
17 local sentry = assert(sentry_lib.new(default_config));
18
19 local log_filters = {
20 source = function (filter_source, name)
21 local source = name:match(":(.+)$") or name;
22 if filter_source == source then
23 return true;
24 end
25 end;
26 message_pattern = function (pattern, _, _, message)
27 return not not message:match(pattern);
28 end;
29 };
30
31 local function sentry_error_handler(e)
32 module:log("error", "Failed to submit event to sentry: %s", e);
33 end
34
35 local function sentry_log_sink_maker(sink_config)
36 local filters = sink_config.ignore or {};
37 local n_filters = #filters;
38
39 local submitting;
40 return function (name, level, message, ...)
41 -- Ignore any log messages that occur during sentry submission
42 -- to avoid loops
43 if submitting then return; end
44 for i = 1, n_filters do
45 local filter = filters[i];
46 local matched;
47 for filter_name, filter_value in pairs(filter) do
48 local f = log_filters[filter_name];
49 if f and f(filter_value, name, level, message) then
50 matched = true;
51 else
52 matched = nil;
53 break;
54 end
55 end
56 if matched then
57 return;
58 end
59 end
60 if level == "warn" then
61 level = "warning";
62 end
63
64 submitting = true;
65 sentry:event(level, name):message(format(message, ...)):send():catch(sentry_error_handler);
66 submitting = false;
67 end;
68 end
69
70 loggingmanager.register_sink_type("sentry", sentry_log_sink_maker);
71
72 function new(conf) --luacheck: ignore 131/new
73 conf = conf or {};
74 for k, v in pairs(default_config) do
75 if conf[k] == nil then
76 conf[k] = v;
77 end
78 end
79 return sentry_lib.new(conf);
80 end