starplast.logging_util
Levels, a log file that has to be asked for, and separate control over what reaches the screen.
The console pane already tees stdout, so a walk's progress is visible while it runs. What a tee cannot do is tell a progress line from a warning from a traceback -- so it cannot filter them, and it keeps nothing once the window closes. Two failures in this project would have been caught in minutes by a log and instead ran for months:
- every AlphaFold fetch returning 404, reported each time as the ordinary "no model available";
- a search completing 40 of 288 configurations with no record of which ones, or how long each took.
Both are the same shape: something that failed reporting itself the way something that succeeded does. That is what levels are for.
Two switches, because they answer different questions
Writing a file is opt-in and off by default. A tool that starts writing to someone's disk without being asked is a tool people stop trusting, and this one is meant to be run on a laptop by someone who did not ask for a logging system.
What reaches the console is a separate choice, and it is never off. DEBUG is exactly what you want in the file during a half-hour walk and exactly what you do not want scrolling past on screen, so the two levels are set independently. With the file disabled the console handler stays, at WARNING: a warning that is only written to a file nobody enabled is a silent failure with extra steps, which is the thing this module exists to end.
The console format is parsed, not just read
Console lines are [LEVEL] message, which is what lets the console pane color them and filter by
level. It is a prefix rather than a suffix or a column so that a wrapped or truncated line still
begins with its level.
The logger for one module: get_logger(__name__).
Always a child of starplast, whatever it is passed, so that configuring one name configures
everything and no message can escape by being logged under an unexpected one.
Where log files go: under the platform cache directory, beside anything else downloaded.
Set logging up, and return the file being written to, or "" when none is.
Idempotent: every call replaces the handlers rather than adding to them, so changing a level in Preferences twice does not print everything twice -- which is how a logging system starts being described as noisy and then gets turned off.
A file that cannot be opened is reported and the rest of the configuration still applies. Losing the console because a directory was read-only would be a strange way to handle a log.
What logging is currently doing: enabled, both levels, and the file if there is one.
The file being written to, or "" when the log is not being kept.
The level a console line was logged at, or None if it was an ordinary print.
The console pane uses this to color and filter. Ordinary prints are not forced into a level:
most of this application's output is print, and calling all of it INFO would make an INFO
filter useless.
Log how long something took, and what happened, whichever way it ends.
A duration is the number that turns "the search finished" into something worth keeping: the walk that quietly did 40 of 288 configurations looked exactly like the one that did all of them until someone timed it.