]> git.puffer.fish Git - mirror/frr.git/commitdiff
lib: Add a helper function to dump Lua stack 16676/head
authorDonatas Abraitis <donatas@opensourcerouting.org>
Wed, 28 Aug 2024 14:08:45 +0000 (17:08 +0300)
committerDonatas Abraitis <donatas@opensourcerouting.org>
Wed, 28 Aug 2024 14:08:45 +0000 (17:08 +0300)
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>
doc/developer/scripting.rst
lib/frrlua.c
lib/frrlua.h

index 7a4331449020f3e4cec7eb49e09f9fd4d4afd806..f51130b1e3e9761d01082332cae6315f30e12704 100644 (file)
@@ -523,6 +523,7 @@ object which contains methods corresponding to each of the ``zlog`` levels:
    log.error("error")
    log.notice("notice")
    log.debug("debug")
+   log.trace("trace")
 
 The log messages will show up in the daemon's log output.
 
@@ -579,14 +580,14 @@ accomplished with scripting.
            RM_FAILURE, RM_NOMATCH, RM_MATCH, RM_MATCH_AND_CHANGE)
 
            log.info("Evaluating route " .. prefix.network .. " from peer " .. peer.remote_id.string)
-   
+
            function on_match (prefix, attributes)
                    log.info("Match")
                    return {
                            attributes = RM_MATCH
                    }
            end
-   
+
            function on_nomatch (prefix, attributes)
                    log.info("No match")
                    return {
index 6ad0b5796a6d5af4a2386ae5399f80297a9ed166..ef081e4bd03495cbfcb20b6ac7626445863d97ab 100644 (file)
@@ -382,6 +382,12 @@ static const char *frrlua_log_thunk(lua_State *L)
        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)
 {
        zlog_debug("%s", frrlua_log_thunk(L));
@@ -413,11 +419,12 @@ static int frrlua_log_error(lua_State *L)
 }
 
 static const luaL_Reg log_funcs[] = {
-       {"debug", frrlua_log_debug},
-       {"info", frrlua_log_info},
-       {"notice", frrlua_log_notice},
-       {"warn", frrlua_log_warn},
-       {"error", frrlua_log_error},
+       { "trace", frrlua_log_trace },
+       { "debug", frrlua_log_debug },
+       { "info", frrlua_log_info },
+       { "notice", frrlua_log_notice },
+       { "warn", frrlua_log_warn },
+       { "error", frrlua_log_error },
        {},
 };
 
@@ -432,6 +439,67 @@ void frrlua_export_logging(lua_State *L)
  * 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)
 {
        int top = lua_gettop(L);
@@ -458,6 +526,11 @@ char *frrlua_stackdump(lua_State *L)
                                 lua_tonumber(L, i));
                        buffer_putstr(buf, tmpbuf);
                        break;
+               case LUA_TTABLE: /* tables */
+                       buffer_putstr(buf, "{\n");
+                       lua_table_dump(L, i, buf, 1);
+                       buffer_putstr(buf, "}\n");
+                       break;
                default: /* other values */
                        snprintf(tmpbuf, sizeof(tmpbuf), "%s\n",
                                 lua_typename(L, t));
index dc0f4d9986be90536c9c6b411cfff7aab917134a..e407a4492f67ec7bba0eaaef328bdc07deb2e484 100644 (file)
@@ -181,6 +181,9 @@ int frrlua_table_get_integer(lua_State *L, const char *key);
  */
 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.
  *