Skip to content

Latest commit

 

History

History
1097 lines (821 loc) · 43.1 KB

README.md

File metadata and controls

1097 lines (821 loc) · 43.1 KB

pyloggermanager

The 'pyloggermanager' package is a vital logging framework for Python applications, providing developers with essential tools to streamline logging operations. Its primary function is to simplify the recording and organization of log messages, including critical information, debugging messages, errors, and warnings. By offering a centralized interface and robust functionalities, the package facilitates efficient monitoring and troubleshooting processes.

With its intuitive interface, the pyloggermanager package enables developers to seamlessly integrate logging mechanisms into their applications. This allows for systematic recording and categorization of log entries based on severity levels, enhancing readability and prioritization of issues. Moreover, the package offers flexibility in customizing logging configurations to suit specific project requirements, including formatting, output destinations, and thread safety.

Beyond technical capabilities, the pyloggermanager package contributes to the reliability and maintainability of Python applications. It establishes consistent logging practices, simplifying collaboration, code reviews, and issue resolution across development teams. Overall, the pyloggermanager package is an invaluable asset for developers aiming to implement robust logging solutions, ensuring efficient and resilient application performance.

Installation

Logger Manager can be installed using pip:

pip install pyloggermanager

Usage

import pyloggermanager

# Load configuration
pyloggermanager.load_config()

# Log a debug message
pyloggermanager.debug("This is a debug message.")

# Log an informational message
pyloggermanager.info("This is an informational message.")

# Log a warning message
pyloggermanager.warning("This is a warning message.")

# Log an error message
pyloggermanager.error("This is an error message.")

# Log a critical message
pyloggermanager.critical("This is a critical message.")

# Output
# 2024-03-22 23:37:21 :: INFO :: This is an informational message.
# 2024-03-22 23:37:21 :: WARNING :: This is a warning message.
# 2024-03-22 23:37:21 :: ERROR :: This is an error message.
# 2024-03-22 23:37:21 :: CRITICAL :: This is a critical message.

Documentation

pyloggermanager

Methods

  • load_config(file_name='default.log', file_mode='a', level=LogLevel.INFO, format_str=DEFAULT_FORMAT, date_format=DATE_FORMAT, stream=None, handlers=None, colorization=None, encoding='UTF-8') - This function loads the logging configuration based on the provided parameters. It acquires a lock for thread safety, configures default handlers if no handlers are specified, configures the formatter and level for each handler, and adds the handlers to the root logger. Finally, it releases the lock.
  • disable(level=LogLevel.CRITICAL) - This function disables logging up to the specified level.
  • critical(self, message: str, ignore_display: bool = False, exec_info: Optional[Tuple[Type, BaseException, Optional[TracebackType]]] = None, stack_info: bool = False, stack_level: int = 1) -> None: Logs a message with CRITICAL level.
  • debug(self, message: str, ignore_display: bool = True, exec_info: Optional[Tuple[Type, BaseException, Optional[TracebackType]]] = None, stack_info: bool = False, stack_level: int = 1) -> None: Logs a message with DEBUG level.
  • error(self, message: str, ignore_display: bool = False, exec_info: Optional[Tuple[Type, BaseException, Optional[TracebackType]]] = None, stack_info: bool = False, stack_level: int = 1) -> None: Logs a message with ERROR level.
  • info(self, message: str, ignore_display: bool = False, exec_info: Optional[Tuple[Type, BaseException, Optional[TracebackType]]] = None, stack_info: bool = False, stack_level: int = 1) -> None: Logs a message with INFO level.
  • log(self, level: int, message: str, ignore_display: bool = False, exec_info: Optional[Tuple[Type, BaseException, Optional[TracebackType]]] = None, stack_info: bool = False, stack_level: int = 1) -> None: Logs a message at the specified level.
  • warning(self, message: str, ignore_display: bool = False, exec_info: Optional[Tuple[Type, BaseException, Optional[TracebackType]]] = None, stack_info: bool = False, stack_level: int = 1) -> None: Logs a message with WARNING level.

CallerFrame

The CallerFrame class represents caller details such as class name, file name, function name, module name, and path name based on the caller's frame information. It provides a method to retrieve caller details from a given frame.

Properties

  • class_name: Represents the name of the class where the function was called.
  • file_name: Represents the name of the file from which the function was called.
  • function_name: Represents the name of the function that called the method.
  • module_name: Represents the name of the module where the function was called.
  • path_name: Represents the path of the file from which the function was called.

Methods

  • __init__(): Initializes the CallerFrame object with default attribute values.
  • get_caller_details(frame: FrameType) -> CallerFrame: Retrieves caller details from the given frame.

Usage

import pyloggermanager
import inspect


