Back to index

python3.2  3.2.2
Classes | Functions | Variables
logging.config Namespace Reference

Classes

class  ConvertingDict
class  ConvertingList
class  ConvertingTuple
class  BaseConfigurator
class  DictConfigurator

Functions

def fileConfig
def _resolve
def _strip_spaces
def _encoded
def _create_formatters
def _install_handlers
def _handle_existing_loggers
def _install_loggers
def valid_ident
def dictConfig
def listen
def stopListening

Variables

 thread = None
int DEFAULT_LOGGING_CONFIG_PORT = 9030
int RESET_ERROR = 10054
 _listener = None
tuple IDENTIFIER = re.compile('^[a-z_][a-z0-9_]*$', re.I)
 dictConfigClass = DictConfigurator
 abort
 timeout
 ready
 rcvr
 hdlr
 port

Function Documentation

def logging.config._create_formatters (   cp) [private]
Create and return formatters

Definition at line 104 of file config.py.

00104 
00105 def _create_formatters(cp):
00106     """Create and return formatters"""
00107     flist = cp["formatters"]["keys"]
00108     if not len(flist):
00109         return {}
00110     flist = flist.split(",")
00111     flist = _strip_spaces(flist)
00112     formatters = {}
00113     for form in flist:
00114         sectname = "formatter_%s" % form
00115         fs = cp.get(sectname, "format", raw=True, fallback=None)
00116         dfs = cp.get(sectname, "datefmt", raw=True, fallback=None)
00117         c = logging.Formatter
00118         class_name = cp[sectname].get("class")
00119         if class_name:
00120             c = _resolve(class_name)
00121         f = c(fs, dfs)
00122         formatters[form] = f
00123     return formatters
00124 

Here is the call graph for this function:

Here is the caller graph for this function:

def logging.config._encoded (   s) [private]

Definition at line 101 of file config.py.

00101 
00102 def _encoded(s):
00103     return s if isinstance(s, str) else s.encode('utf-8')

def logging.config._handle_existing_loggers (   existing,
  child_loggers,
  disable_existing 
) [private]
When (re)configuring logging, handle loggers which were in the previous
configuration but are not in the new configuration. There's no point
deleting them as other threads may continue to hold references to them;
and by disabling them, you stop them doing any logging.

However, don't disable children of named loggers, as that's probably not
what was intended by the user. Also, allow existing loggers to NOT be
disabled if disable_existing is false.

Definition at line 160 of file config.py.

00160 
00161 def _handle_existing_loggers(existing, child_loggers, disable_existing):
00162     """
00163     When (re)configuring logging, handle loggers which were in the previous
00164     configuration but are not in the new configuration. There's no point
00165     deleting them as other threads may continue to hold references to them;
00166     and by disabling them, you stop them doing any logging.
00167 
00168     However, don't disable children of named loggers, as that's probably not
00169     what was intended by the user. Also, allow existing loggers to NOT be
00170     disabled if disable_existing is false.
00171     """
00172     root = logging.root
00173     for log in existing:
00174         logger = root.manager.loggerDict[log]
00175         if log in child_loggers:
00176             logger.level = logging.NOTSET
00177             logger.handlers = []
00178             logger.propagate = True
00179         elif disable_existing:
00180             logger.disabled = True

Here is the caller graph for this function:

def logging.config._install_handlers (   cp,
  formatters 
) [private]
Install and return handlers

Definition at line 125 of file config.py.

00125 
00126 def _install_handlers(cp, formatters):
00127     """Install and return handlers"""
00128     hlist = cp["handlers"]["keys"]
00129     if not len(hlist):
00130         return {}
00131     hlist = hlist.split(",")
00132     hlist = _strip_spaces(hlist)
00133     handlers = {}
00134     fixups = [] #for inter-handler references
00135     for hand in hlist:
00136         section = cp["handler_%s" % hand]
00137         klass = section["class"]
00138         fmt = section.get("formatter", "")
00139         try:
00140             klass = eval(klass, vars(logging))
00141         except (AttributeError, NameError):
00142             klass = _resolve(klass)
00143         args = section["args"]
00144         args = eval(args, vars(logging))
00145         h = klass(*args)
00146         if "level" in section:
00147             level = section["level"]
00148             h.setLevel(logging._levelNames[level])
00149         if len(fmt):
00150             h.setFormatter(formatters[fmt])
00151         if issubclass(klass, logging.handlers.MemoryHandler):
00152             target = section.get("target", "")
00153             if len(target): #the target handler may not be loaded yet, so keep for later...
00154                 fixups.append((h, target))
00155         handlers[hand] = h
00156     #now all handlers are loaded, fixup inter-handler references...
00157     for h, t in fixups:
00158         h.setTarget(handlers[t])
00159     return handlers

