X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=src%2Fpyvalues.c;h=78e6cf9d450413ed242fb73e6126a09f4dd86057;hb=2cbd37356b2a3d3890b335d01e0d563269b448be;hp=cc7e296c020e0a7df6706f432a374371caeb7219;hpb=ce0118ae5a67654cce06dddc9998dc494beb4251;p=collectd.git diff --git a/src/pyvalues.c b/src/pyvalues.c index cc7e296c..78e6cf9d 100644 --- a/src/pyvalues.c +++ b/src/pyvalues.c @@ -32,6 +32,14 @@ #include "cpython.h" +#define FreeAll() do {\ + PyMem_Free(type);\ + PyMem_Free(plugin_instance);\ + PyMem_Free(type_instance);\ + PyMem_Free(plugin);\ + PyMem_Free(host);\ +} while(0) + static PyObject *cpy_common_repr(PyObject *s) { PyObject *ret, *tmp; static PyObject *l_type = NULL, *l_type_instance = NULL, *l_plugin = NULL, *l_plugin_instance = NULL; @@ -91,7 +99,7 @@ static PyObject *cpy_common_repr(PyObject *s) { if (self->time != 0) { CPY_STRCAT(&ret, l_time); - tmp = PyInt_FromLong(self->time); + tmp = PyFloat_FromDouble(self->time); CPY_SUBSTITUTE(PyObject_Repr, tmp, tmp); CPY_STRCAT_AND_DEL(&ret, tmp); } @@ -143,7 +151,7 @@ static PyObject *PluginData_new(PyTypeObject *type, PyObject *args, PyObject *kw static int PluginData_init(PyObject *s, PyObject *args, PyObject *kwds) { PluginData *self = (PluginData *) s; double time = 0; - const char *type = "", *plugin_instance = "", *type_instance = "", *plugin = "", *host = ""; + char *type = NULL, *plugin_instance = NULL, *type_instance = NULL, *plugin = NULL, *host = NULL; static char *kwlist[] = {"type", "plugin_instance", "type_instance", "plugin", "host", "time", NULL}; @@ -151,18 +159,21 @@ static int PluginData_init(PyObject *s, PyObject *args, PyObject *kwds) { NULL, &plugin_instance, NULL, &type_instance, NULL, &plugin, NULL, &host, &time)) return -1; - if (type[0] != 0 && plugin_get_ds(type) == NULL) { + if (type && plugin_get_ds(type) == NULL) { PyErr_Format(PyExc_TypeError, "Dataset %s not found", type); + FreeAll(); return -1; } - sstrncpy(self->host, host, sizeof(self->host)); - sstrncpy(self->plugin, plugin, sizeof(self->plugin)); - sstrncpy(self->plugin_instance, plugin_instance, sizeof(self->plugin_instance)); - sstrncpy(self->type, type, sizeof(self->type)); - sstrncpy(self->type_instance, type_instance, sizeof(self->type_instance)); - + sstrncpy(self->host, host ? host : "", sizeof(self->host)); + sstrncpy(self->plugin, plugin ? plugin : "", sizeof(self->plugin)); + sstrncpy(self->plugin_instance, plugin_instance ? plugin_instance : "", sizeof(self->plugin_instance)); + sstrncpy(self->type, type ? type : "", sizeof(self->type)); + sstrncpy(self->type_instance, type_instance ? type_instance : "", sizeof(self->type_instance)); self->time = time; + + FreeAll(); + return 0; } @@ -351,30 +362,32 @@ static PyObject *Values_new(PyTypeObject *type, PyObject *args, PyObject *kwds) static int Values_init(PyObject *s, PyObject *args, PyObject *kwds) { Values *self = (Values *) s; - int interval = 0; - double time = 0; + double interval = 0, time = 0; PyObject *values = NULL, *meta = NULL, *tmp; - const char *type = "", *plugin_instance = "", *type_instance = "", *plugin = "", *host = ""; + char *type = NULL, *plugin_instance = NULL, *type_instance = NULL, *plugin = NULL, *host = NULL; static char *kwlist[] = {"type", "values", "plugin_instance", "type_instance", "plugin", "host", "time", "interval", "meta", NULL}; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|etOetetetetdiO", kwlist, + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|etOetetetetddO", kwlist, NULL, &type, &values, NULL, &plugin_instance, NULL, &type_instance, NULL, &plugin, NULL, &host, &time, &interval, &meta)) return -1; - if (type[0] != 0 && plugin_get_ds(type) == NULL) { + if (type && plugin_get_ds(type) == NULL) { PyErr_Format(PyExc_TypeError, "Dataset %s not found", type); + FreeAll(); return -1; } - sstrncpy(self->data.host, host, sizeof(self->data.host)); - sstrncpy(self->data.plugin, plugin, sizeof(self->data.plugin)); - sstrncpy(self->data.plugin_instance, plugin_instance, sizeof(self->data.plugin_instance)); - sstrncpy(self->data.type, type, sizeof(self->data.type)); - sstrncpy(self->data.type_instance, type_instance, sizeof(self->data.type_instance)); + sstrncpy(self->data.host, host ? host : "", sizeof(self->data.host)); + sstrncpy(self->data.plugin, plugin ? plugin : "", sizeof(self->data.plugin)); + sstrncpy(self->data.plugin_instance, plugin_instance ? plugin_instance : "", sizeof(self->data.plugin_instance)); + sstrncpy(self->data.type, type ? type : "", sizeof(self->data.type)); + sstrncpy(self->data.type_instance, type_instance ? type_instance : "", sizeof(self->data.type_instance)); self->data.time = time; + FreeAll(); + if (values == NULL) { values = PyList_New(0); PyErr_Clear(); @@ -406,12 +419,21 @@ static meta_data_t *cpy_build_meta(PyObject *meta) { meta_data_t *m = NULL; PyObject *l; - if (!meta) + if ((meta == NULL) || (meta == Py_None)) return NULL; - m = meta_data_create(); - l = PyDict_Items(meta); + l = PyDict_Items(meta); /* New reference. */ + if (!l) { + cpy_log_exception("building meta data"); + return NULL; + } s = PyList_Size(l); + if (s <= 0) { + Py_XDECREF(l); + return NULL; + } + + m = meta_data_create(); for (i = 0; i < s; ++i) { const char *string, *keystring; PyObject *key, *value, *item, *tmp; @@ -475,6 +497,7 @@ static meta_data_t *cpy_build_meta(PyObject *meta) { Py_XDECREF(value); Py_DECREF(key); } + Py_XDECREF(l); return m; } @@ -485,28 +508,30 @@ static PyObject *Values_dispatch(Values *self, PyObject *args, PyObject *kwds) { value_t *value; value_list_t value_list = VALUE_LIST_INIT; PyObject *values = self->values, *meta = self->meta; - double time = self->data.time; - int interval = self->interval; - const char *host = self->data.host; - const char *plugin = self->data.plugin; - const char *plugin_instance = self->data.plugin_instance; - const char *type = self->data.type; - const char *type_instance = self->data.type_instance; + double time = self->data.time, interval = self->interval; + char *host = NULL, *plugin = NULL, *plugin_instance = NULL, *type = NULL, *type_instance = NULL; static char *kwlist[] = {"type", "values", "plugin_instance", "type_instance", "plugin", "host", "time", "interval", "meta", NULL}; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|etOetetetetdiO", kwlist, + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|etOetetetetddO", kwlist, NULL, &type, &values, NULL, &plugin_instance, NULL, &type_instance, NULL, &plugin, NULL, &host, &time, &interval, &meta)) return NULL; - if (type[0] == 0) { + sstrncpy(value_list.host, host ? host : self->data.host, sizeof(value_list.host)); + sstrncpy(value_list.plugin, plugin ? plugin : self->data.plugin, sizeof(value_list.plugin)); + sstrncpy(value_list.plugin_instance, plugin_instance ? plugin_instance : self->data.plugin_instance, sizeof(value_list.plugin_instance)); + sstrncpy(value_list.type, type ? type : self->data.type, sizeof(value_list.type)); + sstrncpy(value_list.type_instance, type_instance ? type_instance : self->data.type_instance, sizeof(value_list.type_instance)); + FreeAll(); + if (value_list.type[0] == 0) { PyErr_SetString(PyExc_RuntimeError, "type not set"); + FreeAll(); return NULL; } - ds = plugin_get_ds(type); + ds = plugin_get_ds(value_list.type); if (ds == NULL) { - PyErr_Format(PyExc_TypeError, "Dataset %s not found", type); + PyErr_Format(PyExc_TypeError, "Dataset %s not found", value_list.type); return NULL; } if (values == NULL || (PyTuple_Check(values) == 0 && PyList_Check(values) == 0)) { @@ -519,36 +544,44 @@ static PyObject *Values_dispatch(Values *self, PyObject *args, PyObject *kwds) { } 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); + PyErr_Format(PyExc_RuntimeError, "type %s needs %d values, got %i", value_list.type, ds->ds_num, size); return NULL; } value = malloc(size * sizeof(*value)); for (i = 0; i < size; ++i) { PyObject *item, *num; - item = PySequence_GetItem(values, i); + item = PySequence_Fast_GET_ITEM(values, i); /* Borrowed reference. */ if (ds->ds->type == DS_TYPE_COUNTER) { - num = PyNumber_Long(item); - if (num != NULL) + num = PyNumber_Long(item); /* New reference. */ + if (num != NULL) { value[i].counter = PyLong_AsUnsignedLongLong(num); + Py_XDECREF(num); + } } else if (ds->ds->type == DS_TYPE_GAUGE) { - num = PyNumber_Float(item); - if (num != NULL) + num = PyNumber_Float(item); /* New reference. */ + if (num != NULL) { value[i].gauge = PyFloat_AsDouble(num); + Py_XDECREF(num); + } } else if (ds->ds->type == DS_TYPE_DERIVE) { /* This might overflow without raising an exception. * Not much we can do about it */ - num = PyNumber_Long(item); - if (num != NULL) + num = PyNumber_Long(item); /* New reference. */ + if (num != NULL) { value[i].derive = PyLong_AsLongLong(num); + Py_XDECREF(num); + } } else if (ds->ds->type == DS_TYPE_ABSOLUTE) { /* This might overflow without raising an exception. * Not much we can do about it */ - num = PyNumber_Long(item); - if (num != NULL) + num = PyNumber_Long(item); /* New reference. */ + if (num != NULL) { value[i].absolute = PyLong_AsUnsignedLongLong(num); + Py_XDECREF(num); + } } else { free(value); - PyErr_Format(PyExc_RuntimeError, "unknown data type %d for %s", ds->ds->type, type); + PyErr_Format(PyExc_RuntimeError, "unknown data type %d for %s", ds->ds->type, value_list.type); return NULL; } if (PyErr_Occurred() != NULL) { @@ -559,13 +592,8 @@ 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; - sstrncpy(value_list.host, host, sizeof(value_list.host)); - sstrncpy(value_list.plugin, plugin, sizeof(value_list.plugin)); - 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.time = DOUBLE_TO_CDTIME_T(time); + value_list.interval = DOUBLE_TO_CDTIME_T(interval); if (value_list.host[0] == 0) sstrncpy(value_list.host, hostname_g, sizeof(value_list.host)); if (value_list.plugin[0] == 0) @@ -573,11 +601,12 @@ static PyObject *Values_dispatch(Values *self, PyObject *args, PyObject *kwds) { Py_BEGIN_ALLOW_THREADS; ret = plugin_dispatch_values(&value_list); Py_END_ALLOW_THREADS; + meta_data_destroy(value_list.meta); + free(value); if (ret != 0) { PyErr_SetString(PyExc_RuntimeError, "error dispatching values, read the logs"); return NULL; } - free(value); Py_RETURN_NONE; } @@ -588,29 +617,29 @@ static PyObject *Values_write(Values *self, PyObject *args, PyObject *kwds) { value_t *value; value_list_t value_list = VALUE_LIST_INIT; PyObject *values = self->values, *meta = self->meta; - double time = self->data.time; - int interval = self->interval; - const char *host = self->data.host; - const char *plugin = self->data.plugin; - const char *plugin_instance = self->data.plugin_instance; - const char *type = self->data.type; - const char *type_instance = self->data.type_instance; - const char *dest = NULL; + double time = self->data.time, interval = self->interval; + char *host = NULL, *plugin = NULL, *plugin_instance = NULL, *type = NULL, *type_instance = NULL, *dest = NULL; static char *kwlist[] = {"destination", "type", "values", "plugin_instance", "type_instance", "plugin", "host", "time", "interval", "meta", NULL}; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|etOetetetetdiO", kwlist, + if (!PyArg_ParseTupleAndKeywords(args, kwds, "et|etOetetetetdiO", kwlist, NULL, &dest, NULL, &type, &values, NULL, &plugin_instance, NULL, &type_instance, NULL, &plugin, NULL, &host, &time, &interval, &meta)) return NULL; - if (type[0] == 0) { + sstrncpy(value_list.host, host ? host : self->data.host, sizeof(value_list.host)); + sstrncpy(value_list.plugin, plugin ? plugin : self->data.plugin, sizeof(value_list.plugin)); + sstrncpy(value_list.plugin_instance, plugin_instance ? plugin_instance : self->data.plugin_instance, sizeof(value_list.plugin_instance)); + sstrncpy(value_list.type, type ? type : self->data.type, sizeof(value_list.type)); + sstrncpy(value_list.type_instance, type_instance ? type_instance : self->data.type_instance, sizeof(value_list.type_instance)); + FreeAll(); + if (value_list.type[0] == 0) { PyErr_SetString(PyExc_RuntimeError, "type not set"); return NULL; } - ds = plugin_get_ds(type); + ds = plugin_get_ds(value_list.type); if (ds == NULL) { - PyErr_Format(PyExc_TypeError, "Dataset %s not found", type); + PyErr_Format(PyExc_TypeError, "Dataset %s not found", value_list.type); return NULL; } if (values == NULL || (PyTuple_Check(values) == 0 && PyList_Check(values) == 0)) { @@ -619,36 +648,44 @@ static PyObject *Values_write(Values *self, PyObject *args, PyObject *kwds) { } 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); + PyErr_Format(PyExc_RuntimeError, "type %s needs %d values, got %i", value_list.type, ds->ds_num, size); return NULL; } value = malloc(size * sizeof(*value)); for (i = 0; i < size; ++i) { PyObject *item, *num; - item = PySequence_GetItem(values, i); + item = PySequence_Fast_GET_ITEM(values, i); /* Borrowed reference. */ if (ds->ds->type == DS_TYPE_COUNTER) { - num = PyNumber_Long(item); - if (num != NULL) + num = PyNumber_Long(item); /* New reference. */ + if (num != NULL) { value[i].counter = PyLong_AsUnsignedLongLong(num); + Py_XDECREF(num); + } } else if (ds->ds->type == DS_TYPE_GAUGE) { - num = PyNumber_Float(item); - if (num != NULL) + num = PyNumber_Float(item); /* New reference. */ + if (num != NULL) { value[i].gauge = PyFloat_AsDouble(num); + Py_XDECREF(num); + } } else if (ds->ds->type == DS_TYPE_DERIVE) { /* This might overflow without raising an exception. * Not much we can do about it */ - num = PyNumber_Long(item); - if (num != NULL) + num = PyNumber_Long(item); /* New reference. */ + if (num != NULL) { value[i].derive = PyLong_AsLongLong(num); + Py_XDECREF(num); + } } else if (ds->ds->type == DS_TYPE_ABSOLUTE) { /* This might overflow without raising an exception. * Not much we can do about it */ - num = PyNumber_Long(item); - if (num != NULL) + num = PyNumber_Long(item); /* New reference. */ + if (num != NULL) { value[i].absolute = PyLong_AsUnsignedLongLong(num); + Py_XDECREF(num); + } } else { free(value); - PyErr_Format(PyExc_RuntimeError, "unknown data type %d for %s", ds->ds->type, type); + PyErr_Format(PyExc_RuntimeError, "unknown data type %d for %s", ds->ds->type, value_list.type); return NULL; } if (PyErr_Occurred() != NULL) { @@ -658,13 +695,8 @@ static PyObject *Values_write(Values *self, PyObject *args, PyObject *kwds) { } value_list.values = value; value_list.values_len = size; - value_list.time = time; - value_list.interval = interval; - sstrncpy(value_list.host, host, sizeof(value_list.host)); - sstrncpy(value_list.plugin, plugin, sizeof(value_list.plugin)); - 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.time = DOUBLE_TO_CDTIME_T(time); + value_list.interval = DOUBLE_TO_CDTIME_T(interval); value_list.meta = cpy_build_meta(meta);; if (value_list.host[0] == 0) sstrncpy(value_list.host, hostname_g, sizeof(value_list.host)); @@ -673,11 +705,12 @@ static PyObject *Values_write(Values *self, PyObject *args, PyObject *kwds) { Py_BEGIN_ALLOW_THREADS; ret = plugin_write(dest, NULL, &value_list); Py_END_ALLOW_THREADS; + meta_data_destroy(value_list.meta); + free(value); if (ret != 0) { PyErr_SetString(PyExc_RuntimeError, "error dispatching values, read the logs"); return NULL; } - free(value); Py_RETURN_NONE; } @@ -701,7 +734,7 @@ static PyObject *Values_repr(PyObject *s) { ret = cpy_common_repr(s); if (self->interval != 0) { CPY_STRCAT(&ret, l_interval); - tmp = PyInt_FromLong(self->interval); + tmp = PyFloat_FromDouble(self->interval); CPY_SUBSTITUTE(PyObject_Repr, tmp, tmp); CPY_STRCAT_AND_DEL(&ret, tmp); } @@ -739,7 +772,7 @@ static void Values_dealloc(PyObject *self) { } static PyMemberDef Values_members[] = { - {"interval", T_INT, offsetof(Values, interval), 0, interval_doc}, + {"interval", T_DOUBLE, offsetof(Values, interval), 0, interval_doc}, {"values", T_OBJECT_EX, offsetof(Values, values), 0, values_doc}, {"meta", T_OBJECT_EX, offsetof(Values, meta), 0, meta_doc}, {NULL} @@ -807,8 +840,8 @@ static int Notification_init(PyObject *s, PyObject *args, PyObject *kwds) { Notification *self = (Notification *) s; int severity = 0; double time = 0; - const char *message = ""; - const char *type = "", *plugin_instance = "", *type_instance = "", *plugin = "", *host = ""; + char *message = NULL; + char *type = NULL, *plugin_instance = NULL, *type_instance = NULL, *plugin = NULL, *host = NULL; static char *kwlist[] = {"type", "message", "plugin_instance", "type_instance", "plugin", "host", "time", "severity", NULL}; @@ -817,20 +850,24 @@ static int Notification_init(PyObject *s, PyObject *args, PyObject *kwds) { NULL, &plugin, NULL, &host, &time, &severity)) return -1; - if (type[0] != 0 && plugin_get_ds(type) == NULL) { + if (type && plugin_get_ds(type) == NULL) { PyErr_Format(PyExc_TypeError, "Dataset %s not found", type); + FreeAll(); + PyMem_Free(message); return -1; } - sstrncpy(self->data.host, host, sizeof(self->data.host)); - sstrncpy(self->data.plugin, plugin, sizeof(self->data.plugin)); - sstrncpy(self->data.plugin_instance, plugin_instance, sizeof(self->data.plugin_instance)); - sstrncpy(self->data.type, type, sizeof(self->data.type)); - sstrncpy(self->data.type_instance, type_instance, sizeof(self->data.type_instance)); + sstrncpy(self->data.host, host ? host : "", sizeof(self->data.host)); + sstrncpy(self->data.plugin, plugin ? plugin : "", sizeof(self->data.plugin)); + sstrncpy(self->data.plugin_instance, plugin_instance ? plugin_instance : "", sizeof(self->data.plugin_instance)); + sstrncpy(self->data.type, type ? type : "", sizeof(self->data.type)); + sstrncpy(self->data.type_instance, type_instance ? type_instance : "", sizeof(self->data.type_instance)); + sstrncpy(self->message, message ? message : "", sizeof(self->message)); self->data.time = time; - - sstrncpy(self->message, message, sizeof(self->message)); self->severity = severity; + + FreeAll(); + PyMem_Free(message); return 0; } @@ -840,12 +877,8 @@ static PyObject *Notification_dispatch(Notification *self, PyObject *args, PyObj notification_t notification; double t = self->data.time; int severity = self->severity; - const char *host = self->data.host; - const char *plugin = self->data.plugin; - const char *plugin_instance = self->data.plugin_instance; - const char *type = self->data.type; - const char *type_instance = self->data.type_instance; - const char *message = self->message; + char *host = NULL, *plugin = NULL, *plugin_instance = NULL, *type = NULL, *type_instance = NULL; + char *message = NULL; static char *kwlist[] = {"type", "message", "plugin_instance", "type_instance", "plugin", "host", "time", "severity", NULL}; @@ -854,27 +887,30 @@ static PyObject *Notification_dispatch(Notification *self, PyObject *args, PyObj NULL, &plugin, NULL, &host, &t, &severity)) return NULL; - if (type[0] == 0) { + notification.time = DOUBLE_TO_CDTIME_T(t); + notification.severity = severity; + sstrncpy(notification.message, message ? message : self->message, sizeof(notification.message)); + sstrncpy(notification.host, host ? host : self->data.host, sizeof(notification.host)); + sstrncpy(notification.plugin, plugin ? plugin : self->data.plugin, sizeof(notification.plugin)); + sstrncpy(notification.plugin_instance, plugin_instance ? plugin_instance : self->data.plugin_instance, sizeof(notification.plugin_instance)); + sstrncpy(notification.type, type ? type : self->data.type, sizeof(notification.type)); + sstrncpy(notification.type_instance, type_instance ? type_instance : self->data.type_instance, sizeof(notification.type_instance)); + notification.meta = NULL; + FreeAll(); + PyMem_Free(message); + + if (notification.type[0] == 0) { PyErr_SetString(PyExc_RuntimeError, "type not set"); return NULL; } - ds = plugin_get_ds(type); + ds = plugin_get_ds(notification.type); if (ds == NULL) { - PyErr_Format(PyExc_TypeError, "Dataset %s not found", type); + PyErr_Format(PyExc_TypeError, "Dataset %s not found", notification.type); return NULL; } - notification.time = t; - notification.severity = severity; - sstrncpy(notification.message, message, sizeof(notification.message)); - sstrncpy(notification.host, host, sizeof(notification.host)); - sstrncpy(notification.plugin, plugin, sizeof(notification.plugin)); - sstrncpy(notification.plugin_instance, plugin_instance, sizeof(notification.plugin_instance)); - sstrncpy(notification.type, type, sizeof(notification.type)); - sstrncpy(notification.type_instance, type_instance, sizeof(notification.type_instance)); - notification.meta = NULL; - if (notification.time < 1) - notification.time = time(0); + if (notification.time == 0) + notification.time = cdtime(); if (notification.host[0] == 0) sstrncpy(notification.host, hostname_g, sizeof(notification.host)); if (notification.plugin[0] == 0)