From: Aurelien DARRAGON Date: Wed, 3 May 2023 17:12:53 +0000 (+0200) Subject: EXAMPLES: mailqueue for lua mailers script X-Git-Tag: v2.8-dev10~6 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=4537ac115aa48b7cb35631c028b4f44d56278bdc;p=thirdparty%2Fhaproxy.git EXAMPLES: mailqueue for lua mailers script Lua mailers scripts now leverages Queue class to implement a mailqueue. Thanks to the mailqueue, emails are still sent asynchronously, but with respect to their generation order (better ordering consistency). That is, previous script limitation (see below) is no longer true: " Current known script limitation: if multiple events are generated simultaneously it is possible that emails could be received out of order since emails are sent asynchronously using smtp_send_email() and there is no sending queue. Relying on the email "date" should help to know which email was generated first.. " For a given server, email-alerts will be sent in the same order as the events were generated. However this does not apply to events between 2 distinct servers, since each server is tracked independently within the lua script. (1 subscription per server, to make sure only relevant servers x events are being tracked and prevent useless wakeups) --- diff --git a/examples/lua/mailers.lua b/examples/lua/mailers.lua index cbc8205aa5..e36800b73f 100644 --- a/examples/lua/mailers.lua +++ b/examples/lua/mailers.lua @@ -16,6 +16,8 @@ local SYSLOG_LEVEL = { ["DEBUG"] = 7 } +local mailqueue = core.queue() + -- smtp : send SMTP message -- -- Copyright 2018 Thierry Fournier @@ -140,28 +142,16 @@ local function send_email_alert(srv, level, message, when) return end - -- email sending is performed asynchronously - core.register_task(function(mailers, msg, when) - for name, mailsrv in pairs(mailers.mailservers) do - local mailsrv_ip, mailsrv_port = string.match(mailsrv, "([^:]+):([^:]+)") - local date = os.date("%a, %d %b %Y %T %z (%Z)", when) - local c = core.concat() + -- email sending is performed asynchronously thanks to mailqueue + local job = {} - c:add(string.format("From: %s\r\n", mailers.smtp_from)) - c:add(string.format("To: %s\r\n", mailers.smtp_to)) - c:add(string.format("Date: %s\r\n", date)) - c:add(string.format("Subject: [HAProxy Alert] %s\r\n", msg)) - c:add("\r\n") - c:add(string.format("%s\r\n", msg)) + job.mailconf = mailers + job.when = when + job.msg = message + + -- enqueue email job + mailqueue:push(job) - local ret, reason = smtp_send_email(mailsrv_ip, mailsrv_port, - mailers.smtp_hostname, mailers.smtp_from, - mailers.smtp_to, c:dump()) - if ret == false then - core.Warning("Can't send email: " .. reason) - end - end - end, mailers, message, when) end local function srv_get_check_details(check) @@ -389,3 +379,40 @@ core.register_task(function() end end) + +-- mail queue +core.register_task(function() + while true + do + local job = mailqueue:pop_wait() + + if job ~= nil then + local date = os.date("%a, %d %b %Y %T %z (%Z)", job.when) + local c = core.concat() + + -- prepare email body + c:add(string.format("From: %s\r\n", job.mailconf.smtp_from)) + c:add(string.format("To: %s\r\n", job.mailconf.smtp_to)) + c:add(string.format("Date: %s\r\n", date)) + c:add(string.format("Subject: [HAProxy Alert] %s\r\n", job.msg)) + c:add("\r\n") + c:add(string.format("%s\r\n", job.msg)) + + -- send email to all mailservers + for name, mailsrv in pairs(job.mailconf.mailservers) do + -- split mailsrv (ip:port) in 2 variables + local mailsrv_ip, mailsrv_port = string.match(mailsrv, "([^:]+):([^:]+)") + + -- finally, send email to server + local ret, reason = smtp_send_email(mailsrv_ip, mailsrv_port, + job.mailconf.smtp_hostname, + job.mailconf.smtp_from, + job.mailconf.smtp_to, + c:dump()) + if ret == false then + core.Warning("Can't send email alert to ".. name .. ": " .. reason) + end + end + end + end +end)