Here is the call graph for this function:

Here is the caller graph for this function:

def logging.config._install_loggers (   cp,
  handlers,
  disable_existing 
) [private]
Create and install loggers

Definition at line 181 of file config.py.

00181 
00182 def _install_loggers(cp, handlers, disable_existing):
00183     """Create and install loggers"""
00184 
00185     # configure the root first
00186     llist = cp["loggers"]["keys"]
00187     llist = llist.split(",")
00188     llist = list(map(lambda x: x.strip(), llist))
00189     llist.remove("root")
00190     section = cp["logger_root"]
00191     root = logging.root
00192     log = root
00193     if "level" in section:
00194         level = section["level"]
00195         log.setLevel(logging._levelNames[level])
00196     for h in root.handlers[:]:
00197         root.removeHandler(h)
00198     hlist = section["handlers"]
00199     if len(hlist):
00200         hlist = hlist.split(",")
00201         hlist = _strip_spaces(hlist)
00202         for hand in hlist:
00203             log.addHandler(handlers[hand])
00204 
00205     #and now the others...
00206     #we don't want to lose the existing loggers,
00207     #since other threads may have pointers to them.
00208     #existing is set to contain all existing loggers,
00209     #and as we go through the new configuration we
00210     #remove any which are configured. At the end,
00211     #what's left in existing is the set of loggers
00212     #which were in the previous configuration but
00213     #which are not in the new configuration.
00214     existing = list(root.manager.loggerDict.keys())
00215     #The list needs to be sorted so that we can
00216     #avoid disabling child loggers of explicitly
00217     #named loggers. With a sorted list it is easier
00218     #to find the child loggers.
00219     existing.sort(key=_encoded)
00220     #We'll keep the list of existing loggers
00221     #which are children of named loggers here...
00222     child_loggers = []
00223     #now set up the new ones...
00224     for log in llist:
00225         section = cp["logger_%s" % log]
00226         qn = section["qualname"]
00227         propagate = section.getint("propagate", fallback=1)
00228         logger = logging.getLogger(qn)
00229         if qn in existing:
00230             i = existing.index(qn) + 1 # start with the entry after qn
00231             prefixed = qn + "."
00232             pflen = len(prefixed)
00233             num_existing = len(existing)
00234             while i < num_existing:
00235                 if existing[i][:pflen] == prefixed:
00236                     child_loggers.append(existing[i])
00237                 i += 1
00238             existing.remove(qn)
00239         if "level" in section:
00240             level = section["level"]
00241             logger.setLevel(logging._levelNames[level])
00242         for h in logger.handlers[:]:
00243             logger.removeHandler(h)
00244         logger.propagate = propagate
00245         logger.disabled = 0
00246         hlist = section["handlers"]
00247         if len(hlist):
00248             hlist = hlist.split(",")
00249             hlist = _strip_spaces(hlist)
00250             for hand in hlist:
00251                 logger.addHandler(handlers[hand])
00252 
00253     #Disable any old loggers. There's no point deleting
00254     #them as other threads may continue to hold references
00255     #and by disabling them, you stop them doing any logging.
00256     #However, don't disable children of named loggers, as that's
00257     #probably not what was intended by the user.
00258     #for log in existing:
00259     #    logger = root.manager.loggerDict[log]
00260     #    if log in child_loggers:
00261     #        logger.level = logging.NOTSET
00262     #        logger.handlers = []
00263     #        logger.propagate = 1
00264     #    elif disable_existing_loggers:
00265     #        logger.disabled = 1
00266     _handle_existing_loggers(existing, child_loggers, disable_existing)

Here is the call graph for this function:

Here is the caller graph for this function:

def logging.config._resolve (   name) [private]
Resolve a dotted name to a global object.

Definition at line 84 of file config.py.

00084 
00085 def _resolve(name):
00086     """Resolve a dotted name to a global object."""
00087     name = name.split('.')
00088     used = name.pop(0)
00089     found = __import__(used)
00090     for n in name:
00091         used = used + '.' + n
00092         try:
00093             found = getattr(found, n)
00094         except AttributeError:
00095             __import__(used)
00096             found = getattr(found, n)
00097     return found

Here is the call graph for this function:

Here is the caller graph for this function:

def logging.config._strip_spaces (   alist) [private]

Definition at line 98 of file config.py.

00098 
00099 def _strip_spaces(alist):
00100     return map(lambda x: x.strip(), alist)

Here is the caller graph for this function:

def logging.config.dictConfig (   config)
Configure logging using a dictionary.

Definition at line 774 of file config.py.

00774 
00775 def dictConfig(config):
00776     """Configure logging using a dictionary."""
00777     dictConfigClass(config).configure()
00778 

Here is the caller graph for this function:

def logging.config.fileConfig (   fname,
  defaults = None,
  disable_existing_loggers = True 
)
Read the logging configuration from a ConfigParser-format file.

This can be called several times from an application, allowing an end user
the ability to select from various pre-canned configurations (if the
developer provides a mechanism to present the choices and load the chosen
configuration).

Definition at line 53 of file config.py.

00053 
00054 def fileConfig(fname, defaults=None, disable_existing_loggers=True):
00055     """
00056     Read the logging configuration from a ConfigParser-format file.
00057 
00058     This can be called several times from an application, allowing an end user
00059     the ability to select from various pre-canned configurations (if the
00060     developer provides a mechanism to present the choices and load the chosen
00061     configuration).
00062     """
00063     import configparser
00064 
00065     cp = configparser.ConfigParser(defaults)
00066     if hasattr(fname, 'readline'):
00067         cp.read_file(fname)
00068     else:
00069         cp.read(fname)
00070 
00071     formatters = _create_formatters(cp)
00072 
00073     # critical section
00074     logging._acquireLock()
00075     try:
00076         logging._handlers.clear()
00077         del logging._handlerList[:]
00078         # Handlers add themselves to logging._handlers
00079         handlers = _install_handlers(cp, formatters)
00080         _install_loggers(cp, handlers, disable_existing_loggers)
00081     finally:
00082         logging._releaseLock()
00083 

Here is the call graph for this function:

Here is the caller graph for this function:

def logging.config.listen (   port = DEFAULT_LOGGING_CONFIG_PORT)
Start up a socket server on the specified port, and listen for new
configurations.

These will be sent as a file suitable for processing by fileConfig().
Returns a Thread object on which you can call start() to start the server,
and which you can join() when appropriate. To stop the server, call
stopListening().

Definition at line 779 of file config.py.

00779 
00780 def listen(port=DEFAULT_LOGGING_CONFIG_PORT):
00781     """
00782     Start up a socket server on the specified port, and listen for new
00783     configurations.
00784 
00785     These will be sent as a file suitable for processing by fileConfig().
00786     Returns a Thread object on which you can call start() to start the server,
00787     and which you can join() when appropriate. To stop the server, call
00788     stopListening().
00789     """
00790     if not thread:
00791         raise NotImplementedError("listen() needs threading to work")
00792 
00793     class ConfigStreamHandler(StreamRequestHandler):
00794         """
00795         Handler for a logging configuration request.
00796 
00797         It expects a completely new logging configuration and uses fileConfig
00798         to install it.
00799         """
00800         def handle(self):
00801             """
00802             Handle a request.
00803 
00804             Each request is expected to be a 4-byte length, packed using
00805             struct.pack(">L", n), followed by the config file.
00806             Uses fileConfig() to do the grunt work.
00807             """
00808             import tempfile
00809             try:
00810                 conn = self.connection
00811                 chunk = conn.recv(4)
00812                 if len(chunk) == 4:
00813                     slen = struct.unpack(">L", chunk)[0]
00814                     chunk = self.connection.recv(slen)
00815                     while len(chunk) < slen:
00816                         chunk = chunk + conn.recv(slen - len(chunk))
00817                     chunk = chunk.decode("utf-8")
00818                     try:
00819                         import json
00820                         d =json.loads(chunk)
00821                         assert isinstance(d, dict)
00822                         dictConfig(d)
00823                     except:
00824                         #Apply new configuration.
00825 
00826                         file = io.StringIO(chunk)
00827                         try:
00828                             fileConfig(file)
00829                         except (KeyboardInterrupt, SystemExit):
00830                             raise
00831                         except:
00832                             traceback.print_exc()
00833                     if self.server.ready:
00834                         self.server.ready.set()
00835             except socket.error as e:
00836                 if not isinstance(e.args, tuple):
00837                     raise
00838                 else:
00839                     errcode = e.args[0]
00840                     if errcode != RESET_ERROR:
00841                         raise
00842 
00843     class ConfigSocketReceiver(ThreadingTCPServer):
00844         """
00845         A simple TCP socket-based logging config receiver.
00846         """
00847 
00848         allow_reuse_address = 1
00849 
00850         def __init__(self, host='localhost', port=DEFAULT_LOGGING_CONFIG_PORT,
00851                      handler=None, ready=None):
00852             ThreadingTCPServer.__init__(self, (host, port), handler)
00853             logging._acquireLock()
00854             self.abort = 0
00855             logging._releaseLock()
00856             self.timeout = 1
00857             self.ready = ready
00858 
00859         def serve_until_stopped(self):
00860             import select
00861             abort = 0
00862             while not abort:
00863                 rd, wr, ex = select.select([self.socket.fileno()],
00864                                            [], [],
00865                                            self.timeout)
00866                 if rd:
00867                     self.handle_request()
00868                 logging._acquireLock()
00869                 abort = self.abort
00870                 logging._releaseLock()
00871             self.socket.close()
00872 
00873     class Server(threading.Thread):
00874 
00875         def __init__(self, rcvr, hdlr, port):
00876             super(Server, self).__init__()
00877             self.rcvr = rcvr
00878             self.hdlr = hdlr
00879             self.port = port
00880             self.ready = threading.Event()
00881 
00882         def run(self):
00883             server = self.rcvr(port=self.port, handler=self.hdlr,
00884                                ready=self.ready)
00885             if self.port == 0:
00886                 self.port = server.server_address[1]
00887             self.ready.set()
00888             global _listener
00889             logging._acquireLock()
00890             _listener = server
00891             logging._releaseLock()
00892             server.serve_until_stopped()
00893 
00894     return Server(ConfigSocketReceiver, ConfigStreamHandler, port)

Here is the call graph for this function:

Here is the caller graph for this function:

Stop the listening server which was created with a call to listen().

Definition at line 895 of file config.py.

00895 
00896 def stopListening():
00897     """
00898     Stop the listening server which was created with a call to listen().
00899     """
00900     global _listener
00901     logging._acquireLock()
00902     try:
00903         if _listener:
00904             _listener.abort = 1
00905             _listener = None
00906     finally:
00907         logging._releaseLock()

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 270 of file config.py.

00270 
00271 def valid_ident(s):
00272     m = IDENTIFIER.match(s)
00273     if not m:
00274         raise ValueError('Not a valid Python identifier: %r' % s)
00275     return True
00276 
00277 
00278 # The ConvertingXXX classes are wrappers around standard Python containers,
00279 # and they serve to convert any suitable values in the container. The
00280 # conversion converts base dicts, lists and tuples to their wrapped
00281 # equivalents, whereas strings which match a conversion format are converted
00282 # appropriately.
00283 #
00284 # Each wrapper should have a configurator attribute holding the actual
00285 # configurator to use for conversion.

Here is the caller graph for this function:


Variable Documentation

Definition at line 51 of file config.py.

Definition at line 853 of file config.py.

Definition at line 39 of file config.py.

Definition at line 772 of file config.py.

Definition at line 877 of file config.py.

tuple logging.config.IDENTIFIER = re.compile('^[a-z_][a-z0-9_]*$', re.I)

Definition at line 267 of file config.py.

Definition at line 878 of file config.py.

Definition at line 876 of file config.py.

Definition at line 856 of file config.py.

Definition at line 42 of file config.py.

Definition at line 34 of file config.py.

Definition at line 855 of file config.py.