]> granicus.if.org Git - python/commitdiff
merge r68915 to py3k
authorJesse Noller <jnoller@gmail.com>
Sun, 25 Jan 2009 03:45:53 +0000 (03:45 +0000)
committerJesse Noller <jnoller@gmail.com>
Sun, 25 Jan 2009 03:45:53 +0000 (03:45 +0000)
Doc/library/multiprocessing.rst
Lib/multiprocessing/__init__.py
Lib/multiprocessing/util.py
Misc/ACKS
Misc/NEWS

index 61788515710841c05f7b31346c65ed1add43378c..f3dd23eded3b10baa6b88a49dd40f94f681c998c 100644 (file)
@@ -1857,30 +1857,74 @@ handler type) for messages from different processes to get mixed up.
    Returns the logger used by :mod:`multiprocessing`.  If necessary, a new one
    will be created.
 
-   When first created the logger has level :data:`logging.NOTSET` and has a
-   handler which sends output to :data:`sys.stderr` using format
-   ``'[%(levelname)s/%(processName)s] %(message)s'``.  (The logger allows use of
-   the non-standard ``'%(processName)s'`` format.)  Message sent to this logger
-   will not by default propagate to the root logger.
+   When first created the logger has level :data:`logging.NOTSET` and no
+   default handler. Messages sent to this logger will not by default propagate
+   to the root logger.
 
    Note that on Windows child processes will only inherit the level of the
    parent process's logger -- any other customization of the logger will not be
    inherited.
 
+.. currentmodule:: multiprocessing
+.. function:: log_to_stderr()
+
+   This function performs a call to :func:`get_logger` but in addition to
+   returning the logger created by get_logger, it adds a handler which sends
+   output to :data:`sys.stderr` using format
+   ``'[%(levelname)s/%(processName)s] %(message)s'``.
+
 Below is an example session with logging turned on::
 
     >>> import multiprocessing, logging
-    >>> logger = multiprocessing.get_logger()
+    >>> logger = multiprocessing.log_to_stderr()
     >>> logger.setLevel(logging.INFO)
     >>> logger.warning('doomed')
     [WARNING/MainProcess] doomed
     >>> m = multiprocessing.Manager()
     [INFO/SyncManager-1] child process calling self.run()
-    [INFO/SyncManager-1] manager bound to '\\\\.\\pipe\\pyc-2776-0-lj0tfa'
+    [INFO/SyncManager-1] created temp directory /.../pymp-Wh47O_
+    [INFO/SyncManager-1] manager serving at '/.../listener-lWsERs'
     >>> del m
     [INFO/MainProcess] sending shutdown message to manager
     [INFO/SyncManager-1] manager exiting with exitcode 0
 
+In addition to having these two logging functions, the multiprocessing also
+exposes two additional logging level attributes. These are  :const:`SUBWARNING`
+and :const:`SUBDEBUG`. The table below illustrates where theses fit in the
+normal level hierarchy.
+
++----------------+----------------+
+| Level          | Numeric value  |
++================+================+
+| ``SUBWARNING`` | 25             |
++----------------+----------------+
+| ``SUBDEBUG``   | 5              |
++----------------+----------------+
+
+For a full table of logging levels, see the :mod:`logging` module.
+
+These additional logging levels are used primarily for certain debug messages
+within the multiprocessing module. Below is the same example as above, except
+with :const:`SUBDEBUG` enabled::
+
+    >>> import multiprocessing, logging
+    >>> logger = multiprocessing.log_to_stderr()
+    >>> logger.setLevel(multiprocessing.SUBDEBUG)
+    >>> logger.warning('doomed')
+    [WARNING/MainProcess] doomed
+    >>> m = multiprocessing.Manager()
+    [INFO/SyncManager-1] child process calling self.run()
+    [INFO/SyncManager-1] created temp directory /.../pymp-djGBXN
+    [INFO/SyncManager-1] manager serving at '/.../pymp-djGBXN/listener-knBYGe'
+    >>> del m
+    [SUBDEBUG/MainProcess] finalizer calling ...
+    [INFO/MainProcess] sending shutdown message to manager
+    [DEBUG/SyncManager-1] manager received shutdown message
+    [SUBDEBUG/SyncManager-1] calling <Finalize object, callback=unlink, ...
+    [SUBDEBUG/SyncManager-1] finalizer calling <built-in function unlink> ...
+    [SUBDEBUG/SyncManager-1] calling <Finalize object, dead>
+    [SUBDEBUG/SyncManager-1] finalizer calling <function rmtree at 0x5aa730> ...
+    [INFO/SyncManager-1] manager exiting with exitcode 0
 
 The :mod:`multiprocessing.dummy` module
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
index aad41914399709c88aa3b479fcae3e46bb31effd..5a13742b064addbe55601de2e2f7fa8beb2a8516 100644 (file)
@@ -48,7 +48,7 @@ __all__ = [
     'allow_connection_pickling', 'BufferTooShort', 'TimeoutError',
     'Lock', 'RLock', 'Semaphore', 'BoundedSemaphore', 'Condition',
     'Event', 'Queue', 'JoinableQueue', 'Pool', 'Value', 'Array',
-    'RawValue', 'RawArray'
+    'RawValue', 'RawArray', 'SUBDEBUG', 'SUBWARNING',
     ]
 
 __author__ = 'R. Oudkerk (r.m.oudkerk@gmail.com)'
