mirror of
				https://github.com/Akkudoktor-EOS/EOS.git
				synced 2025-11-04 08:46:20 +00:00 
			
		
		
		
	Add Documentation 2 (#334)
Add documentation that covers: - configuration - prediction Add Python scripts that support automatic documentation generation for configuration data defined with pydantic. Adapt EOS configuration to provide more methods for REST API and automatic documentation generation. Adapt REST API to allow for EOS configuration file load and save. Sort REST API on generation of openapi markdown for docs. Move logutil to core/logging to allow configuration of logging by standard config. Make Akkudoktor predictions always start extraction of prediction data at start of day. Previously extraction started at actual hour. This is to support the code that assumes prediction data to start at start of day. Signed-off-by: Bobby Noelte <b0661n0e17e@gmail.com>
This commit is contained in:
		@@ -48,8 +48,8 @@ from pendulum import DateTime, Duration
 | 
			
		||||
from pydantic import BaseModel, ConfigDict, Field
 | 
			
		||||
 | 
			
		||||
from akkudoktoreos.core.coreabc import ConfigMixin
 | 
			
		||||
from akkudoktoreos.core.logging import get_logger
 | 
			
		||||
from akkudoktoreos.utils.datetimeutil import compare_datetimes, to_datetime, to_duration
 | 
			
		||||
from akkudoktoreos.utils.logutil import get_logger
 | 
			
		||||
 | 
			
		||||
logger = get_logger(__name__)
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -31,7 +31,7 @@ from pendulum import Date, DateTime, Duration
 | 
			
		||||
from pendulum.tz.timezone import Timezone
 | 
			
		||||
from timezonefinder import TimezoneFinder
 | 
			
		||||
 | 
			
		||||
from akkudoktoreos.utils.logutil import get_logger
 | 
			
		||||
from akkudoktoreos.core.logging import get_logger
 | 
			
		||||
 | 
			
		||||
logger = get_logger(__name__)
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,97 +0,0 @@
 | 
			
		||||
"""Utility functions for handling logging tasks.
 | 
			
		||||
 | 
			
		||||
Functions:
 | 
			
		||||
----------
 | 
			
		||||
- get_logger: Creates and configures a logger with console and optional rotating file logging.
 | 
			
		||||
 | 
			
		||||
Example usage:
 | 
			
		||||
--------------
 | 
			
		||||
    # Logger setup
 | 
			
		||||
    >>> logger = get_logger(__name__, log_file="app.log", logging_level="DEBUG")
 | 
			
		||||
    >>> logger.info("Logging initialized.")
 | 
			
		||||
 | 
			
		||||
Notes:
 | 
			
		||||
------
 | 
			
		||||
- The logger supports rotating log files to prevent excessive log file size.
 | 
			
		||||
"""
 | 
			
		||||
 | 
			
		||||
import logging
 | 
			
		||||
import os
 | 
			
		||||
from logging.handlers import RotatingFileHandler
 | 
			
		||||
from typing import Optional
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def get_logger(
 | 
			
		||||
    name: str,
 | 
			
		||||
    log_file: Optional[str] = None,
 | 
			
		||||
    logging_level: Optional[str] = "INFO",
 | 
			
		||||
    max_bytes: int = 5000000,
 | 
			
		||||
    backup_count: int = 5,
 | 
			
		||||
) -> logging.Logger:
 | 
			
		||||
    """Creates and configures a logger with a given name.
 | 
			
		||||
 | 
			
		||||
    The logger supports logging to both the console and an optional log file. File logging is
 | 
			
		||||
    handled by a rotating file handler to prevent excessive log file size.
 | 
			
		||||
 | 
			
		||||
    Args:
 | 
			
		||||
        name (str): The name of the logger, typically `__name__` from the calling module.
 | 
			
		||||
        log_file (Optional[str]): Path to the log file for file logging. If None, no file logging is done.
 | 
			
		||||
        logging_level (Optional[str]): Logging level (e.g., "INFO", "DEBUG"). Defaults to "INFO".
 | 
			
		||||
        max_bytes (int): Maximum size in bytes for log file before rotation. Defaults to 5 MB.
 | 
			
		||||
        backup_count (int): Number of backup log files to keep. Defaults to 5.
 | 
			
		||||
 | 
			
		||||
    Returns:
 | 
			
		||||
        logging.Logger: Configured logger instance.
 | 
			
		||||
 | 
			
		||||
    Example:
 | 
			
		||||
        logger = get_logger(__name__, log_file="app.log", logging_level="DEBUG")
 | 
			
		||||
        logger.info("Application started")
 | 
			
		||||
    """
 | 
			
		||||
    # Create a logger with the specified name
 | 
			
		||||
    logger = logging.getLogger(name)
 | 
			
		||||
    logger.propagate = True
 | 
			
		||||
    if (env_level := os.getenv("EOS_LOGGING_LEVEL")) is not None:
 | 
			
		||||
        logging_level = env_level
 | 
			
		||||
    if logging_level == "DEBUG":
 | 
			
		||||
        level = logging.DEBUG
 | 
			
		||||
    elif logging_level == "INFO":
 | 
			
		||||
        level = logging.INFO
 | 
			
		||||
    elif logging_level == "WARNING":
 | 
			
		||||
        level = logging.WARNING
 | 
			
		||||
    elif logging_level == "ERROR":
 | 
			
		||||
        level = logging.ERROR
 | 
			
		||||
    else:
 | 
			
		||||
        level = logging.DEBUG
 | 
			
		||||
    logger.setLevel(level)
 | 
			
		||||
 | 
			
		||||
    # The log message format
 | 
			
		||||
    formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
 | 
			
		||||
 | 
			
		||||
    # Prevent loggers from being added multiple times
 | 
			
		||||
    # There may already be a logger from pytest
 | 
			
		||||
    if not logger.handlers:
 | 
			
		||||
        # Create a console handler with a standard output stream
 | 
			
		||||
        console_handler = logging.StreamHandler()
 | 
			
		||||
        console_handler.setLevel(level)
 | 
			
		||||
        console_handler.setFormatter(formatter)
 | 
			
		||||
 | 
			
		||||
        # Add the console handler to the logger
 | 
			
		||||
        logger.addHandler(console_handler)
 | 
			
		||||
 | 
			
		||||
    if log_file and len(logger.handlers) < 2:  # We assume a console logger to be the first logger
 | 
			
		||||
        # If a log file path is specified, create a rotating file handler
 | 
			
		||||
 | 
			
		||||
        # Ensure the log directory exists
 | 
			
		||||
        log_dir = os.path.dirname(log_file)
 | 
			
		||||
        if log_dir and not os.path.exists(log_dir):
 | 
			
		||||
            os.makedirs(log_dir)
 | 
			
		||||
 | 
			
		||||
        # Create a rotating file handler
 | 
			
		||||
        file_handler = RotatingFileHandler(log_file, maxBytes=max_bytes, backupCount=backup_count)
 | 
			
		||||
        file_handler.setLevel(level)
 | 
			
		||||
        file_handler.setFormatter(formatter)
 | 
			
		||||
 | 
			
		||||
        # Add the file handler to the logger
 | 
			
		||||
        logger.addHandler(file_handler)
 | 
			
		||||
 | 
			
		||||
    return logger
 | 
			
		||||
@@ -4,7 +4,7 @@ from typing import Any
 | 
			
		||||
import numpy as np
 | 
			
		||||
 | 
			
		||||
from akkudoktoreos.config.configabc import SettingsBaseModel
 | 
			
		||||
from akkudoktoreos.utils.logutil import get_logger
 | 
			
		||||
from akkudoktoreos.core.logging import get_logger
 | 
			
		||||
 | 
			
		||||
logger = get_logger(__name__)
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user