# Assume we have a function where we want to retrieve caller details
def some_function():
    caller_frame = pyloggermanager.CallerFrame.get_caller_details(inspect.currentframe())
    print("Caller Class:", caller_frame.class_name)
    print("Caller File:", caller_frame.file_name)
    print("Caller Function:", caller_frame.function_name)
    print("Caller Module:", caller_frame.module_name)
    print("Caller Path:", caller_frame.path_name)


# Now we call the function
some_function()

# Output
# Caller Class: Unknown Class
# Caller File: example
# Caller Function: test_function
# Caller Module: example
# Caller Path: /path/to/example.py

FileMode

The FileMode class represents file modes supported by the Python open() function for reading, writing, and appending to files. It provides methods to retrieve the default file mode, get the file mode mappings, check if a mode is valid, set the default file mode, and get readable and writable modes.

Constants

  • READ: Represents the read file mode.
  • READ_PLUS: Represents the read/write file mode.
  • WRITE: Represents the write file mode.
  • WRITE_PLUS: Represents the read/write file mode.
  • EXCLUSIVE_CREATE: Represents the exclusive creation file mode.
  • APPEND: Represents the append file mode.
  • APPEND_PLUS: Represents the read/append file mode.
  • BINARY: Represents the binary file mode.
  • READ_BINARY: Represents the read binary file mode.
  • READ_WRITE_BINARY: Represents the read/write binary file mode.
  • TEXT: Represents the text file mode.
  • UPDATE: Represents the update file mode.

Methods

  • check_mode(mode: str) -> str: Checks if the provided mode exists and returns the same value if it exists; otherwise, raises a ValueError.
  • get_default_mode() -> str: Returns the default file mode.
  • get_file_mode(mode_str: str) -> str: Returns the file mode string corresponding to the provided mode name.
  • get_file_modes() -> dict: Returns a dictionary mapping file mode names to their corresponding strings.
  • get_readable_modes() -> dict: Returns a dictionary of reading file modes and their corresponding strings.
  • get_writable_modes() -> dict: Returns a dictionary of writable file modes and their corresponding strings.
  • is_valid_mode(mode: str) -> bool: Checks if the provided mode string is a valid file mode.
  • set_default_mode(mode: str) -> None: Sets the default file mode.

Usage

# Import the FileMode class
import pyloggermanager

# Check if a mode is valid
mode = 'r'
if pyloggermanager.FileMode.is_valid_mode(mode):
    print(f"The mode '{mode}' is valid.")
else:
    print(f"The mode '{mode}' is invalid.")

# Get default mode
default_mode = pyloggermanager.FileMode.get_default_mode()
print(f"The default mode is: {default_mode}")

# Set default mode
new_default_mode = 'a'
pyloggermanager.FileMode.set_default_mode(new_default_mode)
print(f"New default mode set to: {new_default_mode}")

# Get readable modes
readable_modes = pyloggermanager.FileMode.get_readable_modes()
print("Readable modes:")
for mode_name, mode_str in readable_modes.items():
    print(f"- {mode_name}: {mode_str}")

# Get writable modes
writable_modes = pyloggermanager.FileMode.get_writable_modes()
print("Writable modes:")
for mode_name, mode_str in writable_modes.items():
    print(f"- {mode_name}: {mode_str}")

# Output
# The mode 'r' is valid.
# The default mode is: a
# New default mode set to: a
# Readable modes:
# - READ: r
# - READ_PLUS: r+
# - WRITE_PLUS: w+
# - APPEND_PLUS: a+
# Writable modes:
# - WRITE: w
# - WRITE_PLUS: w+
# - APPEND: a
# - APPEND_PLUS: a+

Lock

The Lock class provides a simple interface to manage locks using the Python threading module. It allows acquiring, creating, checking if a lock is locked, and releasing locks.

Methods

  • acquire(name: str, blocking: bool = True, timeout: float = -1) -> bool: Acquires the lock with the given name.
  • create(name: str) -> None: Creates a new lock with the given name.
  • generate_name(length: int = 10) -> str: Generates a random name for a lock of specified length.
  • locked(name: str) -> bool: Checks if the lock with the given name is currently locked.
  • release(name: str) -> None: Releases the lock with the given name.

Usage

# Import the Lock class
import pyloggermanager
import threading
import time


# Define a function to perform an action using a lock
def perform_action(lock_name):
    print(f"Thread {threading.current_thread().name} attempting to acquire lock {lock_name}")
    if pyloggermanager.Lock.acquire(lock_name, timeout=3):
        print(f"Thread {threading.current_thread().name} acquired lock {lock_name}")
        time.sleep(2)  # Simulating some action being performed
        pyloggermanager.Lock.release(lock_name)
        print(f"Thread {threading.current_thread().name} released lock {lock_name}")
    else:
        print(f"Thread {threading.current_thread().name} couldn't acquire lock {lock_name}")


