-
-
Save haproxytechblog/687109453ec97c686f89dacea9252d86 to your computer and use it in GitHub Desktop.
Your Starter Guide to Using the HAProxy Lua Event Framework
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- Make an http post request to a webhook endpoint to notify about a backend | |
-- going down at a given time. For the sake of the example, contextual data | |
-- is formatted in JSON, webhook handlers often rely on a combination of | |
-- headers and plain POST or JSON formatted POST payloads to extract arguments | |
-- from the request. | |
local function backend_is_down(backend, when) | |
local httpclient = core.httpclient() | |
local api_base_url = os.getenv("DEMO_WEBHOOK_URL") | |
local request_body = string.format("{\ | |
\"type\":\"%s\",\ | |
\"name\":\"%s\",\ | |
\"when\":\"%d\"\ | |
}", | |
"backend_down", | |
backend, | |
when) | |
local response = httpclient:post{url = api_base_url, body=request_body} | |
if (response.status ~= 200) then | |
core.Alert("Error when making request to http endpoint") | |
end | |
end | |
-- this function will be called by event framework each time a server | |
-- from the chosen backend will be transitioning from UP to DOWN | |
local function server_down(event, data, mgmt, when) | |
local server = data.reference -- get a reference to the server | |
if server == nil then | |
-- the server has been removed, we cannot fetch | |
-- (should not happen in our testcase) | |
return | |
end | |
if server:get_proxy():get_srv_act() == 0 then | |
-- no more active servers within the backend, trigger an alert | |
backend_is_down(server:get_proxy():get_name(), when) | |
end | |
end | |
local arguments = table.pack(...) -- fetch global arguments from lua-load | |
core.register_init(function() | |
-- foreach backend name in arguments | |
for index,name in ipairs(arguments) do | |
-- register server_down function for DOWN event for every server | |
-- within current backend | |
for srv_name, srv in pairs(core.backends[name].servers) do | |
srv:event_sub({"SERVER_DOWN"}, server_down) | |
end | |
end | |
end) | |
-- watch for new server addition | |
core.event_sub({"SERVER_ADD"}, function(event, data) | |
local server = data.reference -- get a reference to the server | |
if server == nil then | |
return | |
end | |
-- as new server has been added dynamically, check if it belongs to | |
-- one of the tracked backends passed as optional lua-load arguments | |
for index,name in ipairs(arguments) do | |
if name == server:get_proxy():get_name() then | |
-- track the server for DOWN event | |
server:event_sub({"SERVER_DOWN"}, server_down) | |
break | |
end | |
end | |
end) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$ make TARGET=linux-glibc USE_LUA=1 -j$(nproc) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$ make TARGET=linux-glibc USE_LUA=1 LUA_LIB=/path/to/lua/lib LUA_INC=/path/to/lua/lib/include -j$(nproc) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$ ./haproxy -vv | grep Lua | |
Built with Lua version : Lua 5.4.6 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- Make an http post request to a webhook endpoint to notify about a backend | |
-- going down at a given time. For the sake of the example, contextual data | |
-- is formatted in JSON, webhook handlers often rely on a combination of | |
-- headers and plain POST or JSON formatted POST payloads to extract arguments | |
-- from the request. | |
local function backend_is_down(backend, when) | |
local httpclient = core.httpclient() | |
local api_base_url = os.getenv("DEMO_WEBHOOK_URL") | |
print(api_base_url) | |
local request_body = string.format("{\ | |
\"type\":\"%s\",\ | |
\"name\":\"%s\",\ | |
\"when\":\"%d\"\ | |
}", | |
"backend_down", | |
backend, | |
when) | |
local response = httpclient:post{url = api_base_url, body=request_body} | |
if (response.status ~= 200) then | |
core.Alert("Error when making request to http endpoint") | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- this function will be called by event framework each time a server | |
-- from the chosen backend will be transitioning from UP to DOWN | |
local function server_down(event, data, mgmt, when) | |
local server = data.reference -- get a reference to the server | |
if server == nil then | |
-- the server has been removed, we cannot fetch | |
-- (should not happen in our testcase) | |
return | |
end | |
if server:get_proxy():get_srv_act() == 0 then | |
-- no more active servers within the backend, trigger an alert | |
backend_is_down(server:get_proxy():get_name(), when) | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
core.register_init(function() | |
-- register server_down function for DOWN event for every server | |
-- within "test" backend | |
for srv_name, srv in pairs(core.backends["test"].servers) do | |
srv:event_sub({"SERVER_DOWN"}, server_down) | |
end | |
end) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
global | |
stats socket ipv4@127.0.0.1:9999 level admin | |
lua-load backend_down_webhook.lua | |
# by default, the httpclient DNS resolver will use the IPv6 address, | |
# this changes it to prefer IPv4 | |
httpclient.resolvers.prefer ipv4 | |
defaults | |
timeout connect 5s | |
timeout server 5s | |
timeout client 5s | |
resolvers default | |
# we need to define a default resolver section | |
# for the httpclient in order to resolve hostnames in the URL | |
nameserver ns1 8.8.8.8:53 | |
backend test | |
server webserver1 127.0.0.1:8080 | |
server webserver2 127.0.0.1:8081 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
global | |
lua-load backend_down_webhook.lua backend_name |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
local arguments = table.pack(...) -- fetch global arguments from lua-load | |
core.register_init(function() | |
-- foreach backend name in arguments | |
for index,name in ipairs(arguments) do | |
-- register server_down function for DOWN event for every server | |
-- within current backend | |
for srv_name, srv in pairs(core.backends[name].servers) do | |
srv:event_sub({"SERVER_DOWN"}, server_down) | |
end | |
end | |
end) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- watch for new server addition | |
core.event_sub({"SERVER_ADD"}, function(event, data) | |
local server = data.reference -- get a reference to the server | |
if server == nil then | |
return | |
end | |
-- as new server has been added dynamically, check if it belongs to | |
-- one of the tracked backends passed as optional lua-load arguments | |
for index,name in ipairs(arguments) do | |
if name == server:get_proxy():get_name() then | |
-- track the server for DOWN event | |
server:event_sub({"SERVER_DOWN"}, server_down) | |
break | |
end | |
end | |
end) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment