Closed pscicluna closed 1 year ago
Default setting to log to file (so it's available later), have options for user to print some things to screen for useful warnings and important information.
For once, the main python docs actually have a reasonable amount of well-explained info, if you can find it: https://docs.python.org/3/howto/logging.html This covers our case pretty well, we can set some reasonable defaults and users will have the ability to change logging parameters from their scripts.
I also found a couple of stackoverflow answers that will be useful, covering how to log exceptions raised in other parts of the code so that they go into the AMPERE logs: https://stackoverflow.com/questions/6234405/logging-uncaught-exceptions-in-python/16993115#16993115 https://stackoverflow.com/questions/8050775/using-pythons-logging-module-to-log-all-exceptions-and-errors
Having had some time to read over this recently, I have come up with the start of a plan for logging. Hopefully other (like @jontymarshall ?) can help with it.
I think logging should be controlled by the inference objects (so EmceeSearch etc). This is the main interface for doing things with ampere where users don't want to have to interact with something and want to know that things will just run. this means that the init methods (or other constructors) for Data and Model classes should not do any logging, but raise warnings and exceptions immediately when something is wrong. Other methods, however, should use logging if they are expected to be called from within an inference object, especially if it is writing to file as well as printing to the terminal.
The logging levels are pretty easy to navigate. DEBUG
is only for use when the user wants extra information (we can add a verbose or debug keyword to inference objects for this). INFO
will be how we report the state of objects (e.g. reminding the user how many free parameters they have) or results. WARNING
is for warning the user that they are doing something not recommended or for catching (and suppressing on the terminal) warnings coming from other parts of the code. ERROR
and CRITICAL
are pretty self explanatory. These should be used to report, or catch (and re-raise) exceptions from ampere or other bits of code we call.
I will add some basics in the branch where I am refactoring inference.
Started working on this in https://github.com/ICSM/ampere/commit/5721eef62ec2f5f0380c85771c45e66f58c83acf
Extra book-keeping for logging:
logging
and warnings
play nicely together. We can exploit this method from logging
to automatically redirect warnings to the logger, as long as we use warnings
to control which warnings are emitted or ignored. There are quite a few warnings we probably want to suppress.
Some errors and warnings could be produced many times over by inference codes if they happen inside the sampling loop. We don't want to see them 10,000 times over, so we should either suppress them completely or use this stackoverflow answer to filter the log and count the number of occurrences and only log that.
Completed logging inside ampere to a basic standard. Some finessing perhaps required. Can reopen if something major is missing.
We should use the python standard library package
logging
to provide a smooth interface to logging ampere's work and produce human-readable output.