一、 windows 环境pycharm的控制台日志报错
背景
在windows环境下,当日志文件大小超过配置设定的大小时,有时候会报错:文件另一个程序正在使用此文件,进程无法访问。
原因分析
原因是我打开了多个debug控制台,当我首先打开下图第一个控制台启动django项目时,此时相当开启了一个python进程。
然后打开celery服务的时候,此时celery模块对应的日志模块和django项目的日志模块是同一个,日志文件大小已经超过了阈值,需要滚动日志文件,重新生成。但我打开的第一个控制台此时虽然没有日志生成,但还是引用了日志文件,导致报错。
报错信息详情如下:
[2022-10-09 14:19:42,492: WARNING/MainProcess] --- Logging error ---
[2022-10-09 14:19:42,498: WARNING/MainProcess] Traceback (most recent call last):
[2022-10-09 14:19:42,501: WARNING/MainProcess] File "C:\Users\19768\.conda\envs\py36\lib\logging\handlers.py", line 72, in emit
self.doRollover()
[2022-10-09 14:19:42,503: WARNING/MainProcess] File "C:\Users\19768\.conda\envs\py36\lib\logging\handlers.py", line 173, in doRollover
self.rotate(self.baseFilename, dfn)
[2022-10-09 14:19:42,506: WARNING/MainProcess] File "C:\Users\19768\.conda\envs\py36\lib\logging\handlers.py", line 113, in rotate
os.rename(source, dest)
[2022-10-09 14:19:42,508: WARNING/MainProcess] PermissionError: [WinError 32] 另一个程序正在使用此文件,进程无法访问。: 'D:\\03-canway\\01-code\\logs\\general-check\\general-check.log' -> 'D:\\03-canway\\01-code\\logs\\general-check\\general-check.log.1'
[2022-10-09 14:19:42,510: WARNING/MainProcess] Call stack:
[2022-10-09 14:19:42,513: WARNING/MainProcess] File "D:\program files\PyCharm 2022.1\plugins\python\helpers\pydev\pydevd.py", line 2181, in <module>
main()
[2022-10-09 14:19:42,516: WARNING/MainProcess] File "D:\program files\PyCharm 2022.1\plugins\python\helpers\pydev\pydevd.py", line 2172, in main
globals = debugger.run(setup['file'], None, None, is_module)
[2022-10-09 14:19:42,518: WARNING/MainProcess] File "D:\program files\PyCharm 2022.1\plugins\python\helpers\pydev\pydevd.py", line 1484, in run
return self._exec(is_module, entry_point_fn, module_name, file, globals, locals)
[2022-10-09 14:19:42,520: WARNING/MainProcess] File "D:\program files\PyCharm 2022.1\plugins\python\helpers\pydev\pydevd.py", line 1491, in _exec
pydev_imports.execfile(file, globals, locals) # execute the script
[2022-10-09 14:19:42,522: WARNING/MainProcess] File "D:\program files\PyCharm 2022.1\plugins\python\helpers\pydev\_pydev_imps\_pydev_execfile.py", line 18, in execfile
exec(compile(contents+"\n", file, 'exec'), glob, loc)
[2022-10-09 14:19:42,524: WARNING/MainProcess] File "D:/03-canway/01-code/general-check/manage.py", line 10, in <module>
execute_from_command_line(sys.argv)
[2022-10-09 14:19:42,527: WARNING/MainProcess] File "D:\03-canway\01-code\general-check\venv\lib\site-packages\django\core\management\__init__.py", line 381, in execute_from_command_line
utility.execute()
[2022-10-09 14:19:42,529: WARNING/MainProcess] File "D:\03-canway\01-code\general-check\venv\lib\site-packages\django\core\management\__init__.py", line 375, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
[2022-10-09 14:19:42,531: WARNING/MainProcess] File "D:\03-canway\01-code\general-check\blueapps\contrib\bk_commands\management\commands\celery.py", line 32, in run_from_argv
base.execute_from_commandline(["{0[0]} {0[1]}".format(argv)] + argv[2:],)
[2022-10-09 14:19:42,533: WARNING/MainProcess] File "D:\03-canway\01-code\general-check\venv\lib\site-packages\celery\bin\celery.py", line 495, in execute_from_commandline
super(CeleryCommand, self).execute_from_commandline(argv)))
[2022-10-09 14:19:42,535: WARNING/MainProcess] File "D:\03-canway\01-code\general-check\venv\lib\site-packages\celery\bin\base.py", line 305, in execute_from_commandline
return self.handle_argv(self.prog_name, argv[1:])
[2022-10-09 14:19:42,537: WARNING/MainProcess] File "D:\03-canway\01-code\general-check\venv\lib\site-packages\celery\bin\celery.py", line 487, in handle_argv
return self.execute(command, argv)
[2022-10-09 14:19:42,540: WARNING/MainProcess] File "D:\03-canway\01-code\general-check\venv\lib\site-packages\celery\bin\celery.py", line 419, in execute
).run_from_argv(self.prog_name, argv[1:], command=argv[0])
[2022-10-09 14:19:42,542: WARNING/MainProcess] File "D:\03-canway\01-code\general-check\venv\lib\site-packages\celery\bin\worker.py", line 223, in run_from_argv
return self(*args, **options)
[2022-10-09 14:19:42,544: WARNING/MainProcess] File "D:\03-canway\01-code\general-check\venv\lib\site-packages\celery\bin\base.py", line 253, in __call__
ret = self.run(*args, **kwargs)
[2022-10-09 14:19:42,546: WARNING/MainProcess] File "D:\03-canway\01-code\general-check\venv\lib\site-packages\celery\bin\worker.py", line 259, in run
worker.start()
[2022-10-09 14:19:42,548: WARNING/MainProcess] File "D:\03-canway\01-code\general-check\venv\lib\site-packages\celery\worker\worker.py", line 205, in start
self.blueprint.start(self)
[2022-10-09 14:19:42,550: WARNING/MainProcess] File "D:\03-canway\01-code\general-check\venv\lib\site-packages\celery\bootsteps.py", line 119, in start
step.start(parent)
[2022-10-09 14:19:42,552: WARNING/MainProcess] File "D:\03-canway\01-code\general-check\venv\lib\site-packages\celery\bootsteps.py", line 369, in start
return self.obj.start()
[2022-10-09 14:19:42,554: WARNING/MainProcess] File "D:\03-canway\01-code\general-check\venv\lib\site-packages\celery\worker\consumer\consumer.py", line 318, in start
blueprint.start(self)
[2022-10-09 14:19:42,557: WARNING/MainProcess] File "D:\03-canway\01-code\general-check\venv\lib\site-packages\celery\bootsteps.py", line 119, in start
step.start(parent)
[2022-10-09 14:19:42,559: WARNING/MainProcess] File "D:\03-canway\01-code\general-check\venv\lib\site-packages\celery\worker\consumer\connection.py", line 24, in start
info('Connected to %s', c.connection.as_uri())
解决办法
根据上面的原因分析,就可以知道,先让有操作的控制台启动,将日志文件滚动,即可解决问题。
我的解决办法就是先让第二个控制台启动,其他控制台再启动
二、日志配置
setting.py文件中配置
# load logging settings
LOGGING = get_logging_config(locals())
def get_logging_config(settings_module):
log_class = "logging.handlers.RotatingFileHandler"
log_level = settings_module.get("LOG_LEVEL", "INFO")
if settings_module.get("IS_LOCAL", False):
log_dir = os.path.join(os.path.dirname(BASE_DIR), "logs", APP_CODE)
log_name_prefix = os.getenv("BKPAAS_LOG_NAME_PREFIX", APP_CODE)
logging_format = {
"format": (
"%(levelname)s [%(asctime)s] %(pathname)s "
"%(lineno)d %(funcName)s %(process)d %(thread)d "
"\n \t %(message)s \n"
),
"datefmt": "%Y-%m-%d %H:%M:%S",
}
else:
log_dir = settings_module.get("LOG_DIR_PREFIX", "/app/v3logs/")
rand_str = "".join(random.sample(string.ascii_letters + string.digits, 4))
log_name_prefix = "{}-{}".format(os.getenv("BKPAAS_PROCESS_TYPE"), rand_str)
logging_format = {
"()": "pythonjsonlogger.jsonlogger.JsonFormatter",
"fmt": (
"%(levelname)s %(asctime)s %(pathname)s %(lineno)d " "%(funcName)s %(process)d %(thread)d %(message)s"
),
}
if not os.path.exists(log_dir):
os.makedirs(log_dir)
return {
"version": 1,
"disable_existing_loggers": False,
"formatters": {"verbose": logging_format, "simple": {"format": "%(levelname)s %(message)s"}},
"handlers": {
"null": {"level": "DEBUG", "class": "logging.NullHandler"},
"console": {"level": "DEBUG", "class": "logging.StreamHandler", "formatter": "simple"},
"root": {
"class": log_class,
"formatter": "verbose",
"filename": os.path.join(log_dir, "%s-django.log" % log_name_prefix),
"maxBytes": 1024 * 1024 * 10,
"backupCount": 5,
},
"component": {
"class": log_class,
"formatter": "verbose",
"filename": os.path.join(log_dir, "%s-component.log" % log_name_prefix),
"maxBytes": 1024 * 1024 * 10,
"backupCount": 5,
},
"mysql": {
"class": log_class,
"formatter": "verbose",
"filename": os.path.join(log_dir, "%s-mysql.log" % log_name_prefix),
"maxBytes": 1024 * 1024 * 10,
"backupCount": 5,
},
"celery": {
"class": log_class,
"formatter": "verbose",
"filename": os.path.join(log_dir, "%s-celery.log" % log_name_prefix),
"maxBytes": 1024 * 1024 * 10,
"backupCount": 5,
},
"blueapps": {
"class": log_class,
"formatter": "verbose",
"filename": os.path.join(log_dir, "%s-django.log" % log_name_prefix),
# TODO blueapps log 等待平台提供单独的路径
# log_dir, '%s-blueapps.log' % log_name_prefix),
"maxBytes": 1024 * 1024 * 10,
"backupCount": 5,
},
},
"loggers": {
"django": {"handlers": ["null"], "level": "INFO", "propagate": True},
"django.server": {"handlers": ["console"], "level": log_level, "propagate": True},
"django.request": {"handlers": ["root"], "level": "ERROR", "propagate": True},
"django.db.backends": {"handlers": ["mysql"], "level": log_level, "propagate": True},
# the root logger ,用于整个project的logger
"root": {"handlers": ["root"], "level": log_level, "propagate": True},
# 组件调用日志
"component": {"handlers": ["component"], "level": log_level, "propagate": True},
"celery": {"handlers": ["celery"], "level": log_level, "propagate": True},
# other loggers...
# blueapps
"blueapps": {"handlers": ["blueapps"], "level": log_level, "propagate": True},
# 普通app日志
"app": {"handlers": ["root"], "level": log_level, "propagate": True},
},
}