PyErr_Clear();
}
-static void cpy_log_exception(const char *context) {
+void cpy_log_exception(const char *context) {
int l = 0, i;
const char *typename = NULL, *message = NULL;
PyObject *type, *value, *traceback, *tn, *m, *list;
static int cpy_write_callback(const data_set_t *ds, const value_list_t *value_list, user_data_t *data) {
int i;
cpy_callback_t *c = data->data;
- PyObject *ret, *list;
+ PyObject *ret, *list, *temp, *dict = NULL;
Values *v;
CPY_LOCK_THREADS
}
if (PyErr_Occurred() != NULL) {
cpy_log_exception("value building for write callback");
+ Py_DECREF(list);
CPY_RETURN_FROM_THREADS 0;
}
}
- v = PyObject_New(Values, (void *) &ValuesType);
+ dict = PyDict_New();
+ if (value_list->meta) {
+ int i, num;
+ char **table;
+ meta_data_t *meta = value_list->meta;
+
+ num = meta_data_toc(meta, &table);
+ for (i = 0; i < num; ++i) {
+ int type;
+ char *string;
+ int64_t si;
+ uint64_t ui;
+ double d;
+ _Bool b;
+
+ type = meta_data_type(meta, table[i]);
+ if (type == MD_TYPE_STRING) {
+ if (meta_data_get_string(meta, table[i], &string))
+ continue;
+ temp = cpy_string_to_unicode_or_bytes(string);
+ free(string);
+ PyDict_SetItemString(dict, table[i], temp);
+ Py_XDECREF(temp);
+ } else if (type == MD_TYPE_SIGNED_INT) {
+ if (meta_data_get_signed_int(meta, table[i], &si))
+ continue;
+ temp = PyObject_CallFunctionObjArgs((void *) &SignedType, PyLong_FromLongLong(si), (void *) 0);
+ PyDict_SetItemString(dict, table[i], temp);
+ Py_XDECREF(temp);
+ } else if (type == MD_TYPE_UNSIGNED_INT) {
+ if (meta_data_get_unsigned_int(meta, table[i], &ui))
+ continue;
+ temp = PyObject_CallFunctionObjArgs((void *) &UnsignedType, PyLong_FromUnsignedLongLong(ui), (void *) 0);
+ PyDict_SetItemString(dict, table[i], temp);
+ Py_XDECREF(temp);
+ } else if (type == MD_TYPE_DOUBLE) {
+ if (meta_data_get_double(meta, table[i], &d))
+ continue;
+ temp = PyFloat_FromDouble(d);
+ PyDict_SetItemString(dict, table[i], temp);
+ Py_XDECREF(temp);
+ } else if (type == MD_TYPE_BOOLEAN) {
+ if (meta_data_get_boolean(meta, table[i], &b))
+ continue;
+ if (b)
+ PyDict_SetItemString(dict, table[i], Py_True);
+ else
+ PyDict_SetItemString(dict, table[i], Py_False);
+ }
+ free(table[i]);
+ }
+ free(table);
+ }
+ v = PyObject_New(Values, (void *) &ValuesType); /* New reference. */
sstrncpy(v->data.host, value_list->host, sizeof(v->data.host));
sstrncpy(v->data.type, value_list->type, sizeof(v->data.type));
sstrncpy(v->data.type_instance, value_list->type_instance, sizeof(v->data.type_instance));
v->data.time = value_list->time;
v->interval = value_list->interval;
v->values = list;
+ v->meta = dict;
ret = PyObject_CallFunctionObjArgs(c->callback, v, c->data, (void *) 0); /* New reference. */
+ Py_XDECREF(v);
if (ret == NULL) {
cpy_log_exception("write callback");
} else {
Notification *n;
CPY_LOCK_THREADS
- n = PyObject_New(Notification, (void *) &NotificationType);
+ n = PyObject_New(Notification, (void *) &NotificationType); /* New reference. */
sstrncpy(n->data.host, notification->host, sizeof(n->data.host));
sstrncpy(n->data.type, notification->type, sizeof(n->data.type));
sstrncpy(n->data.type_instance, notification->type_instance, sizeof(n->data.type_instance));
sstrncpy(n->message, notification->message, sizeof(n->message));
n->severity = notification->severity;
ret = PyObject_CallFunctionObjArgs(c->callback, n, c->data, (void *) 0); /* New reference. */
+ Py_XDECREF(n);
if (ret == NULL) {
cpy_log_exception("notification callback");
} else {
user_data->data = c;
ts.tv_sec = interval;
ts.tv_nsec = (interval - ts.tv_sec) * 1000000000;
- plugin_register_complex_read(buf, cpy_read_callback, &ts, user_data);
+ plugin_register_complex_read(/* group = */ NULL, buf,
+ cpy_read_callback, &ts, user_data);
return cpy_string_to_unicode_or_bytes(buf);
}
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) {
PyType_Ready(&ValuesType);
NotificationType.tp_base = &PluginDataType;
PyType_Ready(&NotificationType);
+ SignedType.tp_base = &PyLong_Type;
+ PyType_Ready(&SignedType);
+ UnsignedType.tp_base = &PyLong_Type;
+ PyType_Ready(&UnsignedType);
sys = PyImport_ImportModule("sys"); /* New reference. */
if (sys == NULL) {
cpy_log_exception("python initialization");
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_AddObject(module, "Signed", (void *) &SignedType); /* Steals a reference. */
+ PyModule_AddObject(module, "Unsigned", (void *) &UnsignedType); /* Steals a reference. */
PyModule_AddIntConstant(module, "LOG_DEBUG", LOG_DEBUG);
PyModule_AddIntConstant(module, "LOG_INFO", LOG_INFO);
PyModule_AddIntConstant(module, "LOG_NOTICE", LOG_NOTICE);