nested_logger#

Enhance the default logger, print visual ascii effect for better readability. Please see the examples/nested_logger.ipynb for more usage examples.

Usage:

from fixa.nest_logger import NestedLogger

logger = NestedLogger()

@logger.start_and_end(
    msg="My Function",
    start_emoji="🟢",
    end_emoji="🔴",
    pipe="📦",
)
def my_func(name: str):
    time.sleep(1)
    logger.info(f"{name} do something in my func")

my_func(name="alice")

The Output looks like:

[User 2023-02-25 11:02:05] +----- ⏱ 🟢 Start 'My Function 1' ----------------------------------------------+
[User 2023-02-25 11:02:05] 📦
[User 2023-02-25 11:02:06] 📦 alice do something in my func 1
[User 2023-02-25 11:02:06] 📦
[User 2023-02-25 11:02:06] +----- ⏰ 🔴 End 'My Function 1', elapsed = 1.01 sec ----------------------------+
aws_ops_alpha.vendor.nested_logger.format_line(msg: str, indent: int = 0, tab: str = '  ', nest: int = 0, _pipes: Optional[List[str]] = None) str[source]#

Format message with indentation and nesting.

Example:

>>> format_line("hello")
'[User] | hello'
>>> format_line("hello", indent=1)
'[User] |   hello'
>>> format_line("hello", nest=1)
'[User] | | hello'
>>> format_line("hello", indent=1, nest=1)
'[User] | |   hello'
class aws_ops_alpha.vendor.nested_logger.AlignEnum(value)[source]#

An enumeration.

aws_ops_alpha.vendor.nested_logger.format_ruler(msg: str, char: str = '-', align: AlignEnum = AlignEnum.middle, length: int = 80, left_padding: int = 5, right_padding: int = 5, corner: str = '', nest: int = 0, _pipes: Optional[List[str]] = None) str[source]#

Format message to shape a horizontal ruler.

Parameters:
  • msg – the message to print

  • char – the character to use as ruler

  • align – left, middle, right alignment of the message

  • length – the total number of character of the ruler

  • left_padding – the number of ruler character to pad on the left

  • right_padding – the number of ruler character to pad on the right

  • corner – the character to use as corner

  • nest – the number of pipe to print before the ruler

Example:

>>> format_ruler("Hello", length=40)
'---------------- Hello -----------------'

>>> format_ruler("Hello", length=20)
'------ Hello -------'

>>> format_ruler("Hello", char="=", length=40)
'================ Hello ================='

>>> format_ruler("Hello", corner="+", length=40)
'+--------------- Hello ----------------+'

>>> format_ruler("Hello", align=AlignEnum.left, length=40)
'----- Hello ----------------------------'

>>> format_ruler("Hello", align=AlignEnum.right, length=40)
'---------------------------- Hello -----'

>>> format_ruler("Hello", left_padding=3, align=AlignEnum.left, length=40)
'--- Hello ------------------------------'

>>> format_ruler("Hello", right_padding=3, align=AlignEnum.right, length=40)
'------------------------------ Hello ---'
aws_ops_alpha.vendor.nested_logger.decohints(decorator: Callable) Callable[source]#

fix pycharm type hint bug for decorator.

class aws_ops_alpha.vendor.nested_logger.NestedLogger(logger: Optional[Logger] = None, name: Optional[str] = None, level: int = 20, log_format: str = '[User %(asctime)s] %(message)s', datetime_format: str = '%Y-%m-%d %H:%m:%S', tab: str = '  ', pipe: str = '| ')[source]#

A logger that supports nested logging.

debug(msg: str, indent: int = 0, tab: Optional[str] = None, pipe: Optional[str] = None) str[source]#

Todo: add docstring

info(msg: str, indent: int = 0, tab: Optional[str] = None, pipe: Optional[str] = None) str[source]#

Todo: add docstring

warning(msg: str, indent: int = 0, tab: Optional[str] = None, pipe: Optional[str] = None) str[source]#

Todo: add docstring

error(msg: str, indent: int = 0, tab: Optional[str] = None, pipe: Optional[str] = None) str[source]#

Todo: add docstring

critical(msg: str, indent: int = 0, tab: Optional[str] = None, pipe: Optional[str] = None) str[source]#

Todo: add docstring

ruler(msg: str, char: str = '-', align: AlignEnum = AlignEnum.left, length: int = 80, left_padding: int = 5, right_padding: int = 5, corner: str = '+', pipe: Optional[str] = None, func: Optional[Callable] = None) str[source]#

Todo: add docstring

indent(level: int = 1)[source]#

A context manager that automatically add indent.

Example:

logger.ruler("start test indent")

logger.info("a")

