add logging module, use logging in cli.rename, cli uses decorator to parse options...
[audiomangler.git] / audiomangler / logging.py
blob275512f65a2596972381df20e62b20a4741874a6
1 # -*- coding: utf-8 -*-
2 from twisted.python import log, failure
3 from audiomangler import Config
4 import os, sys, atexit
6 try:
7 from cStringIO import StringIO
8 except ImportError:
9 from StringIO import StringIO
11 loglevels = dict(ERROR=0, WARNING=1, INFO=2, DEBUG=3)
12 locals().update(loglevels)
13 loglevels.update(map(reversed, loglevels.items()))
15 class FilteredFileLogObserver(log.FileLogObserver):
16 def __init__(self, f, loglevel=INFO):
17 self.output = f
18 if isinstance(loglevel, basestring):
19 loglevel = loglevels[loglevel]
20 self.loglevel = loglevel
22 def emit(self, eventDict):
23 if eventDict.get('loglevel',DEBUG) > self.loglevel:
24 return
25 encoding = sys.stdout.encoding
26 if eventDict['isError'] and 'failure' in eventDict:
27 text = log.textFromEventDict(eventDict)
28 elif eventDict['message']:
29 text = ' '.join(s.encode(encoding,'replace') if isinstance(s,unicode) else s for s in eventDict['message'])
30 elif 'format' in eventDict or 'consoleformat' in eventDict:
31 fmt = eventDict.get('format',eventDict.get('consoleformat'))
32 text = (fmt % eventDict).encode(encoding,'replace')
33 else:
34 text = log.textFromEventDict(eventDict)
35 timeStr = self.formatTime(eventDict['time'])
36 self.output.write(timeStr + ' [' + loglevels[eventDict['loglevel']].ljust(7) + '] ' + text + '\n')
38 class FilteredConsoleLogObserver:
39 def __init__(self, loglevel=INFO):
40 self.loglevel = loglevel
42 def start(self):
43 log.addObserver(self.emit)
45 def stop(self):
46 log.removeObserver(self.emit)
48 def emit(self, eventDict):
49 if eventDict.get('loglevel',DEBUG) > self.loglevel:
50 return
51 encoding = sys.stdout.encoding
52 if eventDict['isError'] and 'failure' in eventDict:
53 text = log.textFromEventDict(eventDict)
54 elif eventDict['message']:
55 text = ''.join(s.encode(encoding,'replace') if isinstance(s,unicode) else s for s in eventDict['message'])
56 elif 'format' in eventDict or 'consoleformat' in eventDict:
57 fmt = eventDict.get('consoleformat',eventDict.get('format'))
58 text = (fmt % eventDict).encode(encoding,'replace')
59 else:
60 text = log.textFromEventDict(eventDict)
61 sys.stdout.write(text + '\n')
62 sys.stdout.flush()
64 collector = None
65 logfile = None
66 logout = None
68 def get_level(x, default=ERROR):
69 try:
70 return int(x)
71 except ValueError:
72 pass
73 try:
74 return loglevels[x]
75 except KeyError:
76 return default
78 def err(*msg, **kwargs):
79 global collector, logfile
80 if 'nologerror' not in kwargs:
81 if collector is None:
82 try:
83 collector = FilteredFileLogObserver(StringIO(), ERROR)
84 collector.start()
85 except: pass
86 if logfile is None:
87 try:
88 logfile = FilteredFileLogObserver(open(Config.get('logfile','audiomangler-%d.log' % os.getpid()), 'wb'), get_level(Config['loglevel']))
89 logfile.start()
90 except: pass
91 kwargs['loglevel'] = ERROR
92 if msg and isinstance(msg[0],(failure.Failure,Exception)):
93 log.err(*msg, **kwargs)
94 else:
95 log.msg(*msg, **kwargs)
97 def msg(*msg, **kwargs):
98 global logfile
99 kwargs.setdefault('loglevel',DEBUG)
100 if kwargs['loglevel'] == ERROR:
101 err(*msg, **kwargs)
102 else:
103 if Config['logfile'] and logfile is None and kwargs['loglevel'] <= get_level(Config['loglevel']):
104 try:
105 logfile = FilteredFileLogObserver(open(Config['logfile'], 'wb'), Config['loglevel'])
106 logfile.start()
107 except: pass
108 log.msg(*msg, **kwargs)
110 def fatal(*msg, **kwargs):
111 err(*msg, **kwargs)
112 sys.exit()
114 def cleanup():
115 if logout:
116 sys.stdout.flush()
117 logout.stop()
118 if collector:
119 collector.output.flush()
120 collector.stop()
121 text = collector.output.getvalue()
122 if text:
123 print "The following errors occurred:"
124 print text
125 print "The above errors may also have been reported during processing."
126 if logfile:
127 logfile.output.flush()
128 logfile.stop()
129 print "Errors are also recorded in the logfile '%s'." % os.path.abspath(logfile.output.name)
130 sys.stdout.flush()
132 try:
133 logout = FilteredConsoleLogObserver(Config['consolelevel'])
134 logout.start()
135 if log.defaultObserver:
136 log.defaultObserver.stop()
137 log.defaultObserver = None
138 except:
139 pass
141 atexit.register(cleanup)
143 __all__ = ['err','msg','fatal','ERROR','WARNING','INFO','DEBUG']