# ########################################################################## # Copyright 2020 # ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/> # P.O.Box 2, 7990 AA Dwingeloo, The Netherlands # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # ########################################################################## # ########################################################################## import os import logging import time class MyLogger(object): def __init__(self, log_path=None, file_name=None): self.log_levels = {'DEBUG' : logging.DEBUG, 'INFO' : logging.INFO, 'WARNING': logging.WARNING, 'ERROR' : logging.ERROR} self.log_path = os.getcwd() if log_path is None else log_path try: os.stat(self.log_path) except FileNotFoundError: print("'{}' does not exist, making it now".format(self.log_path)) os.makedirs(self.log_path) self.filename = None self.stdout_log_level = 'WARNING' self.file_log_level = 'INFO' self.backup_depth = 0 self.file_logger_handler = None self.stdout_logger_handler = None self.logger = logging.getLogger('main') self.logger.setLevel(logging.DEBUG) self._setup_stdout_logging() if file_name is not None: self.set_logfile_name(file_name) def get_logger(self): return self.logger def set_logfile_name(self, name): self.filename = name self._backup_logfiles() self._setup_file_logging() def set_stdout_log_level(self, level): _level = level.upper() if _level in self.log_levels: self.stdout_log_level = _level if self.stdout_logger_handler: self.stdout_logger_handler.setLevel(self.log_levels[_level]) else: self.logger.error("'{}' is not a valid level".format(level)) def set_file_log_level(self, level): _level = level.upper() if _level in self.log_levels: self.file_log_level = _level if self.file_logger_handler: self.file_logger_handler.setLevel(self.log_levels[_level]) else: self.logger.error("'{}' is not a valid level".format(level)) def _backup_logfiles(self): for nr in range(self.backup_depth-1, -1, -1): if nr == 0: full_filename = os.path.join(self.log_path, '{}.log'.format(self.filename)) else: full_filename = os.path.join(self.log_path, '{}.log.{}'.format(self.filename, nr)) full_filename_new = os.path.join(self.log_path, '{}.log.{}'.format(self.filename, nr+1)) if os.path.exists(full_filename): os.rename(full_filename, full_filename_new) def _setup_stdout_logging(self): # create console handler stream_handler = logging.StreamHandler() formatter = logging.Formatter('%(asctime)s %(name)-19s %(levelname)-7s %(message)s') stream_handler.setFormatter(formatter) stream_handler.setLevel(self.log_levels[self.stdout_log_level]) self.logger.addHandler(stream_handler) self.stdout_logger_handler = self.logger.handlers[0] def _setup_file_logging(self): # create file handler full_filename = os.path.join(self.log_path, '{}.log'.format(self.filename)) file_handler = logging.FileHandler(full_filename, mode='w') formatter = logging.Formatter('%(asctime)s %(name)-19s %(levelname)-8s %(message)s') file_handler.setFormatter(formatter) file_handler.setLevel(self.log_levels[self.file_log_level]) self.logger.addHandler(file_handler) self.file_logger_handler = self.logger.handlers[1]