From a5cc637f32a262c3ce5f84c064b4f88b15f2cf14 Mon Sep 17 00:00:00 2001 From: Dmitry Simonenko <pmwkaa@gmail.com> Date: Thu, 3 Sep 2015 13:49:29 +0300 Subject: [PATCH] fix for #1004: sophia monitoring access Work the same way as box.stat does. Support access by index: box.sophia['compaction.page_size'] and by call box.sophia() --- src/box/CMakeLists.txt | 1 + src/box/lua/call.cc | 3 +- src/box/lua/info.cc | 50 -------- src/box/lua/info.h | 1 - src/box/lua/sophia.cc | 208 ++++++++++++++++++++++++++++++++ src/box/lua/sophia.h | 37 ++++++ src/box/sophia_engine.cc | 19 ++- src/box/sophia_engine.h | 3 +- test/sophia/monitoring.result | 2 +- test/sophia/monitoring.test.lua | 2 +- 10 files changed, 267 insertions(+), 59 deletions(-) create mode 100644 src/box/lua/sophia.cc create mode 100644 src/box/lua/sophia.h diff --git a/src/box/CMakeLists.txt b/src/box/CMakeLists.txt index bcd9e17b4d..7c4d8a4bff 100644 --- a/src/box/CMakeLists.txt +++ b/src/box/CMakeLists.txt @@ -67,6 +67,7 @@ add_library(box lua/space.cc lua/info.cc lua/stat.cc + lua/sophia.cc lua/error.cc lua/session.cc lua/net_box.cc diff --git a/src/box/lua/call.cc b/src/box/lua/call.cc index 4d933247e2..9b9ed4ce76 100644 --- a/src/box/lua/call.cc +++ b/src/box/lua/call.cc @@ -36,6 +36,7 @@ #include "box/lua/index.h" #include "box/lua/space.h" #include "box/lua/stat.h" +#include "box/lua/sophia.h" #include "box/lua/info.h" #include "box/lua/session.h" #include "box/lua/net_box.h" @@ -726,8 +727,8 @@ box_lua_init(struct lua_State *L) box_lua_index_init(L); box_lua_space_init(L); box_lua_info_init(L); - box_lua_sophia_init(L); box_lua_stat_init(L); + box_lua_sophia_init(L); box_lua_session_init(L); /* Load Lua extension */ diff --git a/src/box/lua/info.cc b/src/box/lua/info.cc index d112e5a971..11b6cc1c6a 100644 --- a/src/box/lua/info.cc +++ b/src/box/lua/info.cc @@ -224,53 +224,3 @@ box_lua_info_init(struct lua_State *L) lua_pop(L, 1); /* info module */ } - -void sophia_info(void (*)(const char*, const char*, int, void*), void*); - -static void -lbox_sophia_cb(const char *key, const char *value, int /* pos */, void *arg) -{ - struct lua_State *L; - L = (struct lua_State*)arg; - if (value == NULL) - return; - lua_pushstring(L, key); - lua_pushstring(L, value); - lua_settable(L, -3); -} - -/** - * When user invokes box.sophia(), return a table of key/value - * pairs containing the current info. - */ -static int -lbox_sophia_call(struct lua_State *L) -{ - lua_newtable(L); - sophia_info(lbox_sophia_cb, (void*)L); - return 1; -} - -/** Initialize box.sophia package. */ -void -box_lua_sophia_init(struct lua_State *L) -{ - static const struct luaL_reg sophialib [] = { - {NULL, NULL} - }; - - luaL_register_module(L, "box.sophia", sophialib); - - lua_newtable(L); - - lua_pushstring(L, "__call"); - lua_pushcfunction(L, lbox_sophia_call); - lua_settable(L, -3); - - lua_pushstring(L, "__serialize"); - lua_pushcfunction(L, lbox_sophia_call); - lua_settable(L, -3); - - lua_setmetatable(L, -2); - lua_pop(L, 1); -} diff --git a/src/box/lua/info.h b/src/box/lua/info.h index ab4695e81e..a6093f47a5 100644 --- a/src/box/lua/info.h +++ b/src/box/lua/info.h @@ -34,6 +34,5 @@ struct lua_State; void box_lua_info_init(struct lua_State *L); -void box_lua_sophia_init(struct lua_State *L); #endif /* INCLUDES_TARANTOOL_LUA_INFO_H */ diff --git a/src/box/lua/sophia.cc b/src/box/lua/sophia.cc new file mode 100644 index 0000000000..de0083702f --- /dev/null +++ b/src/box/lua/sophia.cc @@ -0,0 +1,208 @@ +/* + * Copyright 2010-2015, Tarantool AUTHORS, please see AUTHORS file. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * 1. Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * <COPYRIGHT HOLDER> OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "sophia.h" + +extern "C" { +#include <lua.h> +#include <lauxlib.h> +#include <lualib.h> +} /* extern "C" */ + +#include "lua/utils.h" + +#if 0 +/** + * When user invokes box.sophia(), return a table of key/value + * pairs containing the current info. + */ +static int +lbox_sophia_call(struct lua_State *L) +{ + lua_newtable(L); + sophia_info(lbox_sophia_cb, (void*)L); + return 1; +} + +#if 0 +static int +lbox_sophia_index(struct lua_State *L) +{ + lbox_sophia_call(L); + //lua_pushvalue(L, -2); + lua_gettable(L, -2); + return 1; +} +#endif + +/** Initialize box.sophia package. */ +void +box_lua_sophia_init(struct lua_State *L) +{ + /* + static const struct luaL_reg sophialib [] = { + {NULL, NULL} + }; + */ + + //luaL_register_module(L, "box.sophia", sophialib); + lua_register(L, "box.sophia", lbox_sophia_call); + + //lbox_sophia_call(L); + + /* + lua_newtable(L); + + lua_pushstring(L, "__index"); + lua_pushcfunction(L, lbox_sophia_index); + lua_settable(L, -3); + + lua_pushstring(L, "__serialize"); + lua_pushcfunction(L, lbox_sophia_call); + lua_settable(L, -3); + */ + + //lua_setmetatable(L, -2); + lua_pop(L, 1); +} +#endif + +#if 0 +static void +fill_stat_item(struct lua_State *L, int rps, int64_t total) +{ + lua_pushstring(L, "rps"); + lua_pushnumber(L, rps); + lua_settable(L, -3); + + lua_pushstring(L, "total"); + lua_pushnumber(L, total); + lua_settable(L, -3); +} + +static int +set_stat_item(const char *name, int rps, int64_t total, void *cb_ctx) +{ + struct lua_State *L = (struct lua_State *) cb_ctx; + + lua_pushstring(L, name); + lua_newtable(L); + + fill_stat_item(L, rps, total); + + lua_settable(L, -3); + + return 0; +} + +/** + * A stat_foreach() callback used to handle access to e.g. + * box.stats.DELETE. + */ +static int +seek_stat_item(const char *name, int rps, int64_t total, void *cb_ctx) +{ + struct lua_State *L = (struct lua_State *) cb_ctx; + if (strcmp(name, lua_tostring(L, -1)) != 0) + return 0; + + lua_newtable(L); + fill_stat_item(L, rps, total); + + return 1; +} +#endif + +typedef void (*sophia_info_f)(const char*, const char*, void*); + +int sophia_info(const char *name, sophia_info_f, void*); + +static void +lbox_sophia_cb_index(const char* /* key */, const char *value, void *arg) +{ + struct lua_State *L; + L = (struct lua_State*)arg; + if (value == NULL) { + lua_pushnil(L); + return; + } + lua_pushstring(L, value); +} + +static int +lbox_sophia_index(struct lua_State *L) +{ + luaL_checkstring(L, -1); + const char *name = lua_tostring(L, -1); + return sophia_info(name, lbox_sophia_cb_index, (void*)L); +} + +static void +lbox_sophia_cb(const char *key, const char *value, void *arg) +{ + struct lua_State *L; + L = (struct lua_State*)arg; + if (value == NULL) + return; + lua_pushstring(L, key); + lua_pushstring(L, value); + lua_settable(L, -3); +} + +static int +lbox_sophia_call(struct lua_State *L) +{ + lua_newtable(L); + sophia_info(NULL, lbox_sophia_cb, (void*)L); + return 1; +} + +static const struct luaL_reg lbox_sophia_meta [] = { + {"__index", lbox_sophia_index}, + {"__call", lbox_sophia_call}, + {NULL, NULL} +}; + +void +box_lua_sophia_init(struct lua_State *L) +{ + static const struct luaL_reg sophialib [] = { + {NULL, NULL} + }; + + luaL_register_module(L, "box.sophia", sophialib); + + lua_newtable(L); + luaL_register(L, NULL, lbox_sophia_meta); + lua_setmetatable(L, -2); + + lua_pop(L, 1); /* sophia module */ +} diff --git a/src/box/lua/sophia.h b/src/box/lua/sophia.h new file mode 100644 index 0000000000..165d1b312e --- /dev/null +++ b/src/box/lua/sophia.h @@ -0,0 +1,37 @@ +#ifndef INCLUDES_TARANTOOL_LUA_SOPHIA_H +#define INCLUDES_TARANTOOL_LUA_SOPHIA_H +/* + * Copyright 2010-2015, Tarantool AUTHORS, please see AUTHORS file. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * 1. Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * <COPYRIGHT HOLDER> OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +struct lua_State; +void box_lua_sophia_init(struct lua_State *L); + +#endif /* INCLUDES_TARANTOOL_LUA_SOPHIA_H */ diff --git a/src/box/sophia_engine.cc b/src/box/sophia_engine.cc index 4f5c6ac868..a8a60c941e 100644 --- a/src/box/sophia_engine.cc +++ b/src/box/sophia_engine.cc @@ -62,19 +62,30 @@ void sophia_error(void *env) tnt_raise(ClientError, ER_SOPHIA, msg); } -void sophia_info(void (*cb)(const char*, const char*, int, void*), void *arg) +int sophia_info(const char *name, sophia_info_f cb, void *arg) { SophiaEngine *e = (SophiaEngine *)engine_find("sophia"); void *cursor = sp_getobject(e->env, NULL); void *o = NULL; - int i = 0; + if (name) { + while ((o = sp_get(cursor, o))) { + char *key = (char *)sp_getstring(o, "key", 0); + if (name && strcmp(key, name) != 0) + continue; + char *value = (char *)sp_getstring(o, "value", 0); + cb(key, value, arg); + return 1; + } + sp_destroy(cursor); + return 0; + } while ((o = sp_get(cursor, o))) { char *key = (char *)sp_getstring(o, "key", 0); char *value = (char *)sp_getstring(o, "value", 0); - cb(key, value, i, arg); - i++; + cb(key, value, arg); } sp_destroy(cursor); + return 0; } struct SophiaSpace: public Handler { diff --git a/src/box/sophia_engine.h b/src/box/sophia_engine.h index c9ffcaee88..4c7fd746f3 100644 --- a/src/box/sophia_engine.h +++ b/src/box/sophia_engine.h @@ -64,7 +64,8 @@ struct SophiaEngine: public Engine { ev_idle idle; }; +typedef void (*sophia_info_f)(const char*, const char*, void*); +int sophia_info(const char*, sophia_info_f, void*); void sophia_error(void*); -void sophia_info(void (*)(const char*, const char*, int, void*), void*); #endif /* TARANTOOL_BOX_SOPHIA_ENGINE_H_INCLUDED */ diff --git a/test/sophia/monitoring.result b/test/sophia/monitoring.result index 1d5bac8d48..35f969269b 100644 --- a/test/sophia/monitoring.result +++ b/test/sophia/monitoring.result @@ -4,7 +4,7 @@ space = box.schema.space.create('test', { engine = 'sophia' }) index = space:create_index('primary', { type = 'tree', parts = {1, 'str'} }) --- ... -box.sophia()['sophia.version'] +box.sophia['sophia.version'] --- - 2.1.1 ... diff --git a/test/sophia/monitoring.test.lua b/test/sophia/monitoring.test.lua index e15a49e8c4..e7e2647bfe 100644 --- a/test/sophia/monitoring.test.lua +++ b/test/sophia/monitoring.test.lua @@ -1,5 +1,5 @@ space = box.schema.space.create('test', { engine = 'sophia' }) index = space:create_index('primary', { type = 'tree', parts = {1, 'str'} }) -box.sophia()['sophia.version'] +box.sophia['sophia.version'] space:drop() -- GitLab