problem with interpolation and logging.config.dictConfig with python3.6+
tjwilli58 opened this issue · comments
I'm having a problem using configobj with interpolation to configure a logger. Everything works fine with python3.4, python3.5, but for python3.5 and above, I get an exception.
Here is my test program:
import sys
import configobj
import logging, logging.config
msg = '***** python version: \n{}\n*****\n'.format(sys.version)
print(msg)
config = configobj.ConfigObj('logtest.ini')
# make version an int
config['logging']['version'] = int(config['logging']['version'])
logging.config.dictConfig(config['logging'])
logger=logging.getLogger('root')
logger.info(msg)
and my INI file:
[logging]
version = 1
level = INFO
[[formatters]]
[[[fmt1]]]
format = %(asctime)s: (%(levelname)s) %(message)s
[[handlers]]
[[[console]]]
class = logging.StreamHandler
level = INFO
stream = ext://sys.stderr
formatter = fmt1
[[[file]]]
class = logging.FileHandler
level = INFO
mode = a
formatter = fmt1
filename = test.log
[[loggers]]
[[[root]]]
level = INFO
handlers = console, file
running under python3.4 or python 3.5:
(py36) C:\Users\Tim\workspace\CollectionSoftware>conda.bat activate py35
(py35) C:\Users\Tim\workspace\CollectionSoftware>python testlogging.py
***** python version:
3.5.5 | packaged by conda-forge | (default, Jul 24 2018, 01:52:17) [MSC v.1900 64 bit (AMD64)]
2019-09-29 12:53:27,027: (INFO) ***** python version:
3.5.5 | packaged by conda-forge | (default, Jul 24 2018, 01:52:17) [MSC v.1900 64 bit (AMD64)]
But when I try the same program with python3.6, I get a ValueError when trying to configer my logger format:
(py35) C:\Users\Tim\workspace\CollectionSoftware>conda.bat activate py36
(py36) C:\Users\Tim\workspace\CollectionSoftware>python testlogging.py
***** python version:
3.6.7 (default, Jul 2 2019, 02:21:41) [MSC v.1900 64 bit (AMD64)]
Traceback (most recent call last):
File "C:\Users\Tim\Miniconda3\envs\py36\lib\logging\config.py", line 545, in configure
formatters[name])
File "C:\Users\Tim\Miniconda3\envs\py36\lib\logging\config.py", line 327, in getitem
return self.convert_with_key(key, value)
File "C:\Users\Tim\Miniconda3\envs\py36\lib\logging\config.py", line 293, in convert_with_key
result = self.configurator.convert(value)
File "C:\Users\Tim\Miniconda3\envs\py36\lib\logging\config.py", line 446, in convert
value = ConvertingDict(value)
File "C:\Users\Tim\Miniconda3\envs\py36\lib\site-packages\configobj.py", line 557, in getitem
return self._interpolate(key, val)
File "C:\Users\Tim\Miniconda3\envs\py36\lib\site-packages\configobj.py", line 549, in _interpolate
return engine.interpolate(key, value)
File "C:\Users\Tim\Miniconda3\envs\py36\lib\site-packages\configobj.py", line 352, in interpolate
value = recursive_interpolate(key, value, self.section, {})
File "C:\Users\Tim\Miniconda3\envs\py36\lib\site-packages\configobj.py", line 330, in recursive_interpolate
k, v, s = self._parse_match(match)
File "C:\Users\Tim\Miniconda3\envs\py36\lib\site-packages\configobj.py", line 417, in _parse_match
value, section = self._fetch(key)
File "C:\Users\Tim\Miniconda3\envs\py36\lib\site-packages\configobj.py", line 386, in _fetch
raise MissingInterpolationOption(key)
configobj.MissingInterpolationOption: missing option "asctime" in interpolation.During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "testlogging.py", line 11, in
logging.config.dictConfig(config['logging'])
File "C:\Users\Tim\Miniconda3\envs\py36\lib\logging\config.py", line 802, in dictConfig
dictConfigClass(config).configure()
File "C:\Users\Tim\Miniconda3\envs\py36\lib\logging\config.py", line 548, in configure
'formatter %r: %s' % (name, e))
ValueError: Unable to configure formatter 'fmt1': missing option "asctime" in interpolation.
It could be a bug in logging.config, but I'm thinking it may be somewhere in configobj.interpolate()
Thanks for any help
I think the source my confusion is that the formatting of the logging module LogRecord attributes Is identical to the 'ConfigParser' interpolation.
I changed the interpolation to 'Template', then made sure to change the confiobj key values to have that format, while leaving the format statement alone, e.g.
[MainWindow]
NumCameras = 1
RootDir = TestData
CaptureDrive = "C:/"
LogFile = ${CaptureDrive}${RootDir)/test.log
[logging]
version = 1
level = INFO
[[formatters]]
[[[fmt1]]]
format = %(asctime)s: (%(levelname)s) %(message)s
datefmt =
[[handlers]]
[[[console]]]
class = logging.StreamHandler
level = INFO
stream = ext://sys.stderr
formatter = fmt1
[[[file]]]
class = logging.FileHandler
level = INFO
mode = a
formatter = fmt1
filename = C:/TestData/test_20190530.log
[[loggers]]
[[[root]]]
level = INFO
handlers = console, file