1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
|
#include <assert.h>
#include <errno.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <Python.h>
#include "log.h"
static PyObject *py_logger = NULL;
static PyObject *py_logger_log = NULL;
int logging_level = 0;
int log_setup()
{
if(py_logger == NULL)
{
// Import Python's logging module
PyObject *logging = PyImport_ImportModuleEx("logging",
NULL, NULL, NULL);
if(logging == NULL)
return -1;
// Get the logger
{
PyObject *func = PyObject_GetAttrString(logging, "getLogger");
py_logger = PyObject_CallFunction(func, "(s)", "reprozip");
Py_DECREF(logging);
Py_DECREF(func);
if(py_logger == NULL)
return -1;
}
// Get the log function
py_logger_log = PyObject_GetAttrString(py_logger, "log");
if(py_logger_log == NULL)
{
/* LCOV_EXCL_START : Logger objects always have a 'log' method */
Py_DECREF(py_logger);
py_logger = NULL;
return -1;
/* LCOV_EXCL_STOP */
}
}
// Get the effective logging level
{
PyObject *meth = PyObject_GetAttrString(py_logger,
"getEffectiveLevel");
PyObject *level = PyObject_CallFunctionObjArgs(meth, NULL);
Py_DECREF(meth);
if(level == NULL)
return -1;
logging_level = PyLong_AsLong(level);
if(PyErr_Occurred())
{
/* LCOV_EXCL_START : Logger objects are reliable */
Py_DECREF(level);
return -1;
/* LCOV_EXCL_STOP */
}
Py_DECREF(level);
}
return 0;
}
void log_real_(pid_t tid, int lvl, const char *format, ...)
{
va_list args;
char datestr[13]; /* HH:MM:SS.mmm */
static char *buffer = NULL;
static size_t bufsize = 4096;
size_t length;
/* Fast filter: don't call Python if level is not enough */
if(lvl < logging_level)
return;
if(buffer == NULL)
buffer = malloc(bufsize);
{
struct timeval tv;
gettimeofday(&tv, NULL);
strftime(datestr, 13, "%H:%M:%S", localtime(&tv.tv_sec));
sprintf(datestr+8, ".%03u", (unsigned int)(tv.tv_usec / 1000));
}
va_start(args, format);
length = (size_t)vsnprintf(buffer, bufsize, format, args);
va_end(args);
if(length + 1 >= bufsize)
{
while(length + 1 >= bufsize)
bufsize *= 2;
free(buffer);
buffer = malloc(bufsize);
va_start(args, format);
length = vsnprintf(buffer, bufsize, format, args);
va_end(args);
}
if(tid > 0)
PyObject_CallFunction(py_logger_log, "(l, s, l, s)",
lvl, "[%d] %s", tid, buffer);
else
PyObject_CallFunction(py_logger_log, "(l, s, s)",
lvl, "%s", buffer);
}
|