(continued from previous page) 2010-09-06 22:38:15,300 d.e.f ERROR IP: 123.231.231.123 A␣ ↪ → message at ERROR level with 2 parameters 2010-09-06 22:38:15,300 d.e.f CRITICAL IP: 192.168.0.1 User: jim A␣ ↪ → message at CRITICAL level with 2 parameters 2010-09-06 22:38:15,300 d.e.f CRITICAL IP: 127.0.0.1 User: sheila A␣ ↪ → message at CRITICAL level with 2 parameters 2010-09-06 22:38:15,300 d.e.f DEBUG IP: 192.168.0.1 User: jim A␣ ↪ → message at DEBUG level with 2 parameters 2010-09-06 22:38:15,301 d.e.f ERROR IP: 127.0.0.1 User: sheila A␣ ↪ → message at ERROR level with 2 parameters 2010-09-06 22:38:15,301 d.e.f DEBUG IP: 123.231.231.123 A␣ ↪ → message at DEBUG level with 2 parameters 2010-09-06 22:38:15,301 d.e.f INFO IP: 123.231.231.123 User: fred A␣ ↪ → message at INFO level with 2 parameters 9 Logging to a single file from multiple processes Although logging is thread-safe, and logging to a single file from multiple threads in a single process is supported, logging to a single file from multiple processes is not supported, because there is no standard way to serialize access to a single file across multiple processes in Python. If you need to log to a single file from multiple processes, one way of doing this is to have all the processes log to a$_{SocketHandler}$, and have a separate process which implements a socket server which reads from the socket and logs to file. (If you prefer, you can dedicate one thread in one of the existing processes to perform this function.) This section documents this approach in more detail and includes a working socket receiver which can be used as a starting point for you to adapt in your own applications. You could also write your own handler which uses the Lock class from the $_{multiprocessing}$module to serialize access to the file from your processes. The existing FileHandler and subclasses do not make use of $_{multiprocessing}$at present, though they may do so in the future. Note that at present, the multiprocessing module does not provide working lock functionality on all platforms (see https://bugs.python. org/issue3770). Alternatively, you can use a$_{Queue}$ and a$_{QueueHandler}$to send all logging events to one of the processes in your multi-process application. The following example script demonstrates how you can do this; in the example a separate listener process listens for events sent by other processes and logs them according to its own logging configuration. Although the example only demonstrates one way of doing it (for example, you may want to use a listener thread rather than a separate listener process – the implementation would be analogous) it does allow for completely different logging configurations for the listener and the other processes in your application, and can be used as the basis for code meeting your own specific requirements: # You'll need these imports in your own code import logging import logging.handlers import multiprocessing # Next two import lines for this demo only from random import choice, random import time # # Because you'll want to define the logging configurations for listener and ␣ ↪ → workers, the # listener and worker process functions take a configurer parameter which is a ␣ ↪ → callable # for configuring logging for that process. These functions are also passed the ␣ ↪ → queue, # which they use for communication. # # In practice, you can configure the listener however you want, but note that in ␣ ↪ → this (continues on next page) 13