0

I am new to creating loggers in Python and have written a program (logger.py) to save log messages to a specified file. However, the log messages are not being saved to the file. Here is my code:

# code block formatted by indenting 3 spaces
from collections.abc import Mapping
import logging
from logging import LogRecord
import os
from typing import Any
from textwrap import shorten
from pathlib import Path

class ConsoleFormatter(logging.Formatter):
    def __init__(
        self,
        fmt: str | None = "%(asctime)s [%(name)s] [%(levelname)s] %(message)s",
        datefmt: str | None = "[%x %X %p]",
        style="%",
        validate: bool = True,
        *,
        defaults: Mapping[str, Any] | None = None,
    ) -> None:
        super().__init__(fmt, datefmt, style, validate, defaults=defaults)

    def format(self, record: LogRecord) -> str:
        end_portion = f"[{record.filename}:{record.lineno}]"

        # Hard code total size for now, quite confused to find it dynamically
        used_space = 42 + len(record.name)
        total_space = int(os.get_terminal_size()[0])
        end_part_size = len(end_portion)
        msg_width = total_space - (used_space + end_part_size)
        record.levelname = f"{record.levelname:<10}"
        formatted_msg_size = len(f"{shorten(record.msg,msg_width)[:-5]} ... ")
        end_portion_adjust_size = total_space - (
            used_space + formatted_msg_size + end_part_size
        )
        end_portion = " " * end_portion_adjust_size + end_portion
        record.msg = f"{shorten(record.msg,msg_width)[:-5]} ... {end_portion}"

        return super().format(record)

class FileFormatter(logging.Formatter):
    def __init__(
        self,
        fmt: str | None = "%(asctime)s [%(levelname)s] - %(message)s | [%(filename)s:%(lineno)s] ~ [%(module)s]",
        datefmt: str | None = "[%x %X %p]",
        style="%",
        validate: bool = True,
        *,
        defaults: Mapping[str, Any] | None = None,
    ) -> None:
        super().__init__(fmt, datefmt, style, validate, defaults=defaults)

    def format(self, record: LogRecord) -> str:
        return super().format(record)

class Logger(logging.Logger):
    def __init__(
        self,
        name: str,
        level: int | str = logging.DEBUG,
        log_to_path: str | None | Path = None,
    ) -> None:
        super().__init__(name, level)

        # Console Logging
        console_formatter = ConsoleFormatter()
        console_handler = logging.StreamHandler()
        console_handler.setFormatter(console_formatter)
        self.addHandler(console_handler)

        if not log_to_path is None:
            # File Logging
            file_formatter = FileFormatter()
            file_handler = logging.FileHandler(log_to_path)
            file_handler.setFormatter(file_formatter) # missing this line prevented file handler from logging to file
            self.addHandler(file_handler) # added this line to add file handler to logger

    def debug(
        self,
        *args,
        **kwargs,
    ) -> None:
        return super().debug(
            *args,
            **kwargs,
        )

    def info(
        self,
        *args,
        **kwargs,
    ) -> None:
        return super().info(
            *args,
            **kwargs,
        )

    def warning(
        self,
        *args,
        **kwargs,
    ) -> None:
        return super().warning(
            *args,
            **kwargs,
        )

    def error(
        self,
        *args,
        **kwargs,
    ) -> None:
        return super().error(
            *args,
            **kwargs,
        )

    def critical(
        self,
        *args,
        **kwargs,
    ) -> None:
        return super().critical(
            *args,
            **kwargs,
        )

l = Logger("Test2", log_to_path="tesasd.log")

from time import sleep

for i in range(10):
    l.error("asdadsasdsadsadadsasdasdasds adasds" * 5)
    sleep(0.5)

When I run the program, log messages appear in the console output as expected, but the messages are not being saved to the specified log file, even though the log file was created. Any suggestions for how to fix this issue would be greatly appreciated. Please note that English is not my first language.

Edit:

Well, now my logger , logs to the file , but the issue now is that the ConsoleFormatter is being used, when I wanted to use FileFormatter , Why is it happening?

0 Answers0