def testForwardToPython(self): """Test that `lsst.log` log messages can be forwarded to `logging`.""" log.configure() # Without forwarding we only get python logger messages captured with self.assertLogs(level="WARNING") as cm: log.warn( "lsst.log warning message that will not be forwarded to Python" ) logging.warning("Python logging message that will be captured") self.assertEqual(len(cm.output), 1) log.usePythonLogging() # With forwarding we get 2 logging messages captured with self.assertLogs(level="WARNING") as cm: log.warn( "This is a warning from lsst log meant for python logging") logging.warning("Python warning log message to be captured") self.assertEqual(len(cm.output), 2) loggername = "newlogger" log2 = log.Log.getLogger(loggername) with self.assertLogs(level="INFO", logger=loggername): log2.info("Info message to non-root lsst logger") # Check that debug and info are working properly # This test should return a single log message with self.assertLogs(level="INFO", logger=loggername) as cm: log2.info("Second INFO message to non-root lsst logger") log.debug("Debug message to root lsst logger") self.assertEqual(len(cm.output), 1, f"Got output: {cm.output}") logging.shutdown()
def testPythonLogging(self): """Test logging through the Python logging interface.""" with TestLog.StdoutCapture(self.outputFilename): lgr = logging.getLogger() lgr.setLevel(logging.INFO) log.configure() with self.assertLogs(level="INFO") as cm: # Force the lsst.log handler to be applied as well as the # unittest log handler lgr.addHandler(log.LogHandler()) lgr.info("This is INFO") lgr.debug("This is DEBUG") lgr.warning("This is %s", "WARNING") # message can be arbitrary Python object lgr.info(((1, 2), (3, 4))) lgr.info({1: 2}) # Confirm that Python logging also worked self.assertEqual(len(cm.output), 4, f"Got output: {cm.output}") logging.shutdown() self.check(""" root INFO: This is INFO root WARN: This is WARNING root INFO: ((1, 2), (3, 4)) root INFO: {1: 2} """)
def testBasic(self): """ Test basic log output with default configuration. Since the default threshold is INFO, the DEBUG or TRACE message is not emitted. """ with TestLog.StdoutCapture(self.outputFilename): log.configure() log.log(log.getDefaultLogger(), log.INFO, "This is INFO") log.info(u"This is unicode INFO") log.trace("This is TRACE") log.debug("This is DEBUG") log.warn("This is WARN") log.error("This is ERROR") log.fatal("This is FATAL") log.critical("This is CRITICAL") log.warning("Format %d %g %s", 3, 2.71828, "foo") self.check(""" root INFO: This is INFO root INFO: This is unicode INFO root WARN: This is WARN root ERROR: This is ERROR root FATAL: This is FATAL root FATAL: This is CRITICAL root WARN: Format 3 2.71828 foo """)
def load_imgserv_config(config_path=None, metaserv_url=None): """ Load service configuration into ImageServ. Parameters ---------- config_path : `str` configuration location of this service. metaserv_url : `str` service url of the metaserv instance. """ if config_path is None: # use default root_path for app config_path = image_soda.root_path + "/config/" f_json = os.path.join(config_path, "imgserv_conf.json") # load the general config file current_app.config.from_json(f_json) # configure the log file (log4cxx) log.configure(os.path.join(config_path, "log.properties")) current_app.config["DAX_IMG_CONFIG"] = config_path if metaserv_url: current_app.config["DAX_IMG_META_URL"] = metaserv_url else: current_app.config["DAX_IMG_META_URL"] = current_app.config[ "dax.imgserv.meta.url"] current_app.config["imgserv_api"] = os.path.join(config_path, "image_api_schema.json") # create cache for butler instances current_app.butler_instances = {} # create SODA service current_app.soda = ImageSODA(current_app.config)
def testRedir(self): """ Test redirection to stream. """ with TestRedir.StdoutCapture(self.outputFilename): log.configure() dest = io.StringIO() log_utils.enable_notebook_logging(dest) log.log(log.getDefaultLogger().getName(), log.INFO, "This is INFO") log.info(u"This is unicode INFO") log.trace("This is TRACE") log.debug("This is DEBUG") log.warn("This is WARN") log.error("This is ERROR") log.fatal("This is FATAL") log_utils.disable_notebook_logging() log.warn("Format %d %g %s", 3, 2.71828, "foo") self.assertEqual( dest.getvalue(), """root INFO: This is INFO root INFO: This is unicode INFO root WARN: This is WARN root ERROR: This is ERROR root FATAL: This is FATAL """, ) self.check( """ root WARN: Format 3 2.71828 foo """ )
def load_imgserv_config(config_path=None, dataset=None, metaserv_url=None): """ Load service configuration into ImageServ. Parameters ---------- config_path : `str` configuration location of this service. dataset: `str` the specified dataset configuration. metaserv_url : `str` service url of the metaserv instance. """ if config_path is None: # use default root_path for app config_path = image_soda.root_path + "/config/" # load the general config files for image datasets if dataset is None or dataset == "default": dataset = imgserv_config.config_datasets["default"] current_app.config.update(imgserv_config.config_datasets[dataset]) # configure the log file (log4cxx) log.configure(os.path.join(config_path, "log.properties")) current_app.config["DAX_IMG_CONFIG"] = config_path if metaserv_url: current_app.config["DAX_IMG_META_URL"] = metaserv_url else: current_app.config["DAX_IMG_META_URL"] = current_app.config[ "dax.imgserv.meta.url"] current_app.config["imgserv_api"] = os.path.join(config_path, "image_api_schema.json") # create cache for butler instances current_app.butler_instances = {} # create SODA service current_app.soda = ImageSODA(current_app.config) # Instantiate celery for client access current_app.celery = make_celery()
def testBasicFormat(self): """ Test basic log output with default configuration but using the f variants. Since the default threshold is INFO, the DEBUG or TRACE message is not emitted. """ with TestLog.StdoutCapture(self.outputFilename): log.configure() log.logf(log.getDefaultLoggerName(), log.INFO, "This is {{INFO}} Item 1: {item[1]}", item=["a", "b", "c"]) log.infof(u"This is {unicode} INFO") log.tracef("This is TRACE") log.debugf("This is DEBUG") log.warnf("This is WARN {city}", city="Tucson") log.errorf("This is ERROR {1}->{0}", 2, 1) log.fatalf("This is FATAL {1} out of {0} times for {place}", 4, 3, place="LSST") log.warnf("Format {} {} {}", 3, 2.71828, "foo") self.check(""" root INFO: This is {INFO} Item 1: b root INFO: This is {unicode} INFO root WARN: This is WARN Tucson root ERROR: This is ERROR 1->2 root FATAL: This is FATAL 3 out of 4 times for LSST root WARN: Format 3 2.71828 foo """)
def testForwardToPython(self): """Test that `lsst.log` log messages can be forwarded to `logging`.""" log.configure() # Without forwarding we only get python logger messages captured with self.assertLogs(level="WARNING") as cm: log.warn("lsst.log warning message that will not be forwarded to Python") logging.warning("Python logging message that will be captured") self.assertEqual(len(cm.output), 1) log.usePythonLogging() # With forwarding we get 2 logging messages captured with self.assertLogs(level="WARNING") as cm: log.warn("This is a warning from lsst log meant for python logging") logging.warning("Python warning log message to be captured") self.assertEqual(len(cm.output), 2) loggername = "newlogger" log2 = log.Log.getLogger(loggername) with self.assertLogs(level="INFO", logger=loggername): log2.info("Info message to non-root lsst logger") # Check that debug and info are working properly # This test should return a single log message with self.assertLogs(level="INFO", logger=loggername) as cm: log2.info("Second INFO message to non-root lsst logger") log.debug("Debug message to root lsst logger") self.assertEqual(len(cm.output), 1, f"Got output: {cm.output}") logging.shutdown()
def testBasicFormat(self): """ Test basic log output with default configuration but using the f variants. Since the default threshold is INFO, the DEBUG or TRACE message is not emitted. """ with TestLog.StdoutCapture(self.outputFilename): log.configure() log.logf(log.getDefaultLogger(), log.INFO, "This is {{INFO}} Item 1: {item[1]}", item=["a", "b", "c"]) log.infof(u"This is {unicode} INFO") log.tracef("This is TRACE") log.debugf("This is DEBUG") log.warnf("This is WARN {city}", city="Tucson") log.errorf("This is ERROR {1}->{0}", 2, 1) log.fatalf("This is FATAL {1} out of {0} times for {place}", 4, 3, place="LSST") log.warnf("Format {} {} {}", 3, 2.71828, "foo") self.check(""" root INFO: This is {INFO} Item 1: b root INFO: This is {unicode} INFO root WARN: This is WARN Tucson root ERROR: This is ERROR 1->2 root FATAL: This is FATAL 3 out of 4 times for LSST root WARN: Format 3 2.71828 foo """)
def main(): DefKernel = "lanczos4" DefVerbosity = 1 usage = """usage: %%prog [options] srcExposure refExposure destExposure Computes destExposure = srcExposure warped to match refExposure's WCS and bounding box, where exposure arguments are paths to Exposure fits files""" parser = optparse.OptionParser(usage) parser.add_option( "-k", "--kernel", type=str, default=DefKernel, help="kernel type: bilinear or lancszosN where N = order; default=%s" % (DefKernel, )) parser.add_option( "-v", "--verbosity", type=int, default=DefVerbosity, help= "verbosity of diagnostic trace messages; 1 for just TRACE1, more for more" + " information; default=%s" % (DefVerbosity, )) (opt, args) = parser.parse_args() log.configure() kernelName = opt.kernel.lower() if len(args) != 3: parser.error("You must supply three arguments") srcExposurePath = args[0] refExposurePath = args[1] destExposurePath = args[2] print("Remapping exposure :", srcExposurePath) print("to match wcs and bbox of:", refExposurePath) print("using", kernelName, "kernel") warpingControl = afwMath.WarpingControl(kernelName) srcExposure = afwImage.ExposureF(srcExposurePath) destExposure = afwImage.ExposureF(refExposurePath) if opt.verbosity > 0: print("Verbosity =", opt.verbosity) logUtils.traceSetAt("afw.math.warp", opt.verbosity) numGoodPixels = afwMath.warpExposure(destExposure, srcExposure, warpingControl) print("Warped exposure has %s good pixels" % (numGoodPixels)) print("Writing warped exposure to %s" % (destExposurePath, )) destExposure.writeFits(destExposurePath)
def jobLog(job): """Add a job-specific log destination""" if job is None or job == "None": return packageDir = getPackageDir("ctrl_pool") # Set the environment variable which names the output file os.environ['JOBNAME'] = job lsstLog.configure(os.path.join(packageDir, "config/log4cxx.properties")) lsstLog.MDC("PID", os.getpid())
def jobLog(job): """Add a job-specific log destination""" if job is None or job == "None": return machine = os.uname()[1].split(".")[0] packageDir = getPackageDir("ctrl_pool") # Set the environment variable which names the output file os.environ['JOBNAME'] = job lsstLog.configure(os.path.join(packageDir, "config/log4cxx.properties")) lsstLog.MDC("PID", os.getpid())
def load_imgserv_config(config_path, db_auth_conf): """Load configuration into ImageServ.""" if config_path is None: # use default root_path for imageREST config_path = imageREST.root_path+"/config/" f_json = os.path.join(config_path, "settings.json") # load the general config file current_app.config.from_json(f_json) # configure the log file (log4cxx) log.configure(os.path.join(config_path, "log.properties")) current_app.config['DAX_IMG_DBCONF'] = db_auth_conf
def __init__(self, ds, out_dir): # load the configuration file config_dir = os.path.join(ROOT, "config") if ds is None or ds == "default": ds = imgserv_config.config_datasets["default"] self._config = imgserv_config.config_datasets[ds] # configure the log file (log4cxx) log.configure(os.path.join(config_dir, "log.properties")) self._out_dir = out_dir self._dispatcher = Dispatcher(config_dir) self._schema = os.path.join(config_dir, "image_api_schema.json") self._validate = self._config.get("DAX_IMG_VALIDATE", False) self._config["DAX_IMG_META_URL"] = imgserv_meta_url
def main(): DefKernel = "lanczos4" DefVerbosity = 1 usage = """usage: %%prog [options] srcExposure refExposure destExposure Computes destExposure = srcExposure warped to match refExposure's WCS and bounding box, where exposure arguments are paths to Exposure fits files""" parser = optparse.OptionParser(usage) parser.add_option("-k", "--kernel", type=str, default=DefKernel, help="kernel type: bilinear or lancszosN where N = order; default=%s" % (DefKernel,)) parser.add_option("-v", "--verbosity", type=int, default=DefVerbosity, help="verbosity of diagnostic trace messages; 1 for just TRACE1, more for more" " information; default=%s" % (DefVerbosity,)) (opt, args) = parser.parse_args() log.configure() kernelName = opt.kernel.lower() if len(args) != 3: parser.error("You must supply three arguments") srcExposurePath = args[0] refExposurePath = args[1] destExposurePath = args[2] print("Remapping exposure :", srcExposurePath) print("to match wcs and bbox of:", refExposurePath) print("using", kernelName, "kernel") warpingControl = afwMath.WarpingControl(kernelName) srcExposure = afwImage.ExposureF(srcExposurePath) destExposure = afwImage.ExposureF(refExposurePath) if opt.verbosity > 0: print("Verbosity =", opt.verbosity) logUtils.traceSetAt("afw.math.warp", opt.verbosity) numGoodPixels = afwMath.warpExposure( destExposure, srcExposure, warpingControl) print("Warped exposure has %s good pixels" % (numGoodPixels)) print("Writing warped exposure to %s" % (destExposurePath,)) destExposure.writeFits(destExposurePath)
def testPythonLogging(self): """Test logging through the Python logging interface.""" with TestLog.StdoutCapture(self.outputFilename): import logging lgr = logging.getLogger() lgr.setLevel(logging.INFO) lgr.addHandler(log.LogHandler()) log.configure() lgr.info("This is INFO") logging.shutdown() self.check(""" INFO root null - This is INFO """)
def testContext(self): """Test the log context/component stack.""" with TestLog.StdoutCapture(self.outputFilename): log.configure() log.setLevel('', log.DEBUG) log.trace("This is TRACE") log.info("This is INFO") log.debug("This is DEBUG") with log.LogContext("component"): log.trace("This is TRACE") log.info("This is INFO") log.debug("This is DEBUG") log.trace("This is TRACE 2") log.info("This is INFO 2") log.debug("This is DEBUG 2") with log.LogContext("comp") as ctx: log.trace("This is TRACE 3") log.info("This is INFO 3") log.debug("This is DEBUG 3") ctx.setLevel(log.INFO) self.assertEqual(ctx.getLevel(), log.INFO) self.assert_(ctx.isEnabledFor(log.INFO)) log.trace("This is TRACE 3a") log.info("This is INFO 3a") log.debug("This is DEBUG 3a") with log.LogContext("subcomp", log.TRACE) as ctx2: self.assertEqual(ctx2.getLevel(), log.TRACE) log.trace("This is TRACE 4") log.info("This is INFO 4") log.debug("This is DEBUG 4") log.trace("This is TRACE 5") log.info("This is INFO 5") log.debug("This is DEBUG 5") self.check(""" root INFO: This is INFO root DEBUG: This is DEBUG component INFO: This is INFO component DEBUG: This is DEBUG root INFO: This is INFO 2 root DEBUG: This is DEBUG 2 comp INFO: This is INFO 3 comp DEBUG: This is DEBUG 3 comp INFO: This is INFO 3a comp.subcomp TRACE: This is TRACE 4 comp.subcomp INFO: This is INFO 4 comp.subcomp DEBUG: This is DEBUG 4 comp INFO: This is INFO 5 """)
def testContext(self): """Test the log context/component stack.""" with TestLog.StdoutCapture(self.outputFilename): log.configure() log.setLevel('', log.DEBUG) log.trace("This is TRACE") log.info("This is INFO") log.debug("This is DEBUG") with log.LogContext("component"): log.trace("This is TRACE") log.info("This is INFO") log.debug("This is DEBUG") log.trace("This is TRACE 2") log.info("This is INFO 2") log.debug("This is DEBUG 2") with log.LogContext("comp") as ctx: log.trace("This is TRACE 3") log.info("This is INFO 3") log.debug("This is DEBUG 3") ctx.setLevel(log.INFO) self.assertEqual(ctx.getLevel(), log.INFO) self.assertTrue(ctx.isEnabledFor(log.INFO)) log.trace("This is TRACE 3a") log.info("This is INFO 3a") log.debug("This is DEBUG 3a") with log.LogContext("subcomp", log.TRACE) as ctx2: self.assertEqual(ctx2.getLevel(), log.TRACE) log.trace("This is TRACE 4") log.info("This is INFO 4") log.debug("This is DEBUG 4") log.trace("This is TRACE 5") log.info("This is INFO 5") log.debug("This is DEBUG 5") self.check(""" root INFO: This is INFO root DEBUG: This is DEBUG component INFO: This is INFO component DEBUG: This is DEBUG root INFO: This is INFO 2 root DEBUG: This is DEBUG 2 comp INFO: This is INFO 3 comp DEBUG: This is DEBUG 3 comp INFO: This is INFO 3a comp.subcomp TRACE: This is TRACE 4 comp.subcomp INFO: This is INFO 4 comp.subcomp DEBUG: This is DEBUG 4 comp INFO: This is INFO 5 """)
def testPythonLogging(self): """Test logging through the Python logging interface.""" with TestLog.StdoutCapture(self.outputFilename): import logging lgr = logging.getLogger() lgr.setLevel(logging.INFO) lgr.addHandler(log.LogHandler()) log.configure() lgr.info("This is INFO") lgr.debug("This is DEBUG") logging.shutdown() self.check(""" root INFO: This is INFO """)
def __init__(self, config_dir, out_dir): # load the configuration file if config_dir: config = os.path.join(config_dir, "imgserv_conf.json") else: config_dir = os.path.join(ROOT, "config") config = os.path.join(config_dir, "imgserv_conf.json") with open(config) as f: self._config = json.load(f) # configure the log file (log4cxx) log.configure(os.path.join(config_dir, "log.properties")) self._out_dir = out_dir self._dispatcher = Dispatcher(config_dir) self._schema = os.path.join(config_dir, "image_api_schema.json") self._validate = self._config["DAX_IMG_VALIDATE"] self._config["DAX_IMG_META_URL"] = imgserv_meta_url
def load_imgserv_config(config_path, metaserv_url): """Load configuration info into ImageServ.""" if config_path is None: # use default root_path for image_api_v1 config_path = image_api_v1.root_path + "/config/" f_json = os.path.join(config_path, "imgserv_conf.json") # load the general config file current_app.config.from_json(f_json) # configure the log file (log4cxx) log.configure(os.path.join(config_path, "log.properties")) current_app.config["DAX_IMG_META_URL"] = metaserv_url current_app.config["DAX_IMG_CONFIG"] = config_path current_app.config["imageREST_v1"] = os.path.join(config_path, "image_api_schema.json") # create cache for butler instances current_app.butler_instances = {}
def __init__(self, config_dir, out_dir): # load the configuration file if config_dir: config = os.path.join(config_dir, "imgserv_conf.json") else: config_dir = os.path.join(ROOT, "config") config = os.path.join(config_dir, "imgserv_conf.json") with open(config) as f: self._config = json.load(f) # strip /tests from dataroot if cur_dir is /tests f.close() # configure the log file (log4cxx) log.configure(os.path.join(config_dir, "log.properties")) self._out_dir = out_dir self._dispatcher = Dispatcher(config_dir) self._schema = os.path.join(config_dir, "imageREST_v1.schema") self._validate = self._config["DAX_IMG_VALIDATE"]
def testForwardToPythonContextManager(self): """Test that `lsst.log` log messages can be forwarded to `logging` using context manager""" log.configure() # Without forwarding we only get python logger messages captured with self.assertLogs(level="WARNING") as cm: log.warning("lsst.log: not forwarded") logging.warning("Python logging: captured") self.assertEqual(len(cm.output), 1) # Temporarily turn on forwarding with log.UsePythonLogging(): with self.assertLogs(level="WARNING") as cm: log.warn("lsst.log: forwarded") logging.warning("Python logging: also captured") self.assertEqual(len(cm.output), 2) # Verify that forwarding is disabled self.assertFalse(log.Log.UsePythonLogging)
def testMsgWithPercentS(self): """Test logging messages containing %s (DM-7509) """ with TestLog.StdoutCapture(self.outputFilename): log.configure() logger = log.Log() logger.info("INFO with %s") logger.trace("TRACE with %s") logger.debug("DEBUG with %s") logger.warn("WARN with %s") logger.error("ERROR with %s") logger.fatal("FATAL with %s") logger.logMsg(log.DEBUG, "foo", "bar", 5, "DEBUG with %s") self.check(""" root INFO: INFO with %s root WARN: WARN with %s root ERROR: ERROR with %s root FATAL: FATAL with %s root DEBUG: DEBUG with %s """)
def testLogger(self): """ Test log object. """ with TestLog.StdoutCapture(self.outputFilename): log.configure() logger = log.Log.getLogger("b") self.assertEqual(logger.getName(), "b") logger.trace("This is TRACE") logger.info("This is INFO") logger.debug("This is DEBUG") logger.warn("This is WARN") logger.error("This is ERROR") logger.fatal("This is FATAL") logger.warn("Format %d %g %s", 3, 2.71828, "foo") self.check(""" b INFO: This is INFO b WARN: This is WARN b ERROR: This is ERROR b FATAL: This is FATAL b WARN: Format 3 2.71828 foo """)
def testBasic(self): """ Test basic log output. Since the default threshold is INFO, the TRACE message is not emitted. """ with TestLog.StdoutCapture(self.outputFilename): log.configure() log.trace("This is TRACE") log.info("This is INFO") log.debug("This is DEBUG") log.warn("This is WARN") log.error("This is ERROR") log.fatal("This is FATAL") log.info("Format %d %g %s", 3, 2.71828, "foo") self.check(""" INFO root null - This is INFO DEBUG root null - This is DEBUG WARN root null - This is WARN ERROR root null - This is ERROR FATAL root null - This is FATAL INFO root null - Format 3 2.71828 foo """)
def testBasic(self): """ Test basic log output with default configuration. Since the default threshold is INFO, the DEBUG or TRACE message is not emitted. """ with TestLog.StdoutCapture(self.outputFilename): log.configure() log.log(log.getDefaultLoggerName(), log.INFO, "This is INFO") log.info(u"This is unicode INFO") log.trace("This is TRACE") log.debug("This is DEBUG") log.warn("This is WARN") log.error("This is ERROR") log.fatal("This is FATAL") log.warn("Format %d %g %s", 3, 2.71828, "foo") self.check(""" root INFO: This is INFO root INFO: This is unicode INFO root WARN: This is WARN root ERROR: This is ERROR root FATAL: This is FATAL root WARN: Format 3 2.71828 foo """)
pool.map_async(a, visits) pool.close() pool.join() b() log.info("Leaving main") def a(visit): # Set subcomponent to "a" (sets component to "main.a") with log.LogContext("a"): # Clean out any previous MDC for visit log.MDCRemove("visit") # All subsequent log messages will have visit id log.MDC("visit", visit) log.info("In a, %d", visit) log.debug("Debug message in a") b() log.info("Leaving a") def b(): # Set subcomponent to "b" (sets component to "main.a.b" or "main.b") with log.LogContext("b"): log.info("In b") log.debug("Testing; logged only when called by a") log.info("Leaving b") if __name__ == "__main__": log.configure("examples/log4cxx.properties") main()
from .api_model import * SAFE_NAME_REGEX = r'[A-Za-z_$][A-Za-z0-9_$]*$' SAFE_SCHEMA_PATTERN = re.compile(SAFE_NAME_REGEX) SAFE_TABLE_PATTERN = re.compile(SAFE_NAME_REGEX) ACCEPT_TYPES = ["application/json", "text/html"] meta_api_v1 = Blueprint("api_meta_v1", __name__, static_folder="static", template_folder="templates") # configure the log file (log4cxx) config_path = meta_api_v1.root_path + "/config/" log.configure(os.path.join(config_path, "log.properties")) def Session(): db = getattr(g, '_Session', None) if db is None: db = g._session = session_maker(current_app.config["default_engine"]) return db() # log the user name of the auth token @meta_api_v1.before_request def check_auth(): """ Data Formats HTTP Header Authorization: Bearer <JWT token>
def testLogLoop(self): """Test that Python log forwarding works even if Python logging has been forwarded to lsst.log""" log.configure() # Note that assertLogs causes a specialists Python logging handler # to be added. # Set up some Python loggers loggername = "testLogLoop" lgr = logging.getLogger(loggername) lgr.setLevel(logging.INFO) rootlgr = logging.getLogger() rootlgr.setLevel(logging.INFO) # Declare that we are using the Python logger and that this will # not cause a log loop if we also are forwarding Python logging to # lsst.log log.usePythonLogging() # Ensure that we can log both in lsst.log and Python rootlgr.addHandler(log.LogHandler()) # All three of these messages go through LogHandler # The first two because they have the handler added explicitly, the # the final one because the lsst.log logger is forwarded to the # ROOT Python logger which has the LogHandler registered. with open(self.outputFilename, "w") as fd: # Adding a StreamHandler will cause the LogHandler to no-op streamHandler = logging.StreamHandler(stream=fd) rootlgr.addHandler(streamHandler) # Do not use assertLogs since that messes with handlers lgr.info( "INFO message: Python child logger, lsst.log.LogHandler + PythonLogging" ) rootlgr.info( "INFO message: Python root logger, lsst.log.logHandler + PythonLogging" ) # This will use a ROOT python logger which has a LogHandler attached log.info("INFO message: lsst.log root logger, PythonLogging") rootlgr.removeHandler(streamHandler) self.check(""" INFO message: Python child logger, lsst.log.LogHandler + PythonLogging INFO message: Python root logger, lsst.log.logHandler + PythonLogging INFO message: lsst.log root logger, PythonLogging""") with open(self.outputFilename, "w") as fd: # Adding a StreamHandler will cause the LogHandler to no-op streamHandler = logging.StreamHandler(stream=fd) rootlgr.addHandler(streamHandler) # Do not use assertLogs since that messes with handlers lgr.info( "INFO message: Python child logger, lsst.log.LogHandler + PythonLogging" ) rootlgr.info( "INFO message: Python root logger, lsst.log.logHandler + PythonLogging" ) # This will use a ROOT python logger which has a LogHandler attached log.info("INFO message: lsst.log root logger, PythonLogging") rootlgr.removeHandler(streamHandler) self.check(""" INFO message: Python child logger, lsst.log.LogHandler + PythonLogging INFO message: Python root logger, lsst.log.logHandler + PythonLogging INFO message: lsst.log root logger, PythonLogging""") with self.assertLogs(level="INFO") as cm: rootlgr.info("Python log message forward to lsst.log") log.info("lsst.log message forwarded to Python") self.assertEqual(len(cm.output), 2, f"Got output: {cm.output}") logging.shutdown()
orca.skipglidein = parser.opts.skipglidein orca.dryrun = parser.opts.dryrun orca.envscript = parser.opts.envscript # This is handled via lsst.ctrl.orca (i.e. lsst/ctrl/orca/__init__.py): # # orca.logger = Log(Log.getDefaultLog(), "orca") configPath = None if parser.opts.logconfig is None: package = lsst.utils.getPackageDir("ctrl_orca") configPath = os.path.join(package, "etc", "log4j.properties") else: configPath = parser.opts.logconfig log.configure(configPath) orca.verbosity = parser.opts.verbosity # set the dryrun singleton to the value set on the command line. # we reference this in other classes orca.dryrun = parser.opts.dryrun log.debug("pipelineConfigFile = "+pipelineConfigFile) log.debug("runId = "+runId) # create the ProductionRunManager, configure it, and launch it productionRunManager = ProductionRunManager(runId, pipelineConfigFile)
def testLogLoop(self): """Test that Python log forwarding works even if Python logging has been forwarded to lsst.log""" log.configure() # Note that assertLogs causes a specialists Python logging handler # to be added. # Set up some Python loggers loggername = "testLogLoop" lgr = logging.getLogger(loggername) lgr.setLevel(logging.INFO) rootlgr = logging.getLogger() rootlgr.setLevel(logging.INFO) # Declare that we are using the Python logger and that this will # not cause a log loop if we also are forwarding Python logging to # lsst.log log.usePythonLogging() # Ensure that we can log both in lsst.log and Python rootlgr.addHandler(log.LogHandler()) # All three of these messages go through LogHandler # The first two because they have the handler added explicitly, the # the final one because the lsst.log logger is forwarded to the # ROOT Python logger which has the LogHandler registered. with open(self.outputFilename, "w") as fd: # Adding a StreamHandler will cause the LogHandler to no-op streamHandler = logging.StreamHandler(stream=fd) rootlgr.addHandler(streamHandler) # Do not use assertLogs since that messes with handlers lgr.info("INFO message: Python child logger, lsst.log.LogHandler + PythonLogging") rootlgr.info("INFO message: Python root logger, lsst.log.logHandler + PythonLogging") # This will use a ROOT python logger which has a LogHandler attached log.info("INFO message: lsst.log root logger, PythonLogging") rootlgr.removeHandler(streamHandler) self.check(""" INFO message: Python child logger, lsst.log.LogHandler + PythonLogging INFO message: Python root logger, lsst.log.logHandler + PythonLogging INFO message: lsst.log root logger, PythonLogging""") with open(self.outputFilename, "w") as fd: # Adding a StreamHandler will cause the LogHandler to no-op streamHandler = logging.StreamHandler(stream=fd) rootlgr.addHandler(streamHandler) # Do not use assertLogs since that messes with handlers lgr.info("INFO message: Python child logger, lsst.log.LogHandler + PythonLogging") rootlgr.info("INFO message: Python root logger, lsst.log.logHandler + PythonLogging") # This will use a ROOT python logger which has a LogHandler attached log.info("INFO message: lsst.log root logger, PythonLogging") rootlgr.removeHandler(streamHandler) self.check(""" INFO message: Python child logger, lsst.log.LogHandler + PythonLogging INFO message: Python root logger, lsst.log.logHandler + PythonLogging INFO message: lsst.log root logger, PythonLogging""") with self.assertLogs(level="INFO") as cm: rootlgr.info("Python log message forward to lsst.log") log.info("lsst.log message forwarded to Python") self.assertEqual(len(cm.output), 2, f"Got output: {cm.output}") logging.shutdown()
orca.skipglidein = parser.opts.skipglidein orca.dryrun = parser.opts.dryrun orca.repository = parser.opts.repository orca.envscript = parser.opts.envscript # This is handled via lsst.ctrl.orca (i.e. lsst/ctrl/orca/__init__.py): # # orca.logger = Log(Log.getDefaultLog(), "orca") configPath = None if parser.opts.logconfig is None: package = lsst.utils.getPackageDir("ctrl_orca") configPath = os.path.join(package, "etc", "log4j.properties") else: configPath = parser.opts.logconfig log.configure(configPath) orca.verbosity = parser.opts.verbosity # set the dryrun singleton to the value set on the command line. # we reference this in other classes orca.dryrun = parser.opts.dryrun log.debug("pipelineConfigFile = "+pipelineConfigFile) log.debug("runId = "+runId) # create the ProductionRunManager, configure it, and launch it productionRunManager = ProductionRunManager(runId, pipelineConfigFile, orca.repository)