root/trunk/cheesecake/logger.py

Revision 2, 3.7 kB (checked in by grig, 6 years ago)

Initial import

  • Property svn:executable set to
Line 
1 import sys, re
2
3 ########################################################
4 ############### PRODUCERS ##############################
5 ########################################################
6
7 class Message(object):
8     def __init__(self, keywords, args):
9         self.keywords = keywords
10         self.args = args
11
12     def content(self):
13         return " ".join(map(str, self.args))
14
15     def prefix(self):
16         return "[%s] " % (":".join(self.keywords))
17
18     def __str__(self):
19         return self.prefix() + self.content()
20
21 class Producer(object):
22     """ Log producer API which sends messages to be logged
23         to a 'consumer' object, which then prints them to stdout,
24         stderr, files, etc.
25     """
26    
27     Message = Message  # to allow later customization
28     keywords2consumer = {}
29
30     def __init__(self, keywords):
31         if isinstance(keywords, str):
32             keywords = tuple(keywords.split())
33         self.keywords = keywords
34
35     def __repr__(self):
36         return "<Producer %s>" % ":".join(self.keywords)
37
38     def __getattr__(self, name):
39         if name[0] == '_':
40             raise AttributeError, name
41         producer = self.__class__(self.keywords + (name,))
42         setattr(self, name, producer)
43         return producer
44    
45     def __call__(self, *args):
46         func = self._getconsumer(self.keywords)
47         if func is not None:
48             func(self.Message(self.keywords, args))
49  
50     def _getconsumer(self, keywords):
51         for i in range(len(self.keywords), 0, -1):
52             try:
53                 return self.keywords2consumer[self.keywords[:i]]
54             except KeyError:
55                 continue
56         return self.keywords2consumer.get('default', default_consumer)
57
58 default = Producer('default')
59
60 def default_consumer(msg):
61     print str(msg)
62
63 Producer.keywords2consumer['default'] = default_consumer
64
65 class MultipleProducer(Producer):
66
67     def __call__(self, *args, **kwargs):
68         for func in self._getconsumer(self.keywords):
69             if func is not None:
70                 return func(self.Message(self.keywords, args), **kwargs)
71
72     def _getconsumer(self, keywords):
73         found_consumer = False
74         for keyword in keywords:
75             consumer = self.keywords2consumer.get((keyword,))
76             found_consumer = True
77             yield consumer
78         if not found_consumer:
79             yield self.keywords2consumer.get('default', default_consumer)
80
81 ########################################################
82 ############### CONSUMERS ##############################
83 ########################################################
84
85 class File(object):
86     def __init__(self, f):
87         assert hasattr(f, 'write')
88         assert isinstance(f, file) or not hasattr(f, 'open')
89         self._file = f
90
91     def __call__(self, msg):
92         print >>self._file, str(msg)
93
94 class Path(File):
95     def __init__(self, filename, append=False):
96         mode = append and 'a' or 'w'
97         f = open(str(filename), mode, buffering=1)
98         super(Path, self).__init__(f)
99
100 def STDOUT(msg):
101     print >>sys.stdout, str(msg)
102
103 def STDERR(msg):
104     print >>sys.stderr, str(msg)
105    
106 def setconsumer(keywords, consumer):
107     # normalize to tuples
108     if isinstance(keywords, str):
109         keywords = tuple(map(None, keywords.split()))
110     elif not isinstance(keywords, tuple):
111         raise TypeError("key %r is not a string or tuple" % (keywords,))
112     if consumer is not None and not callable(consumer):
113         if not hasattr(consumer, 'write'):
114             raise TypeError("%r should be None, callable or file-like" % (consumer,))
115         consumer = File(consumer)
116     #print "setting consumer for " + str(keywords) + "to " + str(consumer)
117     Producer.keywords2consumer[keywords] = consumer
118
Note: See TracBrowser for help on using the browser.