summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 867ad62)
raw | patch | inline | side by side (parent: 867ad62)
author | Sven Trenkel <collectd@semidefinite.de> | |
Wed, 5 Jul 2017 21:24:56 +0000 (21:24 +0000) | ||
committer | Sven Trenkel <collectd@semidefinite.de> | |
Wed, 5 Jul 2017 21:24:56 +0000 (21:24 +0000) |
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 41170404368bcbb49cf83ec997ceb808f4877249..5389e7e8178c7328503fb725c3ee4037a3e5ae52 100644 (file)
--- a/src/cpython.h
+++ b/src/cpython.h
typedef struct {
PyObject_HEAD /* No semicolon! */
- PyObject *parent; /* Config */
+ PyObject *parent; /* Config */
PyObject *key; /* String */
PyObject *values; /* Sequence */
PyObject *children; /* Sequence */
typedef struct {
PyObject_HEAD /* No semicolon! */
- double time;
+ double time;
char host[DATA_MAX_NAME_LEN];
char plugin[DATA_MAX_NAME_LEN];
char plugin_instance[DATA_MAX_NAME_LEN];
diff --git a/src/python.c b/src/python.c
index b106e45cbb77e74df010716a455ed619cf3aa377..4807ba7fc24d549d9ffbe840c5a50d1dbffec569 100644 (file)
--- a/src/python.c
+++ b/src/python.c
"The callback function will be called with no parameters except for\n"
" data if it was supplied.";
+static char CollectdError_doc[] =
+ "Basic exception for collectd Python scripts.\n"
+ "\n"
+ "Throwing this exception will not cause a stacktrace to be logged, \n"
+ "even if LogTraces is enabled in the config.";
+
static pthread_t main_thread;
static PyOS_sighandler_t python_sigint_handler;
static _Bool do_interactive = 0;
static PyThreadState *state;
-static PyObject *sys_path, *cpy_format_exception;
+static PyObject *sys_path, *cpy_format_exception, *CollectdError;
static cpy_callback_t *cpy_config_callbacks;
static cpy_callback_t *cpy_init_callbacks;
}
void cpy_log_exception(const char *context) {
- int l = 0;
+ int l = 0, collectd_error;
const char *typename = NULL, *message = NULL;
PyObject *type, *value, *traceback, *tn, *m, *list;
PyErr_NormalizeException(&type, &value, &traceback);
if (type == NULL)
return;
+ collectd_error = PyErr_GivenExceptionMatches(value, CollectdError);
tn = PyObject_GetAttrString(type, "__name__"); /* New reference. */
m = PyObject_Str(value); /* New reference. */
if (tn != NULL)
typename = "NamelessException";
if (message == NULL)
message = "N/A";
- Py_BEGIN_ALLOW_THREADS ERROR("Unhandled python exception in %s: %s: %s",
- context, typename, message);
- Py_END_ALLOW_THREADS Py_XDECREF(tn);
+ Py_BEGIN_ALLOW_THREADS
+ if (collectd_error) {
+ WARNING("%s in %s: %s", typename, context, message);
+ } else {
+ ERROR("Unhandled python exception in %s: %s: %s",
+ context, typename, message);
+ }
+ Py_END_ALLOW_THREADS
+ Py_XDECREF(tn);
Py_XDECREF(m);
- if (!cpy_format_exception || !traceback) {
+ if (!cpy_format_exception || !traceback || collectd_error) {
PyErr_Clear();
Py_DECREF(type);
Py_XDECREF(value);
if (cpy[strlen(cpy) - 1] == '\n')
cpy[strlen(cpy) - 1] = 0;
- Py_BEGIN_ALLOW_THREADS ERROR("%s", cpy);
+ Py_BEGIN_ALLOW_THREADS
+ ERROR("%s", cpy);
Py_END_ALLOW_THREADS
- free(cpy);
+ free(cpy);
}
Py_XDECREF(list);
PyList_SetItem(
list, i, PyLong_FromUnsignedLongLong(value_list->values[i].absolute));
} else {
- Py_BEGIN_ALLOW_THREADS ERROR("cpy_write_callback: Unknown value type %d.",
- ds->ds[i].type);
- Py_END_ALLOW_THREADS Py_DECREF(list);
+ Py_BEGIN_ALLOW_THREADS
+ ERROR("cpy_write_callback: Unknown value type %d.", ds->ds[i].type);
+ Py_END_ALLOW_THREADS
+ Py_DECREF(list);
CPY_RETURN_FROM_THREADS 0;
}
if (PyErr_Occurred() != NULL) {
if (PyArg_ParseTupleAndKeywords(args, kwds, "|etiet", kwlist, NULL, &plugin,
&timeout, NULL, &identifier) == 0)
return NULL;
- Py_BEGIN_ALLOW_THREADS plugin_flush(plugin, timeout, identifier);
- Py_END_ALLOW_THREADS PyMem_Free(plugin);
+ Py_BEGIN_ALLOW_THREADS
+ plugin_flush(plugin, timeout, identifier);
+ Py_END_ALLOW_THREADS
+ PyMem_Free(plugin);
PyMem_Free(identifier);
Py_RETURN_NONE;
}
char *text;
if (PyArg_ParseTuple(args, "et", NULL, &text) == 0)
return NULL;
- Py_BEGIN_ALLOW_THREADS plugin_log(LOG_ERR, "%s", text);
- Py_END_ALLOW_THREADS PyMem_Free(text);
+ Py_BEGIN_ALLOW_THREADS
+ plugin_log(LOG_ERR, "%s", text);
+ Py_END_ALLOW_THREADS
+ PyMem_Free(text);
Py_RETURN_NONE;
}
char *text;
if (PyArg_ParseTuple(args, "et", NULL, &text) == 0)
return NULL;
- Py_BEGIN_ALLOW_THREADS plugin_log(LOG_WARNING, "%s", text);
- Py_END_ALLOW_THREADS PyMem_Free(text);
+ Py_BEGIN_ALLOW_THREADS
+ plugin_log(LOG_WARNING, "%s", text);
+ Py_END_ALLOW_THREADS
+ PyMem_Free(text);
Py_RETURN_NONE;
}
char *text;
if (PyArg_ParseTuple(args, "et", NULL, &text) == 0)
return NULL;
- Py_BEGIN_ALLOW_THREADS plugin_log(LOG_NOTICE, "%s", text);
- Py_END_ALLOW_THREADS PyMem_Free(text);
+ Py_BEGIN_ALLOW_THREADS
+ plugin_log(LOG_NOTICE, "%s", text);
+ Py_END_ALLOW_THREADS
+ PyMem_Free(text);
Py_RETURN_NONE;
}
char *text;
if (PyArg_ParseTuple(args, "et", NULL, &text) == 0)
return NULL;
- Py_BEGIN_ALLOW_THREADS plugin_log(LOG_INFO, "%s", text);
- Py_END_ALLOW_THREADS PyMem_Free(text);
+ Py_BEGIN_ALLOW_THREADS
+ plugin_log(LOG_INFO, "%s", text);
+ Py_END_ALLOW_THREADS
+ PyMem_Free(text);
Py_RETURN_NONE;
}
char *text;
if (PyArg_ParseTuple(args, "et", NULL, &text) == 0)
return NULL;
- Py_BEGIN_ALLOW_THREADS plugin_log(LOG_DEBUG, "%s", text);
- Py_END_ALLOW_THREADS PyMem_Free(text);
+ Py_BEGIN_ALLOW_THREADS
+ plugin_log(LOG_DEBUG, "%s", text);
+ Py_END_ALLOW_THREADS
+ PyMem_Free(text);
#endif
Py_RETURN_NONE;
}
}
PyErr_Print();
- Py_BEGIN_ALLOW_THREADS cpy_unregister_list(&cpy_config_callbacks);
+ Py_BEGIN_ALLOW_THREADS
+ cpy_unregister_list(&cpy_config_callbacks);
cpy_unregister_list(&cpy_init_callbacks);
cpy_unregister_list(&cpy_shutdown_callbacks);
cpy_shutdown_triggered = 1;
Py_END_ALLOW_THREADS
- if (!cpy_num_callbacks) {
+ if (!cpy_num_callbacks) {
Py_Finalize();
return 0;
}
static int cpy_init_python(void) {
PyOS_sighandler_t cur_sig;
- PyObject *sys;
+ PyObject *sys, *errordict;
PyObject *module;
#ifdef IS_PY3K
PyType_Ready(&SignedType);
UnsignedType.tp_base = &PyLong_Type;
PyType_Ready(&UnsignedType);
+ errordict = PyDict_New();
+ PyDict_SetItemString(errordict, "__doc__", cpy_string_to_unicode_or_bytes(CollectdError_doc)); /* New reference. */
+ CollectdError = PyErr_NewException("collectd.CollectdError", NULL, errordict);
sys = PyImport_ImportModule("sys"); /* New reference. */
if (sys == NULL) {
cpy_log_exception("python initialization");
(void *)&SignedType); /* Steals a reference. */
PyModule_AddObject(module, "Unsigned",
(void *)&UnsignedType); /* Steals a reference. */
+ Py_XINCREF(CollectdError);
+ PyModule_AddObject(module, "CollectdError", CollectdError); /* 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 e1856b84b4407e2986c88743cd317a30beca1fe2..4f7e8349af6265575f22ccc205f3a09c0a347170 100644 (file)
--- a/src/pyvalues.c
+++ b/src/pyvalues.c
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
Signed_doc /* tp_doc */
};
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
Unsigned_doc /* tp_doc */
};