-
-
Notifications
You must be signed in to change notification settings - Fork 32.2k
gh-98731: Improvements to the logging documentation #101618
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -30,13 +30,53 @@ is that all Python modules can participate in logging, so your application log | |
can include your own messages integrated with messages from third-party | ||
modules. | ||
|
||
The simplest example: | ||
Here's a simple example of idiomatic usage: :: | ||
|
||
# myapp.py | ||
import logging | ||
import mylib | ||
logger = logging.getLogger(__name__) | ||
|
||
def main(): | ||
logging.basicConfig(filename='myapp.log', level=logging.INFO) | ||
logger.info('Started') | ||
mylib.do_something() | ||
logger.info('Finished') | ||
|
||
if __name__ == '__main__': | ||
main() | ||
|
||
:: | ||
|
||
# mylib.py | ||
import logging | ||
logger = logging.getLogger(__name__) | ||
|
||
def do_something(): | ||
logger.info('Doing something') | ||
|
||
If you run *myapp.py*, you should see this in *myapp.log*: | ||
|
||
.. code-block:: none | ||
|
||
>>> import logging | ||
>>> logging.warning('Watch out!') | ||
WARNING:root:Watch out! | ||
INFO:__main__:Started | ||
INFO:mylib:Doing something | ||
INFO:__main__:Finished | ||
|
||
The key features of this idiomatic usage is that the majority of code is simply | ||
creating a module level logger with ``getLogger(__name__)``, and using that | ||
logger to do any needed logging. This is concise while allowing downstream code | ||
fine grained control if needed. Logged messages to the module-level logger get | ||
forwarded up to handlers of loggers in higher-level modules, all the way up to | ||
the root logger; for this reason this approach is known as hierarchical logging. | ||
|
||
For logging to be useful, it needs to be configured: setting the levels and | ||
destinations for each logger, potentially changing how specific modules log, | ||
often based on command-line arguments or application configuration. In most | ||
cases, like the one above, only the root logger needs to be so configured, since | ||
all the lower level loggers at module level eventually forward their messages to | ||
its handlers. :func:`~logging.basicConfig` provides a quick way to configure | ||
the root logger that handles many use cases. | ||
|
||
The module provides a lot of functionality and flexibility. If you are | ||
unfamiliar with logging, the best way to get to grips with it is to view the | ||
|
@@ -1151,89 +1191,31 @@ functions. | |
|
||
.. function:: debug(msg, *args, **kwargs) | ||
|
||
Logs a message with level :const:`DEBUG` on the root logger. The *msg* is the | ||
message format string, and the *args* are the arguments which are merged into | ||
*msg* using the string formatting operator. (Note that this means that you can | ||
use keywords in the format string, together with a single dictionary argument.) | ||
|
||
There are three keyword arguments in *kwargs* which are inspected: *exc_info* | ||
which, if it does not evaluate as false, causes exception information to be | ||
added to the logging message. If an exception tuple (in the format returned by | ||
:func:`sys.exc_info`) or an exception instance is provided, it is used; | ||
otherwise, :func:`sys.exc_info` is called to get the exception information. | ||
|
||
The second optional keyword argument is *stack_info*, which defaults to | ||
``False``. If true, stack information is added to the logging | ||
message, including the actual logging call. Note that this is not the same | ||
stack information as that displayed through specifying *exc_info*: The | ||
former is stack frames from the bottom of the stack up to the logging call | ||
in the current thread, whereas the latter is information about stack frames | ||
which have been unwound, following an exception, while searching for | ||
exception handlers. | ||
|
||
You can specify *stack_info* independently of *exc_info*, e.g. to just show | ||
how you got to a certain point in your code, even when no exceptions were | ||
raised. The stack frames are printed following a header line which says: | ||
|
||
.. code-block:: none | ||
This is a convenience function that calls :meth:`Logger.debug`, on the root | ||
logger. The handling of the arguments is in every way identical | ||
to what is described in that method. | ||
|
||
Stack (most recent call last): | ||
The only difference is that if the root logger has no handlers, then | ||
:func:`basicConfig` is called, prior to calling ``debug`` on the root logger. | ||
|
||
This mimics the ``Traceback (most recent call last):`` which is used when | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why has this section been removed? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure I understand. The git diff is a bit all over the place. "This mimics the traceback..." is still present in the new version, in the Logger.debug section. In the logging.debug section, yes, it's gone, as with almost everything else, since it now just references Logger.debug. |
||
displaying exception frames. | ||
For very short scripts or quick demonstrations of ``logging`` facilities, | ||
``debug`` and the other module-level functions may be convenient. However, | ||
most programs will want to carefully and explicitly control the logging | ||
configuration, and should therefore prefer creating a module-level logger and | ||
calling :meth:`Logger.debug` (or other level-specific methods) on it, as | ||
described at the beginnning of this documentation. | ||
|
||
The third optional keyword argument is *extra* which can be used to pass a | ||
dictionary which is used to populate the __dict__ of the LogRecord created for | ||
the logging event with user-defined attributes. These custom attributes can then | ||
be used as you like. For example, they could be incorporated into logged | ||
messages. For example:: | ||
|
||
FORMAT = '%(asctime)s %(clientip)-15s %(user)-8s %(message)s' | ||
logging.basicConfig(format=FORMAT) | ||
d = {'clientip': '192.168.0.1', 'user': 'fbloggs'} | ||
logging.warning('Protocol problem: %s', 'connection reset', extra=d) | ||
|
||
would print something like: | ||
|
||
.. code-block:: none | ||
|
||
2006-02-08 22:20:02,165 192.168.0.1 fbloggs Protocol problem: connection reset | ||
|
||
The keys in the dictionary passed in *extra* should not clash with the keys used | ||
by the logging system. (See the :class:`Formatter` documentation for more | ||
information on which keys are used by the logging system.) | ||
|
||
If you choose to use these attributes in logged messages, you need to exercise | ||
some care. In the above example, for instance, the :class:`Formatter` has been | ||
set up with a format string which expects 'clientip' and 'user' in the attribute | ||
dictionary of the LogRecord. If these are missing, the message will not be | ||
logged because a string formatting exception will occur. So in this case, you | ||
always need to pass the *extra* dictionary with these keys. | ||
|
||
While this might be annoying, this feature is intended for use in specialized | ||
circumstances, such as multi-threaded servers where the same code executes in | ||
many contexts, and interesting conditions which arise are dependent on this | ||
context (such as remote client IP address and authenticated user name, in the | ||
above example). In such circumstances, it is likely that specialized | ||
:class:`Formatter`\ s would be used with particular :class:`Handler`\ s. | ||
|
||
This function (as well as :func:`info`, :func:`warning`, :func:`error` and | ||
:func:`critical`) will call :func:`basicConfig` if the root logger doesn't | ||
have any handler attached. | ||
|
||
.. versionchanged:: 3.2 | ||
The *stack_info* parameter was added. | ||
|
||
.. function:: info(msg, *args, **kwargs) | ||
|
||
Logs a message with level :const:`INFO` on the root logger. The arguments are | ||
interpreted as for :func:`debug`. | ||
Logs a message with level :const:`INFO` on the root logger. The arguments and behavior | ||
are otherwise the same as for :func:`debug`. | ||
|
||
|
||
.. function:: warning(msg, *args, **kwargs) | ||
|
||
Logs a message with level :const:`WARNING` on the root logger. The arguments | ||
are interpreted as for :func:`debug`. | ||
Logs a message with level :const:`WARNING` on the root logger. The arguments and behavior | ||
are otherwise the same as for :func:`debug`. | ||
|
||
.. note:: There is an obsolete function ``warn`` which is functionally | ||
identical to ``warning``. As ``warn`` is deprecated, please do not use | ||
|
@@ -1246,26 +1228,26 @@ functions. | |
|
||
.. function:: error(msg, *args, **kwargs) | ||
|
||
Logs a message with level :const:`ERROR` on the root logger. The arguments are | ||
interpreted as for :func:`debug`. | ||
Logs a message with level :const:`ERROR` on the root logger. The arguments and behavior | ||
are otherwise the same as for :func:`debug`. | ||
|
||
|
||
.. function:: critical(msg, *args, **kwargs) | ||
|
||
Logs a message with level :const:`CRITICAL` on the root logger. The arguments | ||
are interpreted as for :func:`debug`. | ||
Logs a message with level :const:`CRITICAL` on the root logger. The arguments and behavior | ||
are otherwise the same as for :func:`debug`. | ||
|
||
|
||
.. function:: exception(msg, *args, **kwargs) | ||
|
||
Logs a message with level :const:`ERROR` on the root logger. The arguments are | ||
interpreted as for :func:`debug`. Exception info is added to the logging | ||
Logs a message with level :const:`ERROR` on the root logger. The arguments and behavior | ||
are otherwise the same as for :func:`debug`. Exception info is added to the logging | ||
message. This function should only be called from an exception handler. | ||
|
||
.. function:: log(level, msg, *args, **kwargs) | ||
|
||
Logs a message with level *level* on the root logger. The other arguments are | ||
interpreted as for :func:`debug`. | ||
Logs a message with level *level* on the root logger. The arguments and behavior | ||
are otherwise the same as for :func:`debug`. | ||
|
||
.. function:: disable(level=CRITICAL) | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did you actually build this documentation locally? If you did, not sure how it got past these errors.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did not. I will try to build them locally and message if I have issues.