Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / tools / src / nas,5.n2.os.2 / lib / python / lib / python2.4 / logging / config.py
CommitLineData
86530b38
AT
1# Copyright 2001-2005 by Vinay Sajip. All Rights Reserved.
2#
3# Permission to use, copy, modify, and distribute this software and its
4# documentation for any purpose and without fee is hereby granted,
5# provided that the above copyright notice appear in all copies and that
6# both that copyright notice and this permission notice appear in
7# supporting documentation, and that the name of Vinay Sajip
8# not be used in advertising or publicity pertaining to distribution
9# of the software without specific, written prior permission.
10# VINAY SAJIP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
11# ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
12# VINAY SAJIP BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
13# ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
14# IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
15# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16
17"""
18Configuration functions for the logging package for Python. The core package
19is based on PEP 282 and comments thereto in comp.lang.python, and influenced
20by Apache's log4j system.
21
22Should work under Python versions >= 1.5.2, except that source line
23information is not available unless 'sys._getframe()' is.
24
25Copyright (C) 2001-2004 Vinay Sajip. All Rights Reserved.
26
27To use, simply 'import logging' and log away!
28"""
29
30import sys, logging, logging.handlers, string, socket, struct, os, traceback
31
32try:
33 import thread
34 import threading
35except ImportError:
36 thread = None
37
38from SocketServer import ThreadingTCPServer, StreamRequestHandler
39
40
41DEFAULT_LOGGING_CONFIG_PORT = 9030
42
43if sys.platform == "win32":
44 RESET_ERROR = 10054 #WSAECONNRESET
45else:
46 RESET_ERROR = 104 #ECONNRESET
47
48#
49# The following code implements a socket listener for on-the-fly
50# reconfiguration of logging.
51#
52# _listener holds the server object doing the listening
53_listener = None
54
55def fileConfig(fname, defaults=None):
56 """
57 Read the logging configuration from a ConfigParser-format file.
58
59 This can be called several times from an application, allowing an end user
60 the ability to select from various pre-canned configurations (if the
61 developer provides a mechanism to present the choices and load the chosen
62 configuration).
63 In versions of ConfigParser which have the readfp method [typically
64 shipped in 2.x versions of Python], you can pass in a file-like object
65 rather than a filename, in which case the file-like object will be read
66 using readfp.
67 """
68 import ConfigParser
69
70 cp = ConfigParser.ConfigParser(defaults)
71 if hasattr(cp, 'readfp') and hasattr(fname, 'readline'):
72 cp.readfp(fname)
73 else:
74 cp.read(fname)
75 #first, do the formatters...
76 flist = cp.get("formatters", "keys")
77 if len(flist):
78 flist = string.split(flist, ",")
79 formatters = {}
80 for form in flist:
81 sectname = "formatter_%s" % form
82 opts = cp.options(sectname)
83 if "format" in opts:
84 fs = cp.get(sectname, "format", 1)
85 else:
86 fs = None
87 if "datefmt" in opts:
88 dfs = cp.get(sectname, "datefmt", 1)
89 else:
90 dfs = None
91 f = logging.Formatter(fs, dfs)
92 formatters[form] = f
93 #next, do the handlers...
94 #critical section...
95 logging._acquireLock()
96 try:
97 try:
98 #first, lose the existing handlers...
99 logging._handlers.clear()
100 #now set up the new ones...
101 hlist = cp.get("handlers", "keys")
102 if len(hlist):
103 hlist = string.split(hlist, ",")
104 handlers = {}
105 fixups = [] #for inter-handler references
106 for hand in hlist:
107 try:
108 sectname = "handler_%s" % hand
109 klass = cp.get(sectname, "class")
110 opts = cp.options(sectname)
111 if "formatter" in opts:
112 fmt = cp.get(sectname, "formatter")
113 else:
114 fmt = ""
115 klass = eval(klass, vars(logging))
116 args = cp.get(sectname, "args")
117 args = eval(args, vars(logging))
118 h = apply(klass, args)
119 if "level" in opts:
120 level = cp.get(sectname, "level")
121 h.setLevel(logging._levelNames[level])
122 if len(fmt):
123 h.setFormatter(formatters[fmt])
124 #temporary hack for FileHandler and MemoryHandler.
125 if klass == logging.handlers.MemoryHandler:
126 if "target" in opts:
127 target = cp.get(sectname,"target")
128 else:
129 target = ""
130 if len(target): #the target handler may not be loaded yet, so keep for later...
131 fixups.append((h, target))
132 handlers[hand] = h
133 except: #if an error occurs when instantiating a handler, too bad
134 pass #this could happen e.g. because of lack of privileges
135 #now all handlers are loaded, fixup inter-handler references...
136 for fixup in fixups:
137 h = fixup[0]
138 t = fixup[1]
139 h.setTarget(handlers[t])
140 #at last, the loggers...first the root...
141 llist = cp.get("loggers", "keys")
142 llist = string.split(llist, ",")
143 llist.remove("root")
144 sectname = "logger_root"
145 root = logging.root
146 log = root
147 opts = cp.options(sectname)
148 if "level" in opts:
149 level = cp.get(sectname, "level")
150 log.setLevel(logging._levelNames[level])
151 for h in root.handlers[:]:
152 root.removeHandler(h)
153 hlist = cp.get(sectname, "handlers")
154 if len(hlist):
155 hlist = string.split(hlist, ",")
156 for hand in hlist:
157 log.addHandler(handlers[hand])
158 #and now the others...
159 #we don't want to lose the existing loggers,
160 #since other threads may have pointers to them.
161 #existing is set to contain all existing loggers,
162 #and as we go through the new configuration we
163 #remove any which are configured. At the end,
164 #what's left in existing is the set of loggers
165 #which were in the previous configuration but
166 #which are not in the new configuration.
167 existing = root.manager.loggerDict.keys()
168 #now set up the new ones...
169 for log in llist:
170 sectname = "logger_%s" % log
171 qn = cp.get(sectname, "qualname")
172 opts = cp.options(sectname)
173 if "propagate" in opts:
174 propagate = cp.getint(sectname, "propagate")
175 else:
176 propagate = 1
177 logger = logging.getLogger(qn)
178 if qn in existing:
179 existing.remove(qn)
180 if "level" in opts:
181 level = cp.get(sectname, "level")
182 logger.setLevel(logging._levelNames[level])
183 for h in logger.handlers[:]:
184 logger.removeHandler(h)
185 logger.propagate = propagate
186 logger.disabled = 0
187 hlist = cp.get(sectname, "handlers")
188 if len(hlist):
189 hlist = string.split(hlist, ",")
190 for hand in hlist:
191 logger.addHandler(handlers[hand])
192 #Disable any old loggers. There's no point deleting
193 #them as other threads may continue to hold references
194 #and by disabling them, you stop them doing any logging.
195 for log in existing:
196 root.manager.loggerDict[log].disabled = 1
197 except:
198 ei = sys.exc_info()
199 traceback.print_exception(ei[0], ei[1], ei[2], None, sys.stderr)
200 del ei
201 finally:
202 logging._releaseLock()
203
204def listen(port=DEFAULT_LOGGING_CONFIG_PORT):
205 """
206 Start up a socket server on the specified port, and listen for new
207 configurations.
208
209 These will be sent as a file suitable for processing by fileConfig().
210 Returns a Thread object on which you can call start() to start the server,
211 and which you can join() when appropriate. To stop the server, call
212 stopListening().
213 """
214 if not thread:
215 raise NotImplementedError, "listen() needs threading to work"
216
217 class ConfigStreamHandler(StreamRequestHandler):
218 """
219 Handler for a logging configuration request.
220
221 It expects a completely new logging configuration and uses fileConfig
222 to install it.
223 """
224 def handle(self):
225 """
226 Handle a request.
227
228 Each request is expected to be a 4-byte length, packed using
229 struct.pack(">L", n), followed by the config file.
230 Uses fileConfig() to do the grunt work.
231 """
232 import tempfile
233 try:
234 conn = self.connection
235 chunk = conn.recv(4)
236 if len(chunk) == 4:
237 slen = struct.unpack(">L", chunk)[0]
238 chunk = self.connection.recv(slen)
239 while len(chunk) < slen:
240 chunk = chunk + conn.recv(slen - len(chunk))
241 #Apply new configuration. We'd like to be able to
242 #create a StringIO and pass that in, but unfortunately
243 #1.5.2 ConfigParser does not support reading file
244 #objects, only actual files. So we create a temporary
245 #file and remove it later.
246 file = tempfile.mktemp(".ini")
247 f = open(file, "w")
248 f.write(chunk)
249 f.close()
250 fileConfig(file)
251 os.remove(file)
252 except socket.error, e:
253 if type(e.args) != types.TupleType:
254 raise
255 else:
256 errcode = e.args[0]
257 if errcode != RESET_ERROR:
258 raise
259
260 class ConfigSocketReceiver(ThreadingTCPServer):
261 """
262 A simple TCP socket-based logging config receiver.
263 """
264
265 allow_reuse_address = 1
266
267 def __init__(self, host='localhost', port=DEFAULT_LOGGING_CONFIG_PORT,
268 handler=None):
269 ThreadingTCPServer.__init__(self, (host, port), handler)
270 logging._acquireLock()
271 self.abort = 0
272 logging._releaseLock()
273 self.timeout = 1
274
275 def serve_until_stopped(self):
276 import select
277 abort = 0
278 while not abort:
279 rd, wr, ex = select.select([self.socket.fileno()],
280 [], [],
281 self.timeout)
282 if rd:
283 self.handle_request()
284 logging._acquireLock()
285 abort = self.abort
286 logging._releaseLock()
287
288 def serve(rcvr, hdlr, port):
289 server = rcvr(port=port, handler=hdlr)
290 global _listener
291 logging._acquireLock()
292 _listener = server
293 logging._releaseLock()
294 server.serve_until_stopped()
295
296 return threading.Thread(target=serve,
297 args=(ConfigSocketReceiver,
298 ConfigStreamHandler, port))
299
300def stopListening():
301 """
302 Stop the listening server which was created with a call to listen().
303 """
304 global _listener
305 if _listener:
306 logging._acquireLock()
307 _listener.abort = 1
308 _listener = None
309 logging._releaseLock()