summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: dda5526)
raw | patch | inline | side by side (parent: dda5526)
author | Sven Trenkel <collectd@semidefinite.de> | |
Fri, 29 Jan 2010 13:12:41 +0000 (14:12 +0100) | ||
committer | Sven Trenkel <collectd@semidefinite.de> | |
Fri, 29 Jan 2010 13:12:41 +0000 (14:12 +0100) |
src/cpython.h | patch | blob | history | |
src/python.c | patch | blob | history | |
src/pyvalues.c | patch | blob | history |
diff --git a/src/cpython.h b/src/cpython.h
index df7fc6a4538c8e586e1e9dbc709cb0236b6a1909..b5a1754a912132931df542e7d6081b98dc688bb3 100644 (file)
--- a/src/cpython.h
+++ b/src/cpython.h
#endif
}
- /* Python object declarations. */
+void cpy_log_exception(const char *context);
+
+/* Python object declarations. */
typedef struct {
PyObject_HEAD /* No semicolon! */
PyObject *values; /* Sequence */
PyObject *children; /* Sequence */
} Config;
-
PyTypeObject ConfigType;
typedef struct {
char type[DATA_MAX_NAME_LEN];
char type_instance[DATA_MAX_NAME_LEN];
} PluginData;
-
PyTypeObject PluginDataType;
typedef struct {
PyObject *meta; /* dict */
int interval;
} Values;
-
PyTypeObject ValuesType;
typedef struct {
int severity;
char message[NOTIF_MAX_MSG_LEN];
} Notification;
-
PyTypeObject NotificationType;
+
+typedef PyLongObject Signed;
+PyTypeObject SignedType;
+
+typedef PyLongObject Unsigned;
+PyTypeObject UnsignedType;
diff --git a/src/python.c b/src/python.c
index a1e6a7e260f6eba8034b23a2bae1da62987e20a5..d193d2d127574713e75e9d2c1db6633f48243d1c 100644 (file)
--- a/src/python.c
+++ b/src/python.c
@@ -259,7 +259,7 @@ static void cpy_build_name(char *buf, size_t size, PyObject *callback, const cha
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;
@@ -400,13 +400,13 @@ static int cpy_write_callback(const data_set_t *ds, const value_list_t *value_li
} else if (type == MD_TYPE_SIGNED_INT) {
if (meta_data_get_signed_int(meta, table[i], &si))
continue;
- temp = PyLong_FromLongLong(si);
+ 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 = PyLong_FromUnsignedLongLong(ui);
+ 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) {
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);
diff --git a/src/pyvalues.c b/src/pyvalues.c
index ed0270f5d0ba8a611b45dc80f041b48c356863d4..a928cbc2803846b68681c18837a9f96d53f7da56 100644 (file)
--- a/src/pyvalues.c
+++ b/src/pyvalues.c
return 0;
}
+static meta_data_t *cpy_build_meta(PyObject *meta) {
+ int i, s;
+ meta_data_t *m = NULL;
+ PyObject *l;
+
+ if (!meta)
+ return NULL;
+
+ m = meta_data_create();
+ l = PyDict_Items(meta);
+ s = PyList_Size(l);
+ for (i = 0; i < s; ++i) {
+ const char *string, *keystring;
+ PyObject *key, *value, *item, *tmp;
+
+ item = PyList_GET_ITEM(l, i);
+ key = PyTuple_GET_ITEM(item, 0);
+ Py_INCREF(key);
+ keystring = cpy_unicode_or_bytes_to_string(&key);
+ if (!keystring) {
+ PyErr_Clear();
+ Py_XDECREF(key);
+ continue;
+ }
+ value = PyTuple_GET_ITEM(item, 1);
+ Py_INCREF(value);
+ if (value == Py_True) {
+ meta_data_add_boolean(m, keystring, 1);
+ } else if (value == Py_False) {
+ meta_data_add_boolean(m, keystring, 0);
+ } else if (PyFloat_Check(value)) {
+ meta_data_add_double(m, keystring, PyFloat_AsDouble(value));
+ } else if (PyObject_TypeCheck(value, &SignedType)) {
+ long long int lli;
+ lli = PyLong_AsLongLong(value);
+ if (!PyErr_Occurred() && (lli == (int64_t) lli))
+ meta_data_add_signed_int(m, keystring, lli);
+ } else if (PyObject_TypeCheck(value, &UnsignedType)) {
+ long long unsigned llu;
+ llu = PyLong_AsUnsignedLongLong(value);
+ if (!PyErr_Occurred() && (llu == (uint64_t) llu))
+ meta_data_add_unsigned_int(m, keystring, llu);
+ } else if (PyNumber_Check(value)) {
+ long long int lli;
+ long long unsigned llu;
+ tmp = PyNumber_Long(value);
+ lli = PyLong_AsLongLong(tmp);
+ if (!PyErr_Occurred() && (lli == (int64_t) lli)) {
+ meta_data_add_signed_int(m, keystring, lli);
+ } else {
+ PyErr_Clear();
+ llu = PyLong_AsUnsignedLongLong(tmp);
+ if (!PyErr_Occurred() && (llu == (uint64_t) llu))
+ meta_data_add_unsigned_int(m, keystring, llu);
+ }
+ Py_XDECREF(tmp);
+ } else {
+ string = cpy_unicode_or_bytes_to_string(&value);
+ if (string) {
+ meta_data_add_string(m, keystring, string);
+ } else {
+ PyErr_Clear();
+ tmp = PyObject_Str(value);
+ string = cpy_unicode_or_bytes_to_string(&tmp);
+ if (string)
+ meta_data_add_string(m, keystring, string);
+ Py_XDECREF(tmp);
+ }
+ }
+ if (PyErr_Occurred())
+ cpy_log_exception("building meta data");
+ Py_XDECREF(value);
+ Py_DECREF(keystring);
+ }
+ return m;
+}
+
static PyObject *Values_dispatch(Values *self, PyObject *args, PyObject *kwds) {
int i, ret;
const data_set_t *ds;
int size;
value_t *value;
value_list_t value_list = VALUE_LIST_INIT;
- PyObject *values = self->values;
+ PyObject *values = self->values, *meta = self->meta;
double time = self->data.time;
int interval = self->interval;
const char *host = self->data.host;
@@ -409,10 +486,10 @@ static PyObject *Values_dispatch(Values *self, PyObject *args, PyObject *kwds) {
const char *type_instance = self->data.type_instance;
static char *kwlist[] = {"type", "values", "plugin_instance", "type_instance",
- "plugin", "host", "time", "interval", NULL};
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "|etOetetetetdi", kwlist,
+ "plugin", "host", "time", "interval", "meta", NULL};
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "|etOetetetetdiO", kwlist,
NULL, &type, &values, NULL, &plugin_instance, NULL, &type_instance,
- NULL, &plugin, NULL, &host, &time, &interval))
+ NULL, &plugin, NULL, &host, &time, &interval, &meta))
return NULL;
if (type[0] == 0) {
@@ -428,6 +505,10 @@ static PyObject *Values_dispatch(Values *self, PyObject *args, PyObject *kwds) {
PyErr_Format(PyExc_TypeError, "values must be list or tuple");
return NULL;
}
+ if (meta != NULL && meta != Py_None && !PyDict_Check(meta)) {
+ PyErr_Format(PyExc_TypeError, "meta must be a dict");
+ return NULL;
+ }
size = (int) PySequence_Length(values);
if (size != ds->ds_num) {
PyErr_Format(PyExc_RuntimeError, "type %s needs %d values, got %i", type, ds->ds_num, size);
@@ -468,6 +549,7 @@ static PyObject *Values_dispatch(Values *self, PyObject *args, PyObject *kwds) {
}
}
value_list.values = value;
+ value_list.meta = cpy_build_meta(meta);
value_list.values_len = size;
value_list.time = time;
value_list.interval = interval;
@@ -476,7 +558,6 @@ static PyObject *Values_dispatch(Values *self, PyObject *args, PyObject *kwds) {
sstrncpy(value_list.plugin_instance, plugin_instance, sizeof(value_list.plugin_instance));
sstrncpy(value_list.type, type, sizeof(value_list.type));
sstrncpy(value_list.type_instance, type_instance, sizeof(value_list.type_instance));
- value_list.meta = NULL;
if (value_list.host[0] == 0)
sstrncpy(value_list.host, hostname_g, sizeof(value_list.host));
if (value_list.plugin[0] == 0)
int size;
value_t *value;
value_list_t value_list = VALUE_LIST_INIT;
- PyObject *values = self->values;
+ PyObject *values = self->values, *meta = self->meta;
double time = self->data.time;
int interval = self->interval;
const char *host = self->data.host;
const char *dest = NULL;
static char *kwlist[] = {"destination", "type", "values", "plugin_instance", "type_instance",
- "plugin", "host", "time", "interval", NULL};
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "|etOetetetetdi", kwlist,
+ "plugin", "host", "time", "interval", "meta", NULL};
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "|etOetetetetdiO", kwlist,
NULL, &type, &values, NULL, &plugin_instance, NULL, &type_instance,
- NULL, &plugin, NULL, &host, &time, &interval))
+ NULL, &plugin, NULL, &host, &time, &interval, &meta))
return NULL;
if (type[0] == 0) {
sstrncpy(value_list.plugin_instance, plugin_instance, sizeof(value_list.plugin_instance));
sstrncpy(value_list.type, type, sizeof(value_list.type));
sstrncpy(value_list.type_instance, type_instance, sizeof(value_list.type_instance));
- value_list.meta = NULL;
+ value_list.meta = cpy_build_meta(meta);;
if (value_list.host[0] == 0)
sstrncpy(value_list.host, hostname_g, sizeof(value_list.host));
if (value_list.plugin[0] == 0)
0, /* tp_alloc */
Notification_new /* tp_new */
};
+
+PyTypeObject SignedType = {
+ CPY_INIT_TYPE
+ "collectd.Signed", /* tp_name */
+ sizeof(Signed), /* tp_basicsize */
+ 0, /* Will be filled in later */
+ 0, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
+};
+
+PyTypeObject UnsignedType = {
+ CPY_INIT_TYPE
+ "collectd.Unsigned", /* tp_name */
+ sizeof(Unsigned), /* tp_basicsize */
+ 0, /* Will be filled in later */
+ 0, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
+};