19

I want to make a logging manager gui. Basically I want to get the tree structure of loggers and show their level and formatter in a pyqt gui. How can I get the format string from a formatter associated a handler object?

eg:

import logging
_logger = logging.getLogger('myLogger')

ch = logging.StreamHandler()
ch.setLevel(logging.INFO)
formatter = logging.Formatter('%(name)s:%(levelname)s: %(message)s')
ch.setFormatter(formatter)
_logger.addHandler(ch)
_logger.propagate=0

Now I have the _logger, how can I get string '%(name)s:%(levelname)s: %(message)s' from the logging.Formatter object?

>>> _logger.handlers[0]
<logging.StreamHandler object at 0x13807610>
>>> _logger.handlers[0].formatter
<logging.Formatter object at 0x13807690>
vvvvv
  • 25,404
  • 19
  • 49
  • 81
Shuman
  • 3,914
  • 8
  • 42
  • 65

1 Answers1

31

logging.Formatter instances have a _fmt attribute:

>>> _logger.handlers[0].formatter
<logging.Formatter object at 0x102c72fd0>
>>> _logger.handlers[0].formatter._fmt
'%(name)s:%(levelname)s: %(message)s'

You can always use dir() and vars() on objects to see what names might be available:

>>> vars(_logger.handlers[0].formatter)
{'_style': <logging.PercentStyle object at 0x102e6bbf0>, '_fmt': '%(name)s:%(levelname)s: %(message)s', 'datefmt': None}

or you could just look at the source code (linked from the top of the module documentation).

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • If accessing an internal `_` attribute (which is generally a frowned-upon practice) is good enough for a million-pointer, it is good enough for me. – PaulMcG May 12 '23 at 19:07
  • @PaulMcG: the logging module is [breaking style conventions in so many ways already](https://stackoverflow.com/a/22993896), and there is no other option to access the format string. Needs must! – Martijn Pieters Jun 14 '23 at 09:24
  • @PaulMcG: the `_` initial underscore convention is more of a warning: *Watch out, this attribute could be removed or change meaning in a future version without notice*. With the logging module however, I'm quite confident that if the attribute were ever to go away that there'd be a long deprecation period first, given the history of the package. – Martijn Pieters Jun 14 '23 at 09:28
  • This comment was as much for my own benefit as for anyone else; I recently wrote code that accessed this `_fmt` field so that I could define a new formatter with some custom placeholders to it. 20 years' worth of Python coding habits gave me pause at committing such an act, but now I know I am in good company. – PaulMcG Jun 16 '23 at 01:30