10000 [3.9] bpo-44399: Update logging cookbook to document patterns to be a… · python/cpython@5a0c6ab · GitHub
[go: up one dir, main page]

Skip to content

Commit 5a0c6ab

Browse files
[3.9] bpo-44399: Update logging cookbook to document patterns to be avoided. (GH-27348) (GH-27350)
(cherry picked from commit 9751f85)
1 parent ce20336 commit 5a0c6ab

File tree

1 file changed

+79
-0
lines changed

1 file changed

+79
-0
lines changed

Doc/howto/logging-cookbook.rst

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2979,3 +2979,82 @@ refer to the comments in the code snippet for more detailed information.
29792979
29802980
if __name__=='__main__':
29812981
main()
2982+
2983+
2984+
.. patterns-to-avoid:
2985+
2986+
Patterns to avoid
2987+
-----------------
2988+
2989+
Although the preceding sections have described ways of doing things you might
2990+
need to do or deal with, it is worth mentioning some usage patterns which are
2991+
*unhelpful*, and which should therefore be avoided in most cases. The following
2992+
sections are in no particular order.
2993+
2994+
2995+
Opening the same log file multiple times
2996+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2997+
2998+
On Windows, you will generally not be able to open the same file multiple times
2999+
as this will lead to a "file is in use by another process" error. However, on
3000+
POSIX platforms you'll not get any errors if you open the same file multiple
3001+
times. This could be done accidentally, for example by:
3002+
3003+
* Adding a file handler more than once which references the same file (e.g. by
3004+
a copy/paste/forget-to-change error).
3005+
3006+
* Opening two files that look different, as they have different names, but are
3007+
the same because one is a symbolic link to the other.
3008+
3009+
* Forking a process, following which both parent and child have a reference to
3010+
the same file. This might be through use of the :mod:`multiprocessing` module,
3011+
for example.
3012+
3013+
Opening a file multiple times might *appear* to work most of the time, but can
3014+
lead to a number of problems in practice:
3015+
3016+
* Logging output can be garbled because multiple threads or processes try to
3017+
write to the same file. Although logging guards against concurrent use of the
3018+
same handler instance by multiple threads, there is no such protection if
3019+
concurrent writes are attempted by two different threads using two different
3020+
handler instances which happen to point to the same file.
3021+
3022+
* An attempt to delete a file (e.g. during file rotation) silently fails,
3023+
because there is another reference pointing to it. This can lead to confusion
3024+
and wasted debugging time - log entries end up in unexpected places, or are
3025+
lost altogether.
3026+
3027+
Use the techniques outlined in :ref:`multiple-processes` to circumvent such
3028+
issues.
3029+
3030+
Using loggers as attributes in a class or passing them as parameters
3031+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
3032+
3033+
While there might be unusual cases where you'll need to do this, in general
3034+
there is no point because loggers are singletons. Code can always access a
3035+
given logger instance by name using ``logging.getLogger(name)``, so passing
3036+
instances around and holding them as instance attributes is pointless. Note
3037+
that in other languages such as Java and C#, loggers are often static class
3038+
attributes. However, this pattern doesn't make sense in Python, where the
3039+
module (and not the class) is the unit of software decomposition.
3040+
3041+
3042+
Adding handlers other than :class:`NullHandler` to a logger in a library
3043+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
3044+
3045+
Configuring logging by adding handlers, formatters and filters is the
3046+
responsibility of the application developer, not the library developer. If you
3047+
are maintaining a library, ensure that you don't add handlers to any of your
3048+
loggers other than a :class:`~logging.NullHandler` instance.
3049+
3050+
3051+
Creating a lot of loggers
3052+
^^^^^^^^^^^^^^^^^^^^^^^^^
3053+
3054+
Loggers are singletons that are never freed during a script execution, and so
3055+
creating lots of loggers will use up memory which can't then be freed. Rather
3056+
than create a logger per e.g. file processed or network connection made, use
3057+
the :ref:`existing mechanisms <context-info>` for passing contextual
3058+
information into your logs and restrict the loggers created to those describing
3059+
areas within your application (generally modules, but occasionally slightly
3060+
more fine-grained than that).

0 commit comments

Comments
 (0)
0