Source code for ossom.utils.logger

# -*- coding: utf-8 -*-
"""
This module provide two classes: `Now` and `Logger`.

The first is just a wrap around time.localtime() with human readable interface of the exact time instant the object is created.
The latter is a simple file logger that uses `Now` instances to record information.

Created on Sat Jun  6 00:39:46 2020

@author: joaovitor
"""

# import json
import time
import random as rd
from typing import TextIO


[docs]class Now(object): """Human readable data about date and time.""" _keys = ('year', 'month', 'day', 'wday', 'hour', 'min', 'sec') _wdays = {0: 'mon', 1: 'tue', 2: 'wed', 3: 'thu', 4: 'fri', 5: 'sat', 6: 'sun'} def __init__(self): localtime = time.localtime() self._hour = f"0{localtime.tm_hour}" if localtime.tm_hour < 10 else f"{localtime.tm_hour}" self._min = f"0{localtime.tm_min}" if localtime.tm_min < 10 else f"{localtime.tm_min}" self._sec = f"0{localtime.tm_sec}" if localtime.tm_sec < 10 else f"{localtime.tm_sec}" self._day = f"0{localtime.tm_mday}" if localtime.tm_mday < 10 else f"{localtime.tm_mday}" self._month = f"0{localtime.tm_mon}" if localtime.tm_mon < 10 else f"{localtime.tm_mon}" self._year = f"{localtime.tm_year}" self._wday = f"{Now._wdays[localtime.tm_wday]}" self._GMT = f"GMT_{localtime.tm_zone}" return def __str__(self): return f"{self.wday}_{self.date}_{self.time}_{self.GMT}" @property def date(self): return f"{self.day}-{self.month}-{self.year}" @property def time(self): return f"{self.hour}-{self.min}-{self.sec}" @property def hour(self): """Wall clock hours.""" return self._hour @property def min(self): """Wall clock minutes.""" return self._min @property def sec(self): """Wall clock seconds.""" return self._sec @property def year(self): """Year.""" return self._year @property def month(self): """Month.""" return self._month @property def day(self): """Month day.""" return self._day @property def wday(self): """Week day.""" return self._wday @property def GMT(self): """Time zone.""" return self._GMT
[docs]class Logger(object): """Simple logger.""" _randlogs = ['Albatroz', 'Jaguatirica', 'Jibóia', 'Arara', 'Mico', 'Boitatá', 'Boto Cor-de-Rosa']
[docs] def __init__(self, name: str = 'common', ext: str = 'log', title: str = 'title', logend: str = 'end.') -> None: """ File based logger. Parameters ---------- name : str, optional File name. The default is 'common'. ext : str, optional File extension. The default is 'log'. title : str, optional A title or description for the log. The default is 'title'. logend : str, optional A tag that represents the end of a logging session. The default is 'end.'. Returns ------- None """ self._name = name self._ext = ext self._title = title self._logend = f"\n# {logend}\n{13*'-'}\n\n" self._time = Now() self._header = f'{13*"-"}\n# LOG OUTPUT FILE\n# {self.name}\n# {self.time}\n\n# {self.title}\n' self.fopen() return
[docs] def __del__(self): """Close underlying file on del statement.""" try: self.fclose() except AttributeError: pass return
@property def name(self) -> str: """Log file name.""" return self._name @property def ext(self) -> str: """File extension.""" return self._ext @property def title(self) -> str: """Log title.""" return self._title @property def time(self) -> str: """Time at log creation.""" return str(self._time) @property def header(self) -> str: """File header.""" return self._header @property def logend(self) -> str: """End of logging.""" return self._logend @property def file(self) -> TextIO: """File pointer.""" return self._file
[docs] def fopen(self): """Open the log file, enabling `read` and `write`.""" self._file = open(f'{self.name}.{self.ext}', mode='a+') return
[docs] def start_log(self): """Write header to log file.""" self.file.write(self.header) return
[docs] def log(self, message: str = None) -> int: """ Write `message` to the log file along with the current time. Parameters ---------- message : str, optional The content of the logging. If no input is given, randomizes an item from `LogFile._randlog`. The default is None. Returns ------- b : int The amount of bytes written to log file. """ time = Now().time msg = message if not message is None \ else Logger._randlogs[rd.randint(0, len(Logger._randlogs)-1)] return self.file.write(f"{time} : {msg}\n")
[docs] def end_log(self): """Write the end of logging tag.""" self.file.write(self.logend) return
[docs] def fclose(self): """Close the log file.""" self.file.close() del self._file return
[docs] def print_log(self): """Print the log file content. File must be opened.""" try: self.file.seek(0) print(self.file.read()) except AttributeError: self.fopen() self.file.seek(0) print(self.file.read()) self.fclose() return
def _random_log(logger, timeout): init = time.time() while (init + timeout) > time.time(): time.sleep(0.125) logger.log() logger.end_log() return if __name__ == '__main__': NAME = 'log' EXT = 'txt' FILENAME = f'{NAME}.{EXT}' TITLE = 'Overall Level' logger = Logger(NAME, EXT, TITLE) _random_log(logger, 2.) logger.fclose() logger.reopen() _random_log(logger, 3.) logger.fclose()