Source code for pyquickhelper.loghelper.custom_log

# -*- coding: utf-8 -*-
"""
Creates a custom log (open a text file and flushes everything in it).


:githublink:`%|py|6`
"""
import datetime
import os


[docs]class CustomLog: """ Implements a custom logging function. This class is not protected against multithreading. Usage: :: clog = CustomLog("folder") clog('[fct]', info) :githublink:`%|py|20` """
[docs] def __init__(self, folder=None, filename=None, create=True, parent=None): """ initialisation :param folder: folder (created if not exists) :param filename: new filename :param create: force the creation :param parent: logging function (called after this one if not None) :githublink:`%|py|30` """ folder = os.path.abspath(folder) self._folder = folder self._parent = parent if not os.path.exists(folder): os.makedirs(folder) # pragma: no cover typstr = str if filename is None: i = 0 filename = "log_custom_%03d.txt" % i fullpath = os.path.join(folder, filename) while os.path.exists(fullpath): i += 1 filename = "custom_log_%03d.txt" % i fullpath = os.path.join(folder, filename) self._filename = filename self._fullpath = fullpath self._handle = open(self._fullpath, "w", encoding="utf-8") self._close = True elif isinstance(filename, typstr): self._filename = filename self._fullpath = os.path.join(folder, filename) self._handle = open(self._fullpath, "w", encoding="utf-8") self._close = True else: self._handle = filename self._close = False self._filename = None self._fullpath = None
@property def filename(self): """ returns *_filename* :githublink:`%|py|64` """ return self._filename @property def fullpath(self): """ returns *_fullpath* :githublink:`%|py|71` """ return self._fullpath
[docs] def __del__(self): """ Closes the stream if needed. :githublink:`%|py|77` """ if self._close: self._handle.close()
[docs] def __call__(self, *args, **kwargs): """ Log anything. :githublink:`%|py|84` """ self.fLOG(*args, **kwargs) if self._parent is not None: self._parent(*args, **kwargs)
[docs] def fLOG(self, *args, **kwargs): """ Builds a message on a single line with the date, it deals with encoding issues. :param args: list of fields :param kwargs: dictionary of fields :githublink:`%|py|95` """ dt = datetime.datetime(2009, 1, 1).now() typstr = str if len(args) > 0: def _str_process(s): if isinstance(s, str): return s if isinstance(s, bytes): return s.decode("utf8") # pragma: no cover try: return str(s) except Exception as e: # pragma: no cover raise Exception( "Unable to convert s into string: type(s)=%r" % type(s)) from e message = str(dt).split( ".")[0] + " " + " ".join([_str_process(s) for s in args]) + "\n" self._handle.write(message) st = " " else: st = typstr(dt).split(".")[0] + " " # pragma: no cover for k, v in kwargs.items(): message = st + \ "%s = %s%s" % ( typstr(k), typstr(v), "\n") if "INNER JOIN" in message: break # pragma: no cover self._handle.write(message) self._handle.flush()