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
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;
}