Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Logging setup for parsers #1372

Open
oliver-s-lee opened this issue Feb 29, 2024 · 0 comments
Open

Logging setup for parsers #1372

oliver-s-lee opened this issue Feb 29, 2024 · 0 comments
Assignees
Milestone

Comments

@oliver-s-lee
Copy link
Contributor

Currently, each Logfile object sets up it's own logging object:

self.loglevel = loglevel
self.logname = logname
self.logger = logging.getLogger(f"{self.logname} {self.inputfile.file_name}")
self.logger.setLevel(self.loglevel)
if len(self.logger.handlers) == 0:
    handler = logging.StreamHandler(logstream)
    handler.setFormatter(logging.Formatter("[%(name)s %(levelname)s] %(message)s"))
    self.logger.addHandler(handler)

While I can see the thinking behind this setup, it causes a few issues that I think should be addressed.

  1. The logger name is extremely complicated and overly specific. It depends not only on the log files being parsed, but also the exact paths given (so foo.log and ./foo.log will result in different loggers being setup for example). This makes it very difficult to access the logger via logging.getLogger(). For Logfile itself this isn't a problem because we always access the logger attribute on self directly, but it makes it difficult for other code to dynamically change the loglevel, for example.

  2. The loglevel is always set in Logfile.__init__(). This means you can't change the loglevel before instantiating the Logfile object, even if you correctly predict the logger name ahead of time. If you're accessing the Logfile class directly this is fine because you can just pass in the loglevel, but if you're accessing some higher level function this is annoying.

  3. Similar problem for the logger handler, you can't redirect the log to a file or something else unless you have a handle to the Logfile object.

I think it's fairly easy to refactor this, but it depends slightly on the intent behind setting up the logger this way. Firstly, would be good to understand why the parser type (ADF, Gaussian etc.) and the log file path(s) are used as the logger name. If it's just to include that information in each log message, then the Formatter would be the right place for this I think, or perhaps even better to use a custom log() method on Logfile (so we don't have to keep changing the Formatter).

If it's to get a unique logger for each parsed log file then I would question if this is necessary, and if it is necessary then more should be done to ensure it's actually unique (use a random name or checksum or something). In that case we should also find some way to remove the logger once it's finished with, as currently that's leaking memory. In either case, the logger for each log file should inherit from the main cclib logger 'cclib.parser' or 'cclib.parser.UNIQUE' etc.

Happy to work on this once we've decided on the right direction.

@oliver-s-lee oliver-s-lee self-assigned this Feb 29, 2024
@berquist berquist added this to the v2.0 milestone Mar 1, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants