Getting error while changing the logging file directory in Python
Question:
Objective
Need to change logging file path under ‘/users/logs’ directory when everytime my python tests executes on Windows machine
Steps
I have logging.conf file with settings as below. This configuration file exists under path ‘{ProjectRoot}/logs’
[loggers]
keys=root,simpleExample
[handlers]
keys=consoleHandler,fileHandler
[formatters]
keys=simpleFormatter
[logger_root]
level=INFO
handlers=consoleHandler,fileHandler
[logger_simpleExample]
level=DEBUG
handlers=consoleHandler,fileHandler
qualname=simpleExample
propagate=0
[handler_consoleHandler]
class=StreamHandler
level=DEBUG
formatter=simpleFormatter
args=(sys.stdout,)
[handler_fileHandler]
class=FileHandler
level=DEBUG
formatter=simpleFormatter
args=('%(logfilename)s', 'a', 'utf8')
[formatter_simpleFormatter]
format= %(levelname)s:%(asctime)s:%(module)s:%(funcName)s:%(lineno)d:%(message)s
And I have initialized logger as below
projectRoot = Path(__file__).parent
loggingConfigFile = f'{projectRoot}\logs\logging.conf'
logging.config.fileConfig(loggingConfigFile, defaults={'logfilename': "C:\Users\user1logs\bp1.log"}, disable_existing_loggers=False)
When I execute this I get error as
File "", line 1
(‘C:Usersinnabal1logsbp1.log’, ‘a’, ‘utf8’)
^
SyntaxError: (unicode error) ‘unicodeescape’ codec can’t decode bytes in position 2-3: truncated UXXXXXXXX escape
When I just give only the file name alone it works fine. But logs are created under the current execution directory.
logging.config.fileConfig(loggingConfigFile, defaults={'logfilename': "bp1.log"}, disable_existing_loggers=False)
Answers:
The issue appears to be that the file name is being parsed at several levels and at one point the U
in C:User
is trying to be decoded as unicode escape sequence.
Python in most situations will allow the path seperator to be a forward slash (/
) even on Windows operating systems. Using pathlib makes it easy to output the path in the "posix" format with Path().as_posix()
.
Using your config file I did the following test:
import datetime
import logging
from logging import config
from pathlib import Path
projectRoot = Path(__file__).parent
logDir = projectRoot.joinpath("logs")
loggingConfigFile = logDir.joinpath("logging.conf")
loggingOutputFile = logDir.joinpath(datetime.datetime.now().strftime("run_%Y%m%d%H%M%S.log"))
print(f"Log config file: {loggingConfigFile}")
print(f"Log output file: {loggingOutputFile.as_posix()}")
config.fileConfig(
loggingConfigFile,
defaults={
'logfilename': loggingOutputFile.as_posix(),
},
disable_existing_loggers=False)
logging.error('This is a logged error')
print("output file contents:")
print(loggingOutputFile.read_text())
Which gave the following output in my test:
Log config file: C:Usersuser1AppDataRoamingJetBrainsPyCharm2021.2scratcheslogslogging.conf
Log output file: C:/Users/user1/AppData/Roaming/JetBrains/PyCharm2021.2/scratches/logs/run_20220918123013.log
ERROR:2022-09-18 12:30:13,583:scratch_82:<module>:20:This is a logged error
output file contents:
ERROR:2022-09-18 12:30:13,583:scratch_82:<module>:20:This is a logged error
Objective
Need to change logging file path under ‘/users/logs’ directory when everytime my python tests executes on Windows machine
Steps
I have logging.conf file with settings as below. This configuration file exists under path ‘{ProjectRoot}/logs’
[loggers]
keys=root,simpleExample
[handlers]
keys=consoleHandler,fileHandler
[formatters]
keys=simpleFormatter
[logger_root]
level=INFO
handlers=consoleHandler,fileHandler
[logger_simpleExample]
level=DEBUG
handlers=consoleHandler,fileHandler
qualname=simpleExample
propagate=0
[handler_consoleHandler]
class=StreamHandler
level=DEBUG
formatter=simpleFormatter
args=(sys.stdout,)
[handler_fileHandler]
class=FileHandler
level=DEBUG
formatter=simpleFormatter
args=('%(logfilename)s', 'a', 'utf8')
[formatter_simpleFormatter]
format= %(levelname)s:%(asctime)s:%(module)s:%(funcName)s:%(lineno)d:%(message)s
And I have initialized logger as below
projectRoot = Path(__file__).parent
loggingConfigFile = f'{projectRoot}\logs\logging.conf'
logging.config.fileConfig(loggingConfigFile, defaults={'logfilename': "C:\Users\user1logs\bp1.log"}, disable_existing_loggers=False)
When I execute this I get error as
File "", line 1
(‘C:Usersinnabal1logsbp1.log’, ‘a’, ‘utf8’)
^
SyntaxError: (unicode error) ‘unicodeescape’ codec can’t decode bytes in position 2-3: truncated UXXXXXXXX escape
When I just give only the file name alone it works fine. But logs are created under the current execution directory.
logging.config.fileConfig(loggingConfigFile, defaults={'logfilename': "bp1.log"}, disable_existing_loggers=False)
The issue appears to be that the file name is being parsed at several levels and at one point the U
in C:User
is trying to be decoded as unicode escape sequence.
Python in most situations will allow the path seperator to be a forward slash (/
) even on Windows operating systems. Using pathlib makes it easy to output the path in the "posix" format with Path().as_posix()
.
Using your config file I did the following test:
import datetime
import logging
from logging import config
from pathlib import Path
projectRoot = Path(__file__).parent
logDir = projectRoot.joinpath("logs")
loggingConfigFile = logDir.joinpath("logging.conf")
loggingOutputFile = logDir.joinpath(datetime.datetime.now().strftime("run_%Y%m%d%H%M%S.log"))
print(f"Log config file: {loggingConfigFile}")
print(f"Log output file: {loggingOutputFile.as_posix()}")
config.fileConfig(
loggingConfigFile,
defaults={
'logfilename': loggingOutputFile.as_posix(),
},
disable_existing_loggers=False)
logging.error('This is a logged error')
print("output file contents:")
print(loggingOutputFile.read_text())
Which gave the following output in my test:
Log config file: C:Usersuser1AppDataRoamingJetBrainsPyCharm2021.2scratcheslogslogging.conf
Log output file: C:/Users/user1/AppData/Roaming/JetBrains/PyCharm2021.2/scratches/logs/run_20220918123013.log
ERROR:2022-09-18 12:30:13,583:scratch_82:<module>:20:This is a logged error
output file contents:
ERROR:2022-09-18 12:30:13,583:scratch_82:<module>:20:This is a logged error