# Create locks
lock1_name = pyloggermanager.Lock.generate_name()
lock2_name = pyloggermanager.Lock.generate_name()
pyloggermanager.Lock.create(lock1_name)
pyloggermanager.Lock.create(lock2_name)

# Spawn threads to perform actions using locks
thread1 = threading.Thread(target=perform_action, args=(lock1_name,))
thread2 = threading.Thread(target=perform_action, args=(lock2_name,))

thread1.start()
thread2.start()

thread1.join()
thread2.join()

# Output
# Thread Thread-1 (perform_action) attempting to acquire lock nzlggljagd
# Thread Thread-2 (perform_action) attempting to acquire lock mbsvxfocxdThread Thread-1 (perform_action) acquired lock nzlggljagd
# 
# Thread Thread-2 (perform_action) acquired lock mbsvxfocxd
# Thread Thread-1 (perform_action) released lock nzlggljagdThread Thread-2 (perform_action) released lock mbsvxfocxd

LogLevel

The LogLevel class represents different log levels used in logging systems. It provides methods to check if a log level is valid, get the default log level, get log level mappings, remove log levels, set the default log level, and set custom log levels.

Constants

  • DEBUG: Constant representing the debug log level (integer: 10)
  • INFO: Constant representing the info log level (integer: 20)
  • WARNING: Constant representing the warning log level (integer: 30)
  • ERROR: Constant representing the error log level (integer: 40)
  • CRITICAL: Constant representing the critical log level (integer: 50)

Methods

  • check_level(level: int) -> int: Checks if the provided level exists and returns the same value if exists, else raises ValueError.
  • get_default_level() -> str: Returns the default log level as a string.
  • get_level(level: int | str) -> str | int: Returns the log level name if an integer level is provided, or returns the log level integer if a string level is provided.
  • get_levels() -> dict: Returns a dictionary mapping log level integers to their corresponding names, sorted by level.
  • get_next_level(current_level: int) -> int | None: Returns the next log level integer after the provided current level, or None if it is the highest level.
  • get_previous_level(current_level: int) -> int | None: Returns the previous log level integer before the provided current level, or None if it is the lowest level.
  • is_valid_level(level: int | str) -> bool: Checks if the provided log level (integer or string) is a valid log level.
  • remove_level(level: int | str) -> None: Removes the log level mapping for the specified level.
  • set_default_level(level: int | str) -> None: Sets the default log level based on the provided integer or string level.
  • set_level(level: int, level_name: str) -> None: Sets a custom log level with the provided level integer and name.

Usage

# Import the LogLevel class
import pyloggermanager

# Check if a log level is valid
print(pyloggermanager.LogLevel.is_valid_level(pyloggermanager.LogLevel.DEBUG))  # Output: True

# Get default log level
print(pyloggermanager.LogLevel.get_default_level())  # Output: INFO

# Get log level mappings
print(
    pyloggermanager.LogLevel.get_levels())  # Output: {10: 'DEBUG', 20: 'INFO', 30: 'WARNING', 40: 'ERROR', 50: 'CRITICAL'}

# Set default log level
pyloggermanager.LogLevel.set_default_level(pyloggermanager.LogLevel.WARNING)
print(pyloggermanager.LogLevel.get_default_level())  # Output: WARNING

# Set custom log level
pyloggermanager.LogLevel.set_level(15, 'CUSTOM')
print(pyloggermanager.LogLevel.get_level(15))  # Output: 'CUSTOM'

# Remove log level
pyloggermanager.LogLevel.remove_level('CUSTOM')
print(pyloggermanager.LogLevel.get_level(15))  # Output: 'Level 15'

Record

The Record class represents a log record with various attributes such as message, logger name, level name, caller frame information, execution information, stack information, and thread/process details. It provides methods to serialize the record to a dictionary and JSON format.

Properties

  • time: Property representing the timestamp of the log record.
  • message: Property representing the log message.
  • logger_name: Property representing the name of the logger.
  • level_number: Property representing the numeric value of the log level.
  • level_name: Property representing the name of the log level.
  • file_name: Property representing the name of the file where the log occurred.
  • class_name: Property representing the name of the class where the log occurred.
  • function_name: Property representing the name of the function/method where the log occurred.
  • module_name: Property representing the name of the module where the log occurred.
  • path_name: Property representing the path of the file where the log occurred.
  • exec_info: Property representing the execution information associated with the log record.
  • stack_info: Property representing the stack information associated with the log record.
  • thread: Property representing the thread ID associated with the log record.
  • thread_name: Property representing the name of the thread associated with the log record.
  • process_id: Property representing the process ID associated with the log record.