@@ -61,6 +61,7 @@ import os
 import sys
 
 from multiprocessing.process import Process, current_process, active_children
+from multiprocessing.util import SUBDEBUG, SUBWARNING
 
 #
 # Exceptions
index ac9d79e71d70f9bc2c23642877e9762e7e2b8045..b13f5652b4f86bc02b0e462eef66fd8a60efa215 100644 (file)
@@ -17,7 +17,8 @@ from multiprocessing.process import current_process, active_children
 __all__ = [
     'sub_debug', 'debug', 'info', 'sub_warning', 'get_logger',
     'log_to_stderr', 'get_temp_dir', 'register_after_fork',
-    'is_exiting', 'Finalize', 'ForkAwareThreadLock', 'ForkAwareLocal'
+    'is_exiting', 'Finalize', 'ForkAwareThreadLock', 'ForkAwareLocal',
+    'SUBDEBUG', 'SUBWARNING',
     ]
 
 #
@@ -57,19 +58,27 @@ def get_logger():
     Returns logger used by multiprocessing
     '''
     global _logger
+    import logging, atexit
 
-    if not _logger:
-        import logging, atexit
+    logging._acquireLock()
+    try:
+        if not _logger:
 
-        # XXX multiprocessing should cleanup before logging
-        if hasattr(atexit, 'unregister'):
-            atexit.unregister(_exit_function)
-            atexit.register(_exit_function)
-        else:
-            atexit._exithandlers.remove((_exit_function, (), {}))
-            atexit._exithandlers.append((_exit_function, (), {}))
+            _logger = logging.getLogger(LOGGER_NAME)
+            _logger.propagate = 0
+            logging.addLevelName(SUBDEBUG, 'SUBDEBUG')
+            logging.addLevelName(SUBWARNING, 'SUBWARNING')
+
+            # XXX multiprocessing should cleanup before logging
+            if hasattr(atexit, 'unregister'):
+                atexit.unregister(_exit_function)
+                atexit.register(_exit_function)
+            else:
+                atexit._exithandlers.remove((_exit_function, (), {}))
+                atexit._exithandlers.append((_exit_function, (), {}))
 
-        _logger = logging.getLogger(LOGGER_NAME)
+    finally:
+        logging._releaseLock()
 
     return _logger
 
@@ -79,14 +88,17 @@ def log_to_stderr(level=None):
     '''
     global _log_to_stderr
     import logging
+
     logger = get_logger()
     formatter = logging.Formatter(DEFAULT_LOGGING_FORMAT)
     handler = logging.StreamHandler()
     handler.setFormatter(formatter)
     logger.addHandler(handler)
-    if level is not None:
+
+    if level:
         logger.setLevel(level)
     _log_to_stderr = True
+    return _logger
 
 #
 # Function returning a temp directory which will be removed on exit
index 272cb66eacf6b7fec330559fd79b6f8a13e90011..c607d52a512b8093ea86f2a62683cc7641e7fea6 100644 (file)
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -785,3 +785,4 @@ Siebren van der Zee
 Uwe Zessin
 Tarek Ziad\8e
 Peter Åstrand
+Jesse Noller
index 5f8eda5f75f2c9398aecf3058b6e0c6683af6bc0..684ba7f8cb38221c4830c1079e1783b8996b163a 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -139,6 +139,10 @@ Core and Builtins
 Library
 -------
 
+- Fix and properly document the multiprocessing module's logging
+  support, expose the internal levels and provide proper usage
+  examples.
+
 - Issue #1672332: fix unpickling of subnormal floats, which was
   producing a ValueError on some platforms.