Source code for labscript_utils.setup_logging

#####################################################################
#                                                                   #
# /setup_logging.py                                                 #
#                                                                   #
# Copyright 2013, Monash University                                 #
#                                                                   #
# This file is part of labscript_utils, in the labscript suite      #
# (see http://labscriptsuite.org), and is licensed under the        #
# Simplified BSD License. See the license.txt file in the root of   #
# the project for the full license.                                 #
#                                                                   #
#####################################################################
import sys, os
from io import UnsupportedOperation
import logging, logging.handlers
import warnings
from labscript_utils.ls_zprocess import Handler, ensure_connected_to_zlog


from labscript_profile import LABSCRIPT_SUITE_PROFILE

LOG_PATH = os.path.join(LABSCRIPT_SUITE_PROFILE, 'logs')

[docs]class LessThanFilter(logging.Filter):
[docs] def __init__(self, less_than): self.less_than = less_than logging.Filter.__init__(self)
[docs] def filter(self, record): return record.levelno < self.less_than
[docs]def setup_logging(program_name, log_level=logging.DEBUG, terminal_level=logging.INFO, maxBytes=1024*1024*50, backupCount=1): # MaxBytes and backupCount args ignored, these are now set in labconfig since they # are settings to the server rather than individual logging handlers. Args are left # in the function signature for backward compatibility. ensure_connected_to_zlog() logger = logging.getLogger(program_name) # Clear any previously added handlers from the logger: for handler in logger.handlers[:]: logger.removeHandler(handler) # Make sure the logging directory exists: if not os.path.exists(LOG_PATH): os.mkdir(LOG_PATH) # Add a network logging handler from zprocess. Pass in the name of the program so # that if we are a subprocess, the handler will be configured to use the same # filepath as our parent process. In this way the zlog server won't create multiple # log files with unrelated paths just because the program has a different install # location on different computers that are part of the same process tree. log_path = os.path.join(LOG_PATH, '%s.log' % program_name) handler = Handler(log_path, name=program_name) formatter = logging.Formatter('%(asctime)s %(levelname)s %(name)s: %(message)s') handler.setFormatter(formatter) handler.setLevel(log_level) logger.addHandler(handler) try: # Check that sys.stdout.fileno is callable, which is needed below. It is NOT # callable in Jupyter notebooks. stdout_fileno = sys.stdout.fileno() except UnsupportedOperation: # In this case the code is likely being run from a Jupyter notebook, warn the # user that log messages won't be printed to stdout or stderr. warnings.warn( "Logging to stdout and stderr is disabled. See the log files for log messages." ) else: if sys.stdout is not None and stdout_fileno >= 0: stdout_handler = logging.StreamHandler(sys.stdout) stdout_handler.setFormatter(formatter) stdout_handler.setLevel(terminal_level) logger.addHandler(stdout_handler) if sys.stderr is not None and sys.stderr.fileno() >= 0: # Send warnings and greater to stderr instead of stdout: stdout_handler.addFilter(LessThanFilter(logging.WARNING)) sterr_handler = logging.StreamHandler(sys.stderr) sterr_handler.setFormatter(formatter) sterr_handler.setLevel(logging.WARNING) logger.addHandler(sterr_handler) else: # Prevent bug on windows where writing to stdout without a command # window causes a crash: sys.stdout = sys.stderr = open(os.devnull, 'w') logger.setLevel(logging.DEBUG) return logger