Methods

  • __init__(message: str, logger_name: str, level_number: int, caller_frame: CallerFrame, exec_info: Optional[Tuple[Type, BaseException, Optional[TracebackType]]] = None, stack_info: Optional[str] = None) -> None: Constructs a new 'Record' object with the provided parameters.
  • json_serializer(obj: Any) -> Union[str, None]: Static method to serialize objects to JSON format.
  • to_dict() -> dict: Converts the 'Record' object to a dictionary.
  • to_json() -> str: Converts the 'Record' object to JSON string.

Usage

# Import the Record class
import inspect
import pyloggermanager

# Create a CallerFrame object (Assuming it's defined elsewhere)
caller_frame = pyloggermanager.CallerFrame.get_caller_details(inspect.currentframe())

# Create a new Record object
record = pyloggermanager.Record(
    message="An example log message",
    logger_name="example_logger",
    level_number=20,
    caller_frame=caller_frame,
    exec_info=(ValueError, ValueError("An example error occurred"), None),
    stack_info="Stack trace information"
)

# Access properties of the Record object
print(record.message)  # Output: An example log message
print(record.level_name)  # Output: INFO
print(record.file_name)  # Output: example

# Serialize the Record object to a dictionary
record_dict = record.to_dict()
print(record_dict)
# Output: {
#     'time': datetime.datetime(2024, 3, 22, 23, 41, 47, 604552),
#     'message': 'An example log message',
#     'logger_name': 'example_logger',
#     'level_name': 'INFO',
#     'level_number': 20,
#     'file_name': 'example',
#     'class_name': 'ExampleClass',
#     'function_name': 'example_function',
#     'module_name': 'example',
#     'path_name': 'example_path',
#     'exec_info': (<class 'ValueError', ValueError('An example error occurred'), None),
#     'stack_info': 'Stack trace information',
#     'thread': 12345,
#     'thread_name': 'MainThread',
#     'process_id': 67890 
# }

# Serialize the Record object to JSON format
json_string = record.to_json()
print(json_string)
# Output:
# {
#     "time": "2024-03-22T23:41:47.604552",
#     "message": "An example log message",
#     "logger_name": "example_logger",
#     "level_name": "INFO",
#     "level_number": 20,
#     "file_name": "example",
#     "class_name": "ExampleClass",
#     "function_name": "example_function",
#     "module_name": "example",
#     "path_name": "example_path",
#     "exec_info": [
#         "ValueError",
#         "An example error occurred",
#         null
#     ],
#     "stack_info": "Stack trace information",
#     "thread": 12345,
#     "thread_name": "MainThread",
#     "process_id": 67890
# }

Logger

The Logger class represents a logger object with various attributes and methods for logging messages.

Properties

  • cache: Gets or sets the cache dictionary.
  • disabled: Indicates whether the logger is disabled or not.
  • handlers: The list of handlers associated with the logger.
  • level: The logging level of the logger.
  • lock_name: Gets or sets the name of the lock used for thread safety.
  • manager: The manager associated with the logger.
  • name: The name of the logger.
  • parent: The parent logger in the logger hierarchy.
  • root: The root logger associated with the logger hierarchy.

Methods

  • __init__(self, name: str, level: int = LogLevel.INFO) -> None: Initializes a new Logger object.
  • add_handler(self, handler: Handler) -> None: Adds a handler to the logger's list of handlers after acquiring the lock.
  • call_handlers(self, record: Record, ignore_display: bool) -> None: Calls the handlers associated with the logger.
  • critical(self, message: str, ignore_display: bool = False, exec_info: Optional[Tuple[Type, BaseException, Optional[TracebackType]]] = None, stack_info: bool = False, stack_level: int = 1) -> None: Logs a message with CRITICAL level.
  • debug(self, message: str, ignore_display: bool = True, exec_info: Optional[Tuple[Type, BaseException, Optional[TracebackType]]] = None, stack_info: bool = False, stack_level: int = 1) -> None: Logs a message with DEBUG level.
  • error(self, message: str, ignore_display: bool = False, exec_info: Optional[Tuple[Type, BaseException, Optional[TracebackType]]] = None, stack_info: bool = False, stack_level: int = 1) -> None: Logs a message with ERROR level.
  • find_caller(self, stack_info: bool = False, stack_level: int = 1) -> Tuple[CallerFrame, str]: Finds the caller frame and optionally collects stack information.
  • get_child(self, suffix: str) -> 'Logger': Get a child logger with the specified suffix.
  • get_effective_level(self) -> int: Retrieves the effective log level for the logger.
  • handle(self, record: Record, ignore_display: bool) -> None: Handles the given log record by calling its handlers if the logger is not disabled.
  • has_handlers(self) -> bool: Checks if the logger or any of its ancestors have handlers.
  • info(self, message: str, ignore_display: bool = False, exec_info: Optional[Tuple[Type, BaseException, Optional[TracebackType]]] = None, stack_info: bool = False, stack_level: int = 1) -> None: Logs a message with INFO level.
  • is_enabled_for(self, level: int) -> bool: Checks if logging is enabled for the specified log level.
  • log(self, level: int, message: str, ignore_display: bool = False, exec_info: Optional[Tuple[Type, BaseException, Optional[TracebackType]]] = None, stack_info: bool = False, stack_level: int = 1) -> None: Logs a message at the specified level.
  • make_record(self, name: str, level: int, message: str, caller_frame: Optional[CallerFrame] = None, exec_info: Optional[Tuple[Type, BaseException, Optional[TracebackType]]] = None, stack_info: Optional[str] = None) -> Record: Creates a Record object with specified attributes.
  • remove_handler(self, handler: Handler) -> None: Removes a handler from the logger's list of handlers after acquiring the lock.
  • warning(self, message: str, ignore_display: bool = False, exec_info: Optional[Tuple[Type, BaseException, Optional[TracebackType]]] = None, stack_info: bool = False, stack_level: int = 1) -> None: Logs a message with WARNING level.

