source: trunk/python/logging.py @ 2323

Last change on this file since 2323 was 2323, checked in by Malte Marquarding, 13 years ago

need to flush stdout to make log messages show immediately

File size: 3.4 KB
Line 
1"""This module presents a logging abstraction layer on top of casa.
2"""
3__all__ = ["asaplog", "asaplog_post_dec", "AsapLogger"]
4
5import inspect
6import sys
7from asap.env import is_casapy
8from asap.parameters import rcParams
9from asap._asap import LogSink, set_global_sink
10try:
11    from functools import wraps as wraps_dec
12except ImportError:
13    from asap.compatibility import wraps as wraps_dec
14
15
16class AsapLogger(object):
17    """Wrapper object to allow for both casapy and asap logging.
18
19    Inside casapy this will connect to `taskinit.casalog`. Otherwise it will
20    create its own casa log sink.
21
22    .. note:: Do not instantiate a new one - use the :obj:`asaplog` instead.
23
24    """
25    def __init__(self):
26        self._enabled = True
27        self._log = ""
28        if is_casapy():
29            from taskinit import casalog
30            self.logger = casalog
31        else:
32            self.logger = LogSink()
33            set_global_sink(self.logger)
34
35    def post(self, level='INFO', origin=""):
36        """Post the messages to the logger. This will clear the buffered
37        logs.
38
39        Parameters:
40
41            level:  The log level (severity). One of INFO, WARN, ERROR.
42
43        """
44        if not self._enabled:
45            return
46
47        if not origin:
48            origin = inspect.getframeinfo(inspect.currentframe().f_back)[2]
49        logs = self._log.strip()
50        if len(logs) > 0:
51            if isinstance(self.logger, LogSink):
52                #can't handle unicode in boost signature
53                logs = str(logs)
54            self.logger.post(logs, priority=level, origin=origin)
55        if isinstance(self.logger, LogSink):
56            logs = self.logger.pop().strip()
57            if len(logs) > 0:
58                print >>sys.stdout, logs
59                sys.stdout.flush()
60        self._log = ""
61
62    def clear(self):
63        if isinstance(self.logger, LogSink):
64            logs = self.logger.pop()
65           
66    def push(self, msg, newline=True):
67        """Push logs into the buffer. post needs to be called to send them.
68
69        Parameters:
70
71            msg:        the log message (string)
72
73            newline:    should we terminate with a newline (default yes)
74
75        """
76        if self._enabled:
77            sep = ""
78            self._log = sep.join([self._log, msg])
79            if newline:
80                self._log += "\n"
81
82    def enable(self, flag=True):
83        """Enable (or disable) logging."""
84        self._enabled = flag
85
86    def disable(self, flag=False):
87        """Disable (or enable) logging"""
88        self._enabled = flag
89
90    def is_enabled(self):
91        return self._enabled
92
93asaplog = AsapLogger()
94"""Default asap logger"""
95
96def asaplog_post_dec(f):
97    """Decorator which posts log at completion of the wrapped method.
98
99    Example::
100
101        @asaplog_post_dec
102        def test(self):
103            do_stuff()
104            asaplog.push('testing...', False)
105            do_more_stuff()
106            asaplog.push('finished')
107    """
108    @wraps_dec(f)
109    def wrap_it(*args, **kw):
110        level = "INFO"
111        try:
112            val = f(*args, **kw)
113            return val
114        except Exception, ex:
115            level = "ERROR"
116            asaplog.push(str(ex))
117            if rcParams['verbose']:
118                pass
119            else:
120                raise
121        finally:
122            asaplog.post(level, f.func_name)
123            #asaplog.post(level, ".".join([f.__module__,f.func_name]))
124    return wrap_it
125
Note: See TracBrowser for help on using the repository browser.