Skip to content

Logger

logger

logger = Logger()

An instantiated logger that you can use directly

Logger

Logger(suppressed_modules: list[str] = SUPPRESSED_MODULES, log_dir: str = './logs')

Custom Logger class utilizing Rich and Loguru for advanced logging.

This class sets up a logging system that uses both the Rich library for enhanced output formatting in the console and Loguru for handling log files and more sophisticated logging features. The logger is configured to display colored and detailed logs in the terminal, while also saving structured logs to a file for debugging purposes.

Key Features:

  • Rich Tracebacks: Automatically installs Rich traceback for more readable error messages in the console, highlighting key information such as line numbers and functions.
  • Log File Handling: Logs are saved in a specified directory with detailed information in JSON-like format, serialized for easier parsing.
  • Log Levels: Configured to handle different log levels, focusing on INFO messages for the console and DEBUG level messages for log files.

Usage Example

from tradingtoolbox.utils.logger import logger, Logger

# [Optional] Create a custom logger
custom_logger = Logger(supressed_modules=["talib"], log_dir="./my_logs")

try:
    # Code that might fail
    print(a)
except Exception as e:
    logger.error()

logger.warning("This is a warning message")
logger.info({"key": "value"})
logger.print("This replaces the standard print")

Notes:

  • The logger's console output is colorized using Rich, and it includes rich tracebacks for easier debugging.
  • Log files are stored in the log_dir directory, defaulting to ./logs.

Initializes the custom logger instance.

Parameters:

Name Type Description Default
suppressed_modules list[str]

A list of modules to suppress from rich traceback (default is SUPPRESSED_MODULES).

SUPPRESSED_MODULES
log_dir str

The directory where log files will be saved (default is "./logs").

'./logs'
Source code in src/tradingtoolbox/utils/logger.py
def __init__(
    self,
    suppressed_modules: list[str] = SUPPRESSED_MODULES,
    log_dir: str = "./logs",
):
    """
    Initializes the custom logger instance.

    Parameters:
        suppressed_modules:
            A list of modules to suppress from rich traceback (default is SUPPRESSED_MODULES).
        log_dir:
            The directory where log files will be saved (default is "./logs").
    """

    self._create_logs_dir(log_dir)

    # This will install rich to traceback, which is quite handy
    rich.traceback.install(
        show_locals=False,
        suppress=[__import__(name) for name in suppressed_modules],
    )

    config = {
        "handlers": [
            {
                "sink": RichHandler(
                    show_level=False,
                    show_time=True,
                    rich_tracebacks=True,
                    markup=True,
                    omit_repeated_times=False,
                ),
                # "sink": sys.stdout,
                # This will force us to only use the rich handler on normal levels
                "filter": lambda record: record["level"].name == "INFO",
                "format": "{message}",
            },
            # {
            #     "sink": sys.stdout,
            #     "colorize": True,
            #     "backtrace": True,
            #     "diagnose": True,
            #     "enqueue": False,
            #     "format": "<cyan>❯ {module}:{function} ({line})</cyan> | <green>{time:YYYY-MM-DD at HH:mm:ss.sss}</green>",
            #     "filter": lambda record: record["level"].name == "INFO",
            # },
            {
                "sink": "./logs/logs.log",
                "level": "DEBUG",
                "serialize": True,
                "enqueue": True,
                "colorize": True,
                "format": "<light-cyan>❯ {module}:{function} ({line})</light-cyan> | <light-black>{time:YYYY-MM-DD at HH:mm:ss.sss}</light-black>\n{message}",
            },
        ],
    }

    _logger.configure(**config)  # type: ignore
    self.logger = _logger.patch(patching)

error

error()

Logs the most recent traceback error in a readable format, useful for. Uses the ERROR level

Source code in src/tradingtoolbox/utils/logger.py
def error(self):
    """
    Logs the most recent traceback error in a readable format, useful for. Uses the ERROR level
    """
    console.print(Traceback())
    recent_traceback = traceback.format_exc(limit=10)
    self.logger.error(recent_traceback)

info

info(*obj)

Logs an informational message, replacing the standard print function. Uses the INFO level

Source code in src/tradingtoolbox/utils/logger.py
def info(self, *obj):
    """
    Logs an informational message, replacing the standard print function. Uses the INFO level
    """
    for item in obj:
        self.logger.opt(depth=2).info(pretty_repr(item))

warning

warning(obj)

Logs a warning message with the option to pretty-print an object. Uses the WARNING level

Source code in src/tradingtoolbox/utils/logger.py
def warning(self, obj):
    """
    Logs a warning message with the option to pretty-print an object. Uses the WARNING level
    """
    self.logger.opt(depth=2).warning(pretty_repr(obj))

print

print(*msg: Any) -> None

Logs the provided object using an advanced logging mechanism.

This method overrides the default print function to utilize a logger for output. It ensures that all output is captured through the logging system rather than standard output.

Parameters:

Name Type Description Default
msg Any

The object to be logged. It can be of any type that the logger can handle, including strings, numbers, or custom objects.

()

Usage Example

from tradingtoolbox.utils.logger import print

print("Hello world")

Source code in src/tradingtoolbox/utils/logger.py
def print(*msg: Any) -> None:
    """
    Logs the provided object using an advanced logging mechanism.

    This method overrides the default `print` function to utilize a
    logger for output. It ensures that all output is captured
    through the logging system rather than standard output.

    Parameters:
        msg: The object to be logged. It can be of any type that the
            logger can handle, including strings, numbers, or custom objects.


    **Usage Example**
    ```python
    from tradingtoolbox.utils.logger import print

    print("Hello world")
    ```
    """
    logger.info(*msg)