lua plugin: first version
authorJulien Ammous <j.ammous@gmail.com>
Sat, 13 Nov 2010 20:37:58 +0000 (21:37 +0100)
committerFlorian Forster <octo@noris.net>
Wed, 24 Nov 2010 09:36:23 +0000 (10:36 +0100)
configure.in
src/Makefile.am
src/lua.c [new file with mode: 0644]
src/lua_exports.c [new file with mode: 0644]

index fd6a257..b866639 100644 (file)
@@ -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 <lua.h> 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
index 1a7ba5b..f6e6b57 100644 (file)
@@ -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 (file)
index 0000000..294aa89
--- /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 <unistd.h> // access
+
+/* Include the Lua API header files. */
+#define lua_c
+#include <lua.h>
+#include <lauxlib.h>
+#include <lualib.h>
+
+#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;
+}
+
+// <Plugin lua>
+//   BasePath /
+//   Script script1.lua
+//   Script script2.lua
+// </Plugin>
+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 (file)
index 0000000..a193f51
--- /dev/null
@@ -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;
+}
+