From 3924acf6f1cdad1c457c312ad00cea4e9d854766 Mon Sep 17 00:00:00 2001
From: Sulverus <sulverus@gmail.com>
Date: Mon, 16 Mar 2015 17:00:55 +0000
Subject: [PATCH] 1.5 lua logging support

---
 src/CMakeLists.txt |  1 +
 src/lua/init.cc    |  2 +
 src/lua/log.lua    | 96 ++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 99 insertions(+)
 create mode 100644 src/lua/log.lua

diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index b1193e7d8b..bbfafd46ec 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -66,6 +66,7 @@ lua_source(lua_sources lua/digest.lua)
 lua_source(lua_sources lua/session.lua)
 lua_source(lua_sources lua/bsdsocket.lua)
 lua_source(lua_sources lua/errno.lua)
+lua_source(lua_sources lua/log.lua)
 
 add_custom_target(generate_lua_sources
     WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/src/box
diff --git a/src/lua/init.cc b/src/lua/init.cc
index e033f03f7f..58c53fbd3c 100644
--- a/src/lua/init.cc
+++ b/src/lua/init.cc
@@ -79,10 +79,12 @@ struct lua_State *tarantool_L;
 extern char uuid_lua[];
 extern char session_lua[];
 extern char digest_lua[];
+extern char log_lua[];
 static const char *lua_sources[] = {
 	uuid_lua,
 	session_lua,
 	digest_lua,
+        log_lua,
 	NULL
 };
 
diff --git a/src/lua/log.lua b/src/lua/log.lua
new file mode 100644
index 0000000000..6650b33e29
--- /dev/null
+++ b/src/lua/log.lua
@@ -0,0 +1,96 @@
+-- log.lua
+--
+local ffi = require('ffi')
+ffi.cdef[[
+char *
+tarantool_error_message(void);
+typedef int32_t pid_t;
+pid_t getpid(void);
+]]
+
+local pcall_lua = pcall
+
+local function pcall_wrap(status, ...)
+    if status == false and ... == 'C++ exception' then
+        return false, ffi.string(ffi.C.tarantool_error_message())
+    end
+    return status, ...
+end
+local pcall = function(fun, ...)
+    return pcall_wrap(pcall_lua(fun, ...))
+end
+
+local dostring = function(s, ...)
+    local chunk, message = loadstring(s)
+    if chunk == nil then
+        error(message, 2)
+    end
+    return chunk(...)
+end
+
+local function pid()
+    return tonumber(ffi.C.getpid())
+end
+
+
+ffi.cdef[[
+    typedef void (*sayfunc_t)(int level, const char *filename, int line,
+               const char *error, const char *format, ...);
+
+    extern sayfunc_t _say;
+    enum say_level {
+        S_FATAL,
+        S_SYSERROR,
+        S_ERROR,
+        S_CRIT,
+        S_WARN,
+        S_INFO,
+        S_DEBUG
+    };
+
+    pid_t logger_pid;
+]]
+
+local function say(level, fmt, ...)
+    local debug = require('debug')
+    local str = string.format(fmt, ...)
+    local frame = debug.getinfo(3, "Sl")
+    local line = 0
+    local file = 'eval'
+    if type(frame) == 'table' then
+        line = frame.currentline
+        if not line then
+            line = 0
+        end
+        file = frame.short_src
+        if not file then
+            file = frame.src
+        end
+        if not file then
+            file = 'eval'
+        end
+    end
+    ffi.C._say(level, file, line, nil, "%s", str)
+end
+
+return {
+    warn = function (fmt, ...)
+        say(ffi.C.S_WARN, fmt, ...)
+    end,
+
+    info = function (fmt, ...)
+        say(ffi.C.S_INFO, fmt, ...)
+    end,
+
+    debug = function (fmt, ...)
+        say(ffi.C.S_DEBUG, fmt, ...)
+    end,
+
+    error = function (fmt, ...)
+        say(ffi.C.S_ERROR, fmt, ...)
+    end,
+
+    logger_pid = function()
+        return tonumber(ffi.C.logger_pid)
+    end
+}
-- 
GitLab