From 14f218ab98b3eef904bebefa00399f5d26356853 Mon Sep 17 00:00:00 2001 From: Alexdyn1927 Date: Sat, 5 Jul 2025 11:08:12 +0000 Subject: [PATCH 1/5] Start draft PR From 72b82cc4a0384f03b6561923ebe8ad36bb350e13 Mon Sep 17 00:00:00 2001 From: Alexdyn1927 Date: Sat, 5 Jul 2025 11:08:27 +0000 Subject: [PATCH 2/5] Add comprehensive .gitignore file --- .gitignore | 35 +++++++++++++---------------------- 1 file changed, 13 insertions(+), 22 deletions(-) diff --git a/.gitignore b/.gitignore index 02eac69..552fe7b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,22 +1,13 @@ -### AL ### -#Template for AL projects for Dynamics 365 Business Central -#launch.json folder -.vscode/ -#Cache folder -.alcache/ -#Symbols folder -.alpackages/ -#Snapshots folder -.snapshots/ -#Testing Output folder -.output/ -#Extension App-file -*.app -#Rapid Application Development File -rad.json -#Translation Base-file -*.g.xlf -#License-file -*.flf -#Test results file -TestResults.xml \ No newline at end of file +__pycache__/ +*.py[cod] +*$py.class +.pytest_cache/ +.coverage +htmlcov/ +.env +.venv/ +venv/ +dist/ +build/ +*.egg-info/ +.DS_Store \ No newline at end of file From 7a1b67d9a03ac556529bdc85b2ecae3eb4cfbdbe Mon Sep 17 00:00:00 2001 From: Alexdyn1927 Date: Sat, 5 Jul 2025 11:08:45 +0000 Subject: [PATCH 3/5] Implement comprehensive ALP logging utility --- src/alp/logging.py | 98 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 src/alp/logging.py diff --git a/src/alp/logging.py b/src/alp/logging.py new file mode 100644 index 0000000..9638603 --- /dev/null +++ b/src/alp/logging.py @@ -0,0 +1,98 @@ +import logging +import time +from typing import Any, Dict, Optional + +class ALPLogger: + """ + Specialized logger for Adaptive Learning Process (ALP) iterations. + Provides comprehensive logging capabilities with performance tracking. + """ + def __init__(self, name: str = "ALP", log_level: int = logging.INFO): + """ + Initialize the ALP logger with configurable name and log level. + + :param name: Name of the logger instance + :param log_level: Logging level (default: logging.INFO) + """ + self.logger = logging.getLogger(name) + self.logger.setLevel(log_level) + + # Create console handler if not already configured + if not self.logger.handlers: + console_handler = logging.StreamHandler() + formatter = logging.Formatter( + '%(asctime)s - %(name)s - %(levelname)s - %(message)s' + ) + console_handler.setFormatter(formatter) + self.logger.addHandler(console_handler) + + def log_iteration( + self, + iteration: int, + metrics: Optional[Dict[str, Any]] = None, + level: int = logging.INFO + ) -> None: + """ + Log details of a single iteration with performance metrics. + + :param iteration: Current iteration number + :param metrics: Dictionary of performance metrics + :param level: Logging level + """ + metrics = metrics or {} + log_message = f"Iteration {iteration}" + + # Add metrics to log message + if metrics: + metric_str = " | ".join(f"{k}: {v}" for k, v in metrics.items()) + log_message += f" - Metrics: {metric_str}" + + # Log the message at specified level + self.logger.log(level, log_message) + + def log_error( + self, + iteration: int, + error: Exception, + context: Optional[Dict[str, Any]] = None + ) -> None: + """ + Log an error that occurred during an iteration. + + :param iteration: Iteration number when error occurred + :param error: Exception that was raised + :param context: Additional context about the error + """ + context = context or {} + error_message = ( + f"Error in iteration {iteration}: {str(error)}\n" + f"Context: {context}" + ) + self.logger.error(error_message, exc_info=True) + + def track_performance( + self, + start_time: float, + end_time: float + ) -> Dict[str, float]: + """ + Calculate and log performance metrics for an iteration. + + :param start_time: Start time of the iteration + :param end_time: End time of the iteration + :return: Performance metrics dictionary + """ + elapsed_time = end_time - start_time + performance_metrics = { + "elapsed_time": elapsed_time, + "timestamp": end_time + } + + # Log performance metrics + self.log_iteration( + iteration=0, # Use 0 for overall performance tracking + metrics=performance_metrics, + level=logging.DEBUG + ) + + return performance_metrics \ No newline at end of file From 861647ec33461a52c3e8925c9ec0e7327af6dfc6 Mon Sep 17 00:00:00 2001 From: Alexdyn1927 Date: Sat, 5 Jul 2025 11:09:00 +0000 Subject: [PATCH 4/5] Add comprehensive tests for ALP logging utility --- tests/test_alp_logging.py | 53 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 tests/test_alp_logging.py diff --git a/tests/test_alp_logging.py b/tests/test_alp_logging.py new file mode 100644 index 0000000..82f9b43 --- /dev/null +++ b/tests/test_alp_logging.py @@ -0,0 +1,53 @@ +import logging +import time +import pytest +from src.alp.logging import ALPLogger + +def test_alp_logger_initialization(): + """Test logger initialization with default and custom parameters.""" + logger = ALPLogger() + assert logger.logger.name == "ALP" + assert logger.logger.level == logging.INFO + + custom_logger = ALPLogger(name="CustomALP", log_level=logging.DEBUG) + assert custom_logger.logger.name == "CustomALP" + assert custom_logger.logger.level == logging.DEBUG + +def test_log_iteration(caplog): + """Test logging of iteration with metrics.""" + logger = ALPLogger() + caplog.set_level(logging.INFO) + + metrics = {"loss": 0.5, "accuracy": 0.95} + logger.log_iteration(iteration=10, metrics=metrics) + + assert "Iteration 10" in caplog.text + assert "loss: 0.5" in caplog.text + assert "accuracy: 0.95" in caplog.text + +def test_log_error(caplog): + """Test error logging with context.""" + logger = ALPLogger() + caplog.set_level(logging.ERROR) + + try: + raise ValueError("Test error") + except ValueError as e: + logger.log_error(iteration=5, error=e, context={"model": "test_model"}) + + assert "Error in iteration 5" in caplog.text + assert "Test error" in caplog.text + assert "model: test_model" in caplog.text + +def test_track_performance(): + """Test performance tracking method.""" + logger = ALPLogger() + + start_time = time.time() - 1.0 # Simulate 1 second elapsed + end_time = time.time() + + performance = logger.track_performance(start_time, end_time) + + assert "elapsed_time" in performance + assert "timestamp" in performance + assert performance["elapsed_time"] >= 1.0 \ No newline at end of file From d45be1231eb3b89a0bb1e77056f478995d1b00a9 Mon Sep 17 00:00:00 2001 From: Alexdyn1927 Date: Sat, 5 Jul 2025 11:09:29 +0000 Subject: [PATCH 5/5] Update error logging to improve context formatting --- src/alp/logging.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/alp/logging.py b/src/alp/logging.py index 9638603..f3e95f4 100644 --- a/src/alp/logging.py +++ b/src/alp/logging.py @@ -64,9 +64,10 @@ def log_error( :param context: Additional context about the error """ context = context or {} + context_str = " | ".join(f"{k}: {v}" for k, v in context.items()) error_message = ( f"Error in iteration {iteration}: {str(error)}\n" - f"Context: {context}" + f"Context: {context_str}" ) self.logger.error(error_message, exc_info=True)