Module given docstrings to explain the purpose and function of defined module functions. Giving parameter and return values of functions. Module now contains `gen_log_header` moved from the `Logger` class, along with global constants for the function.
112 lines
3.8 KiB
Python
112 lines
3.8 KiB
Python
import textwrap
|
|
import time
|
|
from typing import Union
|
|
|
|
from .common import LogLevel
|
|
|
|
|
|
## log message constant format template
|
|
__LOG_TMPL = "[{DATE}] [{0}] {TYPE} "
|
|
## string time format (ISO: 8601, long-form)
|
|
__TIMESTAMP_FMT = "%Y-%m-%dT%H:%M:%S%z"
|
|
|
|
|
|
class Colours:
|
|
NORMAL = '\033[0m'
|
|
RED = '\033[91m'
|
|
GREEN = '\033[92m'
|
|
YELLOW = '\033[93m'
|
|
BLUE = '\033[94m'
|
|
|
|
|
|
def loglevel_as_str(level: Union[LogLevel, int]) -> str:
|
|
"""Convert an integer or enum value into its appropriate enum
|
|
attribute name.
|
|
|
|
`@Params`: level - `LogLevel | int`
|
|
`Returns`: LogLevel enum literal attribute name - `str`
|
|
"""
|
|
## perform a lookup of each attribute of LogLevel and its associate
|
|
## value, and search for the attribute that has the matching level
|
|
## value passed to the function.
|
|
_attrs = [_dir for _dir in dir(LogLevel) \
|
|
if not _dir.startswith('__')] # list of all attributes of LogLevel
|
|
for _ in _attrs: # iterate over all attributes defined
|
|
if getattr(LogLevel, _) == level: # if the level matches
|
|
return "{0: <5}".format(_) # return the attribute name
|
|
|
|
return " " * 5
|
|
|
|
|
|
def log_as_col(level: Union[int, LogLevel]) -> Colours:
|
|
"""Convert an integer or enum value into an associated ANSI escape
|
|
code terminal colour sequence. Depending on log level severity, an
|
|
associated colour is returned to give STDOUT text a distinct
|
|
separation of colour from regular STDOUT text.
|
|
|
|
`@Params`: level - `LogLevel | int`
|
|
`@Return`: Enum of `Colours`
|
|
"""
|
|
## perform a colour lookup based on level number
|
|
if level == LogLevel.DEBUG:
|
|
return Colours.BLUE
|
|
elif level == LogLevel.WARN:
|
|
return Colours.YELLOW
|
|
elif level == LogLevel.ERROR:
|
|
return Colours.RED
|
|
elif level == LogLevel.PASS:
|
|
return Colours.GREEN
|
|
else:
|
|
return Colours.NORMAL
|
|
|
|
def gen_log_header(_type: Union[LogLevel, int, str]) -> str:
|
|
"""Generate a header string for use of standardising log outputs.
|
|
|
|
The header is defined using the following standard header:
|
|
```plaintext
|
|
"[YYYY-MM-DDTHH:MM:SS+OFFSET] [{CALLER}] <LogLevel> {0}"
|
|
```
|
|
|
|
The first column defines the Date-Time following the ISO 8601 (long)
|
|
standard timestamp format, whereby `T` is the separator between Date
|
|
and Time. The `+OFFSET` is the number of hours ahead/behind UTC, the
|
|
currently timezone set by the PC. This is achieved using the following
|
|
string to time format:
|
|
`%Y-%m-%dT%H:%M:%S%z`.
|
|
|
|
The second column is reversed during the return value of the string.
|
|
This column is used to allow for a stacktrace to be attached to the
|
|
log message.
|
|
|
|
The third column defines the level of the log message. This will be
|
|
five blank space characters if a level is passed outside of the
|
|
defined scope of logging levels.
|
|
|
|
The fourth column is reserved during the return value of the string.
|
|
It represents the body of the message to be logged.
|
|
|
|
|
|
`@Params`: _type - `LogLevel | int | str`
|
|
`@Return`: Formattable string - `str`
|
|
"""
|
|
## if the _type represents a LogLevel value, convert it to str
|
|
if not isinstance(_type, str):
|
|
_type = loglevel_as_str(_type)
|
|
|
|
## return newly formatted log message header
|
|
return __LOG_TMPL.format('{CALLER}', DATE=\
|
|
time.strftime(__TIMESTAMP_FMT, time.localtime()),
|
|
TYPE=_type) + "{0}"
|
|
|
|
|
|
def wrap(value: str, *, width: int = 120, tb_size: int = 4) -> str:
|
|
"""Return a hard-wrapped string defined by a fixed width.
|
|
|
|
Wrapped text is separated by a `\\n` character and a fixed width of
|
|
120 characters. Each wrap is appended with a tab size of 4 characters
|
|
at the start of each line-wrap.
|
|
|
|
`@Params`: value - `str`, width = 120 - `int`, tb_size = 4 - `int`
|
|
`@Return`: `str`
|
|
"""
|
|
return "\n".join(textwrap.wrap(value, width=width, tabsize=tb_size)) |