Dynalon
Dynalon

Reputation: 6814

What is the python equivalent of g_log_set_handler when using GLib from python

I want to set the log level in my python glib project. Therefore I am looking for the g_log_set_handler() equivalent when using GLib from python via gi.repository.

But the expected GLib.log_set_handler function seems to be missing. Here is a sample output of my python shell:

~$ python
Python 2.7.3 (default, Apr 10 2013, 06:20:15) 
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from gi.repository import GLib 
>>> GLib.log_set_fatal_mask
<function log_set_fatal_mask at 0x2a7b668> 
>>> GLib.log_set_handler
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.7/dist-packages/gi/module.py", line 316, in __getattr__
    attr = super(DynamicGLibModule, self).__getattr__(name)
  File "/usr/lib/python2.7/dist-packages/gi/module.py", line 243, in __getattr__
     return getattr(self._introspection_module, name)
  File "/usr/lib/python2.7/dist-packages/gi/module.py", line 105, in __getattr__
    self.__name__, name))
  AttributeError: 'gi.repository.GLib' object has no attribute 'log_set_handler'
>>> 

As one can see, GLib from the introspection repository is found and the log_set_fatal_mask function exists (which is the equivalent of the g_log_set_fatal_mask). But log_set_handler is not found.

Why is that and how could I correctly set my loglevel from within python?

Upvotes: 1

Views: 605

Answers (2)

relent95
relent95

Reputation: 4732

Recently I got into this problem, and solved using ctypes, like the following example.

from ctypes import CDLL, CFUNCTYPE, POINTER, Structure, \
    c_int, c_uint, c_size_t, c_void_p, c_char_p
from gi.repository import GLib

libglib = CDLL('libglib-2.0.so.0')
def c_func(func, ret_type, *arg_types):
    func.restype = ret_type
    func.argtypes = arg_types

log_func_t = CFUNCTYPE(None, c_char_p, c_int, c_char_p, c_void_p)
c_func(libglib.g_log, None, c_char_p, c_int, c_char_p)
c_func(libglib.g_log_set_handler, c_uint, c_char_p, c_int, log_func_t, c_void_p)

@log_func_t
def log_func(domain, level, msg, data):
    print('log', domain, level, msg, data)

libglib.g_log_set_handler(None, 0x7f, log_func, None)
libglib.g_log(None, GLib.LogLevelFlags.LEVEL_MESSAGE, b'aaa')

But the modern GLib introduced the structured logging, and you need to call g_log_set_writer_func() to capture all messages. This also can be done with ctypes, but I'll omit that because it's out of the scope of this question.(It's much more complex than the above.)

Upvotes: 0

Dynalon
Dynalon

Reputation: 6814

I found out this is currently not possible and a known bug within either gobject-introspection or glib, since g_log_set_handler is not bindable.

See: https://bugzilla.gnome.org/show_bug.cgi?id=670507

Upvotes: 3

Related Questions