#define PLUGIN_WRITE 2
#define PLUGIN_SHUTDOWN 3
#define PLUGIN_CONFIG 4
+#define PLUGIN_NOTIFICATION 5
typedef struct lua_script_s {
lua_State *lua_state;
return status;
} /* }}} int clua_write */
+static int clua_notification(const notification_t *notify,
+ user_data_t *ud) /* {{{ */
+{
+ clua_callback_data_t *cb = ud->data;
+
+ pthread_mutex_lock(&lua_lock);
+
+ lua_State *L = cb->lua_state;
+
+ int status = clua_load_callback(L, cb->callback_id);
+ if (status != 0) {
+ ERROR("Lua plugin: Unable to load callback \"%s\" (id %i).",
+ cb->lua_function_name, cb->callback_id);
+ pthread_mutex_unlock(&lua_lock);
+ return -1;
+ }
+ /* +1 = 1 */
+
+ /* convert notification_t to table on stack */
+ status = luaC_pushnotification(L, notify);
+ if (status != 0) {
+ lua_pop(L, 1); /* -1 = 0 */
+ pthread_mutex_unlock(&lua_lock);
+ ERROR("Lua plugin: luaC_notification failed.");
+ return -1;
+ }
+ /* +1 = 2 */
+
+ status = lua_pcall(L, 1, 1, 0); /* -2+1 = 1 */
+ if (status != 0) {
+ const char *errmsg = lua_tostring(L, -1);
+ if (errmsg == NULL)
+ ERROR("Lua plugin: Calling the notification callback failed. "
+ "In addition, retrieving the error message failed.");
+ else
+ ERROR("Lua plugin: Calling the notification callback failed:\n%s",
+ errmsg);
+ lua_pop(L, 1); /* -1 = 0 */
+ pthread_mutex_unlock(&lua_lock);
+ return -1;
+ }
+
+ if (!lua_isnumber(L, -1)) {
+ ERROR("Lua plugin: Notification function \"%s\" (id %i) did not return a "
+ "numeric value.",
+ cb->lua_function_name, cb->callback_id);
+ status = -1;
+ } else {
+ status = (int)lua_tointeger(L, -1);
+ }
+
+ lua_pop(L, 1); /* -1 = 0 */
+ pthread_mutex_unlock(&lua_lock);
+ return status;
+} /* }}} int clua_notification */
+
/*
* Exported functions
*/
if (status != 0)
return luaL_error(L, "lua_cb_register_plugin_callbacks(config) failed");
return 0;
+ } else if (PLUGIN_NOTIFICATION == type) {
+ int status =
+ plugin_register_notification(/* name = */ function_name,
+ /* callback = */ clua_notification,
+ &(user_data_t){
+ .data = cb,
+ .free_func = lua_cb_free,
+ });
+ if (status != 0)
+ return luaL_error(L, "plugin_register_notification failed");
+ return 0;
} else {
return luaL_error(L, "%s", "lua_cb_register_generic unsupported type");
}
return lua_cb_register_generic(L, PLUGIN_CONFIG);
}
+static int lua_cb_register_notification(lua_State *L) {
+ return lua_cb_register_generic(L, PLUGIN_NOTIFICATION);
+}
+
static const luaL_Reg collectdlib[] = {
{"log_debug", lua_cb_log_debug},
{"log_error", lua_cb_log_error},
{"register_init", lua_cb_register_init},
{"register_shutdown", lua_cb_register_shutdown},
{"register_config", lua_cb_register_config},
+ {"register_notification", lua_cb_register_notification},
{NULL, NULL}};
static int open_collectd(lua_State *L) /* {{{ */
}
return 0;
} /* }}} int luaC_pushoconfigitem */
+
+static int luaC_pushnotificationmeta(lua_State *L,
+ const notification_meta_t *meta) /* {{{ */
+{
+ /*
+ notification_meta_t will be mapped to the following Lua table:
+ {
+ key1 => value1,
+ ...,
+ keyN => valueN
+
+ }
+ */
+ lua_newtable(L);
+ for (; meta != NULL; meta = meta->next) {
+ switch (meta->type) {
+ case NM_TYPE_STRING:
+ lua_pushstring(L, meta->nm_value.nm_string);
+ break;
+ case NM_TYPE_SIGNED_INT:
+ lua_pushnumber(L, meta->nm_value.nm_signed_int);
+ break;
+ case NM_TYPE_UNSIGNED_INT:
+ lua_pushnumber(L, meta->nm_value.nm_unsigned_int);
+ break;
+ case NM_TYPE_DOUBLE:
+ lua_pushnumber(L, meta->nm_value.nm_double);
+ break;
+ case NM_TYPE_BOOLEAN:
+ lua_pushboolean(L, meta->nm_value.nm_boolean);
+ break;
+ }
+ lua_setfield(L, -2, meta->name);
+ }
+ return 0;
+}
+
+int luaC_pushnotification(lua_State *L,
+ const notification_t *notification) /* {{{ */
+{
+ /*
+ notification_t will be mapped to the following Lua table:
+
+ {
+ severity => ...,
+ time => ...,
+ message => ...,
+ host => ...,
+ plugin => ...,
+ plugin_instance => ...,
+ type => ...,
+ type_instance => ...,
+ meta => luaC_pushnotificationmeta();
+ }
+ */
+
+ lua_newtable(L);
+ switch (notification->severity) {
+ case NOTIF_FAILURE:
+ lua_pushstring(L, "failure");
+ lua_setfield(L, -2, "severity");
+ break;
+ case NOTIF_WARNING:
+ lua_pushstring(L, "warning");
+ lua_setfield(L, -2, "severity");
+ break;
+ case NOTIF_OKAY:
+ lua_pushstring(L, "okay");
+ lua_setfield(L, -2, "severity");
+ break;
+ }
+ luaC_pushcdtime(L, notification->time);
+ lua_setfield(L, -2, "time");
+ lua_pushstring(L, notification->message);
+ lua_setfield(L, -2, "message");
+ lua_pushstring(L, notification->host);
+ lua_setfield(L, -2, "host");
+ lua_pushstring(L, notification->plugin);
+ lua_setfield(L, -2, "plugin");
+ lua_pushstring(L, notification->plugin_instance);
+ lua_setfield(L, -2, "plugin_instance");
+ lua_pushstring(L, notification->type);
+ lua_setfield(L, -2, "type");
+ lua_pushstring(L, notification->type_instance);
+ lua_setfield(L, -2, "type_instance");
+ luaC_pushnotificationmeta(L, notification->meta);
+ lua_setfield(L, -2, "meta");
+ return 0;
+} /* }}} int luaC_pushnotification */