source: publico/il.spdo/trunk/PasteScript-1.7.4.2-py2.6.egg/paste/script/util/logging_config.py @ 5327

Última Alteração nesse arquivo desde 5327 foi 5327, incluída por fabianosantos, 8 anos atrás

Import inicial.

File size: 12.0 KB
Linha 
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, types
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
76    formatters = _create_formatters(cp)
77
78    # critical section
79    logging._acquireLock()
80    try:
81        logging._handlers.clear()
82        if hasattr(logging, '_handlerList'):
83            del logging._handlerList[:]
84        # Handlers add themselves to logging._handlers
85        handlers = _install_handlers(cp, formatters)
86        _install_loggers(cp, handlers)
87    finally:
88        logging._releaseLock()
89
90
91def _resolve(name):
92    """Resolve a dotted name to a global object."""
93    name = string.split(name, '.')
94    used = name.pop(0)
95    found = __import__(used)
96    for n in name:
97        used = used + '.' + n
98        try:
99            found = getattr(found, n)
100        except AttributeError:
101            __import__(used)
102            found = getattr(found, n)
103    return found
104
105
106def _create_formatters(cp):
107    """Create and return formatters"""
108    flist = cp.get("formatters", "keys")
109    if not len(flist):
110        return {}
111    flist = string.split(flist, ",")
112    formatters = {}
113    for form in flist:
114        form = string.strip(form)
115        sectname = "formatter_%s" % form
116        opts = cp.options(sectname)
117        if "format" in opts:
118            fs = cp.get(sectname, "format", 1)
119        else:
120            fs = None
121        if "datefmt" in opts:
122            dfs = cp.get(sectname, "datefmt", 1)
123        else:
124            dfs = None
125        c = logging.Formatter
126        if "class" in opts:
127            class_name = cp.get(sectname, "class")
128            if class_name:
129                c = _resolve(class_name)
130        f = c(fs, dfs)
131        formatters[form] = f
132    return formatters
133
134
135def _install_handlers(cp, formatters):
136    """Install and return handlers"""
137    hlist = cp.get("handlers", "keys")
138    if not len(hlist):
139        return {}
140    hlist = string.split(hlist, ",")
141    handlers = {}
142    fixups = [] #for inter-handler references
143    for hand in hlist:
144        hand = string.strip(hand)
145        sectname = "handler_%s" % hand
146        klass = cp.get(sectname, "class")
147        opts = cp.options(sectname)
148        if "formatter" in opts:
149            fmt = cp.get(sectname, "formatter")
150        else:
151            fmt = ""
152        try:
153            klass = eval(klass, vars(logging))
154        except (AttributeError, NameError):
155            klass = _resolve(klass)
156        args = cp.get(sectname, "args")
157        args = eval(args, vars(logging))
158        h = apply(klass, args)
159        if "level" in opts:
160            level = cp.get(sectname, "level")
161            h.setLevel(logging._levelNames[level])
162        if len(fmt):
163            h.setFormatter(formatters[fmt])
164        #temporary hack for FileHandler and MemoryHandler.
165        if klass == logging.handlers.MemoryHandler:
166            if "target" in opts:
167                target = cp.get(sectname,"target")
168            else:
169                target = ""
170            if len(target): #the target handler may not be loaded yet, so keep for later...
171                fixups.append((h, target))
172        handlers[hand] = h
173    #now all handlers are loaded, fixup inter-handler references...
174    for h, t in fixups:
175        h.setTarget(handlers[t])
176    return handlers
177
178
179def _install_loggers(cp, handlers):
180    """Create and install loggers"""
181
182    # configure the root first
183    llist = cp.get("loggers", "keys")
184    llist = string.split(llist, ",")
185    llist = map(lambda x: string.strip(x), llist)
186    llist.remove("root")
187    sectname = "logger_root"
188    root = logging.root
189    log = root
190    opts = cp.options(sectname)
191    if "level" in opts:
192        level = cp.get(sectname, "level")
193        log.setLevel(logging._levelNames[level])
194    for h in root.handlers[:]:
195        root.removeHandler(h)
196    hlist = cp.get(sectname, "handlers")
197    if len(hlist):
198        hlist = string.split(hlist, ",")
199        for hand in hlist:
200            log.addHandler(handlers[string.strip(hand)])
201
202    #and now the others...
203    #we don't want to lose the existing loggers,
204    #since other threads may have pointers to them.
205    #existing is set to contain all existing loggers,
206    #and as we go through the new configuration we
207    #remove any which are configured. At the end,
208    #what's left in existing is the set of loggers
209    #which were in the previous configuration but
210    #which are not in the new configuration.
211    existing = root.manager.loggerDict.keys()
212    #now set up the new ones...
213    for log in llist:
214        sectname = "logger_%s" % log
215        qn = cp.get(sectname, "qualname")
216        opts = cp.options(sectname)
217        if "propagate" in opts:
218            propagate = cp.getint(sectname, "propagate")
219        else:
220            propagate = 1
221        logger = logging.getLogger(qn)
222        if qn in existing:
223            existing.remove(qn)
224        if "level" in opts:
225            level = cp.get(sectname, "level")
226            logger.setLevel(logging._levelNames[level])
227        for h in logger.handlers[:]:
228            logger.removeHandler(h)
229        logger.propagate = propagate
230        logger.disabled = 0
231        hlist = cp.get(sectname, "handlers")
232        if len(hlist):
233            hlist = string.split(hlist, ",")
234            for hand in hlist:
235                logger.addHandler(handlers[string.strip(hand)])
236
237    #Disable any old loggers. There's no point deleting
238    #them as other threads may continue to hold references
239    #and by disabling them, you stop them doing any logging.
240    for log in existing:
241        root.manager.loggerDict[log].disabled = 1
242
243
244def listen(port=DEFAULT_LOGGING_CONFIG_PORT):
245    """
246    Start up a socket server on the specified port, and listen for new
247    configurations.
248
249    These will be sent as a file suitable for processing by fileConfig().
250    Returns a Thread object on which you can call start() to start the server,
251    and which you can join() when appropriate. To stop the server, call
252    stopListening().
253    """
254    if not thread:
255        raise NotImplementedError, "listen() needs threading to work"
256
257    class ConfigStreamHandler(StreamRequestHandler):
258        """
259        Handler for a logging configuration request.
260
261        It expects a completely new logging configuration and uses fileConfig
262        to install it.
263        """
264        def handle(self):
265            """
266            Handle a request.
267
268            Each request is expected to be a 4-byte length, packed using
269            struct.pack(">L", n), followed by the config file.
270            Uses fileConfig() to do the grunt work.
271            """
272            import tempfile
273            try:
274                conn = self.connection
275                chunk = conn.recv(4)
276                if len(chunk) == 4:
277                    slen = struct.unpack(">L", chunk)[0]
278                    chunk = self.connection.recv(slen)
279                    while len(chunk) < slen:
280                        chunk = chunk + conn.recv(slen - len(chunk))
281                    #Apply new configuration. We'd like to be able to
282                    #create a StringIO and pass that in, but unfortunately
283                    #1.5.2 ConfigParser does not support reading file
284                    #objects, only actual files. So we create a temporary
285                    #file and remove it later.
286                    file = tempfile.mktemp(".ini")
287                    f = open(file, "w")
288                    f.write(chunk)
289                    f.close()
290                    try:
291                        fileConfig(file)
292                    except (KeyboardInterrupt, SystemExit):
293                        raise
294                    except:
295                        traceback.print_exc()
296                    os.remove(file)
297            except socket.error, e:
298                if type(e.args) != types.TupleType:
299                    raise
300                else:
301                    errcode = e.args[0]
302                    if errcode != RESET_ERROR:
303                        raise
304
305    class ConfigSocketReceiver(ThreadingTCPServer):
306        """
307        A simple TCP socket-based logging config receiver.
308        """
309
310        allow_reuse_address = 1
311
312        def __init__(self, host='localhost', port=DEFAULT_LOGGING_CONFIG_PORT,
313                     handler=None):
314            ThreadingTCPServer.__init__(self, (host, port), handler)
315            logging._acquireLock()
316            self.abort = 0
317            logging._releaseLock()
318            self.timeout = 1
319
320        def serve_until_stopped(self):
321            import select
322            abort = 0
323            while not abort:
324                rd, wr, ex = select.select([self.socket.fileno()],
325                                           [], [],
326                                           self.timeout)
327                if rd:
328                    self.handle_request()
329                logging._acquireLock()
330                abort = self.abort
331                logging._releaseLock()
332
333    def serve(rcvr, hdlr, port):
334        server = rcvr(port=port, handler=hdlr)
335        global _listener
336        logging._acquireLock()
337        _listener = server
338        logging._releaseLock()
339        server.serve_until_stopped()
340
341    return threading.Thread(target=serve,
342                            args=(ConfigSocketReceiver,
343                                  ConfigStreamHandler, port))
344
345def stopListening():
346    """
347    Stop the listening server which was created with a call to listen().
348    """
349    global _listener
350    if _listener:
351        logging._acquireLock()
352        _listener.abort = 1
353        _listener = None
354        logging._releaseLock()
Note: Veja TracBrowser para ajuda no uso do navegador do trac.
 

The contents and data of this website are published under license:
Creative Commons 4.0 Brasil - Atribuir Fonte - Compartilhar Igual.