diff --git a/neat/common.py b/neat/common.py index bf2738d..c1ac713 100644 --- a/neat/common.py +++ b/neat/common.py @@ -18,11 +18,15 @@ from contracts import contract from neat.contracts_extra import * +import os import time from neat.config import * from neat.db_utils import * +import logging +log = logging.getLogger(__name__) + @contract def start(init_state, execute, config, time_interval, iterations): @@ -130,3 +134,46 @@ def frange(start, end, step): while start <= end: yield start start += step + + +@contract +def init_logging(log_directory, log_file, log_level): + """ Initialize the logging system. + + :param log_directory: The directory to store log files. + :type log_directory: str + + :param log_file: The file name to store log messages. + :type log_file: str + + :param log_level: The level of emitted log messages. + :type log_level: int + + :return: Whether the logging system has been initialized. + :rtype: bool + """ + if log_level == 0: + logging.disable(logging.CRITICAL) + return True + + if not os.access(log_file, os.F_OK): + if not os.access(log_directory, os.F_OK): + os.makedirs(log_directory) + elif not os.access(log_directory, os.W_OK): + raise IOError( + 'Cannot write to the log directory: ' + log_directory) + elif not os.access(log_file, os.W_OK): + raise IOError('Cannot write to the log file: ' + log_file) + + if log_level == 3: + level = logging.DEBUG + elif log_level == 2: + level = logging.INFO + else: + level = logging.WARNING + + logging.basicConfig( + format='%(asctime)s %(levelname)-8s %(name)s %(message)s', + filename=os.path.join(log_directory, log_file), + level=level) + return True diff --git a/tests/test_common.py b/tests/test_common.py index bf12fb0..b73b9b0 100644 --- a/tests/test_common.py +++ b/tests/test_common.py @@ -16,6 +16,8 @@ from mocktest import * from pyqcy import * import os +import shutil +import logging import libvirt import neat.common as common @@ -73,3 +75,44 @@ class Common(TestCase): [0.0, 0.5, 1.0]) self.assertEqual([round(x, 1) for x in common.frange(0, 1.0, 0.2)], [0.0, 0.2, 0.4, 0.6, 0.8, 1.0]) + + def test_init_logging(self): + log_dir = os.path.join( + os.path.dirname(__file__), 'resources', 'log') + log_file = 'test.log' + log_path = os.path.join(log_dir, log_file) + + with MockTransaction: + expect(logging).disable(logging.CRITICAL).once() + expect(logging).basicConfig.never() + assert common.init_logging(log_dir, log_file, 0) + + with MockTransaction: + shutil.rmtree(log_dir, True) + expect(logging).disable.never() + expect(logging).basicConfig( + format='%(asctime)s %(levelname)-8s %(name)s %(message)s', + filename=log_path, + level=logging.WARNING) + assert common.init_logging(log_dir, log_file, 1) + assert os.access(log_dir, os.W_OK) + + with MockTransaction: + expect(logging).disable.never() + expect(logging).basicConfig( + format='%(asctime)s %(levelname)-8s %(name)s %(message)s', + filename=log_path, + level=logging.INFO) + assert common.init_logging(log_dir, log_file, 2) + assert os.access(log_dir, os.W_OK) + + with MockTransaction: + expect(logging).disable.never() + expect(logging).basicConfig( + format='%(asctime)s %(levelname)-8s %(name)s %(message)s', + filename=log_path, + level=logging.DEBUG) + assert common.init_logging(log_dir, log_file, 3) + assert os.access(log_dir, os.W_OK) + + shutil.rmtree(log_dir, True)