Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python logging in multiprocessing: AttributeError: 'Logger' object has no attribute 'flush'

Based on this code I created a python object that both prints output to the terminal and saves the output to a log file with the date and time appended to its name:

import sys
import time

class Logger(object):
    """
    Creates a class that will both print and log any
    output text. See https://stackoverflow.com/a/5916874
    for original source code. Modified to add date and
    time to end of file name.
    """
    def __init__(self, filename="Default"):
        self.terminal = sys.stdout
        self.filename = filename + ' ' + time.strftime('%Y-%m-%d-%H-%M-%S') + '.txt'
        self.log = open(self.filename, "a")

    def write(self, message):
        self.terminal.write(message)
        self.log.write(message)


sys.stdout = Logger('TestLog')

This works great, but when I try to use it with a script that uses the Pool multiprocessing function, I get the following error:

AttributeError: 'Logger' object has no attribute 'flush'

How can I modify my Logger object so that it will work with any script that runs in parallel?

like image 728
Michael Avatar asked Dec 11 '13 17:12

Michael


People also ask

Does logging work with multiprocessing?

The multiprocessing module has its own logger with the name “multiprocessing“. This logger is used within objects and functions within the multiprocessing module to log messages, such as debug messages that processes are running or have shutdown. We can get this logger and use it for logging.

What is logger handler Python?

Python Logging Handler The log handler is the component that effectively writes/displays a log: Display it in the console (via StreamHandler), in a file (via FileHandler), or even by sending you an email via SMTPHandler, etc. Each log handler has 2 important fields: A formatter which adds context information to a log.


1 Answers

If you're replacing sys.stdout, it must be with a file-like object, which means you have to implement flush. flush can be a no-op:

def flush(self):
    pass
like image 96
ecatmur Avatar answered Nov 13 '22 00:11

ecatmur