I would like to embed some Lua script in my C application…..specifically for LOGGING. I have used LOG4C before but am actually preferring “Lua Logging”….
NOTE: I am no Lua expert at all but am trying my best to get there soon 😉 Please bear with me…
Now I would like to know what the best way to do this is…meaning I want to LOG many events and process roughly 15 – 20 messages per seconds and each may have say 40 log messages. So if I call a C function for each message to be logged and then for EACH function call I do a “luaL_newstate”, “luaL_openlibs” and “lua_close” is that bad? It would appear to be but Lua is so lightweight and FAST I am wondering if it is that bad?
Obvioulsly I should rather have a “constructor” that is called ONCE for “luaL_newstate”, “luaL_openlibs” and then some sort of “destructor” for “”lua_close”..
lua_State *L;
L = luaL_newstate();
luaL_openlibs(L);
...
...
if (luaL_loadfile(L, "test_log.lua"))
bail(L, "luaL_loadfile() failed");
if (lua_pcall(L, 0, 0, 0))
bail(L, "lua_pcall() failed");
lua_getglobal(L, "writeLog");
lua_pushstring(L, buffer);
if (lua_pcall(L, 1, 1, 0))
bail(L, "lua_pcall() failed");
int result = lua_tonumber(L, -1);
....
lua_close(L);
Can you please advise me what the best solution would be here? Meaning if you say I must use a “Lua constructor”, can you please show me a small snippet of code to show me how this “logging process” should work in the best case scenario?
Thanks for the help 😉
Lynton
Your question really has little to do with Lua. It’s really about how to put together a global system in C that needs to be initialized at some point, and then shut down when the program exits.
I’m not a C expert, but the way I would do it is to have a pair of files,
log_system.handlog_system.c. Thelog_system.hwould have a function to log messages, a function to initialize the system, and a function to deinitialize it. The user of the logging system would then be required to initialize the system at the beginning of the program and deinitialize it at the end.The initialize function would set up a
lua_Stateand store it in a static global variable. The deinitialize function would close the staticlua_State. The logging function would check thelua_Stateand if it is valid (ie: non-NULL. The system has been initialized and not deinitialized), it will do whatever logging via Lua is necessary.There are other alternatives, like having a full-fledged object returned by the initialize function, which represents an instance of the logging system. This object would be an opaque pointer (for data hiding purposes) to an internal struct that contains a
lua_State(or it could just return avoid*that happens to be alua_State, but I’d prefer the extensibility of an opaque struct).In this case, the user would be responsible for keeping that object wherever it needs to in order to do appropriate logging.
Oh, and BTW, you have introduced a massive security hole in your application. The
test_log.luacan be replaced by users to their heart’s content. And since you open all of the Lua libraries in that Lua state, they are free to write files to wherever they want.I would suggest doing some reasonable encapsulation here. Get rid of all functions Lua functions that touch files (
dofile,loadfile,require, etc). Either that, ortest_log.luashould not be an external file; it should be something built into your executable. This could be as an internal executable resource or just as a static globalchar*somewhere