with logger.indent():
    logger.info("b")

    with logger.indent():
        logger.info("c")

    logger.info("d")

logger.info("e")

logger.ruler("end test indent")

The output looks like:

[User] +----- start test indent -----------------------------------+
[User] | a
[User] |   b
[User] |     c
[User] |   d
[User] | e
[User] +----- end test indent -------------------------------------+
nested(pipe: Optional[str] = None)[source]#

A context manager that nest logging for one more level.

Example:

logger.ruler("section 1")
logger.info("hello 1")
with logger.nested():
    logger.ruler("section 1.1")
    logger.info("hello 1.1")
    with logger.nested():
        logger.ruler("section 1.1.1")
        logger.info("hello 1.1.1")
        logger.ruler("section 1.1.1")
    logger.ruler("section 1.1")
logger.ruler("section 1")

The output looks like:

[User] +----- section 1 -------------------------------------------+
[User] | hello 1
[User] | +----- section 1.1 ---------------------------------------+
[User] | | hello 1.1
[User] | | +----- section 1.1.1 -----------------------------------+
[User] | | | hello 1.1.1
[User] | | +----- section 1.1.1 -----------------------------------+
[User] | +----- section 1.1 ---------------------------------------+
[User] +----- section 1 -------------------------------------------+
pretty_log(start_msg: str = 'Start {func_name}()', error_msg: str = 'Error {func_name}(), elapsed = {elapsed:.2f} sec', end_msg: str = 'End {func_name}(), elapsed = {elapsed:.2f} sec', char: str = '-', align: AlignEnum = AlignEnum.left, length: int = 80, left_padding: int = 5, right_padding: int = 5, corner: str = '+', nest: int = 0, pipe: Optional[str] = None)[source]#

A decorator that pretty print ruler when a function start, error, end.

start_msg, error_msg and end_msg are string template. the {func_name} will become the function you are decorating, the {elapsed} will become the execution time of the function. You can use {elapsed:.2f} to set the precision to two digits. The execution time measurement are not accuracy, it is just an estimation up to three digits precision.

Example:

@nested_logger.pretty_log(nest=1)
def my_func2(name: str):
    time.sleep(1)
    nested_logger.info(f"{name} do something in my func 2")

@nested_logger.pretty_log()
def my_func1(name: str):
    time.sleep(1)
    nested_logger.info(f"{name} do something in my func 1")
    my_func2(name="bob")

my_func1(name="alice")

The output looks like:

[User] +----- Start my_func1() ------------------------------------+
[User] |
[User] | alice do something in my func 1
[User] | +----- Start my_func2() ----------------------------------+
[User] | |
[User] | | bob do something in my func 2
[User] | |
[User] | +----- End my_func2(), elapsed = 1.00 sec ----------------+
[User] |
[User] +----- End my_func1(), elapsed = 2.00 sec ------------------+
Returns:

a decorator that you can put on top of your function

start_and_end(msg: str, start_emoji: str = '🟢', error_emoji: str = '🔴', end_emoji: str = '🟢', pipe: str = '| ')[source]#

A simplified version of the pretty_log decorator. Visually print the start and the end of a function.

Example:

@logger.start_and_end(
    msg="My Function 1",
    start_emoji="🟢",
    error_emoji="🔴",
    end_emoji="🟢",
    pipe="📦",
)
def my_func1(name: str):
    time.sleep(1)
    logger.info(f"{name} do something in my func 1")

my_func1(name="alice")

The output looks like:

[User] +----- ⏱ 🟢 Start 'My Function 1' --------------------------+
[User] 📦
[User] 📦 alice do something in my func 1
[User] 📦
[User] +----- ⏰ 🟢 End 'My Function 1', elapsed = 1.01 sec --------+
Parameters:
  • msg – indicate the name of the function

  • start_emoji – custom emoji for the start message

  • end_emoji – custom emoji for the end message

  • pipe – custom pipe character

Returns:

a decorator that you can put on top of your function

emoji_block(msg: str, emoji: str)[source]#

A simplified version of the start_and_end decorator. Use emoji to Visually print the function logic block

Example:

@logger.emoji_block(
    msg="Deploy app {app_name}",
    emoji="🚀",
)
def deploy_app(app_name: str):
    logger.info("working ...")
    logger.info("done")

deploy_app(app_name="my_app")

The output looks like:

[User] +----- ⏱ 🚀 Start 'Deploy app my_app' ----------------------+
[User] 🚀
[User] 🚀 working ...
[User] 🚀 done
[User] 🚀
[User] +----- ⏰ ✅ 🚀 End 'Deploy app my_app', elapsed = 1.01 sec -+
Parameters:
  • msg – indicate the name of the function

  • emoji – custom emoji for the visual effect

Returns:

a decorator that you can put on top of your function