1

According to the Doc here and this answer here, asking for a logLevel of my logger should return one of this levelnames

_levelNames = {
    CRITICAL : 'CRITICAL',
    ERROR : 'ERROR',
    WARNING : 'WARNING',
    INFO : 'INFO',
    DEBUG : 'DEBUG',
    NOTSET : 'NOTSET',
    'CRITICAL' : CRITICAL,
    'ERROR' : ERROR,
    'WARN' : WARNING,
    'WARNING' : WARNING,
    'INFO' : INFO,
    'DEBUG' : DEBUG,
    'NOTSET' : NOTSET,
}

but when I call

print logging.getLevelName("debug")

I get:

Level debug

so I can not in a confortable way do something like:

logger.setLevel(foo)

where fo is a string I get from some other method...

Any suggestions why?

Thanks

Community
  • 1
  • 1
ΦXocę 웃 Пepeúpa ツ
  • 47,427
  • 17
  • 69
  • 97

4 Answers4

2

That's not what the doc says at all. It says that if you pass an integer that maps to one of the predefined logging levels, you get a nicely printed string version:

>>> print(logging.getLevelName(logging.DEBUG))
DEBUG

otherwise you get "level x", as you noted.

And the linked answer explicitly states that going from string to integer is not what that function does.

Daniel Roseman
  • 588,541
  • 66
  • 880
  • 895
2

The linked doc does not say what you claim it says. This is what the docstring for getLevelName actually says:

Returns the textual representation of logging level lvl. If the level is one of the predefined levels CRITICAL, ERROR, WARNING, INFO or DEBUG then you get the corresponding string.

Not your case since "debug" is not one of the predefined levels.

If you have associated levels with names using addLevelName() then the name you have associated with lvl is returned.

Not your case since you did not mention using addLevelName.

If a numeric value corresponding to one of the defined levels is passed in, the corresponding string representation is returned.

Not your case since you did not pass a numeric value.

Otherwise, the string “Level %s” % lvl is returned.

This is your case so the expected return value of logging.getLevelName("debug") is "Level debug".

Stop harming Monica
  • 12,141
  • 1
  • 36
  • 56
2

Previous answers discuss the matter sufficiently, but for general viewing I would like to add an alternative way to translate logging level strings to the internal integer values.

getattr(logging, level_string)

Why? Just because the logging.getLevelName() function has a nasty feature to return you those "Level X" strings for invalid arguments.

Let's imagine that you are writing a Flask application that allows setting logging level in the instance configuration file (for example; LOGGING_LEVEL = "WARNING"). That qualifies as user input in my books and in my opinion you should be able to deal with invalid values. The third argument, fallback value, allows us to do this:

app = Flask(...)
app.config.from_pyfile('application.conf')
app.logger.setLevel(
    getattr(
        logging,
        str(app.config.get('LOG_LEVEL', 'DEBUG')),
        logging.DEBUG
    )
)

Now your code should be able to tolerate erroneous/missing configuration value and default to DEBUG logging mode in such cases.

All this is unnecessary and of no concern to you, if your logging level value is not user input (and thus unlikely to be missing or nonsensical). Then you're fine with logging.getLevelName(), I think.

My 5 cents is that people writing the logging module missed an obvious opportunity to address all this by providing us with optional third function argument (the fallback value), but it is what it is...

Hope this helps someone.

Tammi
  • 421
  • 7
  • 12
1

I will give you more details about your doubt:

logging.getLevelName('DEBUG') output as 10

logging.getLevelName(10) output as debug

see this logging.getLevelName.Its may clarified your doubts.

bob marti
  • 1,523
  • 3
  • 11
  • 27