Commits

Vinay Sajip committed 871519e Draft

Issue #17007: Improved logging documentation based on suggestions in the issue.

Comments (0)

Files changed (1)

Doc/library/logging.rst

 ``logging.getLogger(__name__)``.  That's because in a module, ``__name__``
 is the module's name in the Python package namespace.
 
+
 .. class:: Logger
 
 .. attribute:: Logger.propagate
 
-   If this evaluates to true, logging messages are passed by this logger and by
-   its child loggers to the handlers of higher level (ancestor) loggers.
-   Messages are passed directly to the ancestor loggers' handlers - neither the
-   level nor filters of the ancestor loggers in question are considered.
+   If this evaluates to true, events logged to this logger will be passed to the
+   handlers of higher level (ancestor) loggers, in addition to any handlers
+   attached to this logger. Messages are passed directly to the ancestor
+   loggers' handlers - neither the level nor filters of the ancestor loggers in
+   question are considered.
 
    If this evaluates to false, logging messages are not passed to the handlers
    of ancestor loggers.
 
    The constructor sets this attribute to ``True``.
 
+   .. note:: If you attach a handler to several loggers, it may emit the same
+      record multiple times. In general, you should not need to attach a
+      handler to more than one logger - if you just attach it to the
+      appropriate logger which is highest in the logger hierarchy, then it
+      will see all events logged by all descendant loggers, provided that
+      their propagate setting is left set to ``True``. A common scenario is to
+      attach handlers only to the root logger, and let propagation take care of
+      the rest.
 
 .. method:: Logger.setLevel(lvl)
 
 .. method:: Logger.filter(record)
 
    Applies this logger's filters to the record and returns a true value if the
-   record is to be processed.
+   record is to be processed. The filters are consulted in turn, until one of
+   them returns a false value. If none of them return a false value, the record
+   will be processed (passed to handlers). If one returns a false value, no
+   further processing of the record occurs.
 
 
 .. method:: Logger.addHandler(hdlr)
 .. method:: Handler.filter(record)
 
    Applies this handler's filters to the record and returns a true value if the
-   record is to be processed.
+   record is to be processed. The filters are consulted in turn, until one of
+   them returns a false value. If none of them return a false value, the record
+   will be emitted. If one returns a false value, the handler will not emit the
+   record.
 
 
 .. method:: Handler.flush()
       yes. If deemed appropriate, the record may be modified in-place by this
       method.
 
-Note that filters attached to handlers are consulted whenever an event is
+Note that filters attached to handlers are consulted before an event is
 emitted by the handler, whereas filters attached to loggers are consulted
-whenever an event is logged to the handler (using :meth:`debug`, :meth:`info`,
-etc.) This means that events which have been generated by descendant loggers
-will not be filtered by a logger's filter setting, unless the filter has also
-been applied to those descendant loggers.
+whenever an event is logged (using :meth:`debug`, :meth:`info`,
+etc.), before sending an event to handlers. This means that events which have
+been generated by descendant loggers will not be filtered by a logger's filter
+setting, unless the filter has also been applied to those descendant loggers.
 
 You don't actually need to subclass ``Filter``: you can pass any instance
 which has a ``filter`` method with the same semantics.
    record.
 
    :param name:  The name of the logger used to log the event represented by
-                 this LogRecord.
+                 this LogRecord. Note that this name will always have this
+                 value, even though it may be emitted by a handler attached to
+                 a different (ancestor) logger.
    :param level: The numeric level of the logging event (one of DEBUG, INFO etc.)
                  Note that this is converted to *two* attributes of the LogRecord:
                  ``levelno`` for the numeric value and ``levelname`` for the