mirror of https://github.com/labapart/gattlib
common/logging_backend: Introduce Python backend
parent
6751a17cee
commit
5f5cb5bd12
|
@ -61,7 +61,7 @@ endif()
|
|||
# With 'syslog' backend, we enable all logs (ie: up to level debug) and we leave the
|
||||
# application to set the level using 'setlogmask()'
|
||||
set(GATTLIB_LOG_LEVEL 3 CACHE STRING "Define the minimum logging level for Gattlib (0=error, 1=warning, 2=info, 3=debug)")
|
||||
set(GATTLIB_LOG_BACKEND syslog CACHE STRING "Define logging backend: syslog, printf (default: syslog)")
|
||||
set(GATTLIB_LOG_BACKEND syslog CACHE STRING "Define logging backend: syslog, printf, python (default: syslog)")
|
||||
|
||||
if (GATTLIB_DBUS)
|
||||
# Build dbus-based gattlib
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-or-later
|
||||
*
|
||||
* Copyright (c) 2024, Olivier Martin <olivier@labapart.org>
|
||||
*/
|
||||
|
||||
#include <syslog.h>
|
||||
|
||||
#include "gattlib_internal.h"
|
||||
|
||||
static PyObject* m_logging_func;
|
||||
|
||||
void gattlib_log_init(PyObject* logging_func) {
|
||||
m_logging_func = logging_func;
|
||||
}
|
||||
|
||||
void gattlib_log(int level, const char *format, ...) {
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
|
||||
if (m_logging_func == NULL) {
|
||||
FILE *stream = stdout;
|
||||
|
||||
if (level == GATTLIB_ERROR) {
|
||||
stream = stderr;
|
||||
}
|
||||
|
||||
vfprintf(stream, format, args);
|
||||
fprintf(stream, "\n");
|
||||
} else {
|
||||
PyGILState_STATE d_gstate;
|
||||
PyObject *result;
|
||||
char string[400];
|
||||
|
||||
vsnprintf(string, sizeof(string), format, args);
|
||||
|
||||
d_gstate = PyGILState_Ensure();
|
||||
|
||||
PyObject *arglist = Py_BuildValue("Is", level, string);
|
||||
#if PYTHON_VERSION >= PYTHON_VERSIONS(3, 9)
|
||||
result = PyObject_Call(m_logging_func, arglist, NULL);
|
||||
#else
|
||||
result = PyEval_CallObject(m_logging_func, arglist);
|
||||
#endif
|
||||
Py_DECREF(arglist);
|
||||
|
||||
if (result == NULL) {
|
||||
GATTLIB_LOG(GATTLIB_ERROR, "Python notification handler has raised an exception.");
|
||||
PyErr_Print();
|
||||
}
|
||||
|
||||
PyGILState_Release(d_gstate);
|
||||
}
|
||||
|
||||
va_end(args);
|
||||
}
|
|
@ -11,6 +11,28 @@ logger = logging.getLogger(__name__)
|
|||
|
||||
gattlib = CDLL("libgattlib.so")
|
||||
|
||||
def native_logging(level: int, string: str):
|
||||
if level == 3:
|
||||
logger.debug(string)
|
||||
elif level == 2:
|
||||
logger.info(string)
|
||||
elif level == 1:
|
||||
logger.warning(string)
|
||||
elif level == 0:
|
||||
logger.error(string)
|
||||
else:
|
||||
logger.debug(string)
|
||||
|
||||
try:
|
||||
# void gattlib_log_init(PyObject* logging_func)
|
||||
gattlib_log_init = gattlib.gattlib_log_init
|
||||
gattlib_log_init.argtypes = [py_object]
|
||||
|
||||
# Declare Python function for logging native string
|
||||
gattlib_log_init(native_logging)
|
||||
except AttributeError:
|
||||
# Excepted when using a Gattlib logging backend without 'gattlib_log_init'
|
||||
pass
|
||||
|
||||
# typedef struct {
|
||||
# uint8_t data[16];
|
||||
|
|
|
@ -78,7 +78,10 @@ class CMakeBuild(build_ext):
|
|||
cmake_args += [item for item in os.environ["CMAKE_ARGS"].split(" ") if item]
|
||||
|
||||
# In this example, we pass in the version to C++. You might not need to.
|
||||
cmake_args += [f"-DEXAMPLE_VERSION_INFO={self.distribution.get_version()}", "-DGATTLIB_BUILD_EXAMPLES=NO"]
|
||||
cmake_args += [
|
||||
f"-DEXAMPLE_VERSION_INFO={self.distribution.get_version()}",
|
||||
"-DGATTLIB_BUILD_EXAMPLES=NO",
|
||||
"-DGATTLIB_LOG_BACKEND=python"]
|
||||
|
||||
if self.compiler.compiler_type != "msvc":
|
||||
# Using Ninja-build since it a) is available as a wheel and b)
|
||||
|
|
Loading…
Reference in New Issue