Friday, 29 May 2020

How to keep track console output into a log file for python?

class ReDirectSTD(object):
    def __init__(self, fpath=None, console='stdout', immediately_visiable=False):
        import sys
        import os
        assert console in ['stdout', 'stderr']
        self.console = sys.stdout if console == "stdout" else sys.stderr
        self.file = fpath
        self.f = None
        self.immediately_visiable = immediately_visiable
        if fpath is not None:
            # Remove existing log file
            if os.path.exists(fpath):
                os.remove(fpath)
        if console == 'stdout':
            sys.stdout = self
        else:
            sys.stderr = self

    def __del__(self):
        self.close()

    def __enter__(self):
        pass

    def __exit__(self, **args):
        self.close()

    def write(self, msg):
        self.console.write(msg)
        if self.file is not None:
            if not os.path.exists(os.path.dirname(os.path.abspath(self.file))):
                os.mkdir(os.path.dirname(os.path.abspath(self.file)))
            if self.immediately_visiable:
                with open(self.file, 'a') as f:
                    f.write(msg)
            else:
                if self.f is None:
                    self.f = open(self.file, 'w')
                self.f.write(msg)

    def flush(self):
        self.console.flush()
        if self.f is not None:
            self.f.flush()
            import os
            os.fsync(self.f.fileno())

    def close(self):
        self.console.close()
        if self.f is not None:
            self.f.close()


def may_mkdir(fname):
    if not os.path.exists(os.path.dirname(os.path.abspath(fname))):
        os.makedirs(os.path.dirname(os.path.abspath(fname)))

def del_mkdir(folder):
    if os.path.exists(folder):
        shutil.rmtree(
folder)  # delete output folder
    os.makedirs(
folder)  # make new output folder


def time_str(fmt=None):
    if fmt is None:
        fmt = '%Y-%m-%d_%H:%M:%S'
    return datetime.datetime.today().strftime(fmt)


# log
logfiletime = time_str()
stdout_file = os.path.join('log', 'stdout_{}.txt'.format(logfiletime))
stderr_file = os.path.join('log', 'stderr_{}.txt'.format(logfiletime))
may_mkdir(stdout_file)
may_mkdir(stderr_file)
if 1:
    ReDirectSTD(stdout_file, 'stdout', False)
    ReDirectSTD(stderr_file, 'stderr', False)

No comments:

Post a Comment