forked from Mirror/frr
lib: Add a helper function to dump Lua stack
Very handy for debugging. In Lua script just use "log.trace(table)": ``` function on_rib_process_dplane_results(ctx) log.trace(ctx.rinfo.zd_ng) end ``` You will get something like: ``` Aug 28 17:04:36 donatas-laptop zebra[3782199]: [GCZ7N-MM9D9] { 1: { type: 2 weight: 1 flags: 5 backup_idx: 0 vrf_id: 0 nh_encap_type: 0 gate: { value: 5.87967e+08 string: "192.168.11.35" } nh_label_type: 0 srte_color: 0 ifindex: 0 backup_num: 0 } 2: { type: 3 weight: 1 flags: 3 backup_idx: 0 vrf_id: 0 nh_encap_type: 0 nh_label_type: 0 srte_color: 0 ifindex: 4 backup_num: 0 } } ``` Signed-off-by: Donatas Abraitis <donatas@opensourcerouting.org>
This commit is contained in:
parent
b1012b693f
commit
a0a2a35ed3
|
@ -523,6 +523,7 @@ object which contains methods corresponding to each of the ``zlog`` levels:
|
||||||
log.error("error")
|
log.error("error")
|
||||||
log.notice("notice")
|
log.notice("notice")
|
||||||
log.debug("debug")
|
log.debug("debug")
|
||||||
|
log.trace("trace")
|
||||||
|
|
||||||
The log messages will show up in the daemon's log output.
|
The log messages will show up in the daemon's log output.
|
||||||
|
|
||||||
|
|
73
lib/frrlua.c
73
lib/frrlua.c
|
@ -382,6 +382,12 @@ static const char *frrlua_log_thunk(lua_State *L)
|
||||||
return lua_tostring(L, 1);
|
return lua_tostring(L, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int frrlua_log_trace(lua_State *L)
|
||||||
|
{
|
||||||
|
zlog_debug("%s", frrlua_stackdump(L));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int frrlua_log_debug(lua_State *L)
|
static int frrlua_log_debug(lua_State *L)
|
||||||
{
|
{
|
||||||
zlog_debug("%s", frrlua_log_thunk(L));
|
zlog_debug("%s", frrlua_log_thunk(L));
|
||||||
|
@ -413,6 +419,7 @@ static int frrlua_log_error(lua_State *L)
|
||||||
}
|
}
|
||||||
|
|
||||||
static const luaL_Reg log_funcs[] = {
|
static const luaL_Reg log_funcs[] = {
|
||||||
|
{ "trace", frrlua_log_trace },
|
||||||
{ "debug", frrlua_log_debug },
|
{ "debug", frrlua_log_debug },
|
||||||
{ "info", frrlua_log_info },
|
{ "info", frrlua_log_info },
|
||||||
{ "notice", frrlua_log_notice },
|
{ "notice", frrlua_log_notice },
|
||||||
|
@ -432,6 +439,67 @@ void frrlua_export_logging(lua_State *L)
|
||||||
* Debugging.
|
* Debugging.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
void lua_table_dump(lua_State *L, int index, struct buffer *buf, int level)
|
||||||
|
{
|
||||||
|
char tmpbuf[64] = {};
|
||||||
|
|
||||||
|
lua_pushnil(L);
|
||||||
|
|
||||||
|
while (lua_next(L, index) != 0) {
|
||||||
|
int key_type;
|
||||||
|
int value_type;
|
||||||
|
|
||||||
|
for (int i = 0; i < level; i++)
|
||||||
|
buffer_putstr(buf, " ");
|
||||||
|
|
||||||
|
key_type = lua_type(L, -2);
|
||||||
|
if (key_type == LUA_TSTRING) {
|
||||||
|
const char *key = lua_tostring(L, -2);
|
||||||
|
|
||||||
|
buffer_putstr(buf, key);
|
||||||
|
buffer_putstr(buf, ": ");
|
||||||
|
} else if (key_type == LUA_TNUMBER) {
|
||||||
|
snprintf(tmpbuf, sizeof(tmpbuf), "%g",
|
||||||
|
lua_tonumber(L, -2));
|
||||||
|
buffer_putstr(buf, tmpbuf);
|
||||||
|
buffer_putstr(buf, ": ");
|
||||||
|
}
|
||||||
|
|
||||||
|
value_type = lua_type(L, -1);
|
||||||
|
switch (value_type) {
|
||||||
|
case LUA_TSTRING:
|
||||||
|
snprintf(tmpbuf, sizeof(tmpbuf), "\"%s\"\n",
|
||||||
|
lua_tostring(L, -1));
|
||||||
|
buffer_putstr(buf, tmpbuf);
|
||||||
|
break;
|
||||||
|
case LUA_TBOOLEAN:
|
||||||
|
snprintf(tmpbuf, sizeof(tmpbuf), "%s\n",
|
||||||
|
lua_toboolean(L, -1) ? "true" : "false");
|
||||||
|
buffer_putstr(buf, tmpbuf);
|
||||||
|
break;
|
||||||
|
case LUA_TNUMBER:
|
||||||
|
snprintf(tmpbuf, sizeof(tmpbuf), "%g\n",
|
||||||
|
lua_tonumber(L, -1));
|
||||||
|
buffer_putstr(buf, tmpbuf);
|
||||||
|
break;
|
||||||
|
case LUA_TTABLE:
|
||||||
|
buffer_putstr(buf, "{\n");
|
||||||
|
lua_table_dump(L, lua_gettop(L), buf, level + 1);
|
||||||
|
for (int i = 0; i < level; i++)
|
||||||
|
buffer_putstr(buf, " ");
|
||||||
|
buffer_putstr(buf, "}\n");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
snprintf(tmpbuf, sizeof(tmpbuf), "%s\n",
|
||||||
|
lua_typename(L, value_type));
|
||||||
|
buffer_putstr(buf, tmpbuf);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_pop(L, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
char *frrlua_stackdump(lua_State *L)
|
char *frrlua_stackdump(lua_State *L)
|
||||||
{
|
{
|
||||||
int top = lua_gettop(L);
|
int top = lua_gettop(L);
|
||||||
|
@ -458,6 +526,11 @@ char *frrlua_stackdump(lua_State *L)
|
||||||
lua_tonumber(L, i));
|
lua_tonumber(L, i));
|
||||||
buffer_putstr(buf, tmpbuf);
|
buffer_putstr(buf, tmpbuf);
|
||||||
break;
|
break;
|
||||||
|
case LUA_TTABLE: /* tables */
|
||||||
|
buffer_putstr(buf, "{\n");
|
||||||
|
lua_table_dump(L, i, buf, 1);
|
||||||
|
buffer_putstr(buf, "}\n");
|
||||||
|
break;
|
||||||
default: /* other values */
|
default: /* other values */
|
||||||
snprintf(tmpbuf, sizeof(tmpbuf), "%s\n",
|
snprintf(tmpbuf, sizeof(tmpbuf), "%s\n",
|
||||||
lua_typename(L, t));
|
lua_typename(L, t));
|
||||||
|
|
|
@ -181,6 +181,9 @@ int frrlua_table_get_integer(lua_State *L, const char *key);
|
||||||
*/
|
*/
|
||||||
void frrlua_export_logging(lua_State *L);
|
void frrlua_export_logging(lua_State *L);
|
||||||
|
|
||||||
|
/* A helper fuction that dumps the Lua stack */
|
||||||
|
void lua_table_dump(lua_State *L, int index, struct buffer *buf, int level);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Dump Lua stack to a string.
|
* Dump Lua stack to a string.
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in a new issue