0

I am setting up a user interface and want to allow the user to specify what kind of logging is required. For this I want to use something like this:

logging.basicConfig(level=logging.INFO)

where the INFO setting can be specified.

For logging there are the following options: DEBUG, INFO, WARNING, ERROR, CRITICAL and I will have it stored in a string. How can I substitute the string appropriately into the code above?

Michael
  • 199
  • 1
  • 9

4 Answers4

1

You have a few options.

The best is probably a dict:

logtypes = {
    "INFO": logging.INFO,
    "DEBUG": logging.DEBUG,
    ...
}

Another is using conditionals:

if logtype == "INFO":
    logparam = logging.INFO
elif logtype == "DEBUG":
    logparam = logging.DEBUG
else:
    ...

There does exist another option that's shorter but does run the (niche) risk that logtype being something like __dir__ won't error immediately: getattr(logging, logtype).

Also, if you really hate conventions and all that is good and holy in this world, do eval("logging." + logtype).

hyper-neutrino
  • 5,272
  • 2
  • 29
  • 50
  • I like the getattr(logging, logtype) option as it's a one-liner - what is the problem with it? Unpythonic? – Michael May 05 '19 at 01:55
  • 1
    @Michael I mean, it's not actually too bad. Maybe people won't hate me for it lol. I think it may actually be reasonably idiomatic. The only problem is that if the string isn't a valid logging level, if it's something like `__dir__`, that will still return a value. – hyper-neutrino May 05 '19 at 01:57
  • A good over is here: https://stackoverflow.com/questions/4075190/what-is-getattr-exactly-and-how-do-i-use-it#answer-4076099 but I still don't understand what the problem with it is. – Michael May 05 '19 at 01:58
  • @Michael Yeah, I'm editing my answer. It actually seems to be perfectly valid. – hyper-neutrino May 05 '19 at 01:59
  • Provided you use a default value (as the third parameter) which you know is valid it seems pretty safe to me... – Michael May 05 '19 at 01:59
0

logging.LEVEL is an integer value, as seen in the manual.

You can store that value in your config (I guess you're using ConfigParser or JSON or something similar?) and simply load it on application start. About how to link text to value, well, that depends on the UI toolkit, probably easiest way would be a combobox with values based on a dict keys.

Logging setup example with config parser

# read configuration
cfg = configparser.ConfigParser()
cfg.read(config_file_path)

# set logging
...
logging.basicConfig(level=cfg['logging'].getint('level'))
...

icwebndev
  • 413
  • 3
  • 10
0

You can use dictionary to convert it

import logging

converter = {
    "debug": logging.DEBUG,
    "info": logging.INFO,
    "warning": logging.WARNING,
    "error": logging.ERROR,
    "critical": logging.CRITICAL
}

# selected_level = input('select level: ')
# selected_level = sys.argv[1]
selected_level = 'info'

if selected_level in converter:
    selected_level = converter[selected_level]
else:
    selected_level = logging.INFO

logging.basicConfig(level=selected_level)
furas
  • 134,197
  • 12
  • 106
  • 148
0

Despite the name, logging.getLevelName actually converts both ways:

In [1]: import logging

In [2]: logging.getLevelName(logging.CRITICAL)
Out[2]: 'CRITICAL'

In [3]: logging.getLevelName('CRITICAL')
Out[3]: 50

In [4]: logging.CRITICAL
Out[4]: 50
o11c
  • 15,265
  • 4
  • 50
  • 75