Passed
Push — master ( 1b986a...ef0e11 )
by Vinicius
03:22 queued 14s
created

kytos.core.logger_decorators   A

Complexity

Total Complexity 7

Size/Duplication

Total Lines 86
Duplicated Lines 0 %

Test Coverage

Coverage 95.35%

Importance

Changes 0
Metric Value
eloc 51
dl 0
loc 86
rs 10
c 0
b 0
f 0
ccs 41
cts 43
cp 0.9535
wmc 7

3 Functions

Rating   Name   Duplication   Size   Complexity  
A queue_decorator() 0 42 4
A root_decorator() 0 18 1
A apm_decorator() 0 13 2
1
"""Decorators for the logger class."""
2 1
import logging
3 1
from logging.handlers import QueueHandler, QueueListener
4 1
from queue import Queue
5
6 1
from kytos.core.apm import begin_span
7
8
9 1
def queue_decorator(klass):
10
    """Decorates the logger class so it uses queues internally"""
11 1
    class QueueLogger(klass):
12
        """Logger class decorated to use queues internally"""
13 1
        def __init__(self, *args, **kwargs):
14 1
            super().__init__(*args, **kwargs)
15 1
            self.queue = Queue()
16 1
            self.listener = QueueListener(self.queue,
17
                                          respect_handler_level=True)
18 1
            self.listener.start()
19 1
            super().addHandler(QueueHandler(self.queue))
20
21 1
        def _change_handlers(self, *hdlrs):
22
            """Set the handlers of the queue listener"""
23 1
            self.listener.stop()
24 1
            self.listener = QueueListener(self.queue, *hdlrs,
25
                                          respect_handler_level=True)
26 1
            self.listener.start()
27
28
        # pylint: disable=invalid-name
29 1
        def addHandler(self, hdlr):
30
            """Add a handler to the queue listener"""
31 1
            old_handlers = self.listener.handlers
32 1
            self._change_handlers(*old_handlers, hdlr)
33
34 1
        def removeHandler(self, hdlr):
35
            """Remove a handler from the queue listener"""
36 1
            old_handlers = self.listener.handlers
37 1
            new_handlers = [handler for handler in old_handlers
38
                            if handler is not hdlr]
39 1
            self._change_handlers(*new_handlers)
40
41 1
        def hasHandlers(self):
42
            """Check if the queue listener has any handlers"""
43 1
            if self.listener.handlers:
44 1
                return True
45 1
            if self.propagate and self.parent:
46
                return self.parent.hasHandlers()
47 1
            return False
48
        # pylint: disable=invalid-name
49
50 1
    return QueueLogger
51
52
53 1
def apm_decorator(klass):
54
    """Decorates the logger class for performance monitoring"""
55 1
    class APMLogger(klass):
56
        """Logger class decorated for log performance monitoring"""
57 1
        pass
58
59 1
    for func_name in ['debug', 'info', 'warning',
60
                      'error', 'exception', 'critical',
61
                      'fatal', 'log']:
62 1
        setattr(APMLogger, func_name,
63
                begin_span(getattr(klass, func_name), 'logging'))
64
65 1
    return APMLogger
66
67
68 1
def root_decorator(klass):
69
    """Decorator for turning a logger class into a root logger class"""
70 1
    class RootLogger(klass):
71
        """
72
        A root logger is not that different to any other logger, except that
73
        it must have a logging level and there is only one instance of it in
74
        the hierarchy.
75
        """
76 1
        def __init__(self, level):
77
            """
78
            Initialize the logger with the name "root".
79
            """
80 1
            super().__init__("root", level)
81
82 1
        def __reduce__(self):
83
            return logging.getLogger, ()
84
85
    return RootLogger
86