Skip to content

Commit

Permalink
Add the redis.log function in Lua script (#379)
Browse files Browse the repository at this point in the history
We implement the builtin function `redis.log()` for the Lua script,
but the log level was different between Redis and Kvrocks, so we
choose to keep consistency with Redis's log level to avoid compatible
problem with below mappings(which would make the legacy script happy):

LOG_DEBUG   => NULL
LOG_VERBOSE => INFO
LOG_NOTICE  => INFO
LOG_WARNING => WARNING

LOG_DEBUG would never work since the debug level make no sense in kvrocks
  • Loading branch information
git-hulk authored Nov 1, 2021
1 parent d2c0afb commit e16f505
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 0 deletions.
76 changes: 76 additions & 0 deletions src/scripting.cc
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,13 @@
* This should be the size of the buffer given to doule to string */
#define MAX_LONG_DOUBLE_CHARS 5*1024

enum {
LL_DEBUG = 0,
LL_VERBOSE,
LL_NOTICE,
LL_WARNING,
};

extern "C" {
LUALIB_API int (luaopen_cjson)(lua_State *L);
LUALIB_API int (luaopen_struct)(lua_State *L);
Expand Down Expand Up @@ -53,6 +60,27 @@ namespace Lua {
lua_pushcfunction(lua, redisPCallCommand);
lua_settable(lua, -3);

/* redis.log and log levels. */
lua_pushstring(lua, "log");
lua_pushcfunction(lua, redisLogCommand);
lua_settable(lua, -3);

lua_pushstring(lua, "LOG_DEBUG");
lua_pushnumber(lua, LL_DEBUG);
lua_settable(lua, -3);

lua_pushstring(lua, "LOG_VERBOSE");
lua_pushnumber(lua, LL_VERBOSE);
lua_settable(lua, -3);

lua_pushstring(lua, "LOG_NOTICE");
lua_pushnumber(lua, LL_NOTICE);
lua_settable(lua, -3);

lua_pushstring(lua, "LOG_WARNING");
lua_pushnumber(lua, LL_WARNING);
lua_settable(lua, -3);

/* redis.sha1hex */
lua_pushstring(lua, "sha1hex");
lua_pushcfunction(lua, redisSha1hexCommand);
Expand Down Expand Up @@ -112,6 +140,54 @@ namespace Lua {
}
}


int redisLogCommand(lua_State *lua) {
int j, level, argc = lua_gettop(lua);

if (argc < 2) {
lua_pushstring(lua, "redis.log() requires two arguments or more.");
return lua_error(lua);
}
if (!lua_isnumber(lua, -argc)) {
lua_pushstring(lua, "First argument must be a number (log level).");
return lua_error(lua);
}
level = lua_tonumber(lua, -argc);
if (level < LL_DEBUG || level > LL_WARNING) {
lua_pushstring(lua, "Invalid debug level.");
return lua_error(lua);
}
if (level < GetServer()->GetConfig()->loglevel) {
return 0;
}

std::string log_message;
for (j = 1; j < argc; j++) {
size_t len;
const char *s;
s = lua_tolstring(lua, (-argc)+j, &len);
if (s) {
if (j != 1) {
log_message += " "+std::string(s, len);
} else {
log_message = std::string(s, len);
}
}
}

// The min log level was INFO, DEBUG would never take effect
switch (level) {
case LL_VERBOSE: // also regard VERBOSE as INFO here since no VERBOSE level
case LL_NOTICE:
LOG(INFO) << "[Lua] " << log_message;
break;
case LL_WARNING:
LOG(WARNING) << "[Lua] " << log_message;
break;
}
return 0;
}

Status evalGenericCommand(Redis::Connection *conn,
const std::vector<std::string> &args,
bool evalsha,
Expand Down
2 changes: 2 additions & 0 deletions src/scripting.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ int redisSha1hexCommand(lua_State *lua);
int redisStatusReplyCommand(lua_State *lua);
int redisErrorReplyCommand(lua_State *lua);
Status createFunction(Server *srv, const std::string &body, std::string *sha);

int redisLogCommand(lua_State *lua);
Status evalGenericCommand(Redis::Connection *conn,
const std::vector<std::string> &args,
bool evalsha,
Expand Down
11 changes: 11 additions & 0 deletions tests/tcl/tests/unit/scripting.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,17 @@ start_server {tags {"scripting"}} {
r sadd myset a b c d e f g h i l m n o p q r s t u v z aa aaa azz
r eval {return redis.call('smembers',KEYS[1])} 1 myset
} {a aa aaa azz b c d e f g h i l m n o p q r s t u v z}

test "Make sure redis.log() works" {
set v [r eval { return redis.log(redis.LOG_DEBUG, 'debug level'); } 0]
assert_equal "" $v
set v [r eval { return redis.log(redis.LOG_VERBOSE, 'verbose level'); } 0]
assert_equal "" $v
set v [r eval { return redis.log(redis.LOG_NOTICE, 'notice level'); } 0]
assert_equal "" $v
set v [r eval { return redis.log(redis.LOG_WARNING, 'warning level'); } 0]
assert_equal "" $v
} {}
}

start_server {tags {"repl"}} {
Expand Down

0 comments on commit e16f505

Please sign in to comment.