Usage

# Importing the necessary modules
import pyloggermanager
from pyloggermanager.handlers import ConsoleHandler

# Sample usage of the Logger class
# Creating a logger instance
logger = pyloggermanager.Logger("example_logger")

# Adding a handler
handler = ConsoleHandler()
logger.add_handler(handler)

# Logging messages
logger.info("This is an informational message.\n")
logger.error("An error occurred.")

# Removing the handler
logger.remove_handler(handler)

# Output
# 2024-03-22 23:45:14 :: INFO :: This is an informational message.
# 2024-03-22 23:45:14 :: ERROR :: An error occurred.

Manager

The Manager class manages loggers and their settings within a logging hierarchy.

Properties

  • disable: Gets or sets the level at which logging is disabled.
  • lock_name: Gets or sets the name of the lock used for thread safety.
  • logger_class: Gets or sets the logger class used for creating logger instances.
  • logger_dict: Gets or sets the dictionary mapping logger names to their instances.
  • record_factory: Gets or sets the factory used for creating log records.
  • root: Gets or sets the root logger of the logging hierarchy.

Methods

  • __init__(self, root_node: Logger) -> None: Initializes the Manager with a root logger.
  • clear_cache(self) -> None: Clears the cache for all loggers and the root logger.
  • get_logger(self, name: str) -> Logger: Retrieves a logger with the specified name. If the logger does not exist, it creates a new logger.
  • set_logger(self, logger: Logger) -> None: Sets the logger class to be used for creating new loggers.

Usage

# Importing the necessary modules
import pyloggermanager

# Create a root logger
root_logger = pyloggermanager.Logger("root")

# Create a manager with the root logger
manager = pyloggermanager.Manager(root_logger)

# Set the level at which logging is disabled
manager.disable = 20

# Get a logger named 'example_logger'
example_logger = manager.get_logger("example_logger")

# Set the logger class
manager.set_logger(example_logger)

# Clear the cache for all loggers and the root logger
manager.clear_cache()

Registry

The Registry class serves as a registry to store and manage instances of the Logger class.

Properties

  • logger_map: Gets or sets the dictionary mapping loggers to their associated values.

Methods

  • __init__(self, logger: Logger) -> None: Initializes the Registry with a single logger.
  • append(self, logger: Logger) -> None: Adds a new logger to the registry.

Usage

# Importing the necessary modules
import pyloggermanager

# Create a logger
logger = pyloggermanager.Logger("example_logger")

# Create a registry with the logger
registry = pyloggermanager.Registry(logger)

# Append a new logger to the registry
new_logger = pyloggermanager.Logger("new_logger")
registry.append(new_logger)

# Get the logger map
logger_map = registry.logger_map

RootLogger

The RootLogger class represents the root logger in a logging hierarchy. It inherits from the Logger class and initializes itself with the name 'root' and the specified log level. The root logger serves as the ancestor of all other loggers in the logging hierarchy.

Methods

  • __init__(self, level: int) -> None: Constructs a new RootLogger object with the specified log level.

pyloggermanager.formatters

The 'pyloggermanager.formatters' package provides classes for formatting log messages in various formats within the logger manager framework. It includes implementations for formatting log messages as CSV (Comma-Separated Values), JSON (JavaScript Object Notation), and the default text format.

Below listed formatter classes enable users to customize the appearance and structure of log messages according to their requirements. By supporting different formats such as CSV and JSON, users have the flexibility to choose the most suitable format for their logging needs, whether it's for human-readable output, structured data storage, or integration with external systems.

Overall, the 'pyloggermanager.formatters' package enhances the logger manager framework by offering versatile formatting options for log messages, catering to a wide range of logging use cases and preferences.

