From cfa803c101aa2a3bb70b7847bbd493afde4f7650 Mon Sep 17 00:00:00 2001 From: Julien Ammous Date: Sat, 13 Nov 2010 21:37:58 +0100 Subject: [PATCH] lua plugin: first version --- configure.in | 63 ++++++++++++++++++ src/Makefile.am | 11 ++++ src/lua.c | 190 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/lua_exports.c | 40 ++++++++++++ 4 files changed, 304 insertions(+) create mode 100644 src/lua.c create mode 100644 src/lua_exports.c diff --git a/configure.in b/configure.in index fd6a2570..b866639d 100644 --- a/configure.in +++ b/configure.in @@ -1358,6 +1358,66 @@ fi AM_CONDITIONAL(BUILD_WITH_LIBCREDIS, test "x$with_libcredis" = "xyes") # }}} + + + +# --with-lua {{{ +with_lua_cflags="" +with_lua_ldflags="" +with_lua_libs="" +AC_ARG_WITH(lua, [AS_HELP_STRING([--with-lua@<:@=PREFIX@:>@], [Path to lua library.])], +[ + if test "x$withval" != "xno" && test "x$withval" != "xyes" + then + with_lua_cflags="-I$withval/include" + with_lua_ldflags="-L$withval/lib" + with_lua="yes" + else + with_lua="$withval" + fi +], +[ + with_lua="yes" +]) + +SAVE_CFLAGS="$CFLAGS" +SAVE_LDFLAGS="$LDFLAGS" +CFLAGS="$SAVE_CFLAGS $with_lua_cflags" +LDFLAGS="$SAVE_LDFLAGS $with_lua_ldflags" +if test "x$with_lua" = "xyes" +then + AC_CHECK_LIB(lua, lua_settop, + [ + AC_DEFINE(HAVE_LUA, 1, [Define to 1 if you have the lua library (-llua).]) + ], [with_lua="no (lua not found)"]) +fi +if test "x$with_lua" = "xyes" +then + AC_CHECK_HEADERS(lua.h, + [ + AC_DEFINE(HAVE_LUA_H, 1, [Define to 1 if you have the header file.]) + ], [with_lua="no (lua.h not found)"]) +fi + +CFLAGS="$SAVE_CFLAGS" +LDFLAGS="$SAVE_LDFLAGS" + +if test "x$with_lua" = "xyes" +then + BUILD_WITH_LUA_CFLAGS="$with_lua_cflags" + BUILD_WITH_LUA_LDFLAGS="$with_lua_ldflags" + BUILD_WITH_LUA_LIBS="$with_lua_libs" + AC_SUBST(BUILD_WITH_LUA_CFLAGS) + AC_SUBST(BUILD_WITH_LUA_LDFLAGS) + AC_SUBST(BUILD_WITH_LUA_LIBS) +fi +AM_CONDITIONAL(BUILD_WITH_LUA, test "x$with_lua" = "xyes") +# }}} + + + + + # --with-libcurl {{{ with_curl_config="curl-config" with_curl_cflags="" @@ -4570,6 +4630,7 @@ AC_PLUGIN([libvirt], [$plugin_libvirt], [Virtual machine statistics]) AC_PLUGIN([load], [$plugin_load], [System load]) AC_PLUGIN([logfile], [yes], [File logging plugin]) AC_PLUGIN([lpar], [$with_perfstat], [AIX logical partitions statistics]) +AC_PLUGIN([lua], [$with_lua], [lua plugin]) AC_PLUGIN([madwifi], [$have_linux_wireless_h], [Madwifi wireless statistics]) AC_PLUGIN([match_empty_counter], [yes], [The empty counter match]) AC_PLUGIN([match_hashed], [yes], [The hashed match]) @@ -4820,6 +4881,7 @@ Configuration: libjvm . . . . . . . $with_java libkstat . . . . . . $with_kstat libkvm . . . . . . . $with_libkvm + liblua . . . . . . . $with_liblua libmemcached . . . . $with_libmemcached libmodbus . . . . . . $with_libmodbus libmysql . . . . . . $with_libmysql @@ -4896,6 +4958,7 @@ Configuration: load . . . . . . . . $enable_load logfile . . . . . . . $enable_logfile lpar... . . . . . . . $enable_lpar + lua . . . . . . . . . $enable_lua madwifi . . . . . . . $enable_madwifi match_empty_counter . $enable_match_empty_counter match_hashed . . . . $enable_match_hashed diff --git a/src/Makefile.am b/src/Makefile.am index 1a7ba5b1..f6e6b571 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -150,6 +150,17 @@ endif collectd_DEPENDENCIES += apache.la endif +if BUILD_PLUGIN_LUA +pkglib_LTLIBRARIES += lua.la +lua_la_SOURCES = lua.c +lua_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LUA_CFLAGS) +lua_la_LDFLAGS = -module -avoid-version +lua_la_LIBADD = $(BUILD_WITH_LUA_LIBS) +collectd_LDADD += "-dlopen" lua.la +collectd_DEPENDENCIES += lua.la +endif + + if BUILD_PLUGIN_APCUPS pkglib_LTLIBRARIES += apcups.la apcups_la_SOURCES = apcups.c diff --git a/src/lua.c b/src/lua.c new file mode 100644 index 00000000..294aa893 --- /dev/null +++ b/src/lua.c @@ -0,0 +1,190 @@ +/** + * collectd - src/lua.c + * Copyright (C) 2010 Julien Ammous + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; only version 2.1 of the License is + * applicable. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Authors: + * Julien Ammous + **/ + +#include // access + +/* Include the Lua API header files. */ +#define lua_c +#include +#include +#include + +#include "collectd.h" +#include "plugin.h" +#include "common.h" +#include "configfile.h" +#include "utils_cache.h" + +#include "lua_exports.c" + +typedef struct lua_script_s { + char *script_path; + lua_State *lua_state; + + struct lua_script_s *next; +} lua_script_t; + + +static char base_path[MAXPATHLEN]; +static lua_script_t scripts; + + + +/* Declare the Lua libraries we wish to use. */ +/* Note: If you are opening and running a file containing Lua code */ +/* using 'lua_dofile(l, "myfile.lua") - you must delcare all the libraries */ +/* used in that file here also. */ +static const luaL_reg lualibs[] = +{ + // { "base", luaopen_base }, + { NULL, NULL } +}; + +/* A function to open up all the Lua libraries you declared above. */ +static void openlualibs(lua_State *l) +{ + const luaL_reg *lib; + for( lib = lualibs; lib->func != NULL; lib++) { + lib->func(l); + lua_settop(l, 0); + } +} + + + + + +static int lua_config_base_path (const oconfig_item_t *ci) +{ + if( (ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING) ){ + ERROR("lua plugin: The '%s' config option requires a single string argument", ci->key); + return -1; + } + + strncpy(base_path, ci->values[0].value.string, sizeof(base_path)); + + /* add ending slash if not provided */ + if( base_path[strlen(base_path) - 1] != '/' ){ + base_path[strlen(base_path)] = '/'; + } + + INFO("lua plugin: BasePath = '%s'", base_path); + return 0; +} + +static int lua_config_script (const oconfig_item_t *ci) +{ + lua_script_t *script = &scripts; + + if( (ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING) ){ + ERROR("lua plugin: The '%s' config option requires a single string argument", ci->key); + return -1; + } + + /* find a free slot for the structure */ + while( script->next != NULL ){ + script = script->next; + } + + /* build full path : base_path + given path + \0 */ + script->script_path = malloc( + strlen(base_path) + + strlen(ci->values[0].value.string) + 1 + ); + + strncpy(script->script_path, base_path, sizeof(script->script_path)); + strncpy(script->script_path + strlen(base_path), ci->values[0].value.string, sizeof(script->script_path)); + + /* check if the file exists and we can read it */ + if( access(script->script_path, R_OK) == -1 ) { + ERROR("lua plugin: Cannot read file '%s' : %s", script->script_path, strerror(errno)); + free(script->script_path); + return -1; + } + + /* initialize the lua context */ + script->lua_state = lua_open(); + + openlualibs(script->lua_state); + + if( register_exported_functions(script->lua_state) != 0 ) { + ERROR("lua plugin: Cannot register exported functions, aborting"); + free(script->script_path); + return -1; + } + + /* and try to load the file */ + if( luaL_dofile(script->lua_state, "script.lua") != 0 ) { + ERROR("lua plugin: error while loading '%s' => %s\n", script->script_path, lua_tostring(script->lua_state, -1)); + free(script->script_path); + return -1; + } + + INFO("lua plugin: file '%s' loaded succesfully", script->script_path); + + return 0; +} + +// +// BasePath / +// Script script1.lua +// Script script2.lua +// +static int lua_config(oconfig_item_t *ci) +{ + int i; + + for (i = 0; i < ci->children_num; i++) + { + oconfig_item_t *child = ci->children + i; + + if (strcasecmp ("BasePath", child->key) == 0) { + lua_config_base_path(child); + } + else if (strcasecmp ("Script", child->key) == 0){ + lua_config_script(child); + } + else + { + WARNING ("network plugin: Option `%s' is not allowed here.", + child->key); + } + } + + return 0; +} + +static int lua_init() +{ + INFO("Lua plugin loaded."); + + return 0; +} + +void module_register() +{ + plugin_register_complex_config("lua", lua_config); + plugin_register_init("lua", lua_init); +} + + + diff --git a/src/lua_exports.c b/src/lua_exports.c new file mode 100644 index 00000000..a193f513 --- /dev/null +++ b/src/lua_exports.c @@ -0,0 +1,40 @@ +/** + * collectd - src/lua_exports.c + * Copyright (C) 2010 Julien Ammous + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; only version 2.1 of the License is + * applicable. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Authors: + * Julien Ammous + **/ + + +/* this file contains the functions exported to lua scripts */ + +/* log_info(string) */ +static int log_info(lua_State *l) +{ + const char *message = lua_tostring(l, 1); + INFO("%s", message); + // return the number of values pushed on stack + return 0; +} + + +static int register_exported_functions(lua_State *l){ + lua_register(l, "log_info", log_info); + return 0; +} + -- 2.11.0