From: Michael Tremer Date: Mon, 16 Oct 2023 10:35:27 +0000 (+0000) Subject: _pakfire: Setup a default logging callback X-Git-Tag: 0.9.30~1492 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3986b2dfb46934f3ea9c9187b62a1f9526351bb8;p=pakfire.git _pakfire: Setup a default logging callback Signed-off-by: Michael Tremer --- diff --git a/src/_pakfire/_pakfiremodule.c b/src/_pakfire/_pakfiremodule.c index abdb21021..1d93ed023 100644 --- a/src/_pakfire/_pakfiremodule.c +++ b/src/_pakfire/_pakfiremodule.c @@ -49,7 +49,103 @@ PyObject* PyExc_CheckFileVerificationError; struct pakfire_ctx* pakfire_ctx = NULL; +static PyObject* setup_logger(void) { + PyObject* logging = NULL; + PyObject* logger = NULL; + + // import logging + logging = PyImport_ImportModule("logging"); + if (!logging) + goto ERROR; + + // logging.getLogger("pakfire") + logger = PyObject_CallMethod(logging, "getLogger", "s", "pakfire"); + if (!logger) + goto ERROR; + +ERROR: + Py_XDECREF(logging); + + return logger; +} + +static void __pakfire_log_callback(void* data, int level, const char* file, int line, + const char* fn, const char* format, va_list args) { + PyObject* logger = (PyObject*)data; + PyObject* result = NULL; + char* buffer = NULL; + int r; + + PyObject* exception = NULL; + PyObject* type = NULL; + PyObject* value = NULL; + PyObject* traceback = NULL; + + // Do nothing if the logger does not exist + if (!logger) + return; + + // Translate priority to Python logging priorities + switch (level) { + case LOG_DEBUG: + level = 10; + break; + + case LOG_INFO: + level = 20; + break; + + case LOG_ERR: + level = 40; + break; + + // Drop messages of an unknown level + default: + return; + } + + PyGILState_STATE state = PyGILState_Ensure(); + + // Format the log line + r = vasprintf(&buffer, format, args); + if (r < 0) + goto ERROR; + + // Call the logger + result = PyObject_CallMethod(logger, "log", "is", level, buffer); + if (!result) + goto ERROR; + +ERROR: + /* + We cannot really catch any Python errors here, since we cannot send + any error codes up the chain. + + So, in order to debug the problem, We will check if an exception has + occurred and if so, print it to the console. + */ + exception = PyErr_Occurred(); + if (exception) { + PyErr_Print(); + + // Fetch the exception and destroy it + PyErr_Fetch(&type, &value, &traceback); + + Py_XDECREF(type); + Py_XDECREF(value); + Py_XDECREF(traceback); + } + + if (buffer) + free(buffer); + Py_XDECREF(result); + + // Release the GIL + PyGILState_Release(state); +} + static int initialize_context(void) { + PyObject* logger = NULL; int r; // Create a new context @@ -59,12 +155,22 @@ static int initialize_context(void) { goto ERROR; } + // Setup the python logger + logger = setup_logger(); + if (r) + goto ERROR; + + // Pass all log messages to Python + pakfire_ctx_set_log_callback(pakfire_ctx, __pakfire_log_callback, logger); + Py_INCREF(logger); + // Set the log level to DEBUG pakfire_ctx_set_log_level(pakfire_ctx, LOG_DEBUG); ERROR: if (pakfire_ctx) pakfire_ctx_unref(pakfire_ctx); + Py_XDECREF(logger); return r; }