Constants

  • DEFAULT_FORMAT (str): The default format string used for log message formatting.
  • CSV_FORMAT (str): The format string used for CSV log message formatting.
  • JSON_FORMAT (str): The format string used for JSON log message formatting.
  • DATE_FORMAT (str): The default date format string used for log message formatting.

Formatter

Base class for log record formatters. It allows customization of log message format. Subclasses must implement the format method to customize log message formatting.

Placeholder Description
%(time)s The time at which the log record was created, formatted using date_format.
%(message)s The message associated with the log record.
%(logger_name)s The name of the logger.
%(level_name)s The name of the logging level (e.g., INFO, WARNING).
%(level_number)d The numeric value of the logging level.
%(file_name)s The name of the file from which the logging call was made.
%(class_name)s The name of the class containing the logging call.
%(function_name)s The name of the function/method containing the logging call.
%(module_name)s The name of the module containing the logging call.
%(path_name)s The full pathname of the source file.
%(exec_info)s The formatted traceback information if an exception was raised during the logging call.
%(stack_info)s The stack information at the time of the logging call.
%(thread)d The thread ID.
%(thread_name)s The name of the thread.
%(process_id)d The ID of the process.

Methods

  • __init__(format_str: str | dict = DEFAULT_FORMAT, date_format: str = DATE_FORMAT): Initializes the Formatter object.
  • format(record: 'Record') -> str: Formats the log record into a string based on the provided record object.
  • format_time(value: time.struct_time, date_format: str) -> str: Formats the provided time value into a string using the specified date format.
  • format_exception(exec_info: Optional[Tuple[Type[BaseException], BaseException, Optional[TracebackType]]] = None) -> str: Formats the exception information into a string.

DefaultFormatter

Custom formatter for log records. It allows customization of log record formatting using a specified format string. Replaces tokens in the format string with corresponding values from the log record.

Methods

  • __init__(format_str: str = DEFAULT_FORMAT, date_format: str = DATE_FORMAT): Initializes a 'DefaultFormatter' instance with the specified format string.
  • format(record: 'Record') -> str: Formats the given log record according to the format string.

Usage

import inspect
import pyloggermanager
from pyloggermanager.formatters import DefaultFormatter

caller_frame = pyloggermanager.CallerFrame.get_caller_details(inspect.currentframe())

# Create a log record
record = pyloggermanager.Record(
    message="This is a log message",
    logger_name="example_logger",
    level_number=20,
    caller_frame=caller_frame,
    exec_info=None,
    stack_info=None
)

# Create a DefaultFormatter instance
formatter = DefaultFormatter()

# Format the log record
formatted_message = formatter.format(record)
print(formatted_message)

# Output: '2024-03-22 15:30:45 :: INFO :: This is a log message'

CSVFormatter

Subclass of the 'Formatter' class for formatting log records in CSV format. It allows customization of the format string used for formatting log records.

Methods

  • __init__(format_str: str = CSV_FORMAT, date_format: str = DATE_FORMAT): Initializes a 'CSVFormatter' object with the specified format string.
  • format(record: 'Record') -> str: Formats the given log record into a CSV string based on the specified format string.

Usage

import inspect
import pyloggermanager
from pyloggermanager.formatters import CSVFormatter

caller_frame = pyloggermanager.CallerFrame.get_caller_details(inspect.currentframe())

# Create a log record
record = pyloggermanager.Record(
    message="This is a log message",
    logger_name="example_logger",
    level_number=20,
    caller_frame=caller_frame,
    exec_info=None,
    stack_info=None
)

# Create a CSVFormatter instance
formatter = CSVFormatter()

# Format the log record as CSV
formatted_message = formatter.format(record)
print(formatted_message)

# Output: '2024-03-22 23:46:41,INFO,This is a log message'

JSONFormatter

Subclass of the 'Formatter' class for formatting log records into JSON format. It provides methods to initialize the formatter with a custom format string, format log records into JSON strings, and handle JSON decoding errors.

Methods

  • __init__(format_str: dict = None, date_format: str = DATE_FORMAT): Initializes the JSONFormatter object with a custom format string.
  • format(record: 'Record') -> str: Formats the given log record into a JSON string.

Usage

import inspect
import pyloggermanager
from pyloggermanager.formatters import JSONFormatter

caller_frame = pyloggermanager.CallerFrame.get_caller_details(inspect.currentframe())

# Create a log record
record = pyloggermanager.Record(
    message="This is a log message",
    logger_name="example_logger",
    level_number=20,
    caller_frame=caller_frame,
    exec_info=None,
    stack_info=None
)

# Create a JSONFormatter instance
formatter = JSONFormatter()

# Format the log record as JSON
formatted_message = formatter.format(record)
print(formatted_message)

# Output:
# {
#     "time": "2024-03-22 23:47:03",
#     "levelName": "INFO",
#     "message": "This is a log message"
# }

pyloggermanager.handlers

