Statistics
| Branch: | Tag: | Revision:

mininet / mininet / logging_mod.py @ 60d9ead6

History | View | Annotate | Download (2.97 KB)

1 220890a0 Brandon Heller
'''Logging functions for Mininet.'''
2 7b804ffb Brandon Heller
3 220890a0 Brandon Heller
import logging
4 7b804ffb Brandon Heller
import types
5
6 220890a0 Brandon Heller
LEVELS = {'debug': logging.DEBUG,
7
          'info': logging.INFO,
8
          'warning': logging.WARNING,
9
          'error': logging.ERROR,
10
          'critical': logging.CRITICAL}
11
12
# change this to logging.INFO to get printouts when running unit tests
13
LOG_LEVEL_DEFAULT = logging.WARNING
14
15
#default: '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
16
LOG_MSG_FORMAT = '%(message)s'
17
18
19
20
# Modified from python2.5/__init__.py
21
class StreamHandlerNoNewline(logging.StreamHandler):
22
    '''StreamHandler that doesn't print newlines by default.
23

24
    Since StreamHandler automatically adds newlines, define a mod to more
25
    easily support interactive mode when we want it, or errors-only logging for
26
    running unit tests.
27
    '''
28 7b804ffb Brandon Heller
29
    def emit(self, record):
30 220890a0 Brandon Heller
        '''
31 7b804ffb Brandon Heller
        Emit a record.
32

33
        If a formatter is specified, it is used to format the record.
34
        The record is then written to the stream with a trailing newline
35
        [N.B. this may be removed depending on feedback]. If exception
36
        information is present, it is formatted using
37
        traceback.print_exception and appended to the stream.
38 220890a0 Brandon Heller
        '''
39 7b804ffb Brandon Heller
        try:
40
            msg = self.format(record)
41 220890a0 Brandon Heller
            fs = '%s' # was '%s\n'
42
            if not hasattr(types, 'UnicodeType'): #if no unicode support...
43 7b804ffb Brandon Heller
                self.stream.write(fs % msg)
44
            else:
45
                try:
46
                    self.stream.write(fs % msg)
47
                except UnicodeError:
48 220890a0 Brandon Heller
                    self.stream.write(fs % msg.encode('UTF-8'))
49 7b804ffb Brandon Heller
            self.flush()
50
        except (KeyboardInterrupt, SystemExit):
51
            raise
52
        except:
53 220890a0 Brandon Heller
            self.handleError(record)
54
55
56
def set_loglevel(level_name = None):
57
    '''Setup loglevel.
58

59
    @param level_name level name from LEVELS
60
    '''
61
    level = LOG_LEVEL_DEFAULT
62
    if level_name != None:
63
        if level_name not in LEVELS:
64
            raise Exception('unknown loglevel seen in set_loglevel')
65
        else:
66
            level = LEVELS.get(level_name, level)
67
68
    lg.setLevel(level)
69
    if len(lg.handlers) != 1:
70
        raise Exception('lg.handlers length not zero in logging_mod')
71
    lg.handlers[0].setLevel(level)
72
73
74
def _setup_logging():
75
    '''Setup logging for Mininet.'''
76
    global lg
77
78
    # create logger if first time
79
    if 'lg' not in globals():
80
        lg = logging.getLogger('mininet')
81
        # create console handler
82
        ch = StreamHandlerNoNewline()
83
        # create formatter
84
        formatter = logging.Formatter(LOG_MSG_FORMAT)
85
        # add formatter to ch
86
        ch.setFormatter(formatter)
87
        # add ch to lg
88
        lg.addHandler(ch)
89
    else:
90
        raise Exception('setup_logging called twice')
91
92
    set_loglevel()
93
94
95
# There has to be some better way to ensure we only ever have one logging
96
# variable.  If this check isn't in, the order in which imports occur can
97
# affect whether a program runs, because the variable lg may get rebound.
98
if 'lg' not in globals():
99
    _setup_logging()