ccdproc icon indicating copy to clipboard operation
ccdproc copied to clipboard

Use of root level logging interferes with other logging when imported

Open JuanCab opened this issue 2 years ago • 3 comments

In essence, if we use the python logging facility, you should be careful because when you create a logging handler for a function, it seems that it is essentially forked off the root handler. Unless you remove the root handlers they remain active. This was a problem in my case because I imported the ImageFileCollection function and the moment I ran it for the first time, logging was activated including the root handler. This meant when I tried to use logging in my program, I was getting extra copies of the logging because the root handler was also responding to my logging calls.

I removed the root handlers by issuing the following:

    # Turn off root loggers that are activated by ImageFileCollection
    for handler in logging.root.handlers[:]:
        logging.root.removeHandler(handler)

I would suggest unless you are intending to use the root handlers in ccdproc that you remove them yourself when you spin up the logging. That said, if there is another suggested way to handle this situation, I would appreciate the feedback.

JuanCab avatar Aug 08 '23 22:08 JuanCab

Can you please provide an example that demonstrates the problem? At first glance, at least, I'm not seeing any place in ccdproc that uses the root logger.

mwcraig avatar Aug 09 '23 17:08 mwcraig

Well, here is a code that works for me (assuming test_dir points to a directory with FITS images):

import logging
from ccdproc import ImageFileCollection

print(f"There a root handler? {logging.root.hasHandlers()}")

logger=logging.getLogger("__main__")
print(f"There a root handler? {logging.root.hasHandlers()}")

ifc = ImageFileCollection("./exoplanet-project/")
print(f"There a root handler? {logging.root.hasHandlers()}")

On my system, running as the first command in ipython, I get:

There a root handler? False
There a root handler? False
There a root handler? True

JuanCab avatar Aug 09 '23 17:08 JuanCab

Just for humor's sake, try setting the level of the logger you create. When I create a handler, I do all this:

logger = logging.getLogger("multi_image_photometry")
logger(logging.INFO)
console_format = logging.Formatter('%(message)s')
fh = logging.StreamHandler()
fh.setFormatter(console_format)
fh.setLevel(logging.INFO)   # Set the individual handler's response level
logger.addHandler(fh)

Not sure if that somehow decouples it from the root handler, since you are not just using the default settings (from root).

JuanCab avatar Aug 09 '23 17:08 JuanCab