Right now I have a lot of code that uses the traditional C-style string formatters, i.e.
print "Hi, %s" % name
We're working on transitioning over to using string.format()
, i.e.
print "Hi, {}".format(name)
However we're running into issues with logging. For example, consider the following example.
import logging
logging.basicConfig()
logger = logging.getLogger(__name__)
logger.error("hi %s", "1")
logger.error("hi {}", "2")
I would hope that the logging module would be able to make either of these work, however I get the following output to stderr
$ python example.py
ERROR:__main__:hi 1
Traceback (most recent call last):
File "C:\Python27\lib\logging\__init__.py", line 859, in emit
msg = self.format(record)
File "C:\Python27\lib\logging\__init__.py", line 732, in format
return fmt.format(record)
File "C:\Python27\lib\logging\__init__.py", line 471, in format
record.message = record.getMessage()
File "C:\Python27\lib\logging\__init__.py", line 335, in getMessage
msg = msg % self.args
TypeError: not all arguments converted during string formatting
Logged from file example.py, line 6
ERROR:__main__:hi
Now we could just change all of our strings involved with logging back to the C-style strings, but that is pretty ugly and worse, inconsistent. We could also add some extra lines into our code, for example
def run_function(func, arg, err_msg, err_msg_params):
try:
func(arg)
except MyException as e:
logger.error(err_msg.format(err_msg_params))
logger.exception(e)
raise
But that doesn't seem as clean. We could also do the formatting before we call this function, and then just not include the err_msg_params
but that would mean rewriting the function call (and then changing all of the code that uses this function).
Is there a way to make the logging module accept these? Or do I just have do all of my formatting myself?