+/**
+ * collectd - src/python.c
+ * Copyright (C) 2009 Sven Trenkel
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Sven Trenkel <collectd at semidefinite.de>
+ **/
+
#include <Python.h>
#include <structmember.h>
"severity: An integer that should be compared to the LOG_ constants.\n"
"message: The text to be logged.\n"
"data: The optional data parameter passed to the register function.\n"
- " If the parameter was obmitted it will be obmitted here, too.";
+ " If the parameter was omitted it will be omitted here, too.";
static char reg_init_doc[] = "register_init(callback[, data][, name]) -> identifier\n"
"\n"
"Register a callback function that will be executed once after the config.\n"
"file has been read, all plugins heve been loaded and the collectd has\n"
- "forked into the backgroud.\n"
+ "forked into the background.\n"
"\n"
"'callback' is a callable object that will be executed.\n"
"'data' is an optional object that will be passed back to the callback\n"
"The callback function will be called with one or two parameters:\n"
"config: A Config object.\n"
"data: The optional data parameter passed to the register function.\n"
- " If the parameter was obmitted it will be obmitted here, too.";
+ " If the parameter was omitted it will be omitted here, too.";
static char reg_read_doc[] = "register_read(callback[, interval][, data][, name]) -> identifier\n"
"\n"
"The callback function will be called with one or two parameters:\n"
"values: A Values object which is a copy of the dispatched values.\n"
"data: The optional data parameter passed to the register function.\n"
- " If the parameter was obmitted it will be obmitted here, too.";
+ " If the parameter was omitted it will be omitted here, too.";
static char reg_notification_doc[] = "register_notification(callback[, data][, name]) -> identifier\n"
"\n"
"The callback function will be called with one or two parameters:\n"
"notification: A copy of the notification that was dispatched.\n"
"data: The optional data parameter passed to the register function.\n"
- " If the parameter was obmitted it will be obmitted here, too.";
+ " If the parameter was omitted it will be omitted here, too.";
static char reg_flush_doc[] = "register_flush(callback[, data][, name]) -> identifier\n"
"\n"
" be flushed.\n"
"id: Specifies which values are to be flushed.\n"
"data: The optional data parameter passed to the register function.\n"
- " If the parameter was obmitted it will be obmitted here, too.";
+ " If the parameter was omitted it will be omitted here, too.";
static char reg_shutdown_doc[] = "register_shutdown(callback[, data][, name]) -> identifier\n"
"\n"
line = PyList_GET_ITEM(list, i); /* Borrowed reference. */
s = strdup(PyString_AsString(line));
- Py_DECREF(line);
if (s[strlen(s) - 1] == '\n')
s[strlen(s) - 1] = 0;
Py_BEGIN_ALLOW_THREADS
}
if (PyErr_Occurred() != NULL) {
cpy_log_exception("value building for write callback");
+ Py_DECREF(list);
CPY_RETURN_FROM_THREADS 0;
}
}
- v = PyObject_CallFunction((PyObject *) &ValuesType, "sOssssdi", value_list->type, list,
- value_list->plugin_instance, value_list->type_instance, value_list->plugin,
- value_list->host, (double) value_list->time, value_list->interval);
+ v = PyObject_CallFunction((void *) &ValuesType, "sOssssdi", value_list->type,
+ list, value_list->plugin_instance, value_list->type_instance,
+ value_list->plugin, value_list->host, (double) value_list->time,
+ value_list->interval); /* New reference. */
Py_DECREF(list);
ret = PyObject_CallFunctionObjArgs(c->callback, v, c->data, (void *) 0); /* New reference. */
+ Py_XDECREF(v);
if (ret == NULL) {
cpy_log_exception("write callback");
} else {
PyObject *ret, *n;
CPY_LOCK_THREADS
- n = PyObject_CallFunction((PyObject *) &NotificationType, "ssssssdi", notification->type, notification->message,
+ n = PyObject_CallFunction((void *) &NotificationType, "ssssssdi", notification->type, notification->message,
notification->plugin_instance, notification->type_instance, notification->plugin,
- notification->host, (double) notification->time, notification->severity);
+ notification->host, (double) notification->time, notification->severity); /* New reference. */
ret = PyObject_CallFunctionObjArgs(c->callback, n, c->data, (void *) 0); /* New reference. */
+ Py_XDECREF(n);
if (ret == NULL) {
cpy_log_exception("notification callback");
} else {
}
static PyObject *cpy_register_log(PyObject *self, PyObject *args, PyObject *kwds) {
- return cpy_register_generic_userdata(plugin_register_log, cpy_log_callback, args, kwds);
+ return cpy_register_generic_userdata((void *) plugin_register_log,
+ (void *) cpy_log_callback, args, kwds);
}
static PyObject *cpy_register_write(PyObject *self, PyObject *args, PyObject *kwds) {
- return cpy_register_generic_userdata(plugin_register_write, cpy_write_callback, args, kwds);
+ return cpy_register_generic_userdata((void *) plugin_register_write,
+ (void *) cpy_write_callback, args, kwds);
}
static PyObject *cpy_register_notification(PyObject *self, PyObject *args, PyObject *kwds) {
- return cpy_register_generic_userdata(plugin_register_notification, cpy_notification_callback, args, kwds);
+ return cpy_register_generic_userdata((void *) plugin_register_notification,
+ (void *) cpy_notification_callback, args, kwds);
}
static PyObject *cpy_register_flush(PyObject *self, PyObject *args, PyObject *kwds) {
- return cpy_register_generic_userdata(plugin_register_flush, cpy_flush_callback, args, kwds);
+ return cpy_register_generic_userdata((void *) plugin_register_flush,
+ (void *) cpy_flush_callback, args, kwds);
}
static PyObject *cpy_register_shutdown(PyObject *self, PyObject *args, PyObject *kwds) {
static pthread_t thread;
sigset_t sigset;
+ if (!Py_IsInitialized()) {
+ WARNING("python: Plugin loaded but not configured.");
+ plugin_unregister_shutdown("python");
+ return 0;
+ }
PyEval_InitThreads();
/* Now it's finally OK to use python threads. */
for (c = cpy_init_callbacks; c; c = c->next) {
}
}
- item = PyObject_CallFunction((PyObject *) &ConfigType, "sONO", ci->key, parent, values, Py_None);
+ item = PyObject_CallFunction((void *) &ConfigType, "sONO", ci->key, parent, values, Py_None);
if (item == NULL)
return NULL;
children = PyTuple_New(ci->children_num); /* New reference. */
static int cpy_config(oconfig_item_t *ci) {
int i;
+ char *argv = "";
PyObject *sys, *tb;
PyObject *sys_path;
PyObject *module;
cpy_log_exception("python initialization");
return 1;
}
+ PySys_SetArgv(1, &argv);
+ PyList_SetSlice(sys_path, 0, 1, NULL);
+
module = Py_InitModule("collectd", cpy_methods); /* Borrowed reference. */
- PyModule_AddObject(module, "Config", (PyObject *) &ConfigType); /* Steals a reference. */
- PyModule_AddObject(module, "Values", (PyObject *) &ValuesType); /* Steals a reference. */
- PyModule_AddObject(module, "Notification", (PyObject *) &NotificationType); /* Steals a reference. */
+ PyModule_AddObject(module, "Config", (void *) &ConfigType); /* Steals a reference. */
+ PyModule_AddObject(module, "Values", (void *) &ValuesType); /* Steals a reference. */
+ PyModule_AddObject(module, "Notification", (void *) &NotificationType); /* Steals a reference. */
PyModule_AddIntConstant(module, "LOG_DEBUG", LOG_DEBUG);
PyModule_AddIntConstant(module, "LOG_INFO", LOG_INFO);
PyModule_AddIntConstant(module, "LOG_NOTICE", LOG_NOTICE);