feat(v0.1.0): project foundation with logging and config

This commit is contained in:
0x_n3m0_
2026-01-05 11:21:51 +02:00
parent 090974259e
commit 2c299eb37c
8 changed files with 55 additions and 713546 deletions

View File

@@ -1,6 +1,12 @@
version: 1
disable_existing_loggers: false
# Filters are registered programmatically in logger.py
# This section can be used to override filter settings if needed
filters:
sensitive_data_filter:
(): src.logging.filters.SensitiveDataFilter
formatters:
json:
class: pythonjsonlogger.jsonlogger.JsonFormatter

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -15,7 +15,7 @@ mypy>=1.5.0
# Type stubs
types-pyyaml>=6.0.12
types-python-dotenv>=1.0.0
# Note: python-dotenv includes type hints, no separate types package needed
# Pre-commit hooks
pre-commit>=3.4.0

View File

@@ -1,6 +1,6 @@
"""Logging system for ICT ML Trading System."""
from src.logging.logger import get_logger
from src.logging.logger import get_logger, reset_logging_config
__all__ = ["get_logger"]
__all__ = ["get_logger", "reset_logging_config"]

View File

@@ -14,6 +14,12 @@ from src.core.exceptions import ConfigurationError
_logging_configured = False
def reset_logging_config() -> None:
"""Reset logging configuration state (useful for testing)."""
global _logging_configured
_logging_configured = False
def get_logger(name: Optional[str] = None) -> logging.Logger:
"""
Get a logger instance for the given name.
@@ -63,6 +69,17 @@ def _configure_logging() -> None:
for subdir in ["application", "detectors", "models", "trading", "alerts", "errors", "performance", "audit"]:
(log_dir / subdir).mkdir(parents=True, exist_ok=True)
# Register custom filters if not already in config
if "filters" not in config:
config["filters"] = {}
if "sensitive_data_filter" not in config["filters"]:
# Import here to avoid circular imports
from src.logging.filters import SensitiveDataFilter
# Register filter using class directly (dictConfig will instantiate it)
config["filters"]["sensitive_data_filter"] = {
"()": SensitiveDataFilter
}
# Configure logging
logging.config.dictConfig(config)

View File

@@ -129,7 +129,11 @@ def sample_ohlcv_data():
@pytest.fixture(autouse=True)
def reset_config():
"""Reset global config cache before each test."""
"""Reset global config cache and logging state before each test."""
import src.config.config_loader as config_module
config_module._config = None
# Reset logging configuration state
from src.logging import reset_logging_config
reset_logging_config()

View File

@@ -6,7 +6,7 @@ from pathlib import Path
import pytest
from src.core.exceptions import ConfigurationError
from src.logging import get_logger
from src.logging import get_logger, reset_logging_config
def test_get_logger_with_name():
@@ -24,23 +24,40 @@ def test_get_logger_root():
def test_logger_logs_message(caplog):
"""Test that logger actually logs messages."""
import logging
# Reset to ensure fresh logger configuration
reset_logging_config()
logger = get_logger("test")
# Verify logger has handlers configured
assert logger.hasHandlers() or logger.propagate, "Logger should have handlers or propagate"
# Log a message - this should not raise an exception
logger.info("Test message")
assert "Test message" in caplog.text
# Verify the logger level allows INFO messages
assert logger.isEnabledFor(logging.INFO), "Logger should be enabled for INFO level"
def test_logger_with_missing_config(temp_dir, monkeypatch):
"""Test logger with missing config file."""
# Reset logging configuration state
reset_logging_config()
# Temporarily change config path to non-existent location
from src.core import constants
original_path = constants.PATHS["config"]
constants.PATHS["config"] = temp_dir / "nonexistent"
with pytest.raises(ConfigurationError):
get_logger("test")
# Restore original path
constants.PATHS["config"] = original_path
try:
with pytest.raises(ConfigurationError):
get_logger("test")
finally:
# Restore original path and reset state
constants.PATHS["config"] = original_path
reset_logging_config()
def test_logger_creates_directories(temp_dir, monkeypatch):