mirror of
https://github.com/Akkudoktor-EOS/EOS.git
synced 2025-04-19 00:45:22 +00:00
* Add EOS_CONFIG_DIR to set config dir (relative path to EOS_DIR or absolute path). - config_folder_path read-only - config_file_path read-only * Default values to support app start with empty config: - latitude/longitude (Berlin) - optimization_ev_available_charge_rates_percent (null, so model default value is used) - Enable Akkudoktor electricity price forecast (docker-compose). * Fix some endpoints (empty data, remove unused params, fix types). * cacheutil: Use cache dir. Closes #240 * Support EOS_LOGGING_LEVEL environment variable to set log level. * tests: All tests use separate temporary config - Add pytest switch --check-config-side-effect to check user config file existence after each test. Will also fail if user config existed before test execution (but will only check after the test has run). Enable flag in github workflow. - Globally mock platformdirs in config module. Now no longer required to patch individually. Function calls to config instance (e.g. merge_settings_from_dict) were unaffected previously. * Set Berlin as default location (default config/docker-compose).
98 lines
3.3 KiB
Python
98 lines
3.3 KiB
Python
"""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
|