diff --git a/backend/app/main.py b/backend/app/main.py index dcc0f8b..eb639a2 100644 --- a/backend/app/main.py +++ b/backend/app/main.py @@ -1,14 +1,9 @@ import subprocess -import logging from flask import Flask from flask_cors import CORS from flask_restx import Api -# Configuração básica de logging -logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s') -logger = logging.getLogger(__name__) - from src.infrastructure.routes.education.view import education_ns from src.infrastructure.routes.experiences.view import experiences_ns @@ -17,6 +12,9 @@ from src.infrastructure.routes.projects.view import projects_ns from src.infrastructure.routes.social_media.view import social_media_ns from src.infrastructure.dependencie_injection import ApplicationDependencies +from src.infrastructure.utils.logger import get_logger + +logger = get_logger(__name__) class ApplicationSetup: def __init__(self): diff --git a/backend/logs/portfolio_api.log b/backend/logs/portfolio_api.log index b593967..ca088ec 100644 --- a/backend/logs/portfolio_api.log +++ b/backend/logs/portfolio_api.log @@ -260,3 +260,51 @@ Detalhes do erro: 2025-09-25 14:34:39,236 - portfolio_api - ERROR - Error getting experiences: Test error 2025-09-25 14:34:39,246 - portfolio_api - ERROR - Error getting projects: Test error 2025-09-25 14:34:39,254 - portfolio_api - ERROR - Error getting social media: Test error +ERROR - src.infrastructure.routes.education.view - Error getting education: Test error +ERROR - src.infrastructure.routes.experiences.view - Error getting experiences: Test error +ERROR - src.infrastructure.routes.projects.view - Error getting projects: Test error +ERROR - src.infrastructure.routes.social_media.view - Error getting social media: Test error +WARNING - src.infrastructure.services.portfolio_data_service - [CACHE MISS] Dados de projetos não encontrados no cache. Buscando no repositório... +INFO - src.infrastructure.services.portfolio_data_service - Salvando 4 projetos no cache... +WARNING - src.infrastructure.services.portfolio_data_service - [CACHE MISS] Dados de experiências não encontrados no cache. Buscando no repositório... +INFO - src.infrastructure.services.portfolio_data_service - Salvando 4 experiências no cache... +WARNING - src.infrastructure.services.portfolio_data_service - [CACHE MISS] Dados de formações não encontrados no cache. Buscando no repositório... +INFO - src.infrastructure.services.portfolio_data_service - Salvando 4 formações no cache... +WARNING - src.infrastructure.services.portfolio_data_service - [CACHE MISS] Dados de certificações não encontrados no cache. Buscando no repositório... +INFO - src.infrastructure.services.portfolio_data_service - Salvando 4 certificações no cache... +WARNING - src.infrastructure.services.portfolio_data_service - [CACHE MISS] Dados de redes sociais não encontrados no cache. Buscando no repositório... +INFO - src.infrastructure.services.portfolio_data_service - Salvando 4 redes sociais no cache... +INFO - src.infrastructure.services.portfolio_data_service - [CACHE HIT] 4 projetos recuperados do cache +INFO - src.infrastructure.services.portfolio_data_service - [CACHE HIT] 4 experiências recuperadas do cache +ERROR - src.infrastructure.routes.education.view - Error getting education: Test error +ERROR - src.infrastructure.routes.experiences.view - Error getting experiences: Test error +ERROR - src.infrastructure.routes.projects.view - Error getting projects: Test error +ERROR - src.infrastructure.routes.social_media.view - Error getting social media: Test error +WARNING - src.infrastructure.services.portfolio_data_service - [CACHE MISS] Dados de projetos não encontrados no cache. Buscando no repositório... +INFO - src.infrastructure.services.portfolio_data_service - Salvando 4 projetos no cache... +WARNING - src.infrastructure.services.portfolio_data_service - [CACHE MISS] Dados de experiências não encontrados no cache. Buscando no repositório... +INFO - src.infrastructure.services.portfolio_data_service - Salvando 4 experiências no cache... +WARNING - src.infrastructure.services.portfolio_data_service - [CACHE MISS] Dados de formações não encontrados no cache. Buscando no repositório... +INFO - src.infrastructure.services.portfolio_data_service - Salvando 4 formações no cache... +WARNING - src.infrastructure.services.portfolio_data_service - [CACHE MISS] Dados de certificações não encontrados no cache. Buscando no repositório... +INFO - src.infrastructure.services.portfolio_data_service - Salvando 4 certificações no cache... +WARNING - src.infrastructure.services.portfolio_data_service - [CACHE MISS] Dados de redes sociais não encontrados no cache. Buscando no repositório... +INFO - src.infrastructure.services.portfolio_data_service - Salvando 4 redes sociais no cache... +INFO - src.infrastructure.services.portfolio_data_service - [CACHE HIT] 4 projetos recuperados do cache +INFO - src.infrastructure.services.portfolio_data_service - [CACHE HIT] 4 experiências recuperadas do cache +ERROR - src.infrastructure.routes.education.view - Error getting education: Test error +ERROR - src.infrastructure.routes.experiences.view - Error getting experiences: Test error +ERROR - src.infrastructure.routes.projects.view - Error getting projects: Test error +ERROR - src.infrastructure.routes.social_media.view - Error getting social media: Test error +WARNING - src.infrastructure.services.portfolio_data_service - [CACHE MISS] Dados de projetos não encontrados no cache. Buscando no repositório... +INFO - src.infrastructure.services.portfolio_data_service - Salvando 4 projetos no cache... +WARNING - src.infrastructure.services.portfolio_data_service - [CACHE MISS] Dados de experiências não encontrados no cache. Buscando no repositório... +INFO - src.infrastructure.services.portfolio_data_service - Salvando 4 experiências no cache... +WARNING - src.infrastructure.services.portfolio_data_service - [CACHE MISS] Dados de formações não encontrados no cache. Buscando no repositório... +INFO - src.infrastructure.services.portfolio_data_service - Salvando 4 formações no cache... +WARNING - src.infrastructure.services.portfolio_data_service - [CACHE MISS] Dados de certificações não encontrados no cache. Buscando no repositório... +INFO - src.infrastructure.services.portfolio_data_service - Salvando 4 certificações no cache... +WARNING - src.infrastructure.services.portfolio_data_service - [CACHE MISS] Dados de redes sociais não encontrados no cache. Buscando no repositório... +INFO - src.infrastructure.services.portfolio_data_service - Salvando 4 redes sociais no cache... +INFO - src.infrastructure.services.portfolio_data_service - [CACHE HIT] 4 projetos recuperados do cache +INFO - src.infrastructure.services.portfolio_data_service - [CACHE HIT] 4 experiências recuperadas do cache diff --git a/backend/src/infrastructure/adapters/outbound_postgres_adapter.py b/backend/src/infrastructure/adapters/outbound_postgres_adapter.py index ced9752..7038340 100644 --- a/backend/src/infrastructure/adapters/outbound_postgres_adapter.py +++ b/backend/src/infrastructure/adapters/outbound_postgres_adapter.py @@ -15,7 +15,9 @@ from src.domain.dto.project import Project from src.domain.dto.social_media import SocialMedia from src.infrastructure.ports.repository_interface import RepositoryInterface -from src.infrastructure.utils.logger import logger +from src.infrastructure.utils.logger import get_logger + +logger = get_logger(__name__) class PostgresAdapter(RepositoryInterface): diff --git a/backend/src/infrastructure/adapters/outbound_redis_adapter.py b/backend/src/infrastructure/adapters/outbound_redis_adapter.py index c711289..544edcb 100644 --- a/backend/src/infrastructure/adapters/outbound_redis_adapter.py +++ b/backend/src/infrastructure/adapters/outbound_redis_adapter.py @@ -1,3 +1,5 @@ +"""Redis Adapter for caching portfolio data.""" + import json import os from typing import Optional, List, Dict, Any @@ -11,7 +13,9 @@ from src.domain.dto.project import Project from src.domain.dto.social_media import SocialMedia from src.infrastructure.ports.cache_provider_interface import CacheProvider -from src.infrastructure.utils.logger import logger +from src.infrastructure.utils.logger import get_logger + +logger = get_logger(__name__) class RedisAdapter(CacheProvider): @@ -42,7 +46,7 @@ def __init__(self) -> None: try: self.redis.ping() except RedisError as e: - logger.error(f"Redis Connection Error: {e}") + logger.error(f"Erro de conexão com o Redis: {str(e)}", exc_info=True) raise def get_cache_data_by_key(self, key: str): @@ -52,7 +56,7 @@ def get_cache_data_by_key(self, key: str): return None return json.loads(data) except RedisError as e: - logger.error(f"Redis GET Key Error: {e}") + logger.error(f"Erro ao obter chave do Redis: {str(e)}", exc_info=True) raise def get_all_projects(self) -> [] or List[Project]: diff --git a/backend/src/infrastructure/dependencie_injection.py b/backend/src/infrastructure/dependencie_injection.py index 0807217..6626b99 100644 --- a/backend/src/infrastructure/dependencie_injection.py +++ b/backend/src/infrastructure/dependencie_injection.py @@ -1,37 +1,39 @@ -import logging from src.infrastructure.adapters.outbound_postgres_adapter import PostgresAdapter from src.infrastructure.adapters.outbound_redis_adapter import RedisAdapter from src.infrastructure.services.portfolio_data_service import PortfolioDataService +from src.infrastructure.utils.logger import get_logger -logger = logging.getLogger(__name__) +logger = get_logger(__name__) class ApplicationDependencies: _instance = None def __new__(cls): if cls._instance is None: - logger.info("🚀 Criando nova instância de ApplicationDependencies") + logger.info("Criando nova instância de ApplicationDependencies") cls._instance = super().__new__(cls) try: - logger.info("🔄 Inicializando PostgresAdapter...") + logger.info("Inicializando PostgresAdapter...") cls._instance.data_repository = PostgresAdapter() - logger.info("✅ PostgresAdapter inicializado com sucesso!") - logger.info("🔄 Inicializando RedisAdapter...") + logger.info("PostgresAdapter inicializado com sucesso") + + logger.info("Inicializando RedisAdapter...") cls._instance.cache_provider = RedisAdapter() - logger.info("✅ RedisAdapter inicializado com sucesso!") - logger.info("🔄 Inicializando PortfolioDataService...") + logger.info("RedisAdapter inicializado com sucesso") + + logger.info("Inicializando PortfolioDataService...") cls._instance.portfolio_data_service = PortfolioDataService( cls._instance.data_repository, cls._instance.cache_provider ) - logger.info("✅ PortfolioDataService inicializado com sucesso!") + logger.info("PortfolioDataService inicializado com sucesso") except Exception as e: - logger.error(f"❌ Erro ao inicializar ApplicationDependencies: {str(e)}") + logger.error(f"Erro ao inicializar ApplicationDependencies: {str(e)}", exc_info=True) raise - logger.info("🎉 ApplicationDependencies inicializado com sucesso!") + logger.info("ApplicationDependencies inicializado com sucesso") else: - logger.info("♻️Reutilizando instância existente de ApplicationDependencies") + logger.info("Reutilizando instância existente de ApplicationDependencies") return cls._instance diff --git a/backend/src/infrastructure/routes/education/view.py b/backend/src/infrastructure/routes/education/view.py index fad995c..5106736 100644 --- a/backend/src/infrastructure/routes/education/view.py +++ b/backend/src/infrastructure/routes/education/view.py @@ -4,9 +4,11 @@ from flask_restx import Namespace, Resource from src.infrastructure.utils.constants import HTTP_INTERNAL_SERVER_ERROR -from src.infrastructure.utils.logger import logger +from src.infrastructure.utils.logger import get_logger from src.infrastructure.dependencie_injection import ApplicationDependencies +logger = get_logger(__name__) + def get_portfolio_data_service(): return ApplicationDependencies().portfolio_data_service diff --git a/backend/src/infrastructure/routes/experiences/view.py b/backend/src/infrastructure/routes/experiences/view.py index f79692c..350a650 100644 --- a/backend/src/infrastructure/routes/experiences/view.py +++ b/backend/src/infrastructure/routes/experiences/view.py @@ -8,7 +8,9 @@ def get_portfolio_data_service(): return ApplicationDependencies().portfolio_data_service from src.infrastructure.utils.constants import HTTP_INTERNAL_SERVER_ERROR -from src.infrastructure.utils.logger import logger +from src.infrastructure.utils.logger import get_logger + +logger = get_logger(__name__) experiences_ns = Namespace("Experiences", description="Companies experiences") diff --git a/backend/src/infrastructure/routes/projects/view.py b/backend/src/infrastructure/routes/projects/view.py index e0588c8..572df65 100644 --- a/backend/src/infrastructure/routes/projects/view.py +++ b/backend/src/infrastructure/routes/projects/view.py @@ -8,7 +8,9 @@ def get_portfolio_data_service(): return ApplicationDependencies().portfolio_data_service from src.infrastructure.utils.constants import HTTP_INTERNAL_SERVER_ERROR -from src.infrastructure.utils.logger import logger +from src.infrastructure.utils.logger import get_logger + +logger = get_logger(__name__) projects_blueprint = Blueprint("projects_bp", __name__) projects_ns = Namespace( diff --git a/backend/src/infrastructure/routes/social_media/view.py b/backend/src/infrastructure/routes/social_media/view.py index 55efe56..3f99fbf 100644 --- a/backend/src/infrastructure/routes/social_media/view.py +++ b/backend/src/infrastructure/routes/social_media/view.py @@ -8,7 +8,9 @@ def get_portfolio_data_service(): return ApplicationDependencies().portfolio_data_service from src.infrastructure.utils.constants import HTTP_INTERNAL_SERVER_ERROR -from src.infrastructure.utils.logger import logger +from src.infrastructure.utils.logger import get_logger + +logger = get_logger(__name__) social_media_blueprint = Blueprint("social_media_bp", __name__) social_media_ns = Namespace( diff --git a/backend/src/infrastructure/services/portfolio_data_service.py b/backend/src/infrastructure/services/portfolio_data_service.py index af7e9d5..dd60b43 100644 --- a/backend/src/infrastructure/services/portfolio_data_service.py +++ b/backend/src/infrastructure/services/portfolio_data_service.py @@ -1,4 +1,3 @@ -import logging from src.domain.dto.certification import Certification from src.domain.dto.company_duration import CompanyDuration from src.domain.dto.experience import Experience @@ -7,9 +6,9 @@ from src.domain.dto.social_media import SocialMedia from src.infrastructure.ports.repository_interface import RepositoryInterface from src.infrastructure.ports.cache_provider_interface import CacheProvider +from src.infrastructure.utils.logger import get_logger - -logger = logging.getLogger(__name__) +logger = get_logger(__name__) class PortfolioDataService: """Portfolio Data Service""" @@ -23,13 +22,13 @@ def projects(self) -> list[Project]: cache_projects = self.cache_provider.get_all_projects() if cache_projects: - logger.info(f"✅ [CACHE HIT] {len(cache_projects)} projetos recuperados do cache") + logger.info(f"[CACHE HIT] {len(cache_projects)} projetos recuperados do cache") return cache_projects - logger.warning("⚠️ [CACHE MISS] Dados de projetos não encontrados no cache. Buscando no repositório...") + logger.warning("[CACHE MISS] Dados de projetos não encontrados no cache. Buscando no repositório...") repository_projects = self.data_repository.get_all_projects() - logger.info(f"💾 Salvando {len(repository_projects)} projetos no cache...") + logger.info(f"Salvando {len(repository_projects)} projetos no cache...") self.cache_provider.set_projects(repository_projects) return repository_projects @@ -40,13 +39,13 @@ def experiences(self) -> list[Experience]: cache_experiences = self.cache_provider.get_all_experiences() if cache_experiences: - logger.info(f"✅ [CACHE HIT] {len(cache_experiences)} experiências recuperadas do cache") + logger.info(f"[CACHE HIT] {len(cache_experiences)} experiências recuperadas do cache") return cache_experiences - logger.warning("⚠️ [CACHE MISS] Dados de experiências não encontrados no cache. Buscando no repositório...") + logger.warning("[CACHE MISS] Dados de experiências não encontrados no cache. Buscando no repositório...") repository_experiences = self.data_repository.get_all_experiences() - logger.info(f"💾 Salvando {len(repository_experiences)} experiências no cache...") + logger.info(f"Salvando {len(repository_experiences)} experiências no cache...") self.cache_provider.set_experiences(repository_experiences) return repository_experiences @@ -55,13 +54,13 @@ def companies_duration(self) -> list[CompanyDuration]: cached_companies_duration = self.cache_provider.get_company_duration() if cached_companies_duration: - logger.info("✅ [CACHE HIT] Durações de empresas recuperadas do cache") + logger.info("[CACHE HIT] Durações de empresas recuperadas do cache") return cached_companies_duration - logger.warning("⚠️ [CACHE MISS] Dados de duração de empresas não encontrados no cache. Buscando no repositório...") + logger.warning("[CACHE MISS] Dados de duração de empresas não encontrados no cache. Buscando no repositório...") repository_companies_duration = self.data_repository.get_company_duration() - logger.info("💾 Salvando durações de empresas no cache...") + logger.info("Salvando durações de empresas no cache...") self.cache_provider.set_company_duration(repository_companies_duration) return repository_companies_duration @@ -71,13 +70,13 @@ def formations(self) -> list[Formation]: cached_formations = self.cache_provider.get_all_formations() if cached_formations: - logger.info(f"✅ [CACHE HIT] {len(cached_formations)} formações recuperadas do cache") + logger.info(f"[CACHE HIT] {len(cached_formations)} formações recuperadas do cache") return cached_formations - logger.warning("⚠️ [CACHE MISS] Dados de formações não encontrados no cache. Buscando no repositório...") + logger.warning("[CACHE MISS] Dados de formações não encontrados no cache. Buscando no repositório...") repository_formations = self.data_repository.get_all_formations() - logger.info(f"💾 Salvando {len(repository_formations)} formações no cache...") + logger.info(f"Salvando {len(repository_formations)} formações no cache...") self.cache_provider.set_formations(repository_formations) return repository_formations @@ -87,13 +86,13 @@ def certifications(self) -> list[Certification]: cached_certifications = self.cache_provider.get_all_certifications() if cached_certifications: - logger.info(f"✅ [CACHE HIT] {len(cached_certifications)} certificações recuperadas do cache") + logger.info(f"[CACHE HIT] {len(cached_certifications)} certificações recuperadas do cache") return cached_certifications - logger.warning("⚠️ [CACHE MISS] Dados de certificações não encontrados no cache. Buscando no repositório...") + logger.warning("[CACHE MISS] Dados de certificações não encontrados no cache. Buscando no repositório...") repository_certifications = self.data_repository.get_all_certifications() - logger.info(f"💾 Salvando {len(repository_certifications)} certificações no cache...") + logger.info(f"Salvando {len(repository_certifications)} certificações no cache...") self.cache_provider.set_certifications(repository_certifications) return repository_certifications @@ -103,13 +102,13 @@ def social_media(self) -> list[SocialMedia]: cached_social_media = self.cache_provider.get_all_social_media() if cached_social_media: - logger.info(f"✅ [CACHE HIT] {len(cached_social_media)} redes sociais recuperadas do cache") + logger.info(f"[CACHE HIT] {len(cached_social_media)} redes sociais recuperadas do cache") return cached_social_media - logger.warning("⚠️ [CACHE MISS] Dados de redes sociais não encontrados no cache. Buscando no repositório...") + logger.warning("[CACHE MISS] Dados de redes sociais não encontrados no cache. Buscando no repositório...") repository_social_media = self.data_repository.get_all_social_media() - logger.info(f"💾 Salvando {len(repository_social_media)} redes sociais no cache...") + logger.info(f"Salvando {len(repository_social_media)} redes sociais no cache...") self.cache_provider.set_social_media(repository_social_media) return repository_social_media @@ -119,13 +118,13 @@ def total_experience(self) -> dict: cached_total_experience = self.cache_provider.get_total_experience() if cached_total_experience: - logger.info("✅ [CACHE HIT] Experiência total recuperada do cache") + logger.info("[CACHE HIT] Experiência total recuperada do cache") return cached_total_experience - logger.warning("⚠️ [CACHE MISS] Dados de experiência total não encontrados no cache. Buscando no repositório...") + logger.warning("[CACHE MISS] Dados de experiência total não encontrados no cache. Buscando no repositório...") repository_total_experience = self.data_repository.get_total_experience() - logger.info("💾 Salvando experiência total no cache...") + logger.info("Salvando experiência total no cache...") self.cache_provider.set_total_experience(repository_total_experience) return repository_total_experience diff --git a/backend/src/infrastructure/utils/logger.py b/backend/src/infrastructure/utils/logger.py index 3c352ff..c5396ac 100644 --- a/backend/src/infrastructure/utils/logger.py +++ b/backend/src/infrastructure/utils/logger.py @@ -7,36 +7,24 @@ from typing import Optional -class Logger: - """Logger class for the application.""" - - _instance: Optional["Logger"] = None - _logger: Optional[logging.Logger] = None - - def __new__(cls): - if cls._instance is None: - cls._instance = super(Logger, cls).__new__(cls) - cls._logger = cls._configure_logger() - return cls._instance - - @staticmethod - def _configure_logger() -> logging.Logger: - """Configure the logger.""" - log_format = "%(name)s - %(levelname)s - %(message)s" - log_level = os.environ.get("LOG_LEVEL", "INFO") - - # Create logger - logger = logging.getLogger("portfolio_api") - logger.setLevel(getattr(logging, log_level)) - logger.propagate = False - - # Clear existing handlers - if logger.handlers: - logger.handlers.clear() - +def _configure_handler(handler: logging.Handler) -> None: + """Configure a handler with the custom formatter.""" + formatter = logging.Formatter( + '%(levelname)s - %(name)s - %(message)s' + ) + handler.setFormatter(formatter) + + +def _setup_logger(name: str) -> logging.Logger: + """Create and configure a logger with the given name.""" + logger = logging.getLogger(name) + logger.setLevel(os.environ.get("LOG_LEVEL", "INFO")) + + # Avoid adding handlers multiple times in case of module reload + if not logger.handlers: # Console handler console_handler = logging.StreamHandler(sys.stdout) - console_handler.setFormatter(logging.Formatter(log_format)) + _configure_handler(console_handler) logger.addHandler(console_handler) # File handler with rotation @@ -44,49 +32,23 @@ def _configure_logger() -> logging.Logger: os.makedirs(log_dir, exist_ok=True) file_handler = RotatingFileHandler( os.path.join(log_dir, "portfolio_api.log"), - maxBytes=10485760, # 10MB + maxBytes=10 * 1024 * 1024, # 10MB backupCount=5, + encoding='utf-8' ) - file_handler.setFormatter(logging.Formatter(log_format)) + _configure_handler(file_handler) logger.addHandler(file_handler) - - return logger + + return logger - @classmethod - def debug(cls, message: str) -> None: - """Log debug message.""" - if cls._logger is None: - cls._logger = cls._configure_logger() - cls._logger.debug(message) - @classmethod - def info(cls, message: str) -> None: - """Log info message.""" - if cls._logger is None: - cls._logger = cls._configure_logger() - cls._logger.info(message) - - @classmethod - def warning(cls, message: str) -> None: - """Log warning message.""" - if cls._logger is None: - cls._logger = cls._configure_logger() - cls._logger.warning(message) - - @classmethod - def error(cls, message: str) -> None: - """Log error message.""" - if cls._logger is None: - cls._logger = cls._configure_logger() - cls._logger.error(message) - - @classmethod - def critical(cls, message: str) -> None: - """Log critical message.""" - if cls._logger is None: - cls._logger = cls._configure_logger() - cls._logger.critical(message) - - -# Create logger instance -logger = Logger() +def get_logger(name: str) -> logging.Logger: + """Get a logger instance with the given name. + + Args: + name: The name of the logger, typically __name__ + + Returns: + A configured logger instance + """ + return _setup_logger(name) diff --git a/backend/tests/infrastructure/utils/test_logger.py b/backend/tests/infrastructure/utils/test_logger.py index ea4c282..30dae49 100644 --- a/backend/tests/infrastructure/utils/test_logger.py +++ b/backend/tests/infrastructure/utils/test_logger.py @@ -2,13 +2,14 @@ from unittest.mock import patch -from src.infrastructure.utils.logger import Logger +from src.infrastructure.utils.logger import get_logger + +logger = get_logger(__name__) @patch("logging.Logger.debug") def test_logger_debug(mock_debug): """Test that logger debug calls logging.Logger.debug.""" - logger = Logger() logger.debug("test message") mock_debug.assert_called_once_with("test message") @@ -16,7 +17,6 @@ def test_logger_debug(mock_debug): @patch("logging.Logger.info") def test_logger_info(mock_info): """Test that logger info calls logging.Logger.info.""" - logger = Logger() logger.info("test message") mock_info.assert_called_once_with("test message") @@ -24,7 +24,6 @@ def test_logger_info(mock_info): @patch("logging.Logger.warning") def test_logger_warning(mock_warning): """Test that logger warning calls logging.Logger.warning.""" - logger = Logger() logger.warning("test message") mock_warning.assert_called_once_with("test message") @@ -32,7 +31,6 @@ def test_logger_warning(mock_warning): @patch("logging.Logger.error") def test_logger_error(mock_error): """Test that logger error calls logging.Logger.error.""" - logger = Logger() logger.error("test message") mock_error.assert_called_once_with("test message") @@ -40,21 +38,5 @@ def test_logger_error(mock_error): @patch("logging.Logger.critical") def test_logger_critical(mock_critical): """Test that logger critical calls logging.Logger.critical.""" - logger = Logger() logger.critical("test message") mock_critical.assert_called_once_with("test message") - - -def test_logger_singleton(): - """Test that logger is a singleton.""" - with patch("logging.getLogger") as mock_get_logger: - # Reset the singleton instance for testing - Logger._instance = None - Logger._logger = None - - logger1 = Logger() - logger2 = Logger() - - assert logger1 is logger2 - assert Logger._instance is not None - assert mock_get_logger.call_count == 1