Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

get list of named loglevels

Tags:

python

logging

In my application, I'm using python.logging for logging.

Now I want to control the loglevel interactively, so i created a combobox hat lets the user select "ERROR", "WARN", "INFO",...

What I don't really like is that currently the values in the combobox are hardcoded. Instead,Ii would like to have a list of all "named" loglevels (e.g. both the system defaults, but also those added via logging.addLevelName; but not the fake generated loglevels like "Level 42")

The best I have come up with so far is to use the logging._levelNames dictionary.

But then this seems to be a private member, and I somehow have a bad feeling accessing it directly.

So my question is: what's the proper way to list all currently defined "named" loglevels in Python.

like image 258
umläute Avatar asked Sep 17 '13 09:09

umläute


3 Answers

As you are only reading values, logging._levelNames looks an appropriate solution to me. Keep going with logging.addLevelName for setting new values though.

like image 155
giovanni Avatar answered Oct 08 '22 23:10

giovanni


There is no specific function to do what you want, but you have everything you need with logging._levelNames.

Take a look at the addLevelName definition for example:

def addLevelName(level, levelName):
    """
    Associate 'levelName' with 'level'.

    This is used when converting levels to text during message formatting.
    """
    _acquireLock()
    try:    #unlikely to cause an exception, but you never know...
        _levelNames[level] = levelName
        _levelNames[levelName] = level
    finally:
        _releaseLock()

So a getLevelNames() could be implemented like this:

import logging
def getLevelNames():
    for k, v in sorted(logging._levelNames.iteritems()):
        if isinstance(v, basestring):
            yield v, k

import pprint
pprint.pprint(list(getLevelNames()))

Example output:

[('NOTSET', 0),
 ('DEBUG', 10),
 ('INFO', 20),
 ('WARNING', 30),
 ('ERROR', 40),
 ('CRITICAL', 50)]
like image 25
Wolph Avatar answered Oct 08 '22 21:10

Wolph


You should have a bad feeling about using internal variables, because they can and will change. Case in point, you can no longer access logging._levelNames in python 3.

Per the docs the levels are more or less stated as constants, so you can just assume those ones are always available, and then any you add yourself are under your control anyway.

That said, it's a bit silly they don't have a simple method like logging.listLevels() to list out all the named levels currently loaded. You should write them a strongly worded letter. Or feature request depending on how much you really care :)

And it should be strongly worded, because the changes is absurdly simple:

file: /usr/local/lib/python3.9/logging/__init__.py

def listLevelNames():
    return sorted(_nameToLevel.keys())

If you wanted to get really fancy, you could even sort the names by level number.

edit: I made a topic in comp.lang.python. Don't worry, I was very polite.

like image 5
Edward Spencer Avatar answered Oct 08 '22 21:10

Edward Spencer