MINOR: hlua: expose SERVER_STATE event

Exposing SERVER_STATE event in lua and updating the documentation.
This commit is contained in:
Aurelien DARRAGON 2023-04-12 15:47:16 +02:00 committed by Christopher Faulet
parent c249f6d964
commit c99f3adf10
2 changed files with 240 additions and 2 deletions

View File

@ -946,10 +946,14 @@ Core class
* **SERVER_DEL**: when a server is removed
* **SERVER_DOWN**: when a server state goes from UP to DOWN
* **SERVER_UP**: when a server state goes from DOWN to UP
* **SERVER_STATE**: when a server state changes
.. Note::
You may also use **SERVER** in **event_types** to subscribe to all server
events types at once.
Use **SERVER** in **event_types** to subscribe to all server events types
at once. Note that this should only be used for testing purposes since a
single event source could result in multiple events types being generated.
(e.g.: SERVER_STATE will always be generated for each SERVER_DOWN or
SERVER_UP)
The prototype of the Lua function used as argument is:
@ -1522,6 +1526,111 @@ See :js:func:`core.event_sub()` for more info.
(Will never be set for SERVER_DEL event since the server does not exist
anymore)
.. js:attribute:: ServerEvent.state
A :ref:`server_event_state_class`
.. Note::
Only available for SERVER_STATE event
.. _server_event_checkres_class:
ServerEventCheckRes class
=========================
.. js:class:: ServerEventCheckRes
This class describes the result of a server's check.
.. js:attribute:: ServerEventCheckRes.result
Effective check result.
Check result is a string and will be set to one of the following values:
- "FAILED": the check failed
- "PASSED": the check succeeded
- "CONDPASS": the check conditionally passed
.. js:attribute:: ServerEventCheckRes.agent
Boolean set to true if the check is an agent check.
Else it is a health check.
.. js:attribute:: ServerEventCheckRes.duration
Check's duration in milliseconds
.. js:attribute:: ServerEventCheckRes.reason
Check's status. An array containing three fields:
- **short**: a string representing check status short name
- **desc**: a string representing check status description
- **code**: an integer, this extra information is provided for checks
that went through the data analysis stage (>= layer 5)
.. js:attribute:: ServerEventCheckRes.health
An array containing values about check's health (integers):
- **cur**: current health counter:
- 0 to (**rise** - 1) = BAD
- **rise** to (**rise** + **fall** - 1) = GOOD
- **rise**: server will be considered as operational after **rise**
consecutive successful checks
- **fall**: server will be considered as dead after **fall** consecutive
unsuccessful checks
.. _server_event_state_class:
ServerEventState class
======================
.. js:class:: ServerEventState
This class contains additional info related to **SERVER_STATE** event.
.. js:attribute:: ServerEventState.admin
Boolean set to true if the server state change is due to an administrative
change. Else it is an operational change.
.. js:attribute:: ServerEventState.check
A :ref:`server_event_checkres_class`, provided if the state change is
due to a server check (must be an operational change).
.. js:attribute:: ServerEventState.cause
Printable state change cause. Might be empty.
.. js:attribute:: ServerEventState.new_state
New server state due to operational or admin change.
It is a string that can be any of the following values:
- "STOPPED": The server is down
- "STOPPING": The server is up but soft-stopping
- "STARTING": The server is warming up
- "RUNNING": The server is fully up
.. js:attribute:: ServerEventState.old_state
Previous server state prior to the operational or admin change.
Can be any value described in **new_state**, but they should differ.
.. js:attribute:: ServerEventState.requeued
Number of connections that were requeued due to the server state change.
For a server going DOWN: it is the number of pending server connections
that are requeued to the backend (such connections will be redispatched
to any server that is suitable according to the configured load balancing
algorithm).
For a server doing UP: it is the number of pending connections on the
backend that may be redispatched to the server according to the load
balancing algorithm that is in use.
.. _concat_class:
Concat class

View File

@ -66,6 +66,7 @@
#include <haproxy/vars.h>
#include <haproxy/xref.h>
#include <haproxy/event_hdl.h>
#include <haproxy/check.h>
/* Lua uses longjmp to perform yield or throwing errors. This
* macro is used only for identifying the function that can
@ -9029,6 +9030,67 @@ static void hlua_event_handler(struct hlua *hlua)
}
}
__LJMP static void hlua_event_hdl_cb_push_event_checkres(lua_State *L,
struct event_hdl_cb_data_server_checkres *check)
{
lua_pushstring(L, "agent");
lua_pushboolean(L, check->agent);
lua_settable(L, -3);
lua_pushstring(L, "result");
switch (check->result) {
case CHK_RES_FAILED:
lua_pushstring(L, "FAILED");
break;
case CHK_RES_PASSED:
lua_pushstring(L, "PASSED");
break;
case CHK_RES_CONDPASS:
lua_pushstring(L, "CONDPASS");
break;
default:
lua_pushnil(L);
break;
}
lua_settable(L, -3);
lua_pushstring(L, "duration");
lua_pushinteger(L, check->duration);
lua_settable(L, -3);
lua_pushstring(L, "reason");
lua_newtable(L);
lua_pushstring(L, "short");
lua_pushstring(L, get_check_status_info(check->reason.status));
lua_settable(L, -3);
lua_pushstring(L, "desc");
lua_pushstring(L, get_check_status_description(check->reason.status));
lua_settable(L, -3);
if (check->reason.status >= HCHK_STATUS_L57DATA) {
/* code only available when the check reached data analysis stage */
lua_pushstring(L, "code");
lua_pushinteger(L, check->reason.code);
lua_settable(L, -3);
}
lua_settable(L, -3); /* reason table */
lua_pushstring(L, "health");
lua_newtable(L);
lua_pushstring(L, "cur");
lua_pushinteger(L, check->health.cur);
lua_settable(L, -3);
lua_pushstring(L, "rise");
lua_pushinteger(L, check->health.rise);
lua_settable(L, -3);
lua_pushstring(L, "fall");
lua_pushinteger(L, check->health.fall);
lua_settable(L, -3);
lua_settable(L, -3); /* health table */
}
/* This function pushes various arguments such as event type and event data to
* the lua function that will be called to consume the event.
*/
@ -9072,6 +9134,73 @@ __LJMP static void hlua_event_hdl_cb_push_args(struct hlua_event_sub *hlua_sub,
lua_pushinteger(hlua->T, e_server->safe.proxy_uuid);
lua_settable(hlua->T, -3);
/* special events, fetch additional info with explicit type casting */
if (event_hdl_sub_type_equal(EVENT_HDL_SUB_SERVER_STATE, event)) {
struct event_hdl_cb_data_server_state *state = data;
int it;
if (!lua_checkstack(hlua->T, 20))
WILL_LJMP(luaL_error(hlua->T, "Lua out of memory error."));
/* state subclass */
lua_pushstring(hlua->T, "state");
lua_newtable(hlua->T);
lua_pushstring(hlua->T, "admin");
lua_pushboolean(hlua->T, state->safe.type);
lua_settable(hlua->T, -3);
/* is it because of a check ? */
if (!state->safe.type &&
(state->safe.op_st_chg.cause == SRV_OP_STCHGC_HEALTH ||
state->safe.op_st_chg.cause == SRV_OP_STCHGC_AGENT)) {
/* yes, provide check result */
lua_pushstring(hlua->T, "check");
lua_newtable(hlua->T);
hlua_event_hdl_cb_push_event_checkres(hlua->T, &state->safe.op_st_chg.check);
lua_settable(hlua->T, -3); /* check table */
}
lua_pushstring(hlua->T, "cause");
if (state->safe.type)
lua_pushstring(hlua->T, srv_adm_st_chg_cause(state->safe.adm_st_chg.cause));
else
lua_pushstring(hlua->T, srv_op_st_chg_cause(state->safe.op_st_chg.cause));
lua_settable(hlua->T, -3);
/* old_state, new_state */
for (it = 0; it < 2; it++) {
enum srv_state srv_state = (!it) ? state->safe.old_state : state->safe.new_state;
lua_pushstring(hlua->T, (!it) ? "old_state" : "new_state");
switch (srv_state) {
case SRV_ST_STOPPED:
lua_pushstring(hlua->T, "STOPPED");
break;
case SRV_ST_STOPPING:
lua_pushstring(hlua->T, "STOPPING");
break;
case SRV_ST_STARTING:
lua_pushstring(hlua->T, "STARTING");
break;
case SRV_ST_RUNNING:
lua_pushstring(hlua->T, "RUNNING");
break;
default:
lua_pushnil(hlua->T);
break;
}
lua_settable(hlua->T, -3);
}
/* requeued */
lua_pushstring(hlua->T, "requeued");
lua_pushinteger(hlua->T, state->safe.requeued);
lua_settable(hlua->T, -3);
lua_settable(hlua->T, -3); /* state table */
}
/* attempt to provide reference server object
* (if it wasn't removed yet, SERVER_DEL will never succeed here)
*/