The 'pyloggermanager.handlers' package provides classes responsible for handling log records generated within the logger manager framework. It includes various handlers for processing log messages, directing them to different destinations, and performing actions based on logging levels.

Below listed handler classes offer flexibility and customization options for managing log records within the logger manager framework. They enable users to define how log messages are processed, where they are directed, and how they are formatted, catering to various logging scenarios and deployment environments.

Overall, the 'pyloggermanager.handlers' package enhances the functionality of the logger manager framework by providing a robust set of handlers for managing log records effectively and efficiently. Users can choose and configure handlers based on their specific logging needs and infrastructure requirements.

Handler

The Handler class is a base class for different log handlers used in logging systems. It provides methods and properties to manage handler attributes such as name, log level, colorization, and formatter. Additionally, it includes methods to acquire/release locks, close the handler, emit log records, format log records, flush buffered records, and retrieve a list of all handlers.

Properties

  • colorization: Gets or sets the colorization object for the handler.
  • formatter: Gets or sets the formatter object for formatting log records.
  • level: Gets or sets the log level for the handler.
  • name: Gets or sets the name of the handler.

Methods

  • __init__(name: str = None, level: int = 20, colorization: pycolorecho.ColorMapper = None, formatter: Formatter = DefaultFormatter()) - Initializes the handler with optional attributes.
  • close(): Closes the handler.
  • emit(record: 'Record', ignore_display: bool) -> None: Abstract method to emit a log record.
  • format(record: 'Record') -> str: Formats a log record using the handler's formatter.
  • flush(): Flushes buffered records.
  • get_handlers() -> list[Any]: Retrieves a list of all handlers.
  • handle(record: 'Record', ignore_display: bool) -> None: Handles a log record.

Usage

from pyloggermanager.formatters import Formatter
from pyloggermanager.handlers import Handler


# Create a custom formatter
class CustomFormatter(Formatter):
    def format(self, record):
        return f"[{record.level_name}] {record.message}"


# Create a handler with custom formatter
handler = Handler(formatter=CustomFormatter())

ConsoleHandler

The ConsoleHandler class is a subclass of Handler representing a handler that writes log records to the console. It provides methods to set and retrieve the stream used for logging, close the stream, emit log records, and flush the stream.

Properties

  • stream: Gets or sets the stream of the handler.

Methods

  • __init__(name: str = None, level: int = 20, colorization: pycolorecho.ColorMapper = None, formatter: Formatter = DefaultFormatter(), stream: Stream = TerminalStream()) - Initializes a ConsoleHandler instance with optional attributes
  • close(): Closes the stream if it has a close method.
  • emit(record: 'Record', ignore_display: bool = True) -> None: Emits the log record by formatting it, colorizing the message, and writing it to the stream.
  • flush(): Flushes the stream if it has a flush method.

Usage

import inspect
import pyloggermanager
from pyloggermanager.handlers import ConsoleHandler

# Create a console handler
console_handler = ConsoleHandler()

caller_frame = pyloggermanager.CallerFrame.get_caller_details(inspect.currentframe())

# Emit a log record
console_handler.emit(pyloggermanager.Record(
    message="This is a log message",
    logger_name='TestLogger',
    level_number=20,
    caller_frame=caller_frame
))

# Output
# 2024-03-22 23:47:35 :: INFO :: This is a log message

StreamHandler

The StreamHandler class is a subclass of Handler representing a handler that emits log records to a stream. It provides methods to set the log level, formatter, and stream, as well as to emit log records and flush the stream.

Properties

  • stream: Gets or sets the stream of the handler.

Methods

  • __init__(name: str = None, level: int = 20, colorization: pycolorecho.ColorMapper = None, formatter: Formatter = DefaultFormatter(), stream: Stream = StdoutStream()) - Initializes a StreamHandler instance with optional attributes.
  • close(): Closes the stream if it has a close method.
  • emit(record: 'Record', ignore_display: bool) -> None: Emits a log record to the stream.
  • flush(): Flushes the stream if it has a flush method.

Usage

import inspect
import pyloggermanager
from pyloggermanager.handlers import StreamHandler

# Create a stream handler
stream_handler = StreamHandler()

caller_frame = pyloggermanager.CallerFrame.get_caller_details(inspect.currentframe())

# Emit a log record
stream_handler.emit(pyloggermanager.Record(
    message="This is a log message",
    logger_name='TestLogger',
    level_number=20,
    caller_frame=caller_frame
), ignore_display=True)

# Output
# 2024-03-22 23:48:13 :: INFO :: This is a log message

FileHandler

The FileHandler class is a subclass of Handler responsible for handling log records by writing them to a file. It allows customization of various parameters such as file name, file mode, encoding, etc.

Properties

  • encoding: Gets or sets the encoding of the handler.
  • filemode: Gets or sets the file mode for opening the file handler.
  • filename: Gets or sets the file name of the handler.

Methods

  • __init__(name: str = None, level: int = 20, colorization: pycolorecho.ColorMapper = None, formatter: Formatter = DefaultFormatter(), file_name: str = 'default.log', file_mode: str = 'a', encoding: str = 'UTF-8') - Initializes a FileHandler object with optional attributes.
  • close(): Closes the file stream used for writing log records.
  • emit(record: 'Record', ignore_display: bool) -> None: Emits a log record by writing it to the log file.
  • flush(): Flushes the file stream used for writing log records.

Usage

import inspect
import pyloggermanager
from pyloggermanager.handlers import FileHandler

# Create a file handler
file_handler = FileHandler(file_name='app.log', encoding='utf-8')

caller_frame = pyloggermanager.CallerFrame.get_caller_details(inspect.currentframe())

# Emit a log record
file_handler.emit(pyloggermanager.Record(
    message="This is a log message",
    logger_name='TestLogger',
    level_number=20,
    caller_frame=caller_frame
), ignore_display=False)

# Output
# 2024-03-22 23:48:30 :: INFO :: This is a log message

StderrHandler

The StderrHandler class is a subclass of Handler responsible for handling log records by writing them to the standard error stream (stderr).

Properties

  • stream: Gets the standard error stream (stderr).

Methods

  • __init__(self, level: int = 30) - Initializes a StderrHandler object with an optional log level.

pyloggermanager.streams

The 'pyloggermanager.streams' package provides classes related to handling output streams for log records within the logger manager framework. These classes define different types of streams that log messages can be directed to, allowing for flexible and customizable logging behaviour.

Below listed stream classes offer versatility in directing log messages to different output channels, allowing users to customize logging behavior based on their application's requirements and environment configuration. By supporting various stream types, the logger manager framework enables users to control where log records are displayed or stored, facilitating effective logging and troubleshooting processes.

Overall, the 'pyloggermanager.streams' package enhances the functionality of the logger manager framework by providing a range of stream classes for directing log messages to different output channels. Users can leverage these classes to tailor their logging setup to suit their specific needs and preferences, ensuring efficient management and processing of log records.

Stream

The Stream class is an abstract base class representing an output stream. It defines two abstract methods: write() and flush(), which must be implemented by subclasses.

Methods

  • write(message: str) -> None: Abstract method to write the given message to the stream.
  • flush() -> None: Abstract method to flush the stream, ensuring all buffered data is written.

StdoutStream

The StdoutStream class is a subclass of Stream representing a stream that writes messages to the standard output ( sys.stdout). It overrides the write and flush methods inherited from the Stream class.

Methods

  • write(message: str) -> None: Writes the given message to the standard output (sys.stdout).
  • flush() -> None: Flushes the output buffer of the standard output (sys.stdout), ensuring all buffered data is written.

Usage

from pyloggermanager.streams import StdoutStream

# Create an instance of StdoutStream
stdout_stream = StdoutStream()

# Write a message to stdout
stdout_stream.write("This is a message to stdout\n")

# Flush stdout buffer
stdout_stream.flush()

# Output
# This is a message to stdout

StderrStream

The StderrStream class is a subclass of Stream representing a stream for writing messages to the standard error ( sys.stderr) output. It overrides the write and flush methods inherited from the Stream class.

Methods

  • write(message: str) -> None: Writes the provided message to the standard error (sys.stderr) output.
  • flush() -> None: Flushes the standard error (sys.stderr) buffer.

Usage

from pyloggermanager.streams import StderrStream

# Create an instance of StderrStream
stderr_stream = StderrStream()

# Write a message to stderr
stderr_stream.write("This is an error message to stderr\n")

# Flush stderr buffer
stderr_stream.flush()

# Output
# This is an error message to stderr

TerminalStream

The TerminalStream class is a subclass of Stream representing a stream for writing messages to the terminal. It overrides the write and flush methods inherited from the Stream class.

Methods

  • write(message: str) -> None: Writes the provided message to the terminal.
  • flush() -> None: Flushes the output buffer, but does nothing for the terminal stream since output is immediately displayed.

Usage

from pyloggermanager.streams import TerminalStream

# Create an instance of TerminalStream
terminal_stream = TerminalStream()

# Write a message to the terminal
terminal_stream.write("This is a message to the terminal\n")

# Flush the terminal buffer (No operation required)
terminal_stream.flush()

# Output
# This is a message to the terminal

Text Styles

For text colorization and styling, this package utilizes the pycolorecho package. You can find additional details about its usage and features by following this link: pycolorecho package.

License

Please refer to the MIT license within the project for more information.

Contributing

We welcome contributions from the community! Whether you have ideas for new features, bug fixes, or enhancements, feel free to open an issue or submit a pull request on GitHub.