-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy path_loggable.pyx
More file actions
100 lines (79 loc) · 2.98 KB
/
Copy path_loggable.pyx
File metadata and controls
100 lines (79 loc) · 2.98 KB
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
# cython: boundscheck=False
"""
This module provides a mixin class to add debug logging capabilities to other classes.
"""
from cpython.object cimport PyObject, PyObject_CallMethodObjArgs
from logging import Logger, getLogger, DEBUG
cdef PyObject* _DEBUG = <PyObject*>DEBUG
cdef class _LoggerMixin:
"""
A mixin class that adds logging capabilities to other classes.
This mixin provides a cached property for accessing a logger instance and a property to check if debug logging is enabled.
See Also:
- :func:`logging.getLogger`
- :class:`logging.Logger`
"""
@property
def logger(self) -> Logger:
"""
Provides a logger instance specific to the class using this mixin.
The logger ID is constructed from the module and class name, and optionally includes an instance name if available.
Examples:
>>> class MyClass(_LoggerMixin):
... _name = "example"
...
>>> instance = MyClass()
>>> logger = instance.logger
>>> logger.name
'module_name.MyClass.example'
>>> class AnotherClass(_LoggerMixin):
... pass
...
>>> another_instance = AnotherClass()
>>> another_logger = another_instance.logger
>>> another_logger.name
'module_name.AnotherClass'
Note:
Replace `module_name` with the actual module name where the class is defined.
See Also:
- :func:`logging.getLogger`
- :class:`logging.Logger`
"""
return self.get_logger()
cdef object get_logger(self):
cdef object logger, cls
cdef str cls_key, name
logger = self._logger
if logger is None:
cls = type(self)
name = getattr(self, "_name", "")
if name:
logger = getLogger(f"{cls.__module__}.{cls.__qualname__}.{name}")
else:
logger = _get_logger_for_cls(f"{cls.__module__}.{cls.__qualname__}")
self._logger = logger
return logger
@property
def debug_logs_enabled(self) -> bool:
"""
Checks if debug logging is enabled for the logger.
Examples:
>>> class MyClass(_LoggerMixin):
... pass
...
>>> instance = MyClass()
>>> instance.debug_logs_enabled
False
See Also:
- :attr:`logging.Logger.isEnabledFor`
"""
return PyObject_CallMethodObjArgs(self.get_logger(), "isEnabledFor", _DEBUG, NULL)
cdef inline bint check_debug_logs_enabled(self):
return PyObject_CallMethodObjArgs(self.get_logger(), "isEnabledFor", _DEBUG, NULL)
cdef dict[str, object] _class_loggers = {}
cdef object _get_logger_for_cls(str cls_key):
cdef object logger = _class_loggers.get(cls_key)
if logger is None:
logger = getLogger(cls_key)
_class_loggers[cls_key] = logger
return logger