BobC
BobC

Reputation: 2078

Python logging level based on variable value?

I need to change the logging level based on the value of a variable. For example:

if accel >= 10.0:
    log_func = logging.critical # Critical for splat event
elif accel >= 2.0:
    log_func = logging.warning  # Warning for high-G
elif accel >= 1.0:
    log_func = logging.info     # Info for normal
else:
    log_func = logging.debug    # Debug otherwise
log_func("Collision with %0.1fG impact.", accel)

I have instances of this all through my code. Is there a better way?

Upvotes: 6

Views: 4075

Answers (2)

Martijn Pieters
Martijn Pieters

Reputation: 1123350

Yes, use the Logger.log() method instead, and pass in a level constant:

import sys

# Map accel values to log levels
levels = (
    (10.0, logging.CRITICAL),
    (2.0, logging.WARNING), 
    (1.0, logging.INFO),
    (-sys.maxsize, logging.DEBUG)
)

logging.log(next(lev[1] for lev in levels if lev[0] <= accel),
    "Collision with %0.1fG impact.", accel)

You could encapsulate the level selection into a utility function:

def level_for_accel(accel):
    # return next matching log level for the given accel value
    return next(lev[1] for lev in levels if lev[0] <= accel)

logging.log(level_for_accel(accel), "Collision with %0.1fG impact.", accel)

Log levels are really integers, and the CRITICAL, WARNING, etc. values are merely constants. There are any number of ways you can turn one value (e.g. accel) into a matching log level with a few simple rules, in a more readable manner than a large number of if / else branches.

Upvotes: 7

Ahmed Aeon Axan
Ahmed Aeon Axan

Reputation: 2139

You could create a function which takes the variable accel and returns the appropriate logging function. and then call that. It would probably be cleaner and more maintainable code. Not to mention DRY.

def logger(accel):
    if accel >= 10.0:
        return logging.critical # Critical for splat event
    if accel >= 2.0:
        return logging.warning  # Warning for high-G
    if accel >= 1.0:
       return logging.info     # Info for normal
   else:
       return logging.debug    # Debug otherwise

Then you could use it as

logger(12)("hello world")

Upvotes: